Commit 9281f52e authored by GuanHua's avatar GuanHua

feat: 渠道商城装修开发

parent adb1511c
......@@ -4,14 +4,13 @@ import { cloneDeep } from 'lodash';
import { updatePageConfig, STATE_PROPS, SelectedInfoType, PageConfigType } from '@lingxi-disign/core';
import { useSelector } from '@lingxi-disign/react';
import * as MarketingConfigs from '../../../mobileTemplate/shopTemplateEdit/marketing_config';
import styles from './index.less';
interface MarketingSwitchProps {
type: number,
title: string,
icon: any
icon: any,
marketConfigs: any,
}
type SettingPanelType = {
......@@ -20,14 +19,14 @@ type SettingPanelType = {
}
const MarketingSwitch: React.FC<MarketingSwitchProps> = (props: any) => {
const { type, title, icon } = props;
const { type, title, icon, marketConfigs } = props;
const { pageConfig } = useSelector<SettingPanelType, STATE_PROPS>(['pageConfig']);
const _checked = Object.keys(pageConfig).indexOf(`11-${type}`) >= 0;
const _onChange = useCallback((checked: boolean) => {
if (checked) {
let _pageConfig: any = { ...pageConfig }
const _marketingConfig = MarketingConfigs[`marketingConfig_${type}`];
const _marketingConfig = marketConfigs[`marketingConfig_${type}`];
_pageConfig = cloneDeep({ ..._pageConfig, ..._marketingConfig });
const _insertIndex = _pageConfig['0'].childNodes.indexOf('10');
_pageConfig['0'].childNodes?.splice(_insertIndex, 0, `11-${type}`);
......
......@@ -27,10 +27,11 @@ export interface VirtualDOMType {
}
interface MobileClientEditLeftProps {
marketConfigs: any
}
const MobileClientEditLeft: React.FC<MobileClientEditLeftProps> = (props: MobileClientEditLeftProps) => {
const { marketConfigs } = props
return (
<div className={styles.edit_container}>
<Tabs type="card">
......@@ -39,7 +40,7 @@ const MobileClientEditLeft: React.FC<MobileClientEditLeftProps> = (props: Mobile
</TabPane>
<TabPane tab="全部模块" key="2">
<Row gutter={16}>
{ICONS_CONFIG.map((item, index) => <Col key={index} span={12} style={{ marginBottom: 16 }}><MarketingSwitch {...item} /></Col>)}
{ICONS_CONFIG.map((item, index) => <Col key={index} span={12} style={{ marginBottom: 16 }}><MarketingSwitch marketConfigs={marketConfigs} {...item} /></Col>)}
</Row>
</TabPane>
</Tabs>
......
import {
ComponentSchemaType,
PROPS_SETTING_TYPES,
PROPS_TYPES,
} from '@lingxi-disign/core';
const ChannelHeaderNav: ComponentSchemaType = {
propsConfig: {
styleType: {
label: "样式",
type: PROPS_TYPES.objectArray
},
children: {
label: '内容',
type: PROPS_TYPES.string,
},
},
};
const ActionItem: ComponentSchemaType = {
fatherNodesRule: ['ChannelHeaderNav.children'],
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
componentType: {
label: '内容',
type: PROPS_SETTING_TYPES.mobileHeaderNavAction
},
},
};
export default {
ChannelHeaderNav,
'ChannelHeaderNav.ActionItem': ActionItem,
};
import {
ComponentSchemaType,
PROPS_SETTING_TYPES,
PROPS_TYPES,
} from '@lingxi-disign/core';
const HeaderNav: ComponentSchemaType = {
propsConfig: {
styleType: {
label: "样式",
type: PROPS_TYPES.objectArray
},
children: {
label: '内容',
type: PROPS_TYPES.string,
},
},
};
const ActionItem: ComponentSchemaType = {
fatherNodesRule: ['HeaderNav.children'],
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
componentType: {
label: '内容',
type: PROPS_SETTING_TYPES.mobileHeaderNavAction
},
},
};
export default {
HeaderNav,
'HeaderNav.ActionItem': ActionItem,
};
import { ComponentSchemaType, PROPS_TYPES } from '@lingxi-disign/core';
const InfromationCard: ComponentSchemaType = {
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
},
};
export default InfromationCard;
......@@ -26,6 +26,19 @@ const Header: ComponentSchemaType = {
},
};
const ChannelHeader: ComponentSchemaType = {
fatherNodesRule: ['MarketingCard.children'],
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
componentType: {
type: PROPS_SETTING_TYPES.marketingCardHeader,
},
},
};
const ShopHeader: ComponentSchemaType = {
fatherNodesRule: ['MarketingCard.children'],
propsConfig: {
......@@ -158,6 +171,7 @@ export default {
MarketingCard,
'MarketingCard.Header': Header,
'MarketingCard.ShopHeader': ShopHeader,
'MarketingCard.ChannelHeader': ChannelHeader,
'MarketingCard.CommonContainer': CommonContainer,
'MarketingCard.VerticalContainer': VerticalContainer,
'MarketingCard.CollageContainer': CollageContainer,
......
import {
ComponentSchemaType,
PROPS_SETTING_TYPES,
PROPS_TYPES,
} from '@lingxi-disign/core';
const SuggestProduct: ComponentSchemaType = {
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
},
};
const SuggestProductItems: ComponentSchemaType = {
fatherNodesRule: ['SuggestProduct.children'],
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
componentType: {
type: PROPS_SETTING_TYPES.suggestProductItems,
},
},
};
const SuggestProductCommodity: ComponentSchemaType = {
fatherNodesRule: ['SuggestProduct.Items.children'],
propsConfig: {
children: {
label: '内容',
type: PROPS_TYPES.string,
},
componentType: {
type: PROPS_SETTING_TYPES.suggestProductCommodity,
},
},
};
export default {
SuggestProduct,
'SuggestProduct.Items': SuggestProductItems,
'SuggestProduct.Commodity' : SuggestProductCommodity
};
......@@ -50,6 +50,10 @@ import MobileShopCommodity from './MobileShopCommodity'
import CouponsModal from './CouponsModal'
import MarketingCard from './MarketingCard'
import BottomNavigation from './BottomNavigation'
import HeaderNav from './HeaderNav'
import ChannelHeaderNav from './ChannelHeaderNav'
import InformationCard from './InformationCard'
import SuggestProduct from './SuggestProduct'
export default {
View,
......@@ -94,5 +98,9 @@ export default {
...MobileShopCommodity,
...CouponsModal,
...MarketingCard,
...BottomNavigation
...BottomNavigation,
...HeaderNav,
...ChannelHeaderNav,
InformationCard,
...SuggestProduct,
}
@import "../../common.less";
.suggestProduct {
&-box {
margin-bottom: 16px;
&-label {
font-size: 12px;
color: #91959B;
margin-bottom: 8px;
}
}
}
import React from 'react';
import { Input, Radio,Space } from 'antd';
import { changeProps } from '@lingxi-disign/core';
import styles from './index.less';
interface SuggestProductProps {
title?: string,
explain?: string,
type?: number,
num?: number,
customize?: any,
// 当前选中组件的key
selectedKey?: any
}
const SuggestProduct: React.FC<SuggestProductProps> = (props: SuggestProductProps) => {
const { title, explain, type, num, customize, selectedKey } = props;
const _isNull = (list) => {
let _number = 0;
for (let key in list) {
if (list[key]) {
_number += 1
}
}
return _number === list.length ? false : true;
}
const _onChangeTitle = (e: any) => {
const _val = e.target.value;
changeProps({
title: _val || '',
props: Object.assign({ ...props }, { title: _val, isnull: _isNull([_val, explain, type]) })
});
}
const _onChangeExplain = (e: any) => {
const _val = e.target.value;
changeProps({
props: Object.assign({ ...props }, { explain: _val, isnull: _isNull([title, _val, type]) })
});
}
const _onChangeType = (e: any) => {
const _val = e.target.value;
changeProps({
props: Object.assign({ ...props }, { type: _val, isnull: _isNull([title, explain, _val]) }),
addBtnText:_val === 3 ? '添加商品' : '',
});
}
const _onChangeNum = (e: any) => {
const _val = e.target.value.replace(/[^\d]/g,'');
changeProps({
props: Object.assign({ ...props }, { num: _val, isnull: _isNull([title, explain, type]) }),
maxLength: _val
});
}
return (
<div className={styles['suggestProduct']}>
<div className={styles['suggestProduct-box']}>
<div className={styles['suggestProduct-box-label']}>标题</div>
<Input key={`${selectedKey}-title`} defaultValue={title} onBlur={_onChangeTitle} maxLength={8} />
</div>
<div className={styles['suggestProduct-box']}>
<div className={styles['suggestProduct-box-label']}>标题说明</div>
<Input key={`${selectedKey}-explain`} defaultValue={explain} onBlur={_onChangeExplain} maxLength={16} />
</div>
<div className={styles['suggestProduct-box']}>
<div className={styles['suggestProduct-box-label']}>商品展示</div>
<Radio.Group key={`${selectedKey}-type`} onChange={_onChangeType} defaultValue={type}>
<Space direction="vertical">
<Radio value={1}>自动按销量排行展示 (从高到低)</Radio>
<Radio value={2}>自动按上架时间排序 (从新到旧)</Radio>
<Radio value={3}>自定义商品</Radio>
</Space>
</Radio.Group>
</div>
<div className={styles['suggestProduct-box']}>
<div className={styles['suggestProduct-box-label']}>展示数量</div>
<Input key={`${selectedKey}-num`} defaultValue={num} onBlur={_onChangeNum} />
</div>
</div>
)
}
export default SuggestProduct
@import "../../common.less";
.suggestProductCommodity {
&-box {
margin-bottom: 16px;
&-label {
font-size: 12px;
color: #91959B;
margin-bottom: 8px;
}
}
&-detail {
height: 80px;
border: 1px solid #F7F8FA;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 6px 8px;
margin-bottom: 16px;
position: relative;
overflow: hidden;
img {
height: 60px;
width: 60px;
margin-right: 10px;
}
&-right {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
&-title {
color: #303133;
font-size: 12px;
word-break: break-all;
overflow: hidden; // 超出的文本隐藏
text-overflow: ellipsis;
display: -webkit-box; // 将对象作为弹性伸缩盒子模型显示。
-webkit-box-orient: vertical; //从上到下垂直排列子元素(设置伸缩盒子的子元素排列方式)
-webkit-line-clamp: 2; // 结合上面两个属性,表示显示的行数。
}
&-price {
color: #D32F2F;
font-size: 14px;
}
}
&:hover {
.suggestProductCommodity-detail-cover {
display: block;
}
}
&-cover {
position: absolute;
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, .1);
display: none;
z-index: 1;
cursor: pointer;
&-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;
}
}
}
&-activityList {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
margin-bottom: 8px;
cursor: pointer;
img {
width: 24px;
height: 24px;
}
&-name {
flex: 1;
font-size: 12px;
color: #303133;
margin: 0 8px;
word-break: break-all;
overflow: hidden; // 超出的文本隐藏
text-overflow: ellipsis;
}
}
}
.site-tag-plus {
background: #fff;
border-style: dashed;
}
.edit-tag {
user-select: none;
}
.tag-input {
width: 78px;
margin-right: 8px;
vertical-align: top;
}
import React, { useState, useEffect, useRef } from 'react';
import { history } from 'umi';
import { Input, Button, Tag, Tooltip } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import { changeProps } from '@lingxi-disign/core';
import StatusTag from '@/components/StatusTag'
import { PublicApi } from '@/services/api';
import CommodityDrawer from '@/pages/editor/components/drawer/commodityDrawer';
import ActivityImage from '@/assets/couponIcons/ActivityImage.svg';
import { priceFormat } from '@/utils/numberFomat'
import styles from './index.less';
interface SuggestProductCommodityProps {
id?: any,
tags?: any,
// 当前选中组件的key
selectedKey?: any
}
const SuggestProductCommodity: React.FC<SuggestProductCommodityProps> = (props: SuggestProductCommodityProps) => {
const { id, tags, selectedKey } = props;
const { query: { shopId } }: any = history.location
const [record, setRecord] = useState<any>([]);
const [commodityVisible, setCommodityVisible] = useState(false);
const [inputVisible, setInputVisible] = useState(false);
const saveEditInputRef = useRef<any>({});
const saveInputRef = useRef<any>({});
const [editInputIndex, setEditInputIndex] = useState(-1);
const [editInputValue, setEditInputValue] = useState<any>('');
const [inputValue, setInputValue] = useState<any>('');
useEffect(() => {
if (id && id != record[0]?.id) {
const _params: any = {
shopId,
idInList: id,
current: 1,
pageSize: 10
}
PublicApi.getMarketingAdornGoodsListAdorn(_params).then((res) => {
if (res.code === 1000) {
setRecord(res.data.data);
}
}).catch(err => console.log(err))
} else if (!id) {
setRecord([]);
}
}, [id])
const onOk = (data: any) => {
setRecord(data);
const _data = data;
changeProps({
title: _data.name,
props: Object.assign({ ...props }, { ..._data, name: _data.name, image: _data.mainPic, mode: 'vertical', discountPrice: priceFormat(_data.min), buyBtn: false })
});
setCommodityVisible(false);
};
const _onCommodityClose = () => {
setCommodityVisible(false);
}
const _showInput = () => {
setInputVisible(true)
}
const _handleClose = (removedTag: any) => {
const _tags = tags?.filter(tag => tag !== removedTag);
changeProps({
props: Object.assign({ ...props }, { tags: _tags })
});
};
useEffect(() => {
if (inputVisible) {
saveInputRef?.current?.focus();
}
}, [inputVisible])
useEffect(() => {
if (editInputIndex > -1 && editInputValue) {
saveEditInputRef?.current?.focus();
}
}, [editInputIndex, editInputValue])
const _handleEditInputChange = (e: any) => {
setEditInputValue(e.target.value);
}
const _handleEditInputConfirm = () => {
const newTags = [...tags];
newTags[editInputIndex] = editInputValue;
setEditInputIndex(-1);
setEditInputValue('');
changeProps({
props: Object.assign({ ...props }, { tags: newTags })
});
}
const _handleInputChange = (e: any) => {
setInputValue(e.target.value);
}
const _handleInputConfirm = () => {
let _tags = tags ? [...tags] : [];
if (inputValue && _tags.indexOf(inputValue) === -1) {
_tags = [..._tags, inputValue];
}
setInputVisible(false);
setInputValue('');
changeProps({
props: Object.assign({ ...props }, { tags: _tags })
});
};
const _handleToDetailPage = (id, belongType) => {
if (belongType === 1) {
window.open(`/marketing/marketingSearch/preview?id=${id}`);
} else {
window.open(`/marketingManage/merchantMarketing/merchantMarketingSearch/preview?id=${id}`);
}
}
const _record = record[0];
return (
<div className={styles['suggestProductCommodity']}>
{id && record ? (
<>
<div className={styles['suggestProductCommodity-detail']}>
<img src={_record?.mainPic} />
<div className={styles['suggestProductCommodity-detail-right']}>
<Tooltip title={_record?.name}>
<div className={styles['suggestProductCommodity-detail-right-title']}>{_record?.name}</div>
</Tooltip>
<div className={styles['suggestProductCommodity-detail-right-price']}>{_record?.min ? `¥ ${priceFormat(_record?.min)}` : ''}</div>
</div>
<div className={styles['suggestProductCommodity-detail-cover']} onClick={() => { setCommodityVisible(true) }}>
<div className={styles['suggestProductCommodity-detail-cover-bottom']}>
更换商品
</div>
</div>
</div>
<div className={styles['suggestProductCommodity-box']}>
<div className={styles['suggestProductCommodity-box-label']}>商品活动</div>
{_record?.activityList?.map((item, index) => {
return (
<div className={styles['suggestProductCommodity-activityList']} key={index} onClick={() => { _handleToDetailPage(item.id, item.belongType) }}>
<img src={ActivityImage} />
<div className={styles['suggestProductCommodity-activityList-name']}>{item.name}</div>
<StatusTag title={item.type} type='danger' />
</div>
)
})}
</div>
<div className={styles['suggestProductCommodity-box']}>
<div className={styles['suggestProductCommodity-box-label']}>活动标签</div>
<>
{tags?.map((tag, index) => {
if (editInputIndex === index) {
return (
<Input
ref={saveEditInputRef}
key={index}
size="small"
className={styles['tag-input']}
defaultValue={editInputValue}
onChange={_handleEditInputChange}
onBlur={_handleEditInputConfirm}
onPressEnter={_handleEditInputConfirm}
/>
);
}
const isLongTag = tag.length > 20;
const tagElem = (
<Tag
className={styles['edit-tag']}
key={tag}
closable
onClose={() => _handleClose(tag)}
color='red'
>
<span
onDoubleClick={e => {
if (index !== 0) {
setEditInputIndex(index);
setEditInputValue(tag);
e.preventDefault();
}
}}
>
{isLongTag ? `${tag.slice(0, 20)}...` : tag}
</span>
</Tag>
);
return isLongTag ? (
<Tooltip title={tag} key={tag}>
{tagElem}
</Tooltip>
) : (
tagElem
);
})}
{inputVisible && (
<Input
ref={saveInputRef}
type="text"
size="small"
className={styles['tag-input']}
defaultValue={inputValue}
onChange={_handleInputChange}
onBlur={_handleInputConfirm}
onPressEnter={_handleInputConfirm}
/>
)}
{!inputVisible && (
<Tag className={styles['site-tag-plus']} onClick={_showInput}>
<PlusOutlined /> 新增标签
</Tag>
)}
</>
</div>
</>
) : (<Button onClick={() => { setCommodityVisible(true) }}>选择商品</Button>)}
<CommodityDrawer
selectId={id}
visible={commodityVisible}
onClose={_onCommodityClose}
onConfirm={onOk}
/>
</div>
)
}
export default SuggestProductCommodity
......@@ -14,6 +14,8 @@ import MarketingCardCoupon from './components/marketingCardCoupon';
import MarketingCardGood from './components/marketingCardGood'
import MarketingCardHeader from './components/marketingCardHeader'
import BottomNavigationClient from './components/bottomNavigationClient'
import SuggestProduct from './components/suggestProduct'
import SuggestProductCommodity from './components/suggestProductCommodity'
import { LAYOUT_TYPE } from '@/constants'
import styles from './index.less'
......@@ -68,6 +70,10 @@ const PropsSettings: React.FC<PropsSettingsPropsType> = (props) => {
return <MarketingCardGood {..._props} actType={_type} exType={_exType} pageConfig={pageConfig} />
case PROPS_SETTING_TYPES.bottomNavigationItems:
return <BottomNavigationClient {..._props} />
case PROPS_SETTING_TYPES.suggestProductItems:
return <SuggestProduct {..._props} />
case PROPS_SETTING_TYPES.suggestProductCommodity:
return <SuggestProductCommodity {..._props} />
default:
return null
}
......
......@@ -6,9 +6,194 @@
* @Description: In User Settings Edit
* @FilePath: /lingxi-business-paltform/src/pages/mobileTemplate/channelTemplateEdit/config.ts
*/
import { PROPS_SETTING_TYPES } from '@lingxi-disign/core'
import { PROPS_SETTING_TYPES, PageConfigType } from '@lingxi-disign/core'
import categoryNavTemplateDefault from '../shopTemplateEdit/img/category_template_default.png'
import styleThemeImgDefault from './imgs/style_theme_default.png'
import styleThemeImgScience from './imgs/style_theme_science.png'
import RED_PACKAGE from '../shopTemplateEdit/img/red_package.png';
export const defaultHeaderNavData = [
{
name: "我的",
content: "",
status: true,
type: 1
},
]
export const channelLayoutConfig : PageConfigType = {
'0': {
componentName: 'MallLayout',
props: {
style: {
"width": "100%",
"minHeight": "100%",
"background": "#F7F8FA",
"overflowX": "hidden",
"paddingBottom": "50px",
}
},
childNodes: ['1', '3', '5', '7']
},
'1': {
title: '头部导航栏',
componentName: 'ChannelHeaderNav',
canEdit: false,
props: {
styleTheme: '${topStyle}',
title: '${channelName}',
categoryList: '${categoryList}',
},
childNodes: ['2'],
childComponentName: 'ChannelHeaderNav.ActionItem',
},
'2': {
loop: '${top}',
title: '${item.name}',
hideActions: true,
componentName: 'ChannelHeaderNav.ActionItem',
props: {
data: '${item}'
},
},
'3': {
title: '广告图',
componentName: 'Banner',
props: {
style: {
margin: '8px',
},
},
childNodes: ['4'],
childComponentName: 'Banner.Items',
addBtnText: '添加广告',
},
'4': {
loop: '${advert}',
title: '${item.name}',
componentName: 'Banner.Items',
props: {
id: '${item.id}',
type: '${item.type}',
img: '${item.img}',
name: '${item.name}',
isnull: false,
},
},
'5': {
title: '分类导航',
componentName: 'MobileNavCard',
props: {
style: {
margin: '8px',
},
stylesthemelist: [
{
key: 0,
width: 320,
height: 148,
img: categoryNavTemplateDefault,
},
]
},
childNodes: ['6'],
childComponentName: 'MobileNavCard.NavItem',
addBtnText: '添加导航',
},
'6': {
loop: '${navList}',
title: '${item.name}',
componentName: 'MobileNavCard.NavItem',
props: {
id: '${item.id}',
name: '${item.name}',
type: '${item.type}',
url: '${item.url}',
icon: '${item.icon}',
empty: false,
},
},
'7': {
title: '资讯',
componentName: 'InformationCard',
props: {
title: '${informationTitle}'
},
childNodes: [],
canEdit: false,
addBtnText: '添加资讯',
},
}
export const defaultConfig: PageConfigType = {
'8': {
title: '优惠券弹窗',
componentName: 'CouponsModal',
props: {
style: {
display: "none",
position: 'absolute',
backgroundImage: `url(${RED_PACKAGE})`,
width: 312,
height: 425,
top: 0,
left: 0,
bottom: 0,
right: 0,
margin: 'auto',
zIndex: 1,
},
},
childNodes: [],
childComponentName: 'CouponsModal.CouponsItem',
addBtnText: '添加优惠券',
canEdit: true,
canHide: false,
},
'9': {
title: '推荐商品',
componentName: 'SuggestProduct',
props: {},
childNodes: [],
childComponentName: 'SuggestProduct.Items',
addBtnText: '添加分类',
canEdit: true,
canHide: false,
maxLength: 4,
childProps: {
title: '商品容器',
canEdit: true,
canHide: false,
componentName: 'SuggestProduct.Items',
props: {},
childComponentName: 'SuggestProduct.Commodity',
maxLength: 50,
// addBtnText: '添加商品',
childNodes: [],
},
},
'10': {
title: '底部标签栏',
componentName: 'BottomNavigation',
props: {},
childNodes: ['11'],
childComponentName: 'BottomNavigation.Items',
addBtnText: '添加标签',
maxLength: 5,
},
'11': {
loop: '${bottom}',
title: '${item.name}',
componentName: 'BottomNavigation.Items',
props: {
defaultIcon: '${item.defaultIcon}',
selectIcon: '${item.selectIcon}',
name: '${item.name}',
type: '${item.type}',
isnull: false,
},
},
}
export const mallLayoutConfig = {
key: "0",
......
......@@ -7,13 +7,19 @@
* @FilePath: /lingxi-business-paltform/src/pages/mobileTemplate/channelTemplateEdit/index.tsx
*/
import React, { useEffect, useState } from 'react'
import { BrickProvider } from '@lingxi-disign/react';
import { Helmet } from 'umi'
import { BrickProvider, resolveMappingPageConfig } from '@lingxi-disign/react';
import ToolBar from '../../editor/components/toolBar'
import MobileDesignPanel from '../../editor/components/MobileDesignPanel'
import AllComponents from '../../editor/components/ComponentsPreview'
import MobileClientEditLeft from '../../editor/components/mobileClientEditLeft'
import { message } from 'antd'
import config from '../../editor/configs'
import * as MarketingConfigs from './marketing_config'
import { cloneDeep } from 'lodash'
import {
defaultHeaderNavData,
channelLayoutConfig,
defaultConfig,
mallLayoutConfig,
divWrap,
mobileChannelHeaderNav,
......@@ -26,7 +32,7 @@ import {
import Loading from '../../editor/components/Loading'
import { PublicApi } from '@/services/api'
import { LAYOUT_TYPE } from '@/constants'
import { GetTemplateAdornAppChannelFindResponse, GetTemplateWebMemberChannelWebFindCurrMemberChannelResponse } from '@/services/TemplateApi'
import { GetTemplateAdornAppChannelFindResponse, GetTemplateWebMemberChannelWebFindCurrMemberChannelResponse } from '@/services/TemplateV2Api'
// import { GlobalConfig } from '@/global/config'
import MobileSettingPanel from '../../editor/mobileSettingPanel'
import { getAuth } from '@/utils/auth'
......@@ -56,6 +62,7 @@ const mobileShopTempleteEdit: React.FC<ShopPreviewPropsType> = (props) => {
const [loading, setLoading] = useState<boolean>(true)
const [theme, setTheme] = useState<string>('theme-mall-science')
const [componentConfigs, setComponentConfigs] = useState({})
const { memberId, memberRoleId } = getAuth() || {}
const headers: any = {
environment: "4",
......@@ -88,16 +95,16 @@ const mobileShopTempleteEdit: React.FC<ShopPreviewPropsType> = (props) => {
/**
* 获取app店铺装修信息
*/
const getAppChannelConfig = (): Promise<GetTemplateAdornAppChannelFindResponse | null> => {
const getAppChannelConfig = (): Promise<any> => {
return new Promise((resolve, reject) => {
const param: any = {
templateId: id
}
PublicApi.getTemplateAdornAppChannelFind(param).then(res => {
if(res.code === 1000) {
resolve(res.data)
if(res.code === 1000 && res.data) {
resolve(res.data.adornContent)
} else {
reject(res)
resolve({})
}
}).catch((eror) => {
reject(eror)
......@@ -177,55 +184,51 @@ const mobileShopTempleteEdit: React.FC<ShopPreviewPropsType> = (props) => {
return []
}
const getFirstCategoryList = () => {
return new Promise ((resolve) => {
const param: any = {
shopId,
memberId
}
PublicApi.getSearchChannelCommodityTemplateGetFirstCategoryListByMemberId(param).then((res) => {
if (res.code === 1000 && res.data) {
const list = res.data.map(item => {
return {
label: item.name,
value: item.id
}
})
resolve(list)
} else {
resolve([])
}
}).catch(() => {
resolve([])
})
})
}
const getComponentsConfig = async () => {
try {
const appConfig = await getAppChannelConfig()
//渠道信息
const channelInfo = await fetchChannelInfo()
mobileChannelHeaderNav[mobileChannelHeaderNav.key].props.name = channelInfo.memberName
if (channelInfo.memberId) {
const categoryList = await getCustomerCategoryTreeById(channelInfo.memberId)
mobileChannelCategory[mobileChannelCategory.key].props.dataList = categoryList
mobileChannelGoodsCard[mobileChannelGoodsCard.key].props.channelMemberId = channelInfo.memberId
if (appConfig?.productBO) {
mobileChannelGoodsCard[mobileChannelGoodsCard.key].props.dataList = await getProductInfo(appConfig?.productBO.productDetailsBOList, channelInfo.memberId)
}
}
if (appConfig?.topBO) {
mobileChannelHeaderNav[mobileChannelHeaderNav.key].props.styleTheme = appConfig?.topBO.style
mobileChannelHeaderNav[mobileChannelHeaderNav.key].props.dataList = appConfig?.topBO.topDetailsBOList
const _mallLayoutConfig: any = cloneDeep(channelLayoutConfig)
const allState = {
top: defaultHeaderNavData,
channelName: channelInfo.memberName,
categoryList: await getFirstCategoryList(),
informationTitle: '8月钢市价格走势判断',
}
mobileBanner[mobileBanner.key].props.channelMemberId = channelInfo.memberId
if (appConfig?.advertBO) {
mobileBanner[mobileBanner.key].props.dataList = appConfig?.advertBO.advertDetailsBOList
}
if (appConfig?.informationBO) {
mobileChannelInformation[mobileChannelInformation.key].props.title = appConfig?.informationBO.title
mobileChannelInformation[mobileChannelInformation.key].props.informationIdList = appConfig?.informationBO.informationIdList || []
mobileChannelInformation[mobileChannelInformation.key].props.dataList = await getInformationInfo(appConfig?.informationBO.informationIdList)
}
if (appConfig?.bottomBO) {
mobileBottomNavigation[mobileBottomNavigation.key].props.dataList = appConfig?.bottomBO.bottomDetailsBOList
}
_mallLayoutConfig['0'].childNodes = [..._mallLayoutConfig['0'].childNodes, '8', '9', '10']
const config = {
...mallLayoutConfig,
...mobileChannelHeaderNav,
...divWrap,
...mobileBanner,
...mobileChannelCategory,
...mobileChannelGoodsCard,
...mobileChannelInformation,
...mobileBottomNavigation,
..._mallLayoutConfig,
...defaultConfig,
}
setComponentConfigs(config)
const finalConfig = resolveMappingPageConfig(config, allState)
setComponentConfigs(finalConfig)
setLoading(false)
} catch (error) {
console.log(error)
......@@ -237,16 +240,19 @@ const mobileShopTempleteEdit: React.FC<ShopPreviewPropsType> = (props) => {
<BrickProvider
config={config}
>
<Helmet>
<title>渠道装修-渠道主页</title>
</Helmet>
<div className={styles['wrapper']}>
<ToolBar type={1} title="渠道商城-首页" showActions={true} layoutType={LAYOUT_TYPE.channel} templateId={id} />
<div className={styles['content']}>
<AllComponents />
<MobileClientEditLeft marketConfigs={MarketingConfigs} />
<div className={styles['app-wrapper']}>
<div className={styles['app-canvas-container']}>
<MobileDesignPanel onlyEidt theme={theme} pageConfig={componentConfigs} />
</div>
</div>
<MobileSettingPanel />
<MobileSettingPanel shopId={shopId} layoutType={LAYOUT_TYPE.channel} />
</div>
</div>
</BrickProvider>
......
......@@ -2,7 +2,7 @@ import { PROPS_SETTING_TYPES, PageConfigType } from '@lingxi-disign/core'
import categoryNavTemplateDefault from './img/category_template_default.png'
import RED_PACKAGE from './img/red_package.png';
export const mallLayoutConfig : PageConfigType = {
export const shopLayoutConfig : PageConfigType = {
'0': {
componentName: 'MallLayout',
props: {
......
......@@ -14,9 +14,10 @@ import MobileClientEditLeft from '../../editor/components/mobileClientEditLeft'
import { cloneDeep } from 'lodash'
import { message } from 'antd'
import config from '../../editor/configs'
import * as MarketingConfigs from './marketing_config'
import { priceFormat } from '@/utils/numberFomat'
import {
mallLayoutConfig,
shopLayoutConfig,
defaultConfig,
} from './config'
import {
......@@ -111,7 +112,7 @@ const mobileShopTempleteEdit: React.FC<ShopPreviewPropsType> = (props) => {
* 获取app店铺装修信息
*/
const getAppShopConfig = (): Promise<any> => {
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
const param: any = {
templateId: id
}
......@@ -231,7 +232,7 @@ const mobileShopTempleteEdit: React.FC<ShopPreviewPropsType> = (props) => {
//店铺信息
const shopInfo = await fetchShopInfo(shopId)
const _mallLayoutConfig: any = cloneDeep(mallLayoutConfig)
const _mallLayoutConfig: any = cloneDeep(shopLayoutConfig)
const allState: any = {
shopInfo: shopInfo,
navList: appConfig?.navList ? appConfig?.navList.details : [],
......@@ -981,7 +982,7 @@ const mobileShopTempleteEdit: React.FC<ShopPreviewPropsType> = (props) => {
<div className={styles['wrapper']}>
<ToolBar type={1} title="店铺主页" showActions={true} layoutType={LAYOUT_TYPE.shop} templateId={id} />
<div className={styles['content']}>
<MobileClientEditLeft />
<MobileClientEditLeft marketConfigs={MarketingConfigs} />
<div className={styles['app-wrapper']}>
<div className={styles['app-canvas-container']}>
<MobileDesignPanel onlyEidt theme={theme} pageConfig={componentConfigs} />
......
......@@ -128,6 +128,7 @@ const ShopInfo: React.FC<ShopInfoPropsType> = (props) => {
describe: data.describe,
customerUrl: data.customerUrl,
logo: data.logo,
name: data.name,
memberShopAreas: initMemberShopArea(data.memberShopAreas),
workshopPics: data.workshopPics || [],
honorPics: data.honorPics || [],
......@@ -203,6 +204,7 @@ const ShopInfo: React.FC<ShopInfoPropsType> = (props) => {
}
setConfirmLoading(true)
const params = {
name: value.name,
albumName: !isEmpty(file) ? file.albumName : null,
albumUrl: !isEmpty(file) ? file.albumUrl : null,
describe: value.describe,
......@@ -211,7 +213,6 @@ const ShopInfo: React.FC<ShopInfoPropsType> = (props) => {
memberShopAreas: value.memberShopAreas,
workshopPics,
}
console.log(params)
PublicApi.postTemplateWebMemberShopWebSaveCurrMemberShop(params).then(res => {
if (res.code === 1000) {
fetchShopInfo()
......@@ -317,16 +318,11 @@ const ShopInfo: React.FC<ShopInfoPropsType> = (props) => {
>
<Form.Item
labelAlign="left"
name="memberShopAreas"
label={<RequireItem label="归属地市" isRequire={true} />}
rules={[{ required: true, message: "请选择归属地市" }]}
name="name"
label={<RequireItem label="公司名称" isRequire={true} />}
rules={[{ required: true, message: "请输入公司名称" }]}
>
<CitySelect
selectData={selectCityData}
onAdd={handleAddNewCitySelect}
onReduce={handleReduceCitySelect}
onChange={handleCityChange}
/>
<Input className={styles.form_item} placeholder="请输入公司名称" maxLength={20} />
</Form.Item>
<Form.Item
labelAlign="left"
......@@ -348,6 +344,19 @@ const ShopInfo: React.FC<ShopInfoPropsType> = (props) => {
</Form.Item>
<Form.Item
labelAlign="left"
name="memberShopAreas"
label={<RequireItem label="归属地市" isRequire={true} />}
rules={[{ required: true, message: "请选择归属地市" }]}
>
<CitySelect
selectData={selectCityData}
onAdd={handleAddNewCitySelect}
onReduce={handleReduceCitySelect}
onChange={handleCityChange}
/>
</Form.Item>
<Form.Item
labelAlign="left"
name="describe"
label={<RequireItem label="公司简介" isRequire={true} />}
rules={[{ required: true, message: "请输入公司简介" }]}
......
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