Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
J
jinfa-admin
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linweijiong
jinfa-admin
Commits
0d3450e8
Commit
0d3450e8
authored
Sep 26, 2021
by
Bill
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: 平台活动页修改
parent
b7c021d2
Hide whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
1733 additions
and
247 deletions
+1733
-247
index.tsx
...esManagement/activePage/fixtures/common/configs/index.tsx
+0
-1
schema.ts
...esManagement/activePage/fixtures/common/configs/schema.ts
+7
-1
useGetLayout.ts
...nagement/activePage/fixtures/common/hooks/useGetLayout.ts
+371
-0
useGetSameKeys.tsx
...ement/activePage/fixtures/common/hooks/useGetSameKeys.tsx
+4
-1
index.json
...tiesManagement/activePage/fixtures/common/mock/index.json
+4
-21
index.tsx
...nt/activePage/fixtures/components/ComponentTree/index.tsx
+4
-3
index.tsx
...ent/activePage/fixtures/components/CouponSelect/index.tsx
+1
-1
editPanelForm.tsx
...ctivePage/fixtures/components/EditPanel/editPanelForm.tsx
+245
-0
index.less
...ement/activePage/fixtures/components/EditPanel/index.less
+108
-19
schema.tsx
...ement/activePage/fixtures/components/EditPanel/schema.tsx
+74
-0
index.less
...ge/fixtures/components/EditPanelFormily/Coupon/index.less
+32
-0
index.tsx
...age/fixtures/components/EditPanelFormily/Coupon/index.tsx
+184
-0
index.tsx
...ures/components/EditPanelFormily/FormilyProduct/index.tsx
+116
-0
index.tsx
...ePage/fixtures/components/Layouts/Advertisement/index.tsx
+1
-1
index.less
...Page/fixtures/components/Layouts/CommodityList/index.less
+1
-76
index.tsx
...ePage/fixtures/components/Layouts/CommodityList/index.tsx
+81
-102
swapCoupon.less
...fixtures/components/Layouts/CommodityList/swapCoupon.less
+56
-0
swapCoupon.tsx
.../fixtures/components/Layouts/CommodityList/swapCoupon.tsx
+84
-0
swapProduct.less
...ixtures/components/Layouts/CommodityList/swapProduct.less
+71
-0
swapProduct.tsx
...fixtures/components/Layouts/CommodityList/swapProduct.tsx
+84
-0
tabFooter.less
.../fixtures/components/Layouts/CommodityList/tabFooter.less
+42
-0
tabFooter.tsx
...e/fixtures/components/Layouts/CommodityList/tabFooter.tsx
+28
-0
tabbar.less
...age/fixtures/components/Layouts/CommodityList/tabbar.less
+34
-0
tabbar.tsx
...Page/fixtures/components/Layouts/CommodityList/tabbar.tsx
+46
-0
index.tsx
...t/activePage/fixtures/components/Layouts/Coupon/index.tsx
+19
-4
index.tsx
...rketingActivitiesManagement/activePage/fixtures/index.tsx
+24
-16
useFilterSameOption.tsx
...d/categoryNavigation/common/hooks/useFilterSameOption.tsx
+1
-0
editPanel.tsx
...zed/categoryNavigation/components/EditPanel/editPanel.tsx
+1
-1
index.ts
src/utils/index.ts
+10
-0
No files found.
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/common/configs/index.tsx
View file @
0d3450e8
...
...
@@ -20,7 +20,6 @@ const mallLayoutConfig: PageConfigType = {
}
},
"childNodes"
:
[
"1"
,
"2"
,
"3"
,
"4"
,
"5"
,
"6"
,
"7"
,
"8"
,
"9"
,
"10"
,
"11"
,
"12"
,
"13"
,
"14"
,
"15"
,
"16"
,
"17"
,
"18"
,
"19"
,
"20"
,
"21"
,
"22"
,
"23"
]
},
};
...
...
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/common/configs/schema.ts
View file @
0d3450e8
...
...
@@ -95,7 +95,13 @@ const CommodityList = {
type
:
"ProductPanel"
,
// 这里说明打开什么样的修改panel
},
}
}
},
"CommodityList.SwapCoupon"
:
{
propsConfig
:
{}
},
"CommodityList.SwapProduct"
:
{
propsConfig
:
{}
},
};
const
WrapCommodityList
=
{
...
...
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/common/hooks/useGetLayout.ts
0 → 100644
View file @
0d3450e8
import
React
,
{
useEffect
,
useState
}
from
'react'
;
import
omit
from
'lodash/omit'
;
import
{
updatePageConfig
}
from
'@lingxi-disign/core'
;
import
DEFAULT_DATA
from
'../mock/index.json'
;
import
{
GetTemplateWebActivityPageGetResponse
}
from
'@/services/Template2Api'
;
import
{
usePageStatus
}
from
'@/hooks/usePageStatus'
;
import
{
PublicApi
}
from
'@/services/api'
;
import
{
arrayToMap
}
from
'@/utils'
;
type
DataSourceItemType
=
{
sort
:
number
,
dataIndex
:
string
,
props
:
{
theme
?:
0
|
1
|
2
&
number
,
visible
:
boolean
,
childrenData
?:
any
[]
}
&
{
[
propKeys
:
string
]:
any
}
}
type
DataSourceType
=
{
[
key
:
string
]:
DataSourceItemType
}
type
DetailType
=
Omit
<
GetTemplateWebActivityPageGetResponse
,
"adornContent"
>
&
{
adornContent
:
DataSourceType
}
/** 请求钱处理 */
const
formatData
=
{
coupon
:
(
data
:
{
id
:
number
,
type
:
1
|
2
|
number
&
{}
}[])
=>
{
return
{
couponList
:
data
.
map
((
_item
)
=>
({
belongType
:
_item
.
type
,
couponId
:
_item
.
id
}))
};
},
hot
:
(
data
:
number
[])
=>
({
ids
:
data
}),
specialOffer
:
(
data
:
number
[])
=>
({
ids
:
data
}),
plummet
:
(
data
:
number
[])
=>
({
ids
:
data
}),
discount
:
(
data
:
number
[])
=>
({
ids
:
data
}),
fullQuantitySub
:
(
data
:
number
[])
=>
({
ids
:
data
}),
fullQuantityDiscount
:
(
data
:
number
[])
=>
({
ids
:
data
}),
fullMoneySub
:
(
data
:
number
[])
=>
({
ids
:
data
}),
fullMoneyDiscount
:
(
data
:
number
[])
=>
({
ids
:
data
}),
giveProduct
:
(
data
:
number
[])
=>
({
ids
:
data
}),
giveCoupon
:
(
data
:
number
[])
=>
({
ids
:
data
}),
morePiece
:
(
data
:
number
[])
=>
({
ids
:
data
}),
combination
:
(
data
:
number
[])
=>
({
ids
:
data
}),
groupPurchase
:
(
data
:
number
[])
=>
({
ids
:
data
}),
bargain
:
(
data
:
number
[])
=>
({
ids
:
data
}),
secKill
:
(
data
:
number
[])
=>
({
ids
:
data
}),
fullSwap
:
(
data
:
number
[])
=>
({
ids
:
data
}),
buySwap
:
(
data
:
number
[])
=>
({
ids
:
data
}),
preSale
:
(
data
:
number
[])
=>
({
ids
:
data
}),
setMeal
:
(
data
:
number
[])
=>
({
ids
:
data
}),
attempt
:
(
data
:
number
[])
=>
({
ids
:
data
}),
// suggestProductItem: (data: number[]) => ({ids: data.map((_item))}),
};
/** key 对应组件名 */
const
COMPONENT_NAME
=
{
top
:
'Advertisement'
,
coupon
:
'Coupon'
,
hot
:
"CommodityList"
,
plummet
:
"CommodityList"
,
discount
:
"CommodityList"
,
fullQuantitySub
:
"CommodityList"
,
fullQuantityDiscount
:
"CommodityList"
,
fullMoneySub
:
"CommodityList"
,
fullMoneyDiscount
:
"CommodityList"
,
giveProduct
:
"CommodityList"
,
giveCoupon
:
"CommodityList"
,
morePiece
:
"CommodityList"
,
combination
:
"CommodityList"
,
groupPurchase
:
"CommodityList"
,
bargain
:
"CommodityList"
,
secKill
:
"CommodityList"
,
fullSwap
:
"CommodityList"
,
buySwap
:
"CommodityList"
,
preSale
:
"CommodityList"
,
setMeal
:
"CommodityList"
,
attempt
:
"CommodityList"
,
suggestProduct
:
"WrapCommodityList"
,
};
/** key 对应子节点ComponentName */
const
CHILD_COMPONENT_NAME
=
{
coupon
:
'Coupon.Item'
,
hot
:
"CommodityList.Item"
,
plummet
:
"CommodityList.Item"
,
discount
:
"CommodityList.Item"
,
fullQuantitySub
:
"CommodityList.Item"
,
fullQuantityDiscount
:
"CommodityList.Item"
,
fullMoneySub
:
"CommodityList.Item"
,
fullMoneyDiscount
:
"CommodityList.Item"
,
giveProduct
:
"CommodityList.SwapProduct"
,
giveCoupon
:
"CommodityList.SwapCoupon"
,
morePiece
:
"CommodityList.Item"
,
combination
:
"CommodityList.Item"
,
groupPurchase
:
"CommodityList.Item"
,
bargain
:
"CommodityList.Item"
,
secKill
:
"CommodityList.Item"
,
fullSwap
:
"CommodityList.Item"
,
buySwap
:
"CommodityList.Item"
,
preSale
:
"CommodityList.Item"
,
setMeal
:
"CommodityList.CommodityTab"
,
attempt
:
"CommodityList.Item"
,
// suggestProduct: "WrapCommodityList",
};
/**
* key 对应接口
*/
const
service
=
{
coupon
:
PublicApi
.
postMarketingCouponPlatformActivityPageSelectDetail
,
hot
:
PublicApi
.
getMarketingAdornActivityGoodsAdorn
,
specialOffer
:
PublicApi
.
getMarketingAdornActivityGoodsAdorn
,
plummet
:
PublicApi
.
getMarketingAdornActivityGoodsAdorn
,
discount
:
PublicApi
.
getMarketingAdornActivityGoodsAdorn
,
fullQuantitySub
:
PublicApi
.
getMarketingAdornActivityGoodsAdorn
,
fullQuantityDiscount
:
PublicApi
.
getMarketingAdornActivityGoodsAdorn
,
fullMoneySub
:
PublicApi
.
getMarketingAdornActivityGoodsAdorn
,
fullMoneyDiscount
:
PublicApi
.
getMarketingAdornActivityGoodsAdorn
,
giveProduct
:
PublicApi
.
getMarketingAdornActivityGoodsAdorn
,
giveCoupon
:
PublicApi
.
getMarketingAdornActivityGoodsAdorn
,
morePiece
:
PublicApi
.
getMarketingAdornActivityGoodsAdorn
,
combination
:
PublicApi
.
getMarketingAdornActivityGoodsAdorn
,
groupPurchase
:
PublicApi
.
getMarketingAdornActivityGoodsAdorn
,
bargain
:
PublicApi
.
getMarketingAdornActivityGoodsAdorn
,
secKill
:
PublicApi
.
getMarketingAdornActivityGoodsAdorn
,
fullSwap
:
PublicApi
.
getMarketingAdornActivityGoodsAdorn
,
buySwap
:
PublicApi
.
getMarketingAdornActivityGoodsAdorn
,
preSale
:
PublicApi
.
getMarketingAdornActivityGoodsAdorn
,
setMeal
:
PublicApi
.
getMarketingAdornActivityGoodsAdorn
,
attempt
:
PublicApi
.
getMarketingAdornActivityGoodsAdorn
,
suggestProductItem
:
PublicApi
.
getMarketingAdornActivityGoodsAdorn
,
};
const
DEFAULT_RES
=
[];
const
COMMON_FORMAT
=
({
code
,
data
})
=>
{
if
(
code
===
1000
)
{
return
data
;
}
return
DEFAULT_RES
;
};
/**
* 请求后处理
*/
const
afterRequestFormat
=
{
coupon
:
COMMON_FORMAT
,
hot
:
COMMON_FORMAT
,
specialOffer
:
COMMON_FORMAT
,
plummet
:
COMMON_FORMAT
,
discount
:
COMMON_FORMAT
,
fullQuantitySub
:
COMMON_FORMAT
,
fullQuantityDiscount
:
COMMON_FORMAT
,
fullMoneySub
:
COMMON_FORMAT
,
fullMoneyDiscount
:
COMMON_FORMAT
,
giveProduct
:
COMMON_FORMAT
,
giveCoupon
:
COMMON_FORMAT
,
morePiece
:
COMMON_FORMAT
,
combination
:
COMMON_FORMAT
,
groupPurchase
:
COMMON_FORMAT
,
bargain
:
COMMON_FORMAT
,
secKill
:
COMMON_FORMAT
,
fullSwap
:
COMMON_FORMAT
,
buySwap
:
COMMON_FORMAT
,
preSale
:
COMMON_FORMAT
,
setMeal
:
COMMON_FORMAT
,
suggestProductItem
:
COMMON_FORMAT
,
};
const
title
=
{
top
:
'广告图'
,
coupon
:
'优惠券'
,
hot
:
'活动推荐'
};
function
useGetLayout
()
{
const
{
id
}
=
usePageStatus
();
const
[
detail
,
setDetail
]
=
useState
<
DetailType
|
null
>
(
null
);
const
[
loading
,
setLoading
]
=
useState
<
boolean
>
(
false
);
useEffect
(()
=>
{
let
isValid
=
true
;
async
function
fetchData
()
{
setLoading
(
true
);
const
{
code
,
data
}
=
await
PublicApi
.
getTemplateWebActivityPageGet
({
id
:
id
});
if
(
!
isValid
)
{
return
;
}
setLoading
(
false
);
if
(
code
===
1000
)
{
const
isEmptyObject
=
Object
.
keys
(
data
.
adornContent
).
length
===
0
;
console
.
log
(
DEFAULT_DATA
);
const
tempData
=
{
...
data
,
adornContent
:
isEmptyObject
?
DEFAULT_DATA
:
data
.
adornContent
};
// setDetail(isEmptyObject ? DEFAULT_DATA : data as unknown as DetailType);
setDetail
(
tempData
as
unknown
as
DetailType
);
}
}
fetchData
();
return
()
=>
{
isValid
=
false
;
};
},
[
id
]);
/** 设置pageConfig */
useEffect
(()
=>
{
if
(
!
detail
)
{
return
;
}
console
.
log
(
detail
);
/** @review 该方法需要优化,因为suggestProduct 写多了一遍 */
async
function
setData
()
{
const
{
adornContent
}
=
detail
!
;
let
startKey
=
0
;
const
firstChildKeys
:
string
[]
=
[];
let
pageConfig
=
{};
/** 未排序数组 */
const
dataSourceList
:
{
key
:
keyof
typeof
adornContent
,
sort
:
number
}[]
=
[];
Object
.
keys
(
adornContent
).
map
((
_item
:
keyof
typeof
adornContent
)
=>
{
dataSourceList
.
push
({
key
:
_item
,
sort
:
adornContent
[
_item
].
sort
});
});
const
sortedList
=
dataSourceList
.
sort
((
a
,
b
)
=>
a
.
sort
-
b
.
sort
);
for
(
const
_row
of
sortedList
)
{
startKey
=
startKey
+
1
;
firstChildKeys
.
push
(
startKey
.
toString
());
const
target
=
adornContent
[
_row
.
key
];
const
currentProps
=
target
.
props
;
const
childrenData
=
currentProps
.
childrenData
||
[];
const
props
=
_row
.
key
===
'top'
?
{
imageUrl
:
currentProps
.
imageUrl
}
:
{
visible
:
currentProps
.
visible
||
true
,
theme
:
currentProps
.
theme
||
0
,
title
:
currentProps
.
title
,
};
const
childPropsData
=
_row
.
key
===
'top'
?
{}
:
{
childComponentName
:
`
${
CHILD_COMPONENT_NAME
[
_row
.
key
]}
`
,
addBtnText
:
'添加子节点'
,
childProps
:
{
otherProps
:
{
type
:
`
${
_row
.
key
}
Item`
}
},
};
let
tempConfig
=
{
componentName
:
COMPONENT_NAME
[
_row
.
key
],
title
:
title
[
_row
.
key
]
||
currentProps
.
title
,
props
:
props
,
otherProps
:
{
type
:
_row
.
key
},
canDelete
:
false
,
...
childPropsData
,
childNodes
:
[],
};
const
childNodesKeys
:
string
[]
=
[];
if
(
childrenData
.
length
>
0
&&
_row
.
key
!==
'suggestProduct'
)
{
const
formatedData
=
formatData
[
_row
.
key
]?.(
childrenData
);
const
requestData
=
await
service
[
_row
.
key
]?.(
formatedData
);
const
afterRequestFormatedData
=
afterRequestFormat
[
_row
.
key
]?.(
requestData
);
afterRequestFormatedData
?.
forEach
((
_item
,
_index
)
=>
{
const
keyNum
=
`
${
startKey
}
-
${
_index
+
1
}
`
;
childNodesKeys
.
push
(
keyNum
);
const
sonConfig
=
{
componentName
:
`
${
CHILD_COMPONENT_NAME
[
_row
.
key
]}
`
,
title
:
_item
?.
productName
||
_item
.
name
,
props
:
{
...
_item
,
},
otherProps
:
{
type
:
`
${
_row
.
key
}
Item`
},
childNodes
:
[]
};
pageConfig
[
keyNum
]
=
sonConfig
;
});
}
else
if
(
_row
.
key
===
'suggestProduct'
)
{
// const suggestDataKeys: string[] = [];
let
_index
=
0
;
for
(
const
_item
of
childrenData
)
{
const
keyNum
=
`
${
startKey
}
-
${
++
_index
}
`
;
childNodesKeys
.
push
(
keyNum
);
const
suggestConfig
=
{
componentName
:
'CommodityList'
,
title
:
_item
.
title
,
props
:
{
title
:
_item
.
title
,
theme
:
_item
.
theme
,
},
otherProps
:
{
type
:
_row
.
key
},
childNodes
:
[],
};
const
suggestSonKeys
:
string
[]
=
[];
if
(
_item
.
childrenData
?.
length
>
0
)
{
const
requestData
=
await
service
[
"suggestProductItem"
]?.({
ids
:
_item
.
childrenData
.
map
((
_u
)
=>
_u
.
id
)});
const
arrayToMapData
=
arrayToMap
(
_item
.
childrenData
,
"id"
);
// console.log(requestData, _item.childrenData, arrayToMapData);
const
afterRequestFormatedData
=
afterRequestFormat
[
"suggestProductItem"
]?.(
requestData
);
// console.log(afterRequestFormatedData, arrayToMapData);
afterRequestFormatedData
?.
forEach
((
_item
,
_itemIndex
)
=>
{
const
sonKeyNum
=
`
${
keyNum
}
-
${
_itemIndex
+
1
}
`
;
suggestSonKeys
.
push
(
sonKeyNum
);
const
sonConfig
=
{
componentName
:
`CommodityList.Item`
,
title
:
_item
?.
productName
||
_item
.
name
,
props
:
{
...
_item
,
label
:
arrayToMapData
[
_item
.
id
]?.
label
},
otherProps
:
{
type
:
`suggestProductItem`
},
childNodes
:
[]
};
pageConfig
[
sonKeyNum
]
=
sonConfig
;
});
}
pageConfig
[
keyNum
]
=
{
...
suggestConfig
,
childNodes
:
suggestSonKeys
,
};
}
// childNodesKeys
}
tempConfig
=
{
...
tempConfig
,
childNodes
:
childNodesKeys
};
pageConfig
[
startKey
]
=
tempConfig
;
}
pageConfig
=
{
0
:
{
"componentName"
:
"MallLayout"
,
title
:
'组件树'
,
"props"
:
{
"style"
:
{
"width"
:
"100%"
,
"minHeight"
:
"100%"
,
"background"
:
"#DD3041"
,
"overflowX"
:
"hidden"
,
"paddingBottom"
:
"50px"
,
}
},
"childNodes"
:
firstChildKeys
},
...
pageConfig
,
};
console
.
log
(
"pageConfig"
,
pageConfig
);
updatePageConfig
(
pageConfig
);
}
setData
();
},
[
detail
]);
return
{
detail
,
loading
};
}
export
default
useGetLayout
;
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/common/hooks/useGetSameKeys.tsx
View file @
0d3450e8
...
...
@@ -69,7 +69,10 @@ const useGetSameKeys = () => {
if
(
!
element
)
{
return
;
}
const
{
dataIndex
,
childNodes
}
=
element
;
// const { dataIndex, childNodes, otherProps: { type } } = element;
const
{
childNodes
,
otherProps
:
{
type
}
}
=
element
;
const
dataIndex
=
type
;
/** 活动广告图 直接跳过 */
if
(
dataIndex
===
'top'
)
{
return
;
...
...
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/common/mock/index.json
View file @
0d3450e8
...
...
@@ -12,10 +12,7 @@
"props"
:
{
"theme"
:
0
,
"visible"
:
true
,
"childrenData"
:
[
{
"id"
:
4
,
"type"
:
1
},
{
"id"
:
57
,
"type"
:
2
}
]
"childrenData"
:
[]
}
},
"hot"
:{
...
...
@@ -23,7 +20,8 @@
"props"
:
{
"theme"
:
0
,
"visible"
:
true
,
"childrenData"
:
[
26
]
"title"
:
"活动推荐"
,
"childrenData"
:
[]
}
},
"specialOffer"
:{
...
...
@@ -201,22 +199,7 @@
"sort"
:
23
,
"props"
:
{
"visible"
:
true
,
"childrenData"
:[
{
"title"
:
"应季爆款1"
,
"theme"
:
1
,
"childrenData"
:
[
{
"id"
:
26
,
"label"
:[
"特价"
,
"满299减30"
]}
]
},
{
"title"
:
"应季爆款2"
,
"theme"
:
0
,
"childrenData"
:
[
{
"id"
:
26
,
"label"
:[
"特价"
,
"满299减30"
]}
]
}
]
"childrenData"
:[]
}
}
}
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/components/ComponentTree/index.tsx
View file @
0d3450e8
import
React
,
{
useMemo
}
from
'react'
;
import
{
useSelector
}
from
'@lingxi-disign/react'
;
import
{
changeProps
}
from
'@lingxi-disign/core'
;
import
ComponentModule
from
'./ComponentModule'
;
import
styles
from
'./index.less'
;
import
attemptImg
from
'@/asserts/activity/attempt.png'
;
import
bargainImg
from
'@/asserts/activity/bargain.png'
;
import
buySwapImg
from
'@/asserts/activity/buySwap.png'
;
...
...
@@ -21,8 +23,6 @@ import discountImg from '@/asserts/activity/discount.png';
import
specialOfferImg
from
'@/asserts/activity/specialOffer.png'
;
import
giveCouponImg
from
'@/asserts/activity/giveCoupon.png'
;
import
ComponentModule
from
'./ComponentModule'
;
import
styles
from
'./index.less'
;
const
ACTIVITYS
=
[
"specialOffer"
,
"plummet"
,
"discount"
,
"fullQuantitySub"
,
"fullQuantityDiscount"
,
"fullMoneySub"
,
"fullMoneyDiscount"
,
"giveProduct"
,
"giveCoupon"
,
"morePiece"
,
"combination"
,
"groupPurchase"
,
"bargain"
,
"secKill"
,
"fullSwap"
,
"buySwap"
,
"preSale"
,
"setMeal"
,
"attempt"
];
...
...
@@ -40,7 +40,8 @@ const ModuleContainer = () => {
const
config
=
pageConfig
;
const
res
:
ModuleType
[]
=
[];
Object
.
keys
(
config
).
forEach
((
_item
)
=>
{
const
{
props
=
{},
dataIndex
}
=
config
[
_item
];
const
{
props
=
{}
}
=
config
[
_item
];
const
dataIndex
=
config
[
_item
]?.
otherProps
?.
type
;
if
(
ACTIVITYS
.
includes
(
dataIndex
))
{
const
visible
=
typeof
props
.
visible
===
'undefined'
?
true
:
(
props
as
any
)?.
visible
;
res
.
push
({
...
...
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/components/CouponSelect/index.tsx
View file @
0d3450e8
...
...
@@ -191,7 +191,7 @@ const CouponSelect: React.FC<Iprops> = React.forwardRef((props: Iprops, couponRe
formExtra=
{
formExtra
}
radioChange
tableProps=
{
{
rowKey
:
(
record
)
=>
record
.
id
,
rowKey
:
(
record
)
=>
record
?
.
id
,
}
}
effects=
{
(
$
,
actions
)
=>
{
useStateFilterSearchLinkageEffect
(
$
,
actions
,
'id'
,
FORM_FILTER_PATH
);
...
...
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/components/EditPanel/editPanelForm.tsx
0 → 100644
View file @
0d3450e8
import
React
,
{
useState
,
useEffect
,
useMemo
}
from
'react'
;
import
{
changeProps
,
clearSelectedStatus
,
SelectedInfoType
,
STATE_PROPS
}
from
'@lingxi-disign/core'
;
import
{
useSelector
}
from
'@lingxi-disign/react'
;
import
{
PageConfigType
}
from
'@lingxi-disign/utils'
;
import
cs
from
'classnames'
;
import
{
CloseOutlined
,
PlusCircleOutlined
}
from
'@ant-design/icons'
;
import
{
useToggle
}
from
'@umijs/hooks'
;
import
{
Space
,
Button
,
Spin
}
from
'antd'
;
import
{
createFormActions
,
FormPath
}
from
'@formily/antd'
;
import
styles
from
'./index.less'
;
import
{
activityImageSchema
,
couponSchema
,
activityProducts
,
cardSchema
}
from
'./schema'
;
import
FormilyCoupon
from
'../EditPanelFormily/Coupon'
;
import
FormilyProduct
from
'../EditPanelFormily/FormilyProduct'
;
import
useGetSameKeys
from
'../../common/hooks/useGetSameKeys'
;
import
NiceForm
from
'@/components/NiceForm'
;
import
FormilyUpload
from
'@/components/UploadFiles/FormilyUploadFiles'
;
type
SettingPanelType
=
{
selectedInfo
:
SelectedInfoType
,
pageConfig
:
PageConfigType
,
}
const
formActions
=
createFormActions
();
/** 请求借口type, 请求列表接口需要带上type */
const
ACTIVITY_MAP
=
{
"specialOfferItem"
:
1
,
/** 直降促销 */
"plummetItem"
:
2
,
/** 折扣促销 */
"discountItem"
:
3
,
/** 满量促销--满量减 */
"fullQuantitySubItem"
:
4
,
/** 满量促销--满量折 */
"fullQuantityDiscountItem"
:
4
,
/** 满额促销--满额减 */
"fullMoneySubItem"
:
5
,
/** 满额促销--满额折 */
"fullMoneyDiscountItem"
:
5
,
/** "赠送促销--赠送商品(满额赠+买商品赠) */
"giveProductItem"
:
6
,
/** "赠送促销--赠送优惠劵(满额赠+买商品赠)*/
"giveCouponItem"
:
6
,
/** 多件促销 */
"morePieceItem"
:
7
,
/** 组合促销 */
"combinationItem"
:
8
,
/** 拼团 */
"groupPurchaseItem"
:
9
,
"luckDrawItem"
:
10
,
/** 砍价 */
"bargainItem"
:
11
,
/** 秒杀 */
"secKillItem"
:
12
,
/** 组合促销 */
"fullSwapItem"
:
13
,
/** 换购-买商品换购*/
"buySwapItem"
:
13
,
/** 预售 */
"preSaleItem"
:
14
,
/** 套餐 */
"setMealItem"
:
15
,
/** 适用 */
"attemptItem"
:
16
,
};
const
activityListItem
=
Object
.
keys
(
ACTIVITY_MAP
);
const
activityList
=
activityListItem
.
map
((
_item
)
=>
_item
.
substring
(
0
,
_item
.
length
-
4
));
const
EditPanelForm
=
()
=>
{
const
{
selectedInfo
,
pageConfig
}
=
useSelector
<
SettingPanelType
,
STATE_PROPS
>
([
'selectedInfo'
,
'pageConfig'
]);
const
{
state
:
visible
,
toggle
:
setVisible
}
=
useToggle
(
false
);
const
activityImage
=
useMemo
(()
=>
pageConfig
[
1
]?.
props
?.
imageUrl
,
[
pageConfig
]);
const
{
sameKeys
}
=
useGetSameKeys
();
const
[
formValue
,
setFormValue
]
=
useState
<
any
>
(
null
);
const
[
schema
,
setSchema
]
=
useState
<
any
>
(
null
);
const
className
=
cs
(
styles
.
editPanel
,
{
[
styles
.
hide
]:
!
visible
,
[
styles
.
show
]:
visible
});
const
handleOnClose
=
()
=>
{
clearSelectedStatus
();
setVisible
(
false
);
};
console
.
log
(
selectedInfo
);
useEffect
(()
=>
{
if
(
selectedInfo
===
null
)
{
setVisible
(
false
);
return
;
}
const
componentType
=
(
selectedInfo
as
any
)?.
otherProps
?.
type
;
const
propsMapToValue
=
{
top
:
{
imageUrl
:
[{
name
:
'广告图'
,
url
:
selectedInfo
?.
props
?.
imageUrl
}]
},
couponItem
:
{
coupon
:
{
...
selectedInfo
.
props
}
},
hotItem
:
{
product
:
{
...
selectedInfo
.
props
,
}
},
hot
:
{
title
:
selectedInfo
.
props
?.
title
,
},
};
/** 如果是活动子集, 那么现实选择活动商品 */
if
(
activityListItem
.
includes
(
componentType
)
||
componentType
===
'hotItem'
||
componentType
===
'suggestProductItem'
)
{
setFormValue
({
product
:
{
...
selectedInfo
.
props
,
}
});
setSchema
(
activityProducts
);
}
else
{
const
schemaMap
=
{
top
:
activityImageSchema
,
couponItem
:
couponSchema
,
};
/** 如果是 suggestProduct, 或者是hot 或者是活动父级,那么直接设置他的卡片名称 */
const
tempSchema
=
activityList
.
includes
(
componentType
)
||
componentType
===
'hot'
||
componentType
===
'suggestProduct'
?
cardSchema
:
schemaMap
?.[
componentType
];
const
tempFormValue
=
activityList
.
includes
(
componentType
)
||
componentType
===
'hot'
||
componentType
===
'suggestProduct'
?
{
title
:
selectedInfo
.
props
.
title
}
:
propsMapToValue
?.[
componentType
];
setSchema
(
tempSchema
);
setFormValue
(
tempFormValue
);
}
/** 16 种活动,请求是需要带上活动类型 */
const
activityType
=
ACTIVITY_MAP
[
componentType
]
?
{
activityType
:
ACTIVITY_MAP
[
componentType
]
}
:
{};
const
isWithLabels
=
componentType
===
'suggestProductItem'
?
{
isWithLabels
:
true
}
:
{
isWithLabels
:
false
};
// console.log(hotItem".substring(0, 1));
formActions
.
setFieldState
(
'product'
,
(
fieldState
)
=>
{
const
[,
parentKey
]
=
selectedInfo
.
parentKey
.
split
(
'-'
);
FormPath
.
setIn
(
fieldState
,
'props.x-component-props'
,
{
activityImage
:
activityImage
,
...
activityType
,
disabledKeys
:
componentType
===
'suggestProductItem'
?
sameKeys
[
`suggestProduct_
${
parseInt
(
parentKey
)
-
1
}
`
]
:
sameKeys
[
`
${
componentType
?.
substring
(
0
,
componentType
.
length
-
4
)}
`] || [],
...isWithLabels,
// fetchOptions: fetchMemberOptions,
});
});
setVisible(true);
}, [selectedInfo]);
const handleSubmit = (values) => {
const componentType = (selectedInfo as any)?.otherProps?.type;
const valueMapToProps = {
top: {
imageUrl: values?.imageUrl?.[0].url,
},
couponItem: {
...values.coupon
},
hot: {
title: values.title,
},
suggestProduct: {
title: values.title,
}
};
let currentProps = {};
if (activityListItem.includes(componentType) || componentType === 'suggestProductItem') {
currentProps = values.product;
} else if (activityList.includes(componentType)) {
currentProps = {
title: values.title,
};
} else {
currentProps = valueMapToProps[componentType];
}
changeProps({
treeKey: selectedInfo.selectedKey,
props: {
...selectedInfo.props,
...currentProps
},
title: values?.title || values?.name
});
};
const renderUploadChild = (value) => {
const target = value[0];
return (
<div className={styles.image}>
<div className={styles.uploadImage}>上传图片</div>
<div className={styles.imageIcon}>
<Spin spinning={target?.status === 'uploading'}>
{
target?.url ? <img src={target?.url} style={{width: '100%'}} /> : <PlusCircleOutlined />
}
</Spin>
</div>
</div>
);
};
const renderForm = () => {
const formProps = {
onSubmit: handleSubmit,
expressionScope: {
renderUploadChild,
},
actions: formActions,
components: {FormilyUpload, FormilyCoupon, FormilyProduct},
};
return (
<NiceForm
value={formValue}
{...formProps}
schema={schema}
/>
);
};
return (
<div style={{position: 'relative', width: '400px'}}>
<div className={className}>
<div className={styles.header}>
<span className={styles.title}>内容</span>
<CloseOutlined onClick={handleOnClose} />
</div>
<div className={styles.content}>
{renderForm()}
</div>
<div className={styles.footer}>
<Space>
<Button onClick={handleOnClose}>取消</Button>
<Button type="primary" onClick={() => formActions.submit()}>确认</Button>
</Space>
</div>
</div>
</div>
);
};
export default EditPanelForm;
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/components/EditPanel/index.less
View file @
0d3450e8
// .editPanel {
// background-color: #fff;
// height: 100%;
// overflow-y: auto;
// transition: width .25s;
// &.hide {
// width: 0;
// }
// &.show {
// width: 440px;
// }
// .settingTabs {
// :global {
// .ant-tabs-tab {
// margin: 0 32px;
// .ant-tabs-tab-btn {
// color: #909399;
// font-weight: bold;
// font-size: 14px;
// }
// &.ant-tabs-tab-active {
// .ant-tabs-tab-btn {
// color: #303133;
// }
// }
// }
// }
// .panel {
// padding: 0 16px;
// }
// }
// }
.editPanel {
background-color: #fff;
height: 100%;
position: absolute;
bottom: 0;
right: 0;
top: 0;
overflow-y: auto;
transition: width .25s;
display: flex;
flex-direction: column;
&.hide {
width: 0;
}
&.show {
width: 4
4
0px;
width: 4
0
0px;
}
.header {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 16px;
border-bottom: 1px solid #f5f6f7;
.settingTabs {
:global {
.ant-tabs-tab {
margin: 0 32px;
.title {
font-size: 16px;
color: #252d37;
}
}
.ant-tabs-tab-btn {
color: #909399;
font-weight: bold;
font-size: 14px;
}
.content {
padding: 16px;
flex: 1,
}
&.ant-tabs-tab-active {
.ant-tabs-tab-btn {
color: #303133;
}
}
}
.footer {
display: flex;
flex-direction: row-reverse;
padding: 12px;
border-top: 1px solid #f5f6f7;
}
.image {
margin-top: 8px;
width: 100%;
background-color: #fafbfc;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 176px;
position: relative;
cursor: pointer;
overflow: hidden;
.imageIcon {
height: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
overflow: hidden;
}
.panel {
padding: 0 16px;
.uploadImage {
position: absolute;
bottom: -34px;
left: 0;
right: 0;
padding: 4px;
background: rgba(0,0,0,0.3);
z-index: 99;
text-align: center;
color: #fff;
transition: all 0.6s;
}
&:hover {
.uploadImage {
transform: translateY(-34px);
}
}
}
}
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/components/EditPanel/schema.tsx
0 → 100644
View file @
0d3450e8
import
{
ISchema
}
from
"@formily/antd"
;
/** 活动图片广告图 */
export
const
activityImageSchema
:
ISchema
=
{
type
:
'object'
,
properties
:
{
layout
:
{
type
:
'object'
,
"x-component"
:
'mega-layout'
,
"x-component-props"
:
{
labelAlign
:
"top"
},
properties
:
{
imageUrl
:
{
type
:
'string'
,
"x-component"
:
'FormilyUpload'
,
"x-component-props"
:
{
renderUploadChild
:
'{{renderUploadChild}}'
,
showFiles
:
false
,
customizeItemRender
:
null
,
children
:
null
,
maxCount
:
1
,
},
},
}
}
}
};
/** 优惠券 */
export
const
couponSchema
:
ISchema
=
{
type
:
'object'
,
properties
:
{
coupon
:
{
type
:
'object'
,
'x-component'
:
'FormilyCoupon'
}
}
};
/** 卡片容器 */
export
const
cardSchema
:
ISchema
=
{
type
:
'object'
,
properties
:
{
layout
:
{
type
:
'object'
,
"x-component"
:
'mega-layout'
,
"x-component-props"
:
{
labelAlign
:
"top"
},
properties
:
{
title
:
{
type
:
'string'
,
title
:
'活动名称'
}
}
}
}
};
/**
* 活动商品
*/
export
const
activityProducts
:
ISchema
=
{
type
:
'object'
,
properties
:
{
product
:
{
type
:
'object'
,
'x-component'
:
'FormilyProduct'
,
}
}
};
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/components/EditPanelFormily/Coupon/index.less
0 → 100644
View file @
0d3450e8
.container {
display: flex;
flex-direction: column;
.header {
padding: 16px;
}
.content {
.info {
margin-top: 16px;
.row {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 16px;
.name {
color: #91959B;
font-size: 12px;
min-width: 72px;
}
.value {
color: #303133;
font-size: 12px;
}
}
}
}
}
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/components/EditPanelFormily/Coupon/index.tsx
0 → 100644
View file @
0d3450e8
/* eslint-disable react/display-name */
import
React
,
{
useRef
,
useState
,
useCallback
,
useEffect
,
useMemo
,
useContext
}
from
'react'
;
import
{
Button
,
Radio
,
Space
,
message
}
from
'antd'
;
import
{
useToggle
}
from
'@umijs/hooks'
;
import
{
unstable_batchedUpdates
as
batchedUpdates
}
from
'react-dom'
;
import
moment
from
'moment'
;
import
{
changeProps
,
clearSelectedStatus
}
from
'@lingxi-disign/core'
;
import
styles
from
'./index.less'
;
import
CouponSelect
from
'../../CouponSelect'
;
import
{
Context
as
ShopContext
}
from
'../../../common/context/shopContext'
;
import
useGetSameKeys
from
'../../../common/hooks/useGetSameKeys'
;
import
{
PublicApi
}
from
'@/services/api'
;
type
ColumnType
<
T
>
=
{
title
:
string
,
dataIndex
:
string
,
render
?:
(
text
:
string
,
record
:
T
)
=>
React
.
ReactNode
,
}
interface
Iprops
{
value
?:
{
id
:
number
,
name
:
string
},
mutators
:
{
change
:
(
data
:
any
)
=>
void
}
}
const
PLATFORM
=
1
;
const
BUSINESS
=
2
;
const
format
=
'YYYY-MM-DD HH:mm:ss'
;
const
options
=
[
{
label
:
'平台'
,
value
:
PLATFORM
},
{
label
:
'商家'
,
value
:
BUSINESS
},
];
const
FormilyCoupon
:
React
.
FC
<
Iprops
>
&
{
isFieldComponent
:
boolean
}
=
(
props
:
Iprops
)
=>
{
const
{
value
=
null
}
=
props
;
const
{
shopId
}
=
useContext
(
ShopContext
)
||
{};
const
{
sameKeys
}
=
useGetSameKeys
();
const
disabledCouponKeys
=
useMemo
(()
=>
sameKeys
[
'coupon'
],
[
sameKeys
]);
const
{
state
:
drawerVisible
,
toggle
:
setDrawerVisible
}
=
useToggle
();
const
[
radioValue
,
setRadioValue
]
=
useState
(
PLATFORM
);
const
ref
=
useRef
();
const
columns
:
ColumnType
<
any
>
[]
=
[
{
title
:
'优惠券ID'
,
dataIndex
:
'id'
},
{
title
:
"优惠券名称"
,
dataIndex
:
'name'
},
{
title
:
'优惠券类型'
,
dataIndex
:
'typeName'
},
{
title
:
'领券方式'
,
dataIndex
:
'getWayName'
},
{
title
:
'面额'
,
dataIndex
:
'denomination'
},
{
title
:
'使用条件'
,
dataIndex
:
'useConditionMoney'
},
{
title
:
"有效期"
,
dataIndex
:
'validityTime'
,
render
:
(
_text
,
_record
)
=>
{
return
(
<
div
>
<
span
>
{
_record
?.
releaseTimeStart
&&
moment
(
_record
?.
releaseTimeStar
).
format
(
format
)
}
</
span
>
至
<
span
>
{
_record
?.
releaseTimeEnd
&&
moment
(
_record
?.
releaseTimeEnd
).
format
(
format
)
}
</
span
>
</
div
>
);
}
}
];
// useEffect(() => {
// if (!visible) {
// return ;
// }
// setInnerValue(value);
// }, [value]);
const
onChange
=
(
e
)
=>
{
setRadioValue
(
e
.
target
.
value
);
const
pageInfo
=
(
ref
?.
current
as
any
)?.
getPaginationInfo
();
const
values
=
(
ref
?.
current
as
any
)?.
formValues
([
"id"
,
"couponName"
]);
(
ref
?.
current
as
any
)?.
reload
({...
values
,
current
:
pageInfo
?.
page
||
1
,
pageSize
:
pageInfo
?.
pageSize
||
10
,
radio
:
e
.
target
.
value
});
};
const
formExtra
=
(
<
div
style=
{
{
position
:
'absolute'
,
top
:
'4px'
,
right
:
0
}
}
>
<
Radio
.
Group
options=
{
options
}
value=
{
radioValue
}
onChange=
{
onChange
}
optionType=
"button"
/>
</
div
>
);
const
onOk
=
(
selectedKey
:
string
[],
selectedRow
:
any
[])
=>
{
batchedUpdates
(()
=>
{
// setInnerValue(selectedRow[0]);
props
.
mutators
.
change
(
selectedRow
[
0
]);
setDrawerVisible
(
false
);
});
};
const
fetchData
=
useCallback
(
async
(
params
:
any
)
=>
{
const
{
radio
=
PLATFORM
,
...
rest
}
=
params
;
const
service
=
radio
===
PLATFORM
?
PublicApi
.
getMarketingCouponPlatformActivityPageSelectPage
:
PublicApi
.
getMarketingCouponPlatformActivityPageSelectMerchantPage
;
/** @tofix shopId */
const
{
data
,
code
}
=
await
service
({...
rest
,
shopId
:
shopId
!
});
if
(
code
===
1000
)
{
return
data
;
}
return
{
totalCount
:
0
,
data
:
[]
};
},
[]);
const
selectedValue
=
useMemo
(()
=>
[
value
],
[
value
]);
const
rowSelection
=
{
getCheckboxProps
:
(
_record
)
=>
({
disabled
:
disabledCouponKeys
.
includes
(
_record
.
id
)
})
};
return
(
<
div
>
<
div
className=
{
styles
.
container
}
>
<
div
className=
{
styles
.
content
}
>
<
div
className=
{
styles
.
module
}
>
<
Button
onClick=
{
()
=>
setDrawerVisible
(
true
)
}
>
选择优惠券
</
Button
>
</
div
>
<
div
className=
{
styles
.
info
}
>
{
columns
.
map
((
_item
)
=>
{
return
(
<
div
key=
{
_item
.
dataIndex
}
className=
{
styles
.
row
}
>
<
span
className=
{
styles
.
name
}
>
{
_item
.
title
}
</
span
>
<
span
className=
{
styles
.
value
}
>
{
(
_item
?.
render
?.(
value
?.[
_item
.
dataIndex
],
value
))
||
value
?.[
_item
.
dataIndex
]
}
</
span
>
</
div
>
);
})
}
</
div
>
</
div
>
</
div
>
<
CouponSelect
visible=
{
drawerVisible
}
onCancel=
{
()
=>
setDrawerVisible
(
false
)
}
mode=
"radio"
formExtra=
{
formExtra
}
ref=
{
ref
as
any
}
fetchData=
{
fetchData
}
onOk=
{
onOk
}
value=
{
selectedValue
}
rowSelection=
{
rowSelection
}
/>
</
div
>
);
};
FormilyCoupon
.
isFieldComponent
=
true
;
export
default
FormilyCoupon
;
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/components/EditPanelFormily/FormilyProduct/index.tsx
0 → 100644
View file @
0d3450e8
import
React
,
{
useContext
,
useMemo
,
useState
}
from
'react'
;
import
{
useToggle
}
from
'@umijs/hooks'
;
import
{
useSelector
}
from
'@lingxi-disign/react'
;
import
{
Context
as
ShopContext
}
from
'../../../common/context/shopContext'
;
import
{
Product
}
from
'@/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/components/ProductPanel'
;
import
ActivityProductDrawer
from
'@/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/components/ActivityAreaSetting/activityProductDrawer'
;
import
{
PublicApi
}
from
'@/services/api'
;
import
{
GetMarketingAdornPlatformActivityListAdornRequest
}
from
'@/services/MaketingV2Api'
;
import
activityImageSvg
from
'@/asserts/activity/ActivityImage.svg'
;
interface
Iprops
{
value
:
{
id
:
number
,
productName
:
string
,
activityId
:
number
,
activityList
:
any
[],
productImgUrl
:
string
,
price
:
number
,
label
:
string
[],
},
props
:
{
[
'x-component-props'
]:
{
activityType
:
number
,
isWithLabels
?:
boolean
,
activityImage
?:
string
,
/** [`${id}_${activityId}`] */
disabledKeys
?:
string
[]
}
&
{
[
key
:
string
]:
any
},
},
mutators
:
{
change
:
(
params
:
any
)
=>
void
},
}
const
FormilyActivityProduct
:
React
.
FC
<
Iprops
>
&
{
isFieldComponent
:
boolean
}
=
(
props
:
Iprops
)
=>
{
const
{
value
,
mutators
}
=
props
;
const
{
shopId
}
=
useContext
(
ShopContext
)
||
{};
const
componentProps
=
props
.
props
?.[
'x-component-props'
]
||
{};
const
activityImage
=
componentProps
.
activityImage
||
activityImageSvg
;
const
disabledKeys
=
componentProps
.
disabledKeys
||
[];
const
{
state
:
productVisible
,
toggle
:
setProductVisible
}
=
useToggle
();
const
cacheProductList
=
useMemo
(()
=>
[{
...
value
}],
[
value
]);
const
productProps
=
useMemo
(()
=>
({
id
:
value
?.
id
,
activityId
:
value
?.
activityId
,
productName
:
value
?.
productName
,
activityList
:
value
?.
activityList
,
productImgUrl
:
value
?.
productImgUrl
,
price
:
value
?.
price
,
label
:
value
?.
label
}),
[
value
]);
const
onOk
=
(
data
)
=>
{
const
first
=
data
[
0
];
mutators
.
change
(
first
);
setProductVisible
(
false
);
};
const
onLabelChange
=
(
data
:
{
id
:
number
,
activityId
:
number
,
label
:
string
[]
})
=>
{
// const current = {...innerProducts};
// current["label"] = data.label;
// setInnerProducts(current);
const
current
=
{
...
productProps
,
label
:
data
.
label
};
mutators
.
change
(
current
);
};
const
onEdit
=
()
=>
{
setProductVisible
(
true
);
};
const
fetchData
=
async
(
params
:
GetMarketingAdornPlatformActivityListAdornRequest
)
=>
{
const
withActivityType
=
componentProps
?.
activityType
?
{
activityType
:
componentProps
?.
activityType
}
:
{};
const
common
=
{
...
params
,
shopId
:
shopId
?.
toString
(),
...
withActivityType
};
const
isWithActivityType
=
common
;
return
await
PublicApi
.
getMarketingAdornPlatformActivityListAdorn
(
isWithActivityType
as
any
);
};
return
(
<
div
style=
{
{
position
:
'relative'
}
}
>
<
Product
onEdit=
{
onEdit
}
activityImage=
{
activityImage
}
{
...
productProps
}
isWithLabels=
{
componentProps
.
isWithLabels
||
false
}
onLabelChange=
{
onLabelChange
}
/>
<
ActivityProductDrawer
activityImage=
{
activityImage
}
products=
{
cacheProductList
}
onOk=
{
onOk
}
fetchData=
{
fetchData
}
visible=
{
productVisible
}
onCancel=
{
()
=>
setProductVisible
(
false
)
}
mode=
"radio"
disabledList=
{
disabledKeys
}
/>
</
div
>
);
};
FormilyActivityProduct
.
isFieldComponent
=
true
;
export
default
FormilyActivityProduct
;
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/components/Layouts/Advertisement/index.tsx
View file @
0d3450e8
...
...
@@ -10,7 +10,7 @@ interface Iprops {
}
const
Advertisement
:
React
.
FC
<
Iprops
>
=
(
props
:
Iprops
)
=>
{
const
{
imageUrl
,
width
=
"100%"
,
height
=
"100%"
,
style
=
{},
className
,
...
other
}
=
props
;
const
{
imageUrl
,
width
=
"100%"
,
height
=
176
,
style
=
{},
className
,
...
other
}
=
props
;
const
cacheWidth
=
useMemo
(()
=>
typeof
width
===
'number'
?
`
${
width
}
px`
:
width
,
[
width
]);
const
cacheHeight
=
useMemo
(()
=>
typeof
height
===
'number'
?
`
${
height
}
px`
:
height
,
[
height
]);
...
...
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/components/Layouts/CommodityList/index.less
View file @
0d3450e8
...
...
@@ -23,6 +23,7 @@
flex-direction: column;
background: #fff;
padding: 12px;
border-radius: 8px;
.commodityGroupEmpty {
min-height: 430px;
...
...
@@ -49,85 +50,9 @@
background-color: #fff;
}
}
.footer {
margin-top: 12px;
border-top: 1px solid rgba(0, 0, 0, 0.1);
padding: 12px 0 0px 0;
display: flex;
flex-direction: row;
justify-content: space-between;
.price {
display: flex;
flex-direction: row;
align-items: center;
.discount {
color: #F2270E;
font-size: 12px;
.priceInt {
font-size: 16px;
font-weight: 600;
}
}
.originalPrice {
color: #91959B;
font-size: 10px;
text-decoration:line-through;
margin-left: 4px;
}
}
.button {
background-color: #EF3346;
font-size: 14px;
padding: 4px 12px;
border-radius: 50px;
color: #fff;
display: flex;
flex-direction: row;
align-items: center;
}
}
}
.customizeTabBar {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 16px;
.tabbarItem {
color: #91959B;
font-size: 12px;
line-height: 12px;
margin-right: 12px;
}
.activeTabbar {
color: #252D37;
font-size: 16px;
line-height: 24px;
position: relative;
&::after {
content: "";
position: absolute;
bottom: -4px;
left: 50%;
width: 24px;
height: 4px;
background: #EF3346;
border-radius: 2px;
transform: translateX(-12px);
}
}
}
.twoColumns {
display: flex;
...
...
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/components/Layouts/CommodityList/index.tsx
View file @
0d3450e8
...
...
@@ -4,7 +4,11 @@ import { Commodity, Progress } from '@lingxi-disign/ui';
import
{
Tabs
}
from
'antd'
;
import
{
PlusOutlined
,
TagOutlined
}
from
'@ant-design/icons'
;
import
_omit
from
'lodash/omit'
;
import
Tabbar
from
'./tabbar'
;
import
TabFooter
from
'./tabFooter'
;
import
styles
from
'./index.less'
;
import
SwapCoupon
from
'./swapCoupon'
;
import
SwapProduct
from
'./swapProduct'
;
const
{
TabPane
}
=
Tabs
;
interface
Iprops
{
...
...
@@ -15,67 +19,73 @@ interface Iprops {
visible
:
boolean
,
}
const
CommodityList
:
React
.
FC
<
Iprops
>
&
{
Item
:
typeof
CommodityItem
,
CommodityTab
:
typeof
CommodityTab
}
=
(
props
:
Iprops
)
=>
{
const
{
children
,
className
,
title
,
theme
,
visible
=
true
,
...
other
}
=
props
;
const
classNameStr
=
cx
(
styles
.
recommand
,
className
,
{
[
styles
.
hide
]:
!
visible
});
const
{
onClick
,
onDrag
,
onDragEnd
,
onDragEnter
,
onDragStart
,
onMouseOver
,
getOperateState
}
=
other
as
any
;
const
CommodityList
:
React
.
FC
<
Iprops
>
&
{
Item
:
typeof
CommodityItem
,
CommodityTab
:
typeof
CommodityTab
,
SwapCoupon
:
typeof
SwapCoupon
,
SwapProduct
:
typeof
SwapProduct
}
=
(
props
:
Iprops
)
=>
{
const
{
children
,
className
,
title
,
theme
,
visible
=
true
,
...
other
}
=
props
;
const
classNameStr
=
cx
(
styles
.
recommand
,
className
,
{
[
styles
.
hide
]:
!
visible
});
const
{
onClick
,
onDrag
,
onDragEnd
,
onDragEnter
,
onDragStart
,
onMouseOver
,
getOperateState
}
=
other
as
any
;
const
divProps
=
{
onClick
,
onDrag
,
onDragEnd
,
onDragEnter
,
onDragStart
,
onMouseOver
,
};
const
render2Columns
=
()
=>
{
return
(
<
div
className=
{
styles
.
twoColumns
}
>
{
React
.
Children
.
map
(
children
,
(
_child
:
any
)
=>
{
if
(
_child
===
null
)
{
return
null
;
}
return
React
.
cloneElement
(
_child
,
{...
_child
?.
props
||
{},
customizeClassName
:
styles
.
commodityItem
,
mode
:
'vertical'
});
})
}
</
div
>
);
};
const
renderGroup
=
()
=>
{
return
(
<
div
>
{
React
.
Children
.
map
(
children
,
(
_child
:
any
)
=>
{
if
(
_child
===
null
)
{
return
null
;
}
return
React
.
cloneElement
(
_child
,
{...
_child
.
props
});
})
}
</
div
>
);
};
const
divProps
=
{
onClick
,
onDrag
,
onDragEnd
,
onDragEnter
,
onDragStart
,
onMouseOver
,
};
const
render2Columns
=
()
=>
{
return
(
<
div
className=
{
styles
.
twoColumns
}
>
{
React
.
Children
.
map
(
children
,
(
_child
:
any
)
=>
{
if
(
_child
===
null
)
{
return
null
;
}
return
React
.
cloneElement
(
_child
,
{...
_child
?.
props
||
{},
customizeClassName
:
styles
.
commodityItem
,
mode
:
'vertical'
});
})
}
</
div
>
);
};
const
renderComponent
=
()
=>
{
if
(
theme
===
1
)
{
return
render2Columns
();
}
if
(
theme
===
2
)
{
return
renderGroup
();
}
return
children
;
};
const
renderGroup
=
()
=>
{
return
(
<
div
>
{
React
.
Children
.
map
(
children
,
(
_child
:
any
)
=>
{
if
(
_child
===
null
)
{
return
null
;
}
return
React
.
cloneElement
(
_child
,
{...
_child
.
props
});
})
}
<
div
className=
{
classNameStr
}
{
...
divProps
}
>
<
span
className=
{
styles
.
title
}
>
{
title
}
</
span
>
<
div
className=
{
styles
.
container
}
>
{
renderComponent
()
}
</
div
>
</
div
>
);
};
const
renderComponent
=
()
=>
{
if
(
theme
===
1
)
{
return
render2Columns
();
}
if
(
theme
===
2
)
{
return
renderGroup
();
}
return
children
;
};
return
(
<
div
className=
{
classNameStr
}
{
...
divProps
}
>
<
span
className=
{
styles
.
title
}
>
{
title
}
</
span
>
<
div
className=
{
styles
.
container
}
>
{
renderComponent
()
}
</
div
>
</
div
>
);
};
interface
Iprops
{
className
:
string
,
customizeClassName
:
string
,
...
...
@@ -84,7 +94,7 @@ interface Iprops {
const
CommodityItem
:
React
.
FC
<
Iprops
>
=
(
props
:
Iprops
)
=>
{
const
{
className
,
customizeClassName
,
...
other
}
=
props
;
const
classNameStr
=
cx
(
className
,
styles
.
item
,
customizeClassName
);
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
;
...
...
@@ -116,10 +126,13 @@ const CommodityItem: React.FC<Iprops> = (props: Iprops) => {
const
commodityProps
=
mode
===
'horizontal'
?
horizontalData
:
verticalData
;
return
(
<
div
className=
{
classNameStr
}
{
...
divProps
}
>
<
Commodity
{
...
commodityProps
}
/>
<
div
className=
{
classNameStr
}
>
<
div
{
...
divProps
}
className=
{
className
}
>
<
Commodity
{
...
commodityProps
}
/>
</
div
>
</
div
>
);
};
...
...
@@ -130,36 +143,6 @@ CommodityList.Item = CommodityItem;
const
CommodityTab
:
React
.
FC
<
any
>
=
(
props
)
=>
{
const
{
isEmpty
,
id
,
productName
,
productImgUrl
,
price
,
goodsSubsidiaryGroupList
}
=
props
;
const
[
activeKey
,
setActiveKey
]
=
useState
<
string
>
(
"1"
);
console
.
log
(
"CommodityTab"
,
props
);
const
renderTabBar
=
(
tabProps
)
=>
{
const
tabInfo
=
tabProps
.
panes
.
map
((
_item
)
=>
{
const
{
key
,
props
}
=
_item
;
return
{
tab
:
props
.
tab
,
key
,
};
});
return
(
<
div
className=
{
styles
.
customizeTabBar
}
>
{
tabInfo
?.
map
((
_item
)
=>
{
return
(
<
span
onClick=
{
()
=>
setActiveKey
(
_item
.
key
)
}
key=
{
_item
.
key
}
className=
{
cx
(
styles
.
tabbarItem
,
{
[
styles
.
activeTabbar
]:
_item
.
key
===
tabProps
.
activeKey
,
})
}
>
{
_item
.
tab
}
</
span
>
);
})
}
</
div
>
);
};
const
renderEmpty
=
()
=>
{
return
(
...
...
@@ -169,6 +152,10 @@ const CommodityTab: React.FC<any> = (props) => {
);
};
const
handleTabChange
=
(
key
:
string
)
=>
{
setActiveKey
(
key
);
};
const
renderContent
=
()
=>
{
return
(
<>
...
...
@@ -188,7 +175,7 @@ const CommodityTab: React.FC<any> = (props) => {
/>
</
div
>
<
div
className=
{
styles
.
tab
}
>
<
Tabs
activeKey=
{
activeKey
}
renderTabBar=
{
renderTabBar
}
>
<
Tabs
activeKey=
{
activeKey
}
renderTabBar=
{
(
tabProps
)
=>
<
Tabbar
tabProps=
{
tabProps
}
onChange=
{
handleTabChange
}
/>
}
>
{
goodsSubsidiaryGroupList
?.
map
((
_item
,
_index
)
=>
{
const
{
groupNo
,
groupPrice
,
goodsSubsidiaryGroupDetailsList
}
=
_item
;
...
...
@@ -214,18 +201,7 @@ const CommodityTab: React.FC<any> = (props) => {
})
}
</
div
>
<
div
className=
{
styles
.
footer
}
>
<
div
className=
{
styles
.
price
}
>
<
div
className=
{
styles
.
discount
}
>
¥
<
span
className=
{
styles
.
priceInt
}
>
{
discountPrice
[
0
]
}
</
span
>
.
<
span
>
{
discountPrice
?.[
1
]
||
'00'
}
</
span
>
</
div
>
<
span
className=
{
styles
.
originalPrice
}
>
¥
{
allTotal
+
price
}
</
span
>
</
div
>
<
div
className=
{
styles
.
button
}
>
<
span
>
立即抢购
</
span
>
</
div
>
</
div
>
<
TabFooter
discountPrice=
{
discountPrice
}
originalPrice=
{
allTotal
+
price
}
/>
</
TabPane
>
);
})
...
...
@@ -266,4 +242,7 @@ const CommodityGroup = (props) => {
CommodityList
.
CommodityTab
=
CommodityGroup
;
CommodityList
.
SwapCoupon
=
SwapCoupon
;
CommodityList
.
SwapProduct
=
SwapProduct
;
export
default
CommodityList
;
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/components/Layouts/CommodityList/swapCoupon.less
0 → 100644
View file @
0d3450e8
.commodityGroupEmpty {
min-height: 430px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 12px;
border: 1px dashed #C8CACD;
}
.section {
padding: 12px;
background: #fff;
border-radius: 8px;
margin-bottom: 8px;
}
.tab {
// margin-bottom: 12px;
background-color: #fff;
.groupPane {
display: flex;
flex-direction: row;
margin-right: -12px;
}
.couponItem {
background-color: #FFF0F2;
padding: 16px 8px;
margin-right: 12px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: #EF3346;
border-radius: 8px;
.money {
.num {
font-size: 20px;
}
}
.condition {
margin: 8px 0 16px 0;
}
.couponType {
background-image: linear-gradient(90deg, #F87362 0%, #EF3346 100%);
border-radius: 8px;
padding: 2px 6px;
color: #fff;
}
}
}
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/components/Layouts/CommodityList/swapCoupon.tsx
0 → 100644
View file @
0d3450e8
import
React
,
{
useState
}
from
'react'
;
import
_omit
from
'lodash/omit'
;
import
{
Commodity
,
Progress
}
from
'@lingxi-disign/ui'
;
import
{
PlusOutlined
,
TagOutlined
}
from
'@ant-design/icons'
;
import
{
Tabs
}
from
'antd'
;
import
cs
from
'classnames'
;
import
styles
from
'./swapCoupon.less'
;
import
Tabbar
from
'./tabbar'
;
import
TabFooter
from
'./tabFooter'
;
const
{
TabPane
}
=
Tabs
;
const
SwapCoupon
=
(
props
)
=>
{
const
{
className
,
...
other
}
=
props
;
const
[
activeKey
,
setActiveKey
]
=
useState
<
string
>
(
"1"
);
const
restProps
=
_omit
(
other
,
[
"getOperateState"
,
"onClick"
,
"onDrag"
,
"onDragEnd"
,
"onDragEnter"
,
"onDragStart"
,
"onMouseOver"
,
"draggable"
]);
const
isEmpty
=
typeof
restProps
[
'productName'
]
===
'undefined'
;
const
{
onClick
,
onDrag
,
onDragEnd
,
onDragEnter
,
onDragStart
,
onMouseOver
,
getOperateState
}
=
other
as
any
;
const
divProps
=
{
onClick
,
onDrag
,
onDragEnd
,
onDragEnter
,
onDragStart
,
onMouseOver
,
};
const
handleTabChange
=
(
key
:
string
)
=>
{
setActiveKey
(
key
);
};
const
{
productName
,
productImgUrl
,
price
,
giveCouponList
}
=
restProps
;
if
(
isEmpty
)
{
return
(
<
div
className=
{
cs
(
styles
.
commodityGroupEmpty
,
className
)
}
{
...
divProps
}
>
<
div
><
PlusOutlined
style=
{
{
color
:
'#C8CACD'
}
}
/></
div
>
</
div
>
);
}
return
(
<
div
className=
{
className
}
{
...
divProps
}
>
<
div
className=
{
styles
.
section
}
>
<
div
className=
{
styles
.
mainCommodity
}
>
<
Commodity
name=
{
productName
}
image=
{
productImgUrl
}
mode=
"horizontal"
discountPrice=
{
price
}
tags=
{
[
"赠优惠券"
]
}
buyBtn=
{
true
}
/>
</
div
>
<
div
className=
{
styles
.
tab
}
>
<
Tabs
activeKey=
{
activeKey
}
renderTabBar=
{
(
tabProps
)
=>
<
Tabbar
tabProps=
{
tabProps
}
onChange=
{
handleTabChange
}
/>
}
>
{
giveCouponList
?.
map
((
_item
,
_index
)
=>
{
const
{
groupNo
,
limitValue
,
list
}
=
_item
;
return
(
<
TabPane
key=
{
_item
.
groupNo
.
toString
()
}
tab=
{
`满${limitValue}元获赠`
}
>
<
div
className=
{
styles
.
groupPane
}
>
{
list
?.
map
((
_row
,
_key
)
=>
{
return
(
<
div
className=
{
styles
.
couponItem
}
key=
{
_key
}
>
<
div
className=
{
styles
.
money
}
>
¥
<
span
className=
{
styles
.
num
}
>
{
_row
.
denomination
}
</
span
>
</
div
>
<
div
className=
{
styles
.
condition
}
>
{
`满${_row.useConditionMoney}可使用`
}
</
div
>
<
div
className=
{
styles
.
couponType
}
>
{
_row
.
couponName
}
</
div
>
</
div
>
);
})
}
</
div
>
{
/* <TabFooter discountPrice={60} originalPrice={50} /> */
}
</
TabPane
>
);
})
}
</
Tabs
>
</
div
>
</
div
>
</
div
>
);
};
export
default
SwapCoupon
;
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/components/Layouts/CommodityList/swapProduct.less
0 → 100644
View file @
0d3450e8
.commodityGroupEmpty {
min-height: 430px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 12px;
border: 1px dashed #C8CACD;
}
.section {
padding: 12px;
background: #fff;
border-radius: 8px;
margin-bottom: 8px;
}
.tab {
// margin-bottom: 12px;
background-color: #fff;
.groupPane {
display: flex;
flex-direction: row;
margin-right: -12px;
}
.giftItem {
margin-right: 12px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: #EF3346;
border-radius: 8px;
.giftImage {
height: 104px;
width: 104px;
position: relative;
margin-bottom: 12px;
img {
width: 100%;
height: 100%;
}
.num {
position: absolute;
bottom: 0;
right: 0;
}
}
.money {
.num {
font-size: 20px;
}
}
.condition {
margin: 8px 0 16px 0;
}
.couponType {
background-image: linear-gradient(90deg, #F87362 0%, #EF3346 100%);
border-radius: 8px;
padding: 2px 6px;
color: #fff;
}
}
}
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/components/Layouts/CommodityList/swapProduct.tsx
0 → 100644
View file @
0d3450e8
import
React
,
{
useState
}
from
'react'
;
import
_omit
from
'lodash/omit'
;
import
{
Commodity
,
Progress
,
CustomizeTag
}
from
'@lingxi-disign/ui'
;
import
{
PlusOutlined
,
TagOutlined
}
from
'@ant-design/icons'
;
import
{
Tabs
}
from
'antd'
;
import
cs
from
'classnames'
;
import
styles
from
'./swapProduct.less'
;
import
Tabbar
from
'./tabbar'
;
import
TabFooter
from
'./tabFooter'
;
const
{
TabPane
}
=
Tabs
;
const
SwapProduct
=
(
props
)
=>
{
const
{
className
,
...
other
}
=
props
;
const
[
activeKey
,
setActiveKey
]
=
useState
<
string
>
(
"1"
);
const
restProps
=
_omit
(
other
,
[
"getOperateState"
,
"onClick"
,
"onDrag"
,
"onDragEnd"
,
"onDragEnter"
,
"onDragStart"
,
"onMouseOver"
,
"draggable"
]);
const
isEmpty
=
typeof
restProps
[
'productName'
]
===
'undefined'
;
const
{
onClick
,
onDrag
,
onDragEnd
,
onDragEnter
,
onDragStart
,
onMouseOver
,
getOperateState
}
=
other
as
any
;
const
divProps
=
{
onClick
,
onDrag
,
onDragEnd
,
onDragEnter
,
onDragStart
,
onMouseOver
,
};
const
handleTabChange
=
(
key
:
string
)
=>
{
setActiveKey
(
key
);
};
const
{
productName
,
productImgUrl
,
price
,
goodsSubsidiaryGroupList
}
=
restProps
;
if
(
isEmpty
)
{
return
(
<
div
className=
{
cs
(
styles
.
commodityGroupEmpty
,
className
)
}
{
...
divProps
}
>
<
div
><
PlusOutlined
style=
{
{
color
:
'#C8CACD'
}
}
/></
div
>
</
div
>
);
}
return
(
<
div
className=
{
className
}
{
...
divProps
}
>
<
div
className=
{
styles
.
section
}
>
<
div
className=
{
styles
.
mainCommodity
}
>
<
Commodity
name=
{
productName
}
image=
{
productImgUrl
}
mode=
"horizontal"
discountPrice=
{
price
}
tags=
{
[
"赠商品"
]
}
buyBtn=
{
false
}
/>
</
div
>
<
div
className=
{
styles
.
tab
}
>
<
Tabs
activeKey=
{
activeKey
}
renderTabBar=
{
(
tabProps
)
=>
<
Tabbar
tabProps=
{
tabProps
}
onChange=
{
handleTabChange
}
/>
}
>
{
goodsSubsidiaryGroupList
?.
map
((
_item
,
_index
)
=>
{
const
{
groupNo
,
limitValue
,
goodsSubsidiaryGroupDetailsList
}
=
_item
;
return
(
<
TabPane
key=
{
_item
.
groupNo
.
toString
()
}
tab=
{
`满${limitValue}元赠送`
}
>
<
div
className=
{
styles
.
groupPane
}
>
{
goodsSubsidiaryGroupDetailsList
?.
map
((
_row
,
_key
)
=>
{
return
(
<
div
className=
{
styles
.
giftItem
}
key=
{
_key
}
>
<
div
className=
{
styles
.
giftImage
}
>
<
img
src=
{
_row
.
productImgUrl
}
/>
<
div
className=
{
styles
.
num
}
>
x
{
_row
.
num
}
</
div
>
</
div
>
<
CustomizeTag
>
原价
{
`${_row.price}`
}
元
</
CustomizeTag
>
</
div
>
);
})
}
</
div
>
<
TabFooter
discountPrice=
{
60
}
originalPrice=
{
50
}
/>
</
TabPane
>
);
})
}
</
Tabs
>
</
div
>
</
div
>
</
div
>
);
};
export
default
SwapProduct
;
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/components/Layouts/CommodityList/tabFooter.less
0 → 100644
View file @
0d3450e8
.footer {
margin-top: 12px;
border-top: 1px solid rgba(0, 0, 0, 0.1);
padding: 12px 0 0px 0;
display: flex;
flex-direction: row;
justify-content: space-between;
.price {
display: flex;
flex-direction: row;
align-items: center;
.discount {
color: #F2270E;
font-size: 12px;
.priceInt {
font-size: 16px;
font-weight: 600;
}
}
.originalPrice {
color: #91959B;
font-size: 10px;
text-decoration:line-through;
margin-left: 4px;
}
}
.button {
background-color: #EF3346;
font-size: 14px;
padding: 4px 12px;
border-radius: 50px;
color: #fff;
display: flex;
flex-direction: row;
align-items: center;
}
}
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/components/Layouts/CommodityList/tabFooter.tsx
0 → 100644
View file @
0d3450e8
import
React
,
{
useMemo
}
from
'react'
;
import
styles
from
'./tabFooter.less'
;
interface
Iprops
{
originalPrice
:
number
,
discountPrice
:
number
}
const
TabFooter
:
React
.
FC
<
Iprops
>
=
(
props
:
Iprops
)
=>
{
const
{
discountPrice
,
originalPrice
}
=
props
;
const
cacheDiscountPrice
=
useMemo
(()
=>
discountPrice
?.
toString
().
split
(
"."
),
[
discountPrice
])
return
(
<
div
className=
{
styles
.
footer
}
>
<
div
className=
{
styles
.
price
}
>
<
div
className=
{
styles
.
discount
}
>
¥
<
span
className=
{
styles
.
priceInt
}
>
{
cacheDiscountPrice
[
0
]
}
</
span
>
.
<
span
>
{
cacheDiscountPrice
?.[
1
]
||
'00'
}
</
span
>
</
div
>
<
span
className=
{
styles
.
originalPrice
}
>
¥
{
originalPrice
.
toFixed
(
2
)
}
</
span
>
</
div
>
<
div
className=
{
styles
.
button
}
>
<
span
>
立即抢购
</
span
>
</
div
>
</
div
>
);
};
export
default
TabFooter
;
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/components/Layouts/CommodityList/tabbar.less
0 → 100644
View file @
0d3450e8
.customizeTabBar {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 16px;
.tabbarItem {
color: #91959B;
font-size: 12px;
line-height: 12px;
margin-right: 12px;
}
.activeTabbar {
color: #252D37;
font-size: 16px;
line-height: 24px;
position: relative;
&::after {
content: "";
position: absolute;
bottom: -4px;
left: 50%;
width: 24px;
height: 4px;
background: #EF3346;
border-radius: 2px;
transform: translateX(-12px);
}
}
}
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/components/Layouts/CommodityList/tabbar.tsx
0 → 100644
View file @
0d3450e8
import
React
,
{
useState
}
from
'react'
;
import
cx
from
'classnames'
;
import
styles
from
'./tabbar.less'
;
interface
Iprops
{
tabProps
:
any
,
onChange
?:
(
key
:
string
)
=>
void
}
const
Tabbar
:
React
.
FC
<
Iprops
>
=
(
props
:
Iprops
)
=>
{
// const [activeKey, setActiveKey] = useState<string>("1");
const
{
tabProps
,
onChange
}
=
props
;
const
tabInfo
=
tabProps
?.
panes
?.
map
((
_item
)
=>
{
const
{
key
,
props
}
=
_item
;
return
{
tab
:
props
.
tab
,
key
,
};
});
const
handleChange
=
(
key
:
string
)
=>
{
onChange
?.(
key
);
};
return
(
<
div
className=
{
styles
.
customizeTabBar
}
>
{
tabInfo
?.
map
((
_item
)
=>
{
return
(
<
span
onClick=
{
()
=>
handleChange
(
_item
.
key
)
}
key=
{
_item
.
key
}
className=
{
cx
(
styles
.
tabbarItem
,
{
[
styles
.
activeTabbar
]:
_item
.
key
===
tabProps
.
activeKey
,
})
}
>
{
_item
.
tab
}
</
span
>
);
})
}
</
div
>
);
};
export
default
Tabbar
;
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/components/Layouts/Coupon/index.tsx
View file @
0d3450e8
import
React
from
'react'
;
import
React
,
{
useMemo
}
from
'react'
;
import
{
MarketingCard
}
from
'@lingxi-disign/ui'
;
import
cx
from
'classnames'
;
import
styles
from
'./index.less'
;
...
...
@@ -51,19 +51,34 @@ interface ItemIprops {
onDragEnter
:
()
=>
void
,
onDragStart
:
()
=>
void
,
onMouseOver
:
()
=>
void
,
draggable
?:
false
getOperateState
:
any
,
belongName
?:
string
belongType
?:
number
,
denomination
?:
number
,
getWay
?:
number
,
getWayName
?:
string
,
id
?:
number
/** 1 => 平台, 2 商家 */
type
?:
1
|
2
|
number
&
{},
typeName
?:
string
,
useConditionMoney
?:
number
}
const
CouponItem
:
React
.
FC
<
ItemIprops
>
=
(
props
:
ItemIprops
)
=>
{
const
{
children
,
className
,
...
other
}
=
props
;
const
{
onClick
,
onDrag
,
onDragEnd
,
onDragEnter
,
onDragStart
,
onMouseOver
,
getOperateState
,
...
rest
}
=
other
;
const
{
money
,
isnull
,
tag
,
info
,
typeName
}
=
rest
as
any
;
const
{
denomination
,
tag
,
useConditionMoney
,
typeName
}
=
rest
as
any
;
const
divProps
=
{
onClick
,
onDrag
,
onDragEnd
,
onDragEnter
,
onDragStart
,
onMouseOver
,
};
const
isNotNull
=
useMemo
(()
=>
rest
?.
id
&&
true
,
[
rest
]);
return
(
<
div
{
...
divProps
}
className=
{
cx
(
className
,
styles
.
item
)
}
>
<
CouponsItem
money=
{
money
}
isnull=
{
isnull
}
typeName=
{
typeName
}
tag=
{
tag
}
info=
{
info
}
className=
{
styles
.
couponItem
}
/>
<
div
className=
{
cx
(
styles
.
item
)
}
>
<
div
{
...
divProps
}
className=
{
className
}
>
<
CouponsItem
money=
{
denomination
}
isnull=
{
!
isNotNull
}
typeName=
{
typeName
}
tag=
{
tag
}
info=
{
`满${useConditionMoney}可用`
}
className=
{
styles
.
couponItem
}
/>
</
div
>
</
div
>
);
};
...
...
src/pages/marketingManage/marketing/marketingActivitiesManagement/activePage/fixtures/index.tsx
View file @
0d3450e8
...
...
@@ -5,41 +5,46 @@ import _get from 'lodash/get';
import
_omit
from
'lodash/omit'
;
import
_pick
from
'lodash/pick'
;
import
{
history
}
from
'umi'
;
import
{
usePageStatus
}
from
'@/hooks/usePageStatus'
;
import
{
PublicApi
}
from
'@/services/api'
;
import
MobileDesignPanel
from
'./components/MobileDesignPanel'
;
import
componentConfigs
from
'./common/configs'
;
import
Toolbar
from
'./components/Toolbar'
;
import
styles
from
'./index.less'
;
import
EditPanel
from
'./components/EditPanel'
;
// import EditPanel from './components/EditPanel';
import
EditPanel
from
'./components/EditPanel/editPanelForm'
;
import
configs
from
'./common/configs/pageConfigs'
;
import
useGetData
from
'./common/hooks/useGetData'
;
import
useGetLayout
from
'./common/hooks/useGetLayout'
;
import
Module
from
'./components/ComponentTree'
;
import
ToolbarSubmit
from
'./components/Toolbar/toolbarSubmit'
;
import
{
RenovationProvider
}
from
'./common/context/shopContext'
;
import
{
PublicApi
}
from
'@/services/api'
;
import
{
usePageStatus
}
from
'@/hooks/usePageStatus'
;
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
{
id
}
=
usePageStatus
();
const
{
detail
,
loading
}
=
useGetData
(
componentConfigs
as
any
);
// const { detail, loading } = useGetData(componentConfigs as any);
const
{
detail
,
loading
}
=
useGetLayout
();
const
[
submitLoading
,
setSubmitLoading
]
=
useState
<
boolean
>
(
false
);
const
onSave
=
async
(
pageConfig
:
any
)
=>
{
const
onSave
=
async
(
pageConfig
)
=>
{
const
childNodes
=
pageConfig
[
0
].
childNodes
;
setSubmitLoading
(
true
);
let
result
:
any
=
{};
childNodes
.
map
((
_item
,
_index
)
=>
{
const
target
=
pageConfig
[
_item
];
const
{
dataIndex
,
props
}
=
target
||
{};
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
{
childNodes
}
=
target
;
const
childrenData
=
childNodes
.
map
((
_record
)
=>
{
const
childTargetProps
=
pageConfig
[
_record
].
props
;
return
{
...
...
@@ -55,8 +60,12 @@ const Fixtures = () => {
}
});
}
else
if
(
primaryKey
.
includes
(
dataIndex
))
{
const
{
products
,
...
otherProps
}
=
props
||
{};
const
childrenData
=
products
?.
map
((
_item
)
=>
_item
.
id
)
||
[];
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
:
{
...
...
@@ -65,7 +74,7 @@ const Fixtures = () => {
}
});
}
else
if
(
dataIndex
===
'suggestProduct'
)
{
const
{
products
,
childrenData
,
...
otherProps
}
=
props
||
{};
const
{
...
otherProps
}
=
props
||
{};
console
.
log
(
otherProps
,
"suggestProduct"
);
const
{
childNodes
}
=
target
;
const
temp
=
{
...
...
@@ -74,14 +83,15 @@ const Fixtures = () => {
visible
:
true
,
childrenData
:
childNodes
?.
filter
((
_record
)
=>
/
\d
+-
\d
+/
.
test
(
_record
)).
map
((
_row
)
=>
{
const
childrenNodeTarget
=
pageConfig
[
_row
];
const
{
products
:
productList
,
...
childRestProps
}
=
childrenNodeTarget
?.
props
;
const
{
...
childRestProps
}
=
childrenNodeTarget
?.
props
;
return
{
title
:
childRestProps
.
title
,
theme
:
childRestProps
.
theme
||
0
,
childrenData
:
productList
?.
map
((
_listItem
)
=>
{
childrenData
:
childrenNodeTarget
.
childNodes
?.
map
((
_listItem
)
=>
{
const
sonNodeTarget
=
pageConfig
[
_listItem
];
return
{
id
:
_listItem
.
id
,
label
:
_listItem
?.
label
||
[]
id
:
sonNodeTarget
?.
props
.
id
,
label
:
sonNodeTarget
?.
props
?.
label
||
[]
};
})
};
...
...
@@ -91,8 +101,6 @@ const Fixtures = () => {
result
=
generaterData
(
result
,
dataIndex
,
temp
);
}
});
console
.
log
(
result
);
// return;
const
{
data
,
code
}
=
await
PublicApi
.
postTemplateWebActivityPageAdorn
({
id
:
id
,
adornContent
:
result
...
...
src/pages/pageCustomized/categoryNavigation/common/hooks/useFilterSameOption.tsx
View file @
0d3450e8
...
...
@@ -63,6 +63,7 @@ export function useFilterSameOption() {
});
});
});
console
.
log
(
result
);
return
result
;
},
[
pageConfig
]);
...
...
src/pages/pageCustomized/categoryNavigation/components/EditPanel/editPanel.tsx
View file @
0d3450e8
...
...
@@ -53,7 +53,7 @@ const EditPanel = () => {
/** 精选商品type */
const
[
type
,
setType
]
=
useState
<
number
>
(
0
);
/**
* 当每次点
解
selectInfo 时,都把selectInfo.props 映射到formily 的value 上
* 当每次点
击
selectInfo 时,都把selectInfo.props 映射到formily 的value 上
* 但当一级类型没有被选择的时候,那么必须选择一级导航类型
*/
useEffect
(()
=>
{
...
...
src/utils/index.ts
View file @
0d3450e8
...
...
@@ -408,6 +408,16 @@ export const getIChannelInfo = () => {
return
url
.
split
(
'.'
).
slice
(
-
2
).
join
(
'.'
)
}
/** 数组转对象 */
export
function
arrayToMap
<
T
>
(
list
:
T
[],
primaryKey
:
keyof
T
)
{
const
result
:
{
[
props
:
string
]:
T
}
=
{};
list
.
forEach
((
_item
:
T
)
=>
{
const
key
=
_item
[
primaryKey
];
(
result
as
any
)[
key
]
=
_item
;
});
return
result
;
}
export
default
{
isArray
,
isObject
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment