Commit 6cbd3a90 authored by XieZhiXiong's avatar XieZhiXiong
parents 8033988c 763ce5bd
/** 活动相关 */
/** 活动推荐 */
export const ACTIVITY_HOT = 'hot';
/** 活动-特价促销 */
export const ACTIVITY_SPECIALOFFER = 'specialOffer';
/** 直降促销 */
export const ACTIVITY_PLUMMET = 'plummet';
/** 折扣促销 */
export const ACTIVITY_DISCOUNT = 'discount';
/** 满量促销-满量减 */
export const ACTIVITY_FULLQUANTITYSUB = 'fullQuantitySub';
/** 满量促销--满量折 */
export const ACTIVITY_FULLQUANTITYDISCOUNT = 'fullQuantityDiscount';
/** 满额促销--满额减 */
export const ACTIVITY_FULLMONEYSUB = 'fullMoneySub'
/** 满额促销--满额折 */
export const ACTIVITY_FULLMONEYDISCOUNT = 'fullMoneyDiscount'
/** 赠送促销-赠送商品 */
export const ACTIVITY_GIVEPRODUCT = 'giveProduct'
/** 赠送促销-赠送优惠券 */
export const ACTIVITY_GIVECOUPON = 'giveCoupon'
/** 赠送促销-多件促销 */
export const ACTIVITY_MOREPIECE = 'morePiece'
/** 赠送促销-组合促销 */
export const ACTIVITY_COMBINATION = 'combination'
/** 赠送促销-拼团 */
export const ACTIVITY_GROUPPURCHASE = 'groupPurchase'
/** 砍价 */
export const ACTIVITY_BARGAIN = 'bargain'
/** 秒杀 */
export const ACTIVITY_SECKILL = 'secKill'
/** 换购-满额换购 */
export const ACTIVITY_FULLSWAP = 'fullSwap'
/** 换购-满额换购 */
export const ACTIVITY_BUYSWAP = 'buySwap'
/** 换购-预售 */
export const ACTIVITY_PRESALE = 'preSale'
/** 套餐 */
export const ACTIVITY_SETMEAL = 'setMeal';
/** 试用 */
export const ACTIVITY_ATTEMPT = 'attempt';
/** 活动类型ID */
/** 活动-特价促销 */
export const ACTIVITY_SPECIALOFFER_NUMBER = 1;
/** 直降促销 */
export const ACTIVITY_PLUMMET_NUMBER = 2;
/** 折扣促销 */
export const ACTIVITY_DISCOUNT_NUMBER = 3;
/** 满量促销-满量减, minType: 1 */
export const ACTIVITY_FULLQUANTITYSUB_NUMBER = 4;
/** 满量促销--满量折 minType: 2 */
export const ACTIVITY_FULLQUANTITYDISCOUNT_NUMBER = 4;
/** 满额促销--满额减 minType: 1 */
export const ACTIVITY_FULLMONEYSUB_NUMBER = 5
/** 满额促销--满额折 minType: 2 */
export const ACTIVITY_FULLMONEYDISCOUNT_NUMBER = 5
/** 赠送促销-赠送商品 minType: 1 */
export const ACTIVITY_GIVEPRODUCT_NUMBER = 6
/** 赠送促销-赠送优惠券 minType: 2 */
export const ACTIVITY_GIVECOUPON_NUMBER = 6
/** 赠送促销-多件促销 */
export const ACTIVITY_MOREPIECE_NUMBER = 7
/** 赠送促销-组合促销 */
export const ACTIVITY_COMBINATION_NUMBER = 8
/** 拼团 */
export const ACTIVITY_GROUPPURCHASE_NUMBER = 9
/** 砍价 */
export const ACTIVITY_BARGAIN_NUMBER = 11
/** 秒杀 */
export const ACTIVITY_SECKILL_NUMBER = 12
/** 换购-满额换购 minType = 1 */
export const ACTIVITY_FULLSWAP_NUMBER = 13
/** 换购-满额换购 minType = 2 */
export const ACTIVITY_BUYSWAP_NUMBER = 13
/** 换购-预售 */
export const ACTIVITY_PRESALE_NUMBER = 14
/** 套餐 */
export const ACTIVITY_SETMEAL_NUMBER = 15;
/** 试用 */
export const ACTIVITY_ATTEMPT_NUMBER = 16;
export const ACTIVITY_LIST = [
ACTIVITY_HOT,
ACTIVITY_SPECIALOFFER,
ACTIVITY_PLUMMET,
ACTIVITY_DISCOUNT,
ACTIVITY_FULLQUANTITYSUB,
ACTIVITY_FULLQUANTITYDISCOUNT,
ACTIVITY_FULLMONEYSUB,
ACTIVITY_FULLMONEYDISCOUNT,
ACTIVITY_GIVEPRODUCT,
ACTIVITY_GIVECOUPON,
ACTIVITY_MOREPIECE,
ACTIVITY_COMBINATION,
ACTIVITY_GROUPPURCHASE,
ACTIVITY_BARGAIN,
ACTIVITY_SECKILL,
ACTIVITY_FULLSWAP,
ACTIVITY_BUYSWAP,
ACTIVITY_PRESALE,
ACTIVITY_SETMEAL,
ACTIVITY_ATTEMPT
] as const
......@@ -158,9 +158,12 @@ const MemberDetail: React.FC<{}> = () => {
menuId: node ? node.id : nodeRecord.id,
...params,
});
console.log(data, 'data')
if (!isAdd && data.orgIds) {
let plateformTreeDataList = mapkey(plateformTreeData, data.orgIds)
console.log(plateformTreeData, 'plateformTreeData');
console.log(data.orgIds, 'data.orgIds');
let plateformTreeDataList = mapkey(plateformTreeData, data.orgIds, [])
console.log(plateformTreeDataList)
setplateformTreeList(plateformTreeDataList)
}
setButtonAuth(node.id, data);
......@@ -388,8 +391,7 @@ const MemberDetail: React.FC<{}> = () => {
</Space>
);
const mapkey = (plateformTreeData: any, selectKeys: any) => {
let plateformTreeDataList = [];
const mapkey = (plateformTreeData: any, selectKeys: any, plateformTreeDataList = []) => {
plateformTreeData.map((item: any) => {
if (selectKeys.includes(item.id)) {
plateformTreeDataList.push(
......@@ -398,13 +400,14 @@ const MemberDetail: React.FC<{}> = () => {
title: item.title
}
)
if (item.children) {
const arr = mapkey(item.children, selectKeys)
plateformTreeDataList = [...plateformTreeDataList, ...arr];
if (item.children.length > 0) {
const arr = mapkey(item.children, selectKeys, plateformTreeDataList)
plateformTreeDataList = [...arr];
}
} else {
const arr = mapkey(item.children, selectKeys, plateformTreeDataList)
plateformTreeDataList = [...arr];
}
})
return plateformTreeDataList
}
......@@ -422,7 +425,10 @@ const MemberDetail: React.FC<{}> = () => {
{ orgIds: selectKeys },
),
});
let plateformTreeDataList = mapkey(plateformTreeData, selectKeys)
console.log(plateformTreeData, 'plateformTreeData');
console.log(selectKeys, 'selectKeys');
let plateformTreeDataList = mapkey(plateformTreeData, selectKeys, [])
console.log(plateformTreeDataList)
setplateformTreeList(plateformTreeDataList)
// console.log(plateformTreeDataList, 'plateformTreeData')
setOrgModalVisible(false);
......
......@@ -136,8 +136,15 @@ const CommodityWithProcess = {
}
}
const MobileLayout = {
propsConfig: {
backgroundColor: PROPS_TYPES.string,
}
}
export default {
MobileLayout,
Commodity,
Advertisement,
View,
......
......@@ -66,6 +66,7 @@ const COMPONENT_NAME = {
top: 'Advertisement',
coupon: 'Coupon',
hot: "CommodityWithProcess",
specialOffer: "CommodityList",
plummet: "CommodityList",
discount: "CommodityList",
fullQuantitySub: "CommodityList",
......@@ -92,6 +93,7 @@ const CHILD_COMPONENT_NAME = {
coupon: 'Coupon.Item',
hot: "CommodityWithProcess.Item",
plummet: "CommodityList.Item",
specialOffer: "CommodityList.Item",
discount: "CommodityList.Item",
fullQuantitySub: "CommodityList.Item",
fullQuantityDiscount: "CommodityList.Item",
......@@ -217,10 +219,11 @@ function useGetLayout() {
if (!detail) {
return;
}
console.log(detail);
/** @review 该方法需要优化,因为suggestProduct 写多了一遍 */
async function setData() {
setLoading(true);
const { adornContent } = detail!;
const themeStyle = adornContent['themeStyle']
let startKey = 0;
const firstChildKeys: string[] = [];
let pageConfig = {};
......@@ -232,7 +235,7 @@ function useGetLayout() {
sort: adornContent[_item].sort
});
});
const sortedList = dataSourceList.sort((a, b) => a.sort - b.sort);
const sortedList = dataSourceList.sort((a, b) => a.sort - b.sort).filter((_item) => _item.key !== 'themeStyle');
for (const _row of sortedList) {
startKey = startKey + 1;
firstChildKeys.push(startKey.toString());
......@@ -242,11 +245,12 @@ function useGetLayout() {
const props = _row.key === 'top' ? {
imageUrl: currentProps.imageUrl
} : {
visible: currentProps.visible ?? true,
status: currentProps.visible ?? true,
theme: currentProps.theme || 0,
title: currentProps.title,
};
const suggestProductSonProps = _row.key === 'suggestProduct' ? {
hideAction: true,
childComponentName: `CommodityList.Item`,
addBtnText: `${intl.formatMessage({ id: 'marketingAbility.tianjiashangpinjiedian'})}`,
childProps: {
......@@ -266,6 +270,7 @@ function useGetLayout() {
},
};
let tempConfig = {
hideAction: true,
componentName: COMPONENT_NAME[_row.key],
title: title[_row.key] || currentProps.title,
props: props,
......@@ -366,22 +371,16 @@ function useGetLayout() {
}
pageConfig = {
0: {
"componentName": "div",
"componentName": "MobileLayout",
title: `${intl.formatMessage({ id: 'marketingAbility.zujianshu'})}`,
"props": {
"style": {
"width": "100%",
"minHeight": "100%",
"background": "#DD3041",
"overflowX": "hidden",
"paddingBottom": "50px",
}
backgroundColor: themeStyle?.props?.color || "#00A98F"
},
"childNodes": firstChildKeys
},
...pageConfig,
};
setLoading(false);
console.log("pageConfig", pageConfig);
updatePageConfig(pageConfig);
......
......@@ -222,6 +222,7 @@ function useGetWebLayout() {
console.log(detail);
/** @review 该方法需要优化,因为suggestProduct 写多了一遍 */
async function setData() {
setLoading(true)
const { adornContent } = detail!;
const themeStyle = adornContent['themeStyle']
let startKey = 0;
......@@ -382,7 +383,7 @@ function useGetWebLayout() {
},
...pageConfig,
};
setLoading(false)
console.log("pageConfig", pageConfig);
updatePageConfig(pageConfig);
}
......
import { ACTIVITY_LIST } from '@/constants/activity';
import { postTemplateWebActivityPageAdorn } from '@/services/TemplateV2Api';
import { CodeSandboxCircleFilled } from '@ant-design/icons';
import { omit, pick } from 'lodash';
import { useState } from 'react';
import { history } from 'umi';
type Options = {
id: number;
}
/** 数组转合集 */
type TupleToUnion<T extends readonly any[]> = T[number];
type ACTIVITY_KEYS = TupleToUnion<typeof ACTIVITY_LIST>
type ActivityContent = {
[key in ACTIVITY_KEYS]?: {
props: {
/** 活动商品id */
childrenData: number[]
theme: number
/** 容器名 */
title: string
/** 显示或者隐藏 */
visible: boolean
},
/** 排序 */
sort: number
};
}
type ResultType = {
themeStyle?: {
props: {
/** 背景颜色 */
color: string;
},
sort: number
},
top?: {
props: {
/** 活动图片 */
imageUrl: string;
},
sort: number
},
coupon?: {
props: {
/** 优惠券, type => 平台或商家 */
childrenData: {id: number, type: 1 | 2 | number & {}}[]
theme: number
visible: boolean
}
sort: number
}
} & ActivityContent
function useSaveData(options: Options) {
const { id } = options
const [saving, setSaving] = useState<boolean>(false);
const generaterData = (source: ResultType, dataIndex: string, assignData: {[key: string]: any} ) => {
const result = Object.assign(source, {
[dataIndex]: assignData
});
return result;
};
const onSave = async (pageConfig: any) => {
const childNodes = pageConfig[0].childNodes;
setSaving(true);
let result: ResultType = {} as ResultType;
childNodes.map((_item, _index) => {
const target = pageConfig[_item];
const childNodes = target.childNodes;
const { props } = target || {};
const dataIndex: ACTIVITY_KEYS | 'top' | 'coupon' | 'suggestProduct' = target.otherProps.type;
const sort = _index + 1;
if (dataIndex === 'top') {
const current = { sort: sort, props: omit(props, 'style') };
result = generaterData(result, 'top', current);
} else if(dataIndex === 'coupon') {
const childrenData = childNodes.map((_record) => {
const childTargetProps = pageConfig[_record].props;
if(!childTargetProps?.id) {
return null
}
return {
id: childTargetProps.id,
type: childTargetProps.belongType
};
}).filter(Boolean);
result = generaterData(result, 'coupon', {
sort: sort,
props: {
...pick(props, ['theme']),
visible: props.status ?? true,
childrenData: childrenData
}
});
} else if (ACTIVITY_LIST.includes( dataIndex as ACTIVITY_KEYS )) {
const { ...otherProps } = props || {};
const childrenData = childNodes.map((_record) => {
const childTargetProps = pageConfig[_record].props;
return childTargetProps.id;
});
// const childrenData = products?.map((_item) => _item.id) || [];
result = generaterData(result, dataIndex, {
sort: sort,
props: {
...pick(otherProps, ['theme', 'title']),
visible: props.status ?? true,
childrenData: childrenData
}
});
} else if (dataIndex === 'suggestProduct') {
const { ...otherProps } = props || {};
const { childNodes } = target;
const temp = {
sort: sort,
props: {
visible: otherProps.status ?? true,
childrenData: childNodes?.filter((_record) => /\d+-\d+/.test(_record)).map((_row) => {
const childrenNodeTarget = pageConfig[_row];
const { ...childRestProps } = childrenNodeTarget?.props;
return {
title: childRestProps.title,
theme: childRestProps.theme || 0,
childrenData: childrenNodeTarget.childNodes?.map((_listItem) => {
const sonNodeTarget = pageConfig[_listItem];
return {
id: sonNodeTarget?.props.id,
label: sonNodeTarget?.props?.label || []
};
})
};
})
}
};
result = generaterData(result, 'suggestProduct', temp);
}
});
const withThemeStyle = {
...result,
themeStyle: {
sort: 0,
props: {
color: pageConfig[0]?.props?.backgroundColor || '#E80047'
}
}
}
const { data, code } = await postTemplateWebActivityPageAdorn({
id: +id,
adornContent: withThemeStyle
} as any);
setSaving(false);
if (code === 1000) {
history.goBack();
}
}
return { saving, onSave };
}
export default useSaveData
\ No newline at end of file
{
"themeStyle": {
"sort": 0,
"props": {
"color": "#00A98F"
}
},
"top":{
"sort":1,
"props": {
......
......@@ -23,108 +23,280 @@ import setMealImg from '@/assets/activity/setMeal.png';
import discountImg from '@/assets/activity/discount.png';
import specialOfferImg from '@/assets/activity/specialOffer.png';
import giveCouponImg from '@/assets/activity/giveCoupon.png';
const ACTIVITYS = [
"specialOffer",
"plummet",
"discount",
"fullQuantitySub",
"fullQuantityDiscount",
"fullMoneySub",
"fullMoneyDiscount",
"giveProduct",
"giveCoupon",
"morePiece",
"combination",
"groupPurchase",
"bargain",
"secKill",
"fullSwap",
"buySwap",
"preSale",
"setMeal",
"attempt"
] as const;
import { ACTIVITY_ATTEMPT, ACTIVITY_BARGAIN, ACTIVITY_BUYSWAP, ACTIVITY_COMBINATION, ACTIVITY_DISCOUNT, ACTIVITY_FULLMONEYDISCOUNT, ACTIVITY_FULLMONEYSUB, ACTIVITY_FULLQUANTITYDISCOUNT, ACTIVITY_FULLQUANTITYSUB, ACTIVITY_FULLSWAP, ACTIVITY_GIVECOUPON, ACTIVITY_GIVEPRODUCT, ACTIVITY_GROUPPURCHASE, ACTIVITY_LIST, ACTIVITY_MOREPIECE, ACTIVITY_PLUMMET, ACTIVITY_PRESALE, ACTIVITY_SECKILL, ACTIVITY_SETMEAL, ACTIVITY_SPECIALOFFER } from '@/constants/activity';
const ACTIVITYS_MAP = {
"specialOffer": {
[ACTIVITY_SPECIALOFFER]: {
title: '特价促销',
image: specialOfferImg
},
"plummet": {
[ACTIVITY_PLUMMET]: {
title: '直降促销',
image: plummetImg
},
"discount": {
[ACTIVITY_DISCOUNT]: {
title: '折扣促销',
image: discountImg
},
"fullQuantitySub": {
[ACTIVITY_FULLQUANTITYSUB]: {
title: '满量促销--满量减"',
image: fullQuantitySubImg
},
"fullQuantityDiscount": {
[ACTIVITY_FULLQUANTITYDISCOUNT]: {
title: '满量促销--满量折',
image: fullQuantityDiscountImg
},
"fullMoneySub": {
[ACTIVITY_FULLMONEYSUB]: {
title: '满额促销--满额减',
image: fullMoneySubImg
},
"fullMoneyDiscount": {
[ACTIVITY_FULLMONEYDISCOUNT]: {
title: '满额促销--满额折"',
image: fullMoneyDiscountImg
},
"giveProduct": {
[ACTIVITY_GIVEPRODUCT]: {
title: '赠送促销--赠送商品',
image: giveProductImg
},
"giveCoupon": {
[ACTIVITY_GIVECOUPON]: {
title: '赠送促销--赠送优惠劵',
image: giveCouponImg
},
"morePiece": {
[ACTIVITY_MOREPIECE]: {
title: '多件促销',
image: morePieceImg
},
"combination": {
[ACTIVITY_COMBINATION]: {
title: '组合促销',
image: combinationImg
},
"groupPurchase": {
[ACTIVITY_GROUPPURCHASE]: {
title: '拼团',
image: groupPurchaseImg
},
"bargain": {
[ACTIVITY_BARGAIN]: {
title: '砍价',
image: bargainImg
},
"secKill": {
[ACTIVITY_SECKILL]: {
title: '秒杀',
image: secKillImg
},
"fullSwap": {
[ACTIVITY_FULLSWAP]: {
title: '换购-满额换购',
image: fullSwapImg
},
"buySwap": {
[ACTIVITY_BUYSWAP]: {
title: '换购-买商品换购',
image: buySwapImg
},
"preSale": {
[ACTIVITY_PRESALE]: {
title: '预售',
image: preSaleImg
},
"setMeal": {
[ACTIVITY_SETMEAL]: {
title: '套装',
image: setMealImg
},
"attempt": {
[ACTIVITY_ATTEMPT]: {
title: '试用',
image: attemptImg
}
} as const;
const COMPONENT_NAME = {
[ACTIVITY_SPECIALOFFER]: {
mobile: {
container: 'CommodityList',
childContainer: 'CommodityList.Item'
},
web: {
container: 'WebCommodityContainer',
childContainer: 'WebCommodity'
}
},
[ACTIVITY_PLUMMET]: {
mobile: {
container: 'CommodityList',
childContainer: 'CommodityList.Item'
},
web: {
container: 'WebCommodityContainer',
childContainer: 'WebCommodity'
}
},
[ACTIVITY_DISCOUNT]: {
mobile: {
container: 'CommodityList',
childContainer: 'CommodityList.Item'
},
web: {
container: 'WebCommodityContainer',
childContainer: 'WebCommodity'
}
},
[ACTIVITY_FULLQUANTITYSUB]: {
mobile: {
container: 'CommodityList',
childContainer: 'CommodityList.Item'
},
web: {
container: 'WebCommodityContainer',
childContainer: 'WebCommodity'
}
},
[ACTIVITY_FULLQUANTITYDISCOUNT]: {
mobile: {
container: 'CommodityList',
childContainer: 'CommodityList.Item'
},
web: {
container: 'WebCommodityContainer',
childContainer: 'WebCommodity'
}
},
[ACTIVITY_FULLMONEYSUB]: {
mobile: {
container: 'CommodityList',
childContainer: 'CommodityList.Item'
},
web: {
container: 'WebCommodityContainer',
childContainer: 'WebCommodity'
}
},
[ACTIVITY_FULLMONEYDISCOUNT]: {
mobile: {
container: 'CommodityList',
childContainer: 'CommodityList.Item'
},
web: {
container: 'WebCommodityContainer',
childContainer: 'WebCommodity'
}
},
[ACTIVITY_GIVEPRODUCT]: {
mobile: {
container: 'CommodityList',
childContainer: 'CommodityList.Item'
},
web: {
container: 'WebCommodityContainer',
childContainer: 'WebCommodity'
}
},
[ACTIVITY_GIVECOUPON]: {
mobile: {
container: 'CommodityList',
childContainer: 'CommodityList.Item'
},
web: {
container: 'WebCommodityContainer',
childContainer: 'WebCommodity'
}
},
[ACTIVITY_MOREPIECE]: {
mobile: {
container: 'CommodityList',
childContainer: 'CommodityList.Item'
},
web: {
container: 'WebCommodityContainer',
childContainer: 'WebCommodity'
}
},
// combination: "Combination",
[ACTIVITY_COMBINATION]: {
mobile: {
container: 'Combination',
childContainer: 'Combination.Item'
},
web: {
container: 'WebCommodityContainer',
childContainer: 'WebCommodity'
}
},
[ACTIVITY_GROUPPURCHASE]: {
mobile: {
container: 'CommodityList',
childContainer: 'CommodityList.Item'
},
web: {
container: 'WebCommodityContainer',
childContainer: 'WebCommodity'
}
},
[ACTIVITY_BARGAIN]: {
mobile: {
container: 'CommodityList',
childContainer: 'CommodityList.Item'
},
web: {
container: 'WebCommodityContainer',
childContainer: 'WebCommodity'
}
},
[ACTIVITY_SECKILL]: {
mobile: {
container: 'CommodityList',
childContainer: 'CommodityList.Item'
},
web: {
container: 'WebCommodityContainer',
childContainer: 'WebCommodity'
}
},
[ACTIVITY_FULLSWAP]: {
mobile: {
container: 'CommodityList',
childContainer: 'CommodityList.Item'
},
web: {
container: 'WebCommodityContainer',
childContainer: 'WebCommodity'
}
},
[ACTIVITY_BUYSWAP]: {
mobile: {
container: 'CommodityList',
childContainer: 'CommodityList.Item'
},
web: {
container: 'WebCommodityContainer',
childContainer: 'WebCommodity'
}
},
[ACTIVITY_PRESALE]: {
mobile: {
container: 'CommodityList',
childContainer: 'CommodityList.Item'
},
web: {
container: 'WebCommodityContainer',
childContainer: 'WebCommodity'
}
},
[ACTIVITY_SETMEAL]: {
mobile: {
container: 'CommodityList',
childContainer: 'CommodityList.Item'
},
web: {
container: 'WebCommodityContainer',
childContainer: 'WebCommodity'
}
},
[ACTIVITY_ATTEMPT]: {
mobile: {
container: 'CommodityList',
childContainer: 'CommodityList.Item'
},
web: {
container: 'WebCommodityContainer',
childContainer: 'WebCommodity'
}
},
};
type ModuleType = {
// title: string,
......@@ -137,17 +309,21 @@ type Turple<T extends readonly string[], P> = {
[key in T[number]]: P
}
interface Iprops {
isWeb?: boolean
}
const WebComponentModule = () => {
const WebComponentModule: React.FC<Iprops> = (props: Iprops) => {
const { pageConfig } = useSelector(['pageConfig']);
const { isWeb = true } = props;
console.log("pageConfig", pageConfig)
const modules = useMemo(() => {
const config = pageConfig;
const res: Turple<typeof ACTIVITYS, ModuleType> = {} as Turple<typeof ACTIVITYS, ModuleType>;
const res: Turple<typeof ACTIVITY_LIST, ModuleType> = {} as Turple<typeof ACTIVITY_LIST, ModuleType>;
Object.keys(config).forEach((_item) => {
const { props = {} } = config[_item];
const dataIndex = config[_item]?.otherProps?.type;
if (ACTIVITYS.includes(dataIndex)) {
if (ACTIVITY_LIST.includes(dataIndex)) {
// const visible = props.visible ?? true
res[dataIndex] = {
treeKey: _item
......@@ -156,19 +332,7 @@ const WebComponentModule = () => {
});
return res;
}, [pageConfig]);
// const onModuleVisibleChange = (checked: boolean, option) => {
// const props = pageConfig[option.treeKey];
// changeProps({
// treeKey: option.treeKey,
// props: {
// ...props,
// visible: checked
// }
// });
// };
const platform = isWeb ? 'web' : 'mobile';
const handleChange = (isChecked: boolean, _item: keyof typeof ACTIVITYS_MAP) => {
console.log(modules, (isChecked), "_item", _item)
......@@ -184,13 +348,13 @@ const WebComponentModule = () => {
addChildComponent({
newKey: `${newKey}`,
componentName: 'WebCommodityContainer',
componentName: COMPONENT_NAME[_item][platform]['container'],
parentPropName: '',
parentKey: '0',
childProps: {
addBtnText: "添加子节点",
canDelete: false,
childComponentName: "WebCommodity",
childComponentName: COMPONENT_NAME[_item][platform]['childContainer'],
childNodes: [],
childProps: {
otherProps: {
......@@ -201,7 +365,6 @@ const WebComponentModule = () => {
props: {visible: true, theme: 0, title: ACTIVITYS_MAP[_item].title},
title: ACTIVITYS_MAP[_item].title,
}
})
}
......
......@@ -7,15 +7,16 @@ import { PlusOutlined } from '@ant-design/icons';
import omit from 'lodash/omit'
interface Iprops {
children,
children: React.ReactNode,
className: string
title: string,
visible?: boolean,
status?: boolean,
theme: number
}
const Combination: React.FC<Iprops> & { Item: typeof CombinationItem } = (props: Iprops) => {
const { children, className, title, theme, visible = true, ...other } = props;
const { children, className, title, theme, status = true, ...other } = props;
const visible = status
const classNameStr = cx(styles.combiantion, className, { [styles.hide]: !visible });
const omitGetOperateState = omit(other, 'getOperateState')
......
......@@ -20,6 +20,8 @@ interface Iprops extends GetMarketingAdornActivityGoodsAdornResponse {
title: string,
theme: 0 | 1 | 2,
visible: boolean,
/** 控制显示隐藏 */
status: boolean,
}
const CommodityList: React.FC<Iprops> & {
......@@ -29,7 +31,8 @@ const CommodityList: React.FC<Iprops> & {
SwapProduct: typeof SwapProduct
} =
(props: Iprops) => {
const { children, className, title, theme, visible = true, ...other } = props;
const { children, className, title, theme, status = true, ...other } = props;
const visible = status
const classNameStr = cx(styles.recommand, className, { [styles.hide]: !visible });
const { onClick, onDrag, onDragEnd, onDragEnter, onDragStart, onMouseOver, getOperateState } = other as any;
......@@ -100,10 +103,10 @@ const CommodityItem: React.FC<Iprops> = (props: Iprops) => {
const classNameStr = cx(styles.item, customizeClassName);
const rest = omit(other, ["draggable", "getOperateState", "onClick", "onDrag", "onDragEnd", "onDragEnter", "onDragStart", "onMouseOver"]);
const { onClick, onDrag, onDragEnd, onDragEnter, onDragStart, onMouseOver, getOperateState } = other as any;
const { onClick, onMouseOver, getOperateState } = other as any;
const divProps = {
onClick, onDrag, onDragEnd, onDragEnter, onDragStart, onMouseOver,
onClick, onMouseOver,
};
const {
......
......@@ -6,10 +6,6 @@ import classNames from 'classnames';
interface IChildprops {
className: string,
onClick: () => void,
onDrag: () => void,
onDragEnd: () => void,
onDragEnter: () => void,
onDragStart: () => void,
onMouseOver: () => void,
draggable?: boolean,
getOperateState: any,
......@@ -27,18 +23,23 @@ interface Iprops {
children: React.ReactNode,
title: string,
theme: 0 | 1 | 2,
visible: boolean,
status: boolean,
}
const CommodityWithProcess: React.FC<Iprops> & { Item: typeof Item} = (props: Iprops) => {
const { children, className, title, theme, visible = true, ...other } = props;
const classNameStr = classNames(styles.recommand, className, { [styles.hide]: !visible });
const { onClick, onDrag, onDragEnd, onDragEnter, onDragStart, onMouseOver, getOperateState } = other as any;
const { children, className, title, theme, status = true, ...other } = props;
const classNameStr = classNames(styles.recommand, className);
const { onClick, onMouseOver, getOperateState } = other as any;
const visible = status;
const divProps = {
onClick, onDrag, onDragEnd, onDragEnter, onDragStart, onMouseOver,
onClick, onMouseOver,
};
if (!visible) {
return null;
}
const renderChild = () => {
return (
<div>
......@@ -67,9 +68,9 @@ const CommodityWithProcess: React.FC<Iprops> & { Item: typeof Item} = (props: Ip
}
const Item: React.FC<IChildprops> = (props: IChildprops) => {
const { className, onClick, onDrag, onDragEnd, onDragEnter, onDragStart, onMouseOver, ...other } = props;
const { className, onClick, onMouseOver, ...other } = props;
const divProps = {
onClick, onDrag, onDragEnd, onDragEnter, onDragStart, onMouseOver,
onClick, onMouseOver,
};
return (
......
......@@ -11,26 +11,29 @@ const { CouponsItem } = MarketingCard;
interface Iprops {
children: React.ReactNode,
className: string,
visible: 0 | 1,
/** 控制显示隐藏 */
status: boolean,
// visible: 0 | 1,
onClick: () => void,
onDrag: () => void,
onDragEnd: () => void,
onDragEnter: () => void,
onDragStart: () => void,
// onDrag: () => void,
// onDragEnd: () => void,
// onDragEnter: () => void,
// onDragStart: () => void,
onMouseOver: () => void,
getOperateState: any,
}
const Coupon: React.FC<Iprops> & { Item: typeof CouponItem } = (props: Iprops) => {
const { children, className, visible = true, ...other } = props;
const { children, className, status = true, ...other } = props;
const visible = status;
const classNameStr = cx(
styles.container,
className,
);
const { onClick, onDrag, onDragEnd, onDragEnter, onDragStart, onMouseOver, getOperateState } = other;
const { onClick, onMouseOver, getOperateState } = other;
const divProps = {
onClick, onDrag, onDragEnd, onDragEnter, onDragStart, onMouseOver,
onClick, onMouseOver,
};
return (
<>
......
import React from 'react';
interface Iprops {
backgroundColor: string;
children: React.ReactNode,
}
const MobileLayout: React.FC<Iprops> = (props: Iprops) => {
const { children, backgroundColor } = props
return (
<div
style={{
width: "100%",
minHeight: "100%",
background: backgroundColor,
overflowX: "hidden",
paddingBottom: "50px",
}}
>
{children}
</div>
)
}
export default MobileLayout
\ No newline at end of file
......@@ -49,7 +49,6 @@ const WebCommodity: React.FC<Iprops> = (props: Iprops) => {
const renderLabels = () => {
const labels = productData.activityList.map((_item: ActivityListType) => _item.label).concat(productData.label).filter(Boolean);
console.log(labels);
return (
<div className={styles['commodity-info-tags']}>
{
......
......@@ -7,18 +7,25 @@ import { getIntl } from 'umi'
const intl = getIntl();
interface Iprops {
className: any,
children: any
children: React.ReactNode,
/** 控制显示隐藏 */
status: boolean,
}
const WrapCommodityList: React.FC<Iprops> = (props: Iprops) => {
// const intl = useIntl();
const { children, className, ...other } = props;
const { children, className, status = true, ...other } = props;
const visible = status;
const classNameStr = cx(className);
const { onClick, onDrag, onDragEnd, onDragEnter, onDragStart, onMouseOver, getOperateState } = other as any;
const { onClick, onMouseOver, getOperateState } = other as any;
if (!visible) {
return null;
}
const divProps = {
onClick, onDrag, onDragEnd, onDragEnter, onDragStart, onMouseOver,
onClick, onMouseOver,
};
const renderComponent = () => {
return (
......
......@@ -4,6 +4,7 @@ import CommodityList from './CommodityList';
import WrapCommodityList from './WrapCommodityList';
import Combination from './Combination';
import CommodityWithProcess from './CommodityWithProcess';
import MobileLayout from './MobileLayout';
/** WEB */
import WebAdvertise from './WebAdvertise';
......@@ -16,6 +17,7 @@ import WebCommodity from './WebCommodity/item'
import WebCustomCommodity from './WebCustomCommodity';
export default {
MobileLayout,
Advertisement,
Coupon,
CommodityList,
......
......@@ -44,6 +44,7 @@
top: 0;
display: none;
padding-top: 32px;
z-index: 99;
}
&:hover {
......
@content-height: calc(100vh - 120px);
.page {
position: relative;
:global {
.ant-spin-nested-loading > div > .ant-spin,
.ant-spin-spinning {
position: absolute;
top: 50%;
left: 50%;
height: 80px;
transform: translate(-50%, -50%);
}
.ant-spin-blur {
opacity: 0;
}
}
.loading {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
margin-top: 40px;
font-size: 20px;
font-weight: 600;
}
}
.wrapper {
background: white;
display: flex;
......@@ -41,6 +70,9 @@
align-items: center;
justify-content: center;
}
.ant-tabs-ink-bar {
display: none;
}
}
.module {
......
import { useIntl } from 'umi';
import { useState } from 'react';
import { Spin, message , Tabs } from 'antd';
import { BrickProvider, ModuleTree } from '@linkseeks/design-react';
import { omit, pick } from 'lodash';
import { history } from 'umi';
import { BrickProvider, ModuleTreeCollapse } from '@linkseeks/design-react';
import MobileDesignPanel from './components/MobileDesignPanel';
import Toolbar from './components/Toolbar';
import styles from './index.less';
import EditPanel from './components/EditPanel/editPanelForm';
import configs from './common/configs/pageConfigs';
import Module from './components/ComponentTree';
import Module from './components/ComponentTree/web';
import ToolbarSubmit from './components/Toolbar/toolbarSubmit';
import { RenovationProvider } from './common/context/shopContext';
import { usePageStatus } from '@/hooks/usePageStatus';
import useGetLayout from './common/hooks/useGetLayout';
import { postTemplateWebActivityPageAdorn } from '@/services/TemplateV2Api';
import useSaveData from './common/hooks/useSaveData';
const { TabPane } = Tabs;
const primaryKey = ["hot", "specialOffer", "plummet", "discount", "fullQuantitySub", "fullQuantityDiscount", "fullMoneySub", "fullMoneyDiscount", "giveProduct", "giveCoupon", "morePiece", "combination", "groupPurchase", "bargain", "secKill", "fullSwap", "buySwap", "preSale", "setMeal", "attempt"];
const Fixtures = () => {
const intl = useIntl();
const { id } = usePageStatus();
const { detail, loading } = useGetLayout();
// const { detail, loading } = useGetData(componentConfigs as any);
const [submitLoading, setSubmitLoading] = useState<boolean>(false);
const onSave = async (pageConfig: any) => {
const childNodes = pageConfig[0].childNodes;
setSubmitLoading(true);
let result: any = {};
childNodes.map((_item, _index) => {
const target = pageConfig[_item];
const childNodes = target.childNodes;
const { props } = target || {};
const dataIndex = target.otherProps.type;
const sort = _index + 1;
if (dataIndex === 'top') {
const current = { sort: sort, props: omit(props, 'style') };
result = generaterData(result, dataIndex, current);
} else if(dataIndex === 'coupon') {
const childrenData = childNodes.map((_record) => {
const childTargetProps = pageConfig[_record].props;
if(!childTargetProps?.id) {
return null
}
return {
id: childTargetProps.id,
type: childTargetProps.belongType
};
}).filter(Boolean);
result = generaterData(result, dataIndex, {
sort: sort,
props: {
...pick(props, ['theme', 'visible']),
childrenData: childrenData
}
});
} else if (primaryKey.includes( dataIndex )) {
const { ...otherProps } = props || {};
const childrenData = childNodes.map((_record) => {
const childTargetProps = pageConfig[_record].props;
return childTargetProps.id;
});
// const childrenData = products?.map((_item) => _item.id) || [];
result = generaterData(result, dataIndex, {
sort: sort,
props: {
...pick(otherProps, ['theme', 'visible', 'title']),
childrenData: childrenData
}
});
} else if (dataIndex === 'suggestProduct') {
const { ...otherProps } = props || {};
const { childNodes } = target;
const temp = {
sort: sort,
props: {
visible: true,
childrenData: childNodes?.filter((_record) => /\d+-\d+/.test(_record)).map((_row) => {
const childrenNodeTarget = pageConfig[_row];
const { ...childRestProps } = childrenNodeTarget?.props;
return {
title: childRestProps.title,
theme: childRestProps.theme || 0,
childrenData: childrenNodeTarget.childNodes?.map((_listItem) => {
const sonNodeTarget = pageConfig[_listItem];
return {
id: sonNodeTarget?.props.id,
label: sonNodeTarget?.props?.label || []
};
})
};
})
}
};
result = generaterData(result, dataIndex, temp);
}
});
const { data, code } = await postTemplateWebActivityPageAdorn({
id: +id,
adornContent: result
} as any);
setSubmitLoading(false);
if (code === 1000) {
history.goBack();
}
};
const generaterData = (source: { [key: string]: any }, dataIndex: string, assignData: {[key: string]: any} ) => {
const result = Object.assign(source, {
[dataIndex]: assignData
});
return result;
};
const { saving, onSave } = useSaveData({ id: +id });
return (
<div className={styles.page}>
<Spin spinning={loading}>
<BrickProvider
config={configs}
......@@ -125,16 +32,26 @@ const Fixtures = () => {
}}
>
<div className={styles['wrapper']}>
<Toolbar title={intl.formatMessage({ id: 'activityPage.editingShopActivityPage' })} extra={<ToolbarSubmit loading={submitLoading} onSubmit={onSave}>{ intl.formatMessage({ id: 'activePage.save'}) }</ToolbarSubmit>} />
<Toolbar
title={intl.formatMessage({ id: 'activityPage.editingShopActivityPage' })}
extra={
<ToolbarSubmit loading={saving}
onSubmit={onSave}
>
{ intl.formatMessage({ id: 'activePage.save'}) }
</ToolbarSubmit>
}
/>
<div className={styles['content']}>
<div className={styles.tree}>
<Tabs >
<TabPane tab={intl.formatMessage({ id: 'activityPage.alreadyAdd' })} key="1">
<ModuleTree />
{/* <ModuleTree /> */}
<ModuleTreeCollapse />
</TabPane>
<TabPane tab={intl.formatMessage({ id: 'activityPage.allModules' })} key="2">
<div className={styles.module}>
<Module />
<Module isWeb={false} />
</div>
</TabPane>
</Tabs>
......@@ -152,6 +69,15 @@ const Fixtures = () => {
</BrickProvider>
</Spin>
{
loading && (
<div className={styles.loading}>
正在加载中
</div>
) || null
}
</div>
);
};
......
@content-height: calc(100vh - 120px);
.container {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
:global {
.ant-spin-nested-loading > div > .ant-spin,
.ant-spin-spinning {
position: fixed;
top: 50%;
left: 50%;
height: 80px;
transform: translate(-50%, -50%);
}
.ant-spin-blur {
opacity: 0;
}
}
.loading {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
margin-top: 40px;
font-size: 20px;
font-weight: 600;
}
}
.page {
position: fixed;
top: 0;
......
import React, { useRef, useState } from 'react';
import { message, Spin, Tabs } from 'antd'
import { BrickProvider, ModuleTree } from '@linkseeks/design-react';
import { BrickProvider, ModuleTreeCollapse } from '@linkseeks/design-react';
import className from 'classnames'
import { LeftOutlined, RightOutlined } from '@ant-design/icons';
import Toolbar from './components/Toolbar';
import styles from './web.less';
import { useIntl, history } from 'umi';
import ToolbarSubmit from './components/Toolbar/toolbarSubmit';
import useGetLayout from './common/hooks/useGetLayout';
import configs from './common/configs/pageConfigs';
import WebDesignPanel from './components/WebDesignPanel';
import WebEditPanel from './components/WebEditPanel';
......@@ -15,10 +13,9 @@ import { RenovationProvider } from './common/context/shopContext';
import useGetWebLayout from './common/hooks/useGetWebLayout';
import useDraggable from './common/hooks/useDrag';
import WebScale from './components/WebScale';
import { omit, pick } from 'lodash';
import { usePageStatus } from '@/hooks/usePageStatus';
import { postTemplateWebActivityPageAdorn } from '@/services/TemplateV2Api';
import Module from './components/ComponentTree/web';
import useSaveData from './common/hooks/useSaveData';
const TabPane = Tabs.TabPane
......@@ -26,122 +23,19 @@ const Web = () => {
const el = useRef<HTMLDivElement>(null);
// useDraggable(el);
const { id } = usePageStatus();
// const [scale, setScale] = useState(0.75);
const [scale, setScale] = useState(0.75);
const { saving, onSave } = useSaveData({ id: +id });
const [leftBarVisible, setLeftBarVisible] = useState<boolean>(true);
const { detail, loading } = useGetWebLayout();
const [submitLoading, setSubmitLoading] = useState<boolean>(false);
const intl = useIntl();
const primaryKey = [
"hot", "specialOffer", "plummet", "discount", "fullQuantitySub", "fullQuantityDiscount", "fullMoneySub", "fullMoneyDiscount", "giveProduct", "giveCoupon", "morePiece", "combination", "groupPurchase", "bargain", "secKill", "fullSwap", "buySwap", "preSale", "setMeal", "attempt"
] as const;
const generaterData = (source: { [key: string]: any }, dataIndex: string, assignData: {[key: string]: any} ) => {
const result = Object.assign(source, {
[dataIndex]: assignData
});
return result;
};
const onSave = async (pageConfig: any) => {
const childNodes = pageConfig[0].childNodes;
setSubmitLoading(true);
let result: any = {};
childNodes.map((_item, _index) => {
const target = pageConfig[_item];
const childNodes = target.childNodes;
const { props } = target || {};
const dataIndex = target.otherProps.type;
const sort = _index + 1;
if (dataIndex === 'top') {
const current = { sort: sort, props: omit(props, 'style') };
result = generaterData(result, dataIndex, current);
} else if(dataIndex === 'coupon') {
const childrenData = childNodes.map((_record) => {
const childTargetProps = pageConfig[_record].props;
if(!childTargetProps?.id) {
return null
}
return {
id: childTargetProps.id,
type: childTargetProps.belongType
};
}).filter(Boolean);
result = generaterData(result, dataIndex, {
sort: sort,
props: {
...pick(props, ['theme']),
visible: props.status ?? true,
childrenData: childrenData
}
});
} else if (primaryKey.includes( dataIndex )) {
const { ...otherProps } = props || {};
const childrenData = childNodes.map((_record) => {
const childTargetProps = pageConfig[_record].props;
return childTargetProps.id;
});
// const childrenData = products?.map((_item) => _item.id) || [];
result = generaterData(result, dataIndex, {
sort: sort,
props: {
...pick(otherProps, ['theme', 'title']),
visible: props.status ?? true,
childrenData: childrenData
}
});
} else if (dataIndex === 'suggestProduct') {
const { ...otherProps } = props || {};
const { childNodes } = target;
const temp = {
sort: sort,
props: {
visible: otherProps.status ?? true,
childrenData: childNodes?.filter((_record) => /\d+-\d+/.test(_record)).map((_row) => {
const childrenNodeTarget = pageConfig[_row];
const { ...childRestProps } = childrenNodeTarget?.props;
return {
title: childRestProps.title,
theme: childRestProps.theme || 0,
childrenData: childrenNodeTarget.childNodes?.map((_listItem) => {
const sonNodeTarget = pageConfig[_listItem];
return {
id: sonNodeTarget?.props.id,
label: sonNodeTarget?.props?.label || []
};
})
};
})
}
};
result = generaterData(result, dataIndex, temp);
}
});
const withThemeStyle = {
...result,
themeStyle: {
sort: 0,
props: {
color: pageConfig[0].props.backgroundColor
}
}
}
const { data, code } = await postTemplateWebActivityPageAdorn({
id: +id,
adornContent: withThemeStyle
} as any);
setSubmitLoading(false);
if (code === 1000) {
history.goBack();
}
const onChangeScale = (value: number) => {
setScale(value);
}
// const onChangeScale = (value: number) => {
// setScale(value);
// }
return (
<div className={styles.container}>
<Spin spinning={loading}>
<BrickProvider
config={configs}
......@@ -155,7 +49,7 @@ const Web = () => {
title={intl.formatMessage({ id: 'activityPage.editingShopActivityPage' })}
extra={
<ToolbarSubmit
loading={submitLoading}
loading={saving}
onSubmit={onSave}
>
{ intl.formatMessage({ id: 'activePage.save'}) }
......@@ -171,7 +65,7 @@ const Web = () => {
<div className={styles['module-tree']}>
<Tabs >
<TabPane tab={intl.formatMessage({ id: 'activityPage.alreadyAdd' })} key="1">
<ModuleTree />
<ModuleTreeCollapse />
</TabPane>
<TabPane tab={intl.formatMessage({ id: 'activityPage.allModules' })} key="2">
<div className={styles.module}>
......@@ -189,13 +83,13 @@ const Web = () => {
<div className={styles['screen-view-inner']} >
<div
className={styles['screen-view-content']}
// style={
// {
// transform: `scale(${scale})`,
style={
{
transform: `scale(${scale})`,
// marginLeft: `-${(SCREEN_VIEW_WIDTH * scale) / 2}px`,
// marginTop: `-${(1600 * scale) / 2}px`
// }
// }
}
}
>
<WebDesignPanel theme={'theme-mall-science'} />
</div>
......@@ -206,10 +100,18 @@ const Web = () => {
<WebEditPanel />
</RenovationProvider>
</div>
{/* <WebScale scaleValue={scale as 0.75} onChange={onChangeScale} /> */}
<WebScale scaleValue={scale as 0.75} onChange={onChangeScale} />
</div>
</BrickProvider>
</Spin>
{
loading && (
<div className={styles.loading}>
正在加载中
</div>
) || null
}
</div>
)
}
......
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