Commit 2ab5218f authored by GuanHua's avatar GuanHua

fix: APP B端商城装修修改

parent c3f696ac
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="design-iconfont">
<path d="M12,2 C17.5228475,2 22,6.4771525 22,12 C22,17.5228475 17.5228475,22 12,22 C6.4771525,22 2,17.5228475 2,12 C2,6.4771525 6.4771525,2 12,2 Z M12,7 C11.4477153,7 11,7.44771525 11,8 L11,8 L11,11 L8,11 C7.44771525,11 7,11.4477153 7,12 C7,12.5522847 7.44771525,13 8,13 L8,13 L11,13 L11,16 C11,16.5522847 11.4477153,17 12,17 C12.5522847,17 13,16.5522847 13,16 L13,16 L13,13 L16,13 C16.5522847,13 17,12.5522847 17,12 C17,11.4477153 16.5522847,11 16,11 L16,11 L13,11 L13,8 C13,7.44771525 12.5522847,7 12,7 Z" fill="#C8CACD" fill-rule="evenodd"/>
</svg>
import React from 'react';
import { PageConfigType } from '@lingxi-disign/core';
import { BrickDesign } from '@lingxi-disign/react';
import { PageConfigType } from '@lingxi-disign/core';
import { BrickDesign, useSelector } from '@lingxi-disign/react';
interface DesignPanelPropsType {
pageConfig: PageConfigType,
pageConfig?: PageConfigType,
theme: string,
onlyEidt?: boolean,
pageName?: string
}
const DesignPanel: React.FC<DesignPanelPropsType> = (props) => {
const { pageConfig, theme, pageName = 'index', onlyEidt } = props;
const { theme, pageName = 'index', onlyEidt } = props;
const { pageConfig } = useSelector(['pageConfig']);
return <BrickDesign
pageName={pageName}
initState={{ pageConfig }}
......
......@@ -3,7 +3,7 @@ import { PageConfigType } from '@lingxi-disign/core';
import { BrickPreview } from '@lingxi-disign/react';
interface DesignPanelPropsType {
pageConfig: PageConfigType,
pageConfig?: PageConfigType,
theme: string,
onlyEidt?: boolean,
pageName?: string
......
......@@ -6,20 +6,21 @@ import DesignPreview from './DesignPreview';
import styles from './index.less';
import { useSelector } from '@lingxi-disign/react';
interface MobileDesignPanelPropsType {
pageConfig: PageConfigType,
pageConfig?: PageConfigType,
theme: string,
isPreview?: boolean,
onlyEidt?: boolean,
}
const MobileDesignPanel: React.FC<MobileDesignPanelPropsType> = (props) => {
const { theme, isPreview, pageConfig, onlyEidt } = props;
const { theme, isPreview, onlyEidt } = props;
return (
<div className={styles.mobileDesignContainer}>
<div className={styles.mobileDesignWrap}>
{
isPreview ? <DesignPreview theme={theme} pageConfig={pageConfig} /> : <DesignPanel onlyEidt={onlyEidt} theme={theme} pageConfig={pageConfig} />
isPreview ? <DesignPreview theme={theme} /> : <DesignPanel onlyEidt={onlyEidt} theme={theme} />
}
</div>
<div className={styles.appBottom}>
......
.allcomponents_container {
width: 320px;
background-color: #FFF;
.header {
height: 48px;
padding: 0 20px;
line-height: 48px;
color: #303133;
font-size: 16px;
font-weight: bold;
border-bottom: 1px solid #EEF0F3;
}
.components_list {
padding: 16px 0;
display: flex;
flex-direction: column;
}
}
import React from 'react';
import { ModuleTree } from '@lingxi-disign/react'
import styles from './index.less';
const MobileEditLeft = () => {
return (
<div className={styles.allcomponents_container}>
<div className={styles.header}>
<span>我的模块</span>
</div>
<div className={styles.components_list}>
<ModuleTree />
</div>
</div>
);
};
export default MobileEditLeft;
......@@ -6,6 +6,10 @@ import {
const HeaderNav: ComponentSchemaType = {
propsConfig: {
styleType: {
label: "样式",
type: PROPS_TYPES.objectArray
},
children: {
label: '内容',
type: PROPS_TYPES.string,
......@@ -20,6 +24,10 @@ const ActionItem: ComponentSchemaType = {
label: '内容',
type: PROPS_TYPES.string,
},
componentType: {
label: '内容',
type: PROPS_SETTING_TYPES.mobileHeaderNavAction
},
},
};
......
......@@ -64,8 +64,6 @@ export const headerConfig = {
export const bannerConfig = {
'2': {
title: '广告图',
canEdit: false,
canHide: true,
componentName: 'Banner',
props: {
style: {
......@@ -81,8 +79,6 @@ export const bannerConfig = {
export const categoryGuidanceConfig = {
'3': {
title: '品类导航',
canEdit: false,
canHide: true,
componentName: 'MobileNavCard',
props: {
style: {
......@@ -760,12 +756,8 @@ export const suggestProductConfig = {
childNodes: [],
childComponentName: 'SuggestProduct.Items',
addBtnText: '添加分类',
canEdit: false,
canHide: true,
childProps: {
title: '商品容器',
canEdit: false,
canHide: true,
componentName: 'SuggestProduct.Items',
props: {},
childComponentName: 'Commodity',
......@@ -783,8 +775,6 @@ export const bottomNavigationConfig = {
childNodes: [],
childComponentName: 'BottomNavigation.Items',
addBtnText: '添加标签',
canEdit: false,
canHide: true,
},
};
......
import { PROPS_SETTING_TYPES } from '@lingxi-disign/core'
import { PROPS_SETTING_TYPES, PageConfigType } from '@lingxi-disign/core'
import { resolveMappingPageConfig } from '@lingxi-disign/react'
import styleThemeImgDefault from './imgs/style_theme_default.png'
import styleThemeImgScience from './imgs/style_theme_science.png'
......@@ -6,70 +7,78 @@ import mineIcon from './imgs/mine_icon.png'
import orderIcon from './imgs/order_icon.png'
import kefuIcon from './imgs/kefu_icon.png'
export const mallLayoutConfig = {
key: "0",
"0": {
"componentName": "MallLayout",
"props": {
"style": {
"width": "100%",
"minHeight": "100%",
"background": "#F7F8FA",
"overflowX": "hidden",
"paddingBottom": "50px",
}
},
"childNodes": ["1", "5", "6", "7", "8", "9", "10"]
const categoryList = [
{
value: 1,
label: "建材"
},
}
{
value: 2,
label: "热卷"
},
{
value: 3,
label: "冷镀"
},
{
value: 4,
label: "中厚板"
},
{
value: 5,
label: "型管"
}
]
export const divWrap = {
key: "1",
"1": {
"componentName": "div",
"props": {
"style": {
"width": "100%",
"background": "#FFF",
}
},
"childNodes": ["2", "3"]
const defaultHeaderNavData = [
{
name: "我的",
content: "",
status: true,
type: 1
},
{
name: "进货单",
content: "",
status: true,
type: 2
},
{
name: "客服",
content: "",
status: true,
type: 3
},
{
name: "搜索框",
content: "灯具",
status: true,
type: 4
}
}
]
export const mobileHeaderNav = {
key: "2",
"2": {
"componentName": "MobileHeaderNav",
"componentType": PROPS_SETTING_TYPES.mobileHeaderNav,
"title": "顶部导航",
"canEdit": true,
"canHide": false,
"props": {
styleTheme: 0,
dataList: [
{
name: "我的",
content: mineIcon,
status: true,
},
{
name: "进货单",
content: orderIcon,
status: true,
},
{
name: "客服",
content: kefuIcon,
status: true,
},
{
name: "搜索框",
content: "",
status: true,
}
],
stylesThemeList: [
export const defaultConfig: PageConfigType = {
'0': {
componentName: 'MallLayout',
props: {
style: {
width: '100%',
minHeight: '100%',
background: '#F7F8FA',
overflowX: 'hidden',
paddingBottom: '56px',
position: 'relative',
},
},
childNodes: ["1"]
},
'1': {
title: '头部导航栏',
componentName: 'HeaderNav',
props: {
styleTheme: 1,
categoryList: categoryList,
stylesthemelist: [
{
key: 0,
img: styleThemeImgDefault,
......@@ -80,9 +89,68 @@ export const mobileHeaderNav = {
}
]
},
childNodes: ['2'],
childComponentName: 'HeaderNav.ActionItem',
},
'2': {
loop: '${headerNav}',
title: '${item.name}',
hideActions: true,
componentName: 'HeaderNav.ActionItem',
props: {
data: '${item}'
},
},
}
const allState = { headerNav: defaultHeaderNavData }
export const moduleConfig = resolveMappingPageConfig(defaultConfig, allState)
console.log(moduleConfig, 'moduleConfig')
export const mallLayoutConfig = {
'0': {
componentName: 'MallLayout',
props: {
style: {
width: '100%',
minHeight: '100%',
background: '#F7F8FA',
overflowX: 'hidden',
paddingBottom: '56px',
position: 'relative',
},
},
childNodes: ["1", "5", "6", "7", "8", "9", "10"]
}
}
export const divWrap = {
1: {
componentName: "div",
props: {
style: {
width: "100%",
background: "#FFF",
}
},
childNodes: ["2", "3"]
}
}
export const mobileHeaderNav = {
2: {
title: '头部导航栏',
canEdit: false,
canHide: true,
componentName: 'HeaderNav',
props: {},
childNodes: [],
childComponentName: 'HeaderNav.ActionItem',
},
}
export const bannerWrap = {
key: "3",
"3": {
......
import React, { useEffect, useState } from 'react';
import { BrickProvider } from '@lingxi-disign/react';
import { updatePageConfig } from '@lingxi-disign/core'
import { message } from 'antd';
import { PublicApi } from '@/services/api';
import { GetTemplateAdornAppEnterpriseFindResponse } from '@/services/TemplateApi';
import {
moduleConfig,
mallLayoutConfig,
divWrap,
bannerWrap,
......@@ -19,7 +21,7 @@ import {
import styles from './index.less';
import ToolBar from '../components/toolBar';
import MobileDesignPanel from '../components/MobileDesignPanel';
import AllComponents from '../components/ComponentsPreview';
import MobileEditLeft from '../components/mobileEditLeft'
import config from '../configs';
import Loading from '../components/Loading';
// import { GlobalConfig } from '@/global/config'
......@@ -54,14 +56,24 @@ const appMallEdit: React.FC<ShopPreviewPropsType> = (props) => {
};
useEffect(() => {
if (!TemplateList.includes(template)) {
setTheme(`theme-mall-${TemplateList[0]}`);
} else {
setTheme(`theme-mall-${template}`);
}
getComponentsConfig();
initConfig()
// getComponentsConfig();
}, []);
const initConfig = () => {
setTimeout(() => {
setLoading(false)
updatePageConfig(moduleConfig)
}, 2000);
}
/**
* 获取app企业商城装修信息
*/
......@@ -268,10 +280,10 @@ const appMallEdit: React.FC<ShopPreviewPropsType> = (props) => {
<div className={styles['wrapper']}>
<ToolBar type={1} title="APP首页" showActions={true} templateId={id} />
<div className={styles['content']}>
<AllComponents />
<MobileEditLeft />
<div className={styles['app-wrapper']}>
<div className={styles['app-canvas-container']}>
<MobileDesignPanel theme={theme} onlyEidt pageConfig={componentConfigs} />
<MobileDesignPanel theme={theme} onlyEidt />
</div>
</div>
<MobileSettingPanel />
......
......@@ -21,6 +21,7 @@ const MobileSettingPanel: React.FC = ()=> {
const [ newSelectInfo, setNewSelectInfo ] = useState<SelectedInfoType>();
useEffect(() => {
console.log(pageConfig, 'pageConfig')
const updateSelectInfo = () => {
if(selectedInfo) {
const { props: oldProps ,selectedKey } = selectedInfo;
......@@ -40,9 +41,13 @@ const MobileSettingPanel: React.FC = ()=> {
defaultActiveKey="1"
className={styles.settingTabs}
>
<TabPane tab="编辑" key="props">
<PropsSettings selectedInfo={newSelectInfo} />
</TabPane>
{
(propsConfig && propsConfig.componentType) && (
<TabPane tab={propsConfig.componentType.label || '编辑'} key="props">
<PropsSettings selectedInfo={newSelectInfo} />
</TabPane>
)
}
{
(propsConfig && propsConfig.styleType) && (
<TabPane tab="样式" key="style">
......
@import "../../common.less";
.banner {
&-box {
margin-bottom: 16px;
:global {
.ant-upload {
width: 100%;
}
}
&-label {
font-size: 12px;
color: #91959B;
margin-bottom: 8px;
}
&-icon {
height: 96px;
background-color: #FAFBFC;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
&>img {
width: 100%;
}
&-add {
width: 24px;
height: 24px;
}
&:hover {
.banner-box-icon-cover {
display: block;
}
}
&-cover {
position: absolute;
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, .1);
display: none;
z-index: 1;
&-delete {
position: absolute;
right: 10px;
top: 10px;
font-size: 20px;
color: #fff;
}
&-bottom {
position: absolute;
height: 24px;
line-height: 24px;
text-align: center;
background-color: rgba(0, 0, 0, 0.24);
font-size: 12px;
color: #fff;
width: 100%;
bottom: 0;
left: 0;
}
}
}
}
&-record {
&-shop {
height: 56px;
border: 1px solid #EDEEEF;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 0 8px;
img {
width: 40px;
height: 40px;
margin-right: 8px;
}
span {
flex: 1;
color: #303133;
font-size: 12px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
&-integral {
height: 56px;
border: 1px solid #EDEEEF;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 0 8px;
img {
width: 40px;
height: 40px;
margin-right: 8px;
}
&-right {
flex: 1;
display: flex;
flex-direction: column;
&-top {
flex: 1;
color: #303133;
font-size: 12px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
&-bottom {
flex: 1;
color: #EA8000;
font-size: 12px;
}
}
}
&-activity {
height: 56px;
border: 1px solid #EDEEEF;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 0 8px;
position: relative;
img {
width: 40px;
height: 40px;
border-radius: 4px;
margin-right: 8px;
}
&-right {
flex: 1;
display: flex;
flex-direction: column;
font-size: 12px;
&-top {
flex: 1;
color: #303133;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
&-bottom {
flex: 1;
color: #91959B;
}
}
&-tag{
position: absolute;
right: 0;
top: -3px;
}
}
}
}
import React, { useMemo, useState, useEffect } from 'react';
import { Input, Select, Row, Col, Button, Tooltip } from 'antd';
import { PlusCircleOutlined, DeleteOutlined } from '@ant-design/icons';
import { changeProps } from '@lingxi-disign/core';
import { PublicApi } from '@/services/api';
import UploadImage from '@/components/UploadImage';
import StatusTag from '@/components/StatusTag'
import { priceFormat } from '@/utils/numberFomat';
import MixDrawer from '@/pages/pageCustomized/Drawers/MixDrawer';
import ActivityDrawer from '@/pages/pageCustomized/Drawers/ActivityDrawer';
import uploadImgIcon from '@/asserts/icons/upload_img_icon.svg'
import styles from './index.less';
interface BannerClientProps {
// 名称
name?: string,
// 图片
img?: any,
// 跳转类型
type?: any,
// 跳转类型的id
id?: any,
// 当前选中组件的key
selectedKey?: any,
// 1.B端 2.C端 3.SRM
property?: 1 | 2 | 3
}
const RedirectTypeList_C = [
{
value: 1,
label: '商品详情',
},
{
value: 2,
label: '活动主页',
},
{
value: 3,
label: '积分详情',
},
{
value: 4,
label: '店铺主页',
},
{
value: 5,
label: '不跳转',
},
];
const RedirectTypeList_B = [
{
value: 1,
label: '商品详情',
},
{
value: 2,
label: '活动主页',
},
{
value: 3,
label: '积分详情',
},
{
value: 4,
label: '店铺主页',
},
{
value: 5,
label: '资讯详情',
},
{
value: 6,
label: '不跳转',
},
];
const HeaderNavAction: React.FC<BannerClientProps> = (props: BannerClientProps) => {
const { name, img, id, type, property = 2, selectedKey } = props;
const [mixVisible, setMixVisible] = useState<boolean>(false);
const [actVisible, setActVisible] = useState<boolean>(false);
const [record, setRecord] = useState<any>();
const _fetch: any = useMemo(() => {
switch (type) {
case 1:
case 3:
return PublicApi.getProductCommodityGetCommodity
case 2:
return PublicApi.getTemplateWebActivityPageGet
case 4:
return PublicApi.getTemplateWebMemberShopWebFindById
}
return async () => { }
}, [type])
const _isNull = (list) => {
let _flag = true;
for (let key in list) {
if (list[key]) {
_flag = false
}
}
return _flag;
}
useEffect(() => {
switch (type) {
case 1:
case 2:
case 3:
case 4:
id && _fetch?.({ id: id }).then((res) => {
if (res.code === 1000) {
setRecord(res.data)
}
}).catch(_ => setRecord(''));
break;
default:
setRecord('')
break;
}
}, [_fetch, id, type])
const _selectOption = useMemo(() => {
if (property === 1) {
return RedirectTypeList_B
}
if (property === 2) {
return RedirectTypeList_C
}
}, [property])
const _recordDetail = useMemo(() => {
if (record) {
if (type === 2) {
return (
<div className={styles['banner-record-activity']}>
<img src={record?.templatePicUrl} />
<div className={styles['banner-record-activity-right']}>
<Tooltip title={record?.name}>
<div className={styles['banner-record-activity-right-top']}>{record?.name}</div>
</Tooltip>
{record?.type === 2 && <div className={styles['banner-record-activity-right-bottom']}>{record?.memberName}</div>}
</div>
<div className={styles['banner-record-activity-tag']}><StatusTag title={record?.type === 1 ? '平台' : '商家'} type={record?.type === 1 ? 'success' : 'primary'} /></div>
</div>
)
}
if (type === 3) {
return (
<div className={styles['banner-record-integral']}>
<img src={record?.mainPic} />
<div className={styles['banner-record-integral-right']}>
<Tooltip title={record?.name}>
<div className={styles['banner-record-integral-right-top']}>{record?.name}</div>
</Tooltip>
<div className={styles['banner-record-integral-right-bottom']}>{priceFormat(record?.unitPrice?.['0-0'])} 积分</div>
</div>
</div>
)
}
if (type === 4) {
return (
<div className={styles['banner-record-shop']}>
<img src={record?.logo} />
<Tooltip title={record?.memberName}>
<span>{record?.memberName}</span>
</Tooltip>
</div>
)
}
}
}, [type, record])
const _showChoose = useMemo(() => {
if (property === 1 && type === 6) {
return false
}
if (property === 2 && type === 5) {
return false
}
return true;
}, [type, property])
const _onChangeName = (e: any) => {
const _val = e.target.value;
changeProps({
title: _val || '',
props: Object.assign({ ...props }, { name: _val, isnull: _isNull([_val, img, type]) })
});
}
const _onChangeType = (value: any) => {
changeProps({
props: Object.assign({ ...props }, { type: value, isnull: _isNull([name, img, value]) }, !_showChoose ? { id: '' } : {})
});
}
const _onChangeImg = (url: any) => {
changeProps({
props: Object.assign({ ...props }, { img: url, isnull: _isNull([name, url, type]) })
});
}
const _onShopClose = () => {
setMixVisible(false);
}
const _onActClose = () => {
setActVisible(false);
}
const _onChoose = () => {
switch (type) {
case 2:
setActVisible(true);
break;
case 3:
case 4:
setMixVisible(true);
break;
}
}
const _onChooseConfirm = (record) => {
setRecord(record);
switch (type) {
case 2:
changeProps({
props: Object.assign({ ...props }, { id: record.id, isnull: _isNull([name, img, type]) })
});
_onActClose();
break;
case 3:
case 4:
changeProps({
props: Object.assign({ ...props }, { id: record.id, isnull: _isNull([name, img, type]) })
});
_onShopClose()
break;
}
}
return (
<div className={styles['banner']}>
<div className={styles['banner-box']}>
<div className={styles['banner-box-label']}>名称</div>
<Input key={`${selectedKey}-name`} defaultValue={name} onChange={_onChangeName} />
</div>
<div className={styles['banner-box']}>
<div className={styles['banner-box-label']}>图片</div>
{img ? (
<div className={styles['banner-box-icon']}>
<img src={img} />
<div className={styles['banner-box-icon-cover']}>
<UploadImage
onChange={(url) => { _onChangeImg(url) }}
listType="text"
>
<div className={styles['banner-box-icon-cover-bottom']}>
添加图像
</div>
</UploadImage>
<DeleteOutlined className={styles['banner-box-icon-cover-delete']} onClick={() => { _onChangeImg('') }} />
</div>
</div>
) : (
<UploadImage
onChange={(url) => { _onChangeImg(url) }}
listType="text"
>
<div className={styles['banner-box-icon']}>
<img src={uploadImgIcon} className={styles['banner-box-icon-add']} />
<div className={styles['banner-box-icon-cover']}>
<div className={styles['banner-box-icon-cover-bottom']}>
添加图像
</div>
</div>
</div>
</UploadImage>
)}
</div>
<div className={styles['banner-box']}>
<div className={styles['banner-box-label']}>跳转链接</div>
<Row gutter={20} style={{ marginBottom: 16 }}>
<Col span={18}>
<Select key={`${selectedKey}-type`} defaultValue={type} onChange={_onChangeType} style={{ width: '100%' }} >
{
_selectOption?.map(selectItem => <Select.Option value={selectItem.value} key={`redirect_type_${selectItem.value}`}>{selectItem.label}</Select.Option>)
}
</Select>
</Col>
{_showChoose && <Col span={6}>
<Button block onClick={_onChoose}>选择</Button>
</Col>}
</Row>
{_recordDetail}
</div>
<MixDrawer
onClose={_onShopClose}
property={property}
type={type}
onConfirm={_onChooseConfirm}
visible={mixVisible}
/>
<ActivityDrawer
selectId={id}
visible={actVisible}
onClose={_onActClose}
onConfirm={_onChooseConfirm}
/>
</div>
)
}
export default HeaderNavAction
import React from 'react';
import { SelectedInfoType, PROPS_SETTING_TYPES } from '@lingxi-disign/core';
import HeaderNav from './components/headerNav';
import HeaderNavAction from './components/headerNavAction'
import Banner from './components/banner';
import QuickNav from './components/quickNav';
import ShowCase from './components/showCase';
......@@ -54,6 +55,8 @@ const PropsSettings: React.FC<PropsSettingsPropsType> = (props) => {
return <BannerClient {..._props} />
case PROPS_SETTING_TYPES.suggestProductItems:
return <SuggestProduct {..._props} />
case PROPS_SETTING_TYPES.mobileHeaderNavAction:
return <HeaderNavAction {..._props} />
default:
return null;
}
......
......@@ -28,7 +28,7 @@ const StyleSettings: React.FC<StyleSettingsPropsType> = ({ selectedInfo }) => {
<div className={styles.styleSettings}>
<div className={styles.styleList}>
{
(selectProps && selectProps.stylesThemeList) && selectProps.stylesThemeList.map(item => (
(selectProps && selectProps.stylesthemelist) && selectProps.stylesthemelist.map(item => (
<div className={cx(styles.styleItem, selectKey === item.key ? styles.active : {})} key={item.key} onClick={() => handleChangeStyleTheme(item.key)}>
<img className={styles.themeImg} src={item.img} title={item.key} />
</div>
......
......@@ -10,7 +10,7 @@
--category_content_title_text: #303133;
--category_content_title_text_hover: #00B37A;
--category_content_sub_title_text: #606266;
overflow-x: hidden;
}
// 渠道科技类模板
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment