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
shenshaokai
jinfa-admin
Commits
b16e219c
Commit
b16e219c
authored
Jul 28, 2021
by
Bill
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 添加营销活动页
parent
0aa96a0b
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
934 additions
and
72 deletions
+934
-72
index.ts
config/routes/index.ts
+5
-3
marketingRoutes.ts
config/routes/marketingRoutes.ts
+28
-0
index.tsx
src/components/DescProgress/index.tsx
+57
-64
FormilyRangeTime.tsx
src/components/RangeTime/FormilyRangeTime.tsx
+57
-0
createRichText.tsx
src/components/RangeTime/createRichText.tsx
+46
-0
index.less
src/components/RangeTime/index.less
+14
-0
index.tsx
src/components/RangeTime/index.tsx
+109
-0
index.ts
src/constants/index.ts
+2
-2
index.tsx
src/pages/home/components/StatisticsColumn/index.tsx
+3
-3
index.less
...g/marketingActivitiesManagement/activePage/add/index.less
+12
-0
index.tsx
...ng/marketingActivitiesManagement/activePage/add/index.tsx
+44
-0
schema.tsx
...g/marketingActivitiesManagement/activePage/add/schema.tsx
+69
-0
index.less
...iesManagement/activePage/components/ActiveItem/index.less
+56
-0
index.tsx
...tiesManagement/activePage/components/ActiveItem/index.tsx
+45
-0
index.less
...nagement/activePage/components/FormilyCheckBox/index.less
+18
-0
index.tsx
...anagement/activePage/components/FormilyCheckBox/index.tsx
+59
-0
index.tsx
...esManagement/activePage/components/SearchPannel/index.tsx
+33
-0
layout.tsx
...sManagement/activePage/components/SearchPannel/layout.tsx
+37
-0
schema.tsx
...sManagement/activePage/components/SearchPannel/schema.tsx
+104
-0
index.less
...eting/marketingActivitiesManagement/activePage/index.less
+61
-0
index.tsx
...keting/marketingActivitiesManagement/activePage/index.tsx
+75
-0
No files found.
config/routes/index.ts
View file @
b16e219c
...
...
@@ -21,7 +21,7 @@
// import rfqRoute from './rfqRoute' // 询价单路由
// import rfqOfferRoute from './rfqOfferRoute' // 询价单路由
// import commentRoutes from './commentRoutes';
import
contentRoute
from
'./contentRoute'
;
// 内容管理
//
import contentRoute from './contentRoute'; // 内容管理
// import balancedRoute from './balancedRoute'; // 平台结算管理
// import capitalAccount from './capitalAccountRoute'; // 会员资金账户
// import messageRoute from './messgeRoute'; // 消息管理
...
...
@@ -31,8 +31,9 @@ import contentRoute from './contentRoute'; // 内容管理
// import exchangeManageRoutes from './exchangeManageRoute'; // 换货申请单管理
// import returnManageRoute from './returnManageRoute'; // 退货申请单管理
// import repairManageRoute from './repairManageRoute'; // 维修申请单管理
import
purchaseBidRoute
from
'./purchaseBidRoute'
;
// 采购竞价单审核
import
seoSettingRoutes
from
'./seoSettingRoutes'
// seo优化
// import purchaseBidRoute from './purchaseBidRoute'; // 采购竞价单审核
// import seoSettingRoutes from './seoSettingRoutes'; // seo优化
// import marketingRoutes from './marketingRoutes'; // 营销
//@ts-ignore
import
asyncRoutes
from
'../router.config.json'
...
...
@@ -103,6 +104,7 @@ const router = [
// icon: 'BarChartOutlined'
// },
// ...routeList,
// marketingRoutes,
...
asyncRoutes
,
// purchaseBidRoute,
{
...
...
config/routes/marketingRoutes.ts
0 → 100644
View file @
b16e219c
const
marketingRoutes
=
{
path
:
'/marketing'
,
name
:
'marketing'
,
routes
:[
{
path
:
'/marketing/activitiesManagement'
,
name
:
'营销活动管理'
,
routes
:
[
/** 营销活动页管理 */
{
path
:
'/marketing/activitiesManagement/activePage'
,
name
:
'营销活动页管理'
,
component
:
'@/pages/marketing/marketingActivitiesManagement/activePage'
},
/** 营销活动页管理 */
{
path
:
'/marketing/activitiesManagement/activePage/add'
,
name
:
'营销活动页管理'
,
component
:
'@/pages/marketing/marketingActivitiesManagement/activePage/add/index'
,
hidePageHeader
:
true
,
noMargin
:
true
,
}
]
},
]
}
export
default
marketingRoutes
src/components/DescProgress/index.tsx
View file @
b16e219c
/*
* @Author: XieZhiXiong
* @Date: 2021-05-12 14:00:38
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-05-12 14:37:54
* @Description: 带描述信息的进度条
*/
import
React
from
'react'
;
import
{
Progress
}
from
'antd'
;
import
{
ProgressProps
}
from
'antd/lib/progress'
;
import
styles
from
'./index.less'
;
export
interface
DescriptionsItem
{
/**
* 标题
*/
title
:
React
.
ReactNode
,
/**
* 值
*/
value
:
React
.
ReactNode
,
/**
* 自定义渲染
*/
customRender
?:
React
.
ReactNode
,
}
interface
IProps
extends
ProgressProps
{
/**
* 描述列表
*/
descriptions
:
DescriptionsItem
[],
}
const
DescProgress
:
React
.
FC
<
IProps
>
=
(
props
:
IProps
)
=>
{
const
{
descriptions
,
...
rest
}
=
props
;
return
(
<
div
className=
{
styles
[
'desc-progress'
]
}
>
<
div
className=
{
styles
[
'desc-progress-statistic'
]
}
>
{
descriptions
.
map
((
item
,
index
)
=>
(
!
item
.
customRender
?
(
<
div
key=
{
index
}
className=
{
styles
[
'desc-progress-statistic-item'
]
}
>
<
div
className=
{
styles
[
'desc-progress-statistic-item-title'
]
}
>
{
item
.
title
}
</
div
>
<
div
className=
{
styles
[
'desc-progress-statistic-item-content'
]
}
>
{
item
.
value
}
</
div
>
</
div
>
)
:
(
item
.
customRender
)
))
}
</
div
>
<
Progress
strokeColor=
"#6B778C"
showInfo=
{
false
}
{
...
rest
}
/>
</
div
>
);
};
export
default
DescProgress
;
import
React
from
'react'
;
import
{
Progress
}
from
'antd'
;
import
{
ProgressProps
}
from
'antd/lib/progress'
;
import
styles
from
'./index.less'
;
export
interface
DescriptionsItem
{
/**
* 标题
*/
title
:
React
.
ReactNode
,
/**
* 值
*/
value
:
React
.
ReactNode
,
/**
* 自定义渲染
*/
customRender
?:
React
.
ReactNode
,
}
interface
IProps
extends
ProgressProps
{
/**
* 描述列表
*/
descriptions
:
DescriptionsItem
[],
}
const
DescProgress
:
React
.
FC
<
IProps
>
=
(
props
:
IProps
)
=>
{
const
{
descriptions
,
...
rest
}
=
props
;
return
(
<
div
className=
{
styles
[
'desc-progress'
]
}
>
<
div
className=
{
styles
[
'desc-progress-statistic'
]
}
>
{
descriptions
.
map
((
item
,
index
)
=>
(
!
item
.
customRender
?
(
<
div
key=
{
index
}
className=
{
styles
[
'desc-progress-statistic-item'
]
}
>
<
div
className=
{
styles
[
'desc-progress-statistic-item-title'
]
}
>
{
item
.
title
}
</
div
>
<
div
className=
{
styles
[
'desc-progress-statistic-item-content'
]
}
>
{
item
.
value
}
</
div
>
</
div
>
)
:
(
item
.
customRender
)
))
}
</
div
>
<
Progress
strokeColor=
"#6B778C"
showInfo=
{
false
}
{
...
rest
}
/>
</
div
>
);
};
export
default
DescProgress
;
src/components/RangeTime/FormilyRangeTime.tsx
0 → 100644
View file @
b16e219c
import
React
,
{
useEffect
}
from
'react'
;
import
RangeTime
from
'./index'
;
import
{
Moment
}
from
'moment'
;
interface
Iprops
{
value
:
Moment
[]
|
string
,
editable
:
boolean
,
ruleErrors
:
string
[],
props
:
{
[
'x-component-props'
]:
any
,
},
mutators
:
{
change
:
(
params
:
Moment
[])
=>
void
},
}
const
toArray
=
(
value
:
string
|
Moment
[]):
Moment
[]
=>
{
if
(
!
value
)
{
return
[];
}
if
(
Array
.
isArray
(
value
))
{
return
value
;
}
return
[]
}
const
FormilyRangeTime
:
React
.
FC
<
Iprops
>
=
(
props
:
Iprops
)
=>
{
const
{
value
,
editable
,
ruleErrors
}
=
props
;
// const schemaProps = useSchemaProps()
// console.log(schemaProps);
const
componentProps
=
props
.
props
?.[
'x-component-props'
]
||
{};
const
momentValue
=
toArray
(
value
)
const
hasError
=
ruleErrors
.
length
>
0
;
const
onChange
=
(
info
:
Moment
[])
=>
{
props
.
mutators
.
change
(
info
)
}
return
(
<
div
>
<
RangeTime
disabled=
{
!
editable
}
rangeTime=
{
momentValue
}
onChange=
{
onChange
}
{
...
componentProps
}
/>
{
hasError
&&
(
<
p
style=
{
{
marginBottom
:
0
,
color
:
'#ff4d4f'
}
}
>
{
ruleErrors
.
join
(
","
)
}
</
p
>
)
}
</
div
>
)
}
const
WrapFormilyRangeTime
:
typeof
FormilyRangeTime
&
{
isFieldComponent
?:
boolean
,
}
=
FormilyRangeTime
;
WrapFormilyRangeTime
.
isFieldComponent
=
true
export
default
WrapFormilyRangeTime
src/components/RangeTime/createRichText.tsx
0 → 100644
View file @
b16e219c
import
React
from
"react"
import
{
Tooltip
}
from
'antd'
;
import
{
QuestionCircleOutlined
}
from
"@ant-design/icons"
const
createRichTextUtils
=
()
=>
{
return
{
text
(...
args
)
{
return
React
.
createElement
(
'span'
,
{},
...
args
)
},
link
(
text
:
string
,
href
:
string
,
target
:
"_blank"
|
"_self"
|
"_parent"
|
"_top"
)
{
return
React
.
createElement
(
'a'
,
{
href
,
target
},
text
)
},
gray
(
text
:
string
)
{
return
React
.
createElement
(
'span'
,
{
style
:
{
color
:
'gray'
,
margin
:
'0 3px'
}
},
text
)
},
red
(
text
:
string
)
{
return
React
.
createElement
(
'span'
,
{
style
:
{
color
:
'red'
,
margin
:
'0 3px'
}
},
text
)
},
help
(
text
:
string
,
offset
=
3
)
{
return
React
.
createElement
(
Tooltip
,
{
title
:
text
},
<
QuestionCircleOutlined
style=
{
{
margin
:
'0 3px'
,
cursor
:
'default'
,
marginLeft
:
offset
}
}
/>
)
},
tips
(
text
:
string
,
tips
:
string
)
{
return
React
.
createElement
(
Tooltip
,
{
title
:
tips
},
<
span
style=
{
{
margin
:
'0 3px'
,
cursor
:
'default'
}
}
>
{
text
}
</
span
>
)
}
}
}
export
default
createRichTextUtils
src/components/RangeTime/index.less
0 → 100644
View file @
b16e219c
.container {
display: flex;
flex-direction: row;
align-items: center;
.wrapFlex {
flex: 1;
}
.splitChar {
text-align: center;
width: 32px;
}
}
src/components/RangeTime/index.tsx
0 → 100644
View file @
b16e219c
import
React
,
{
CSSProperties
,
useCallback
,
useEffect
,
useState
}
from
'react'
;
import
{
DatePicker
}
from
'antd'
;
import
cx
from
'classnames'
;
import
styles
from
'./index.less'
;
import
moment
,
{
Moment
}
from
'moment'
;
interface
Iprops
{
containerStyle
?:
CSSProperties
,
/**
* 默认时间
*/
rangeTime
?:
Moment
[],
/**
* placeholader
*/
placeholader
?:
[
string
,
string
],
/**
* 规定起始时间是否大于当前日期
*/
shouldGtCurrent
?:
boolean
,
onChange
?:
((
rangeTime
:
Moment
[])
=>
void
)
|
null
,
disabled
?:
boolean
,
showTime
?:
boolean
,
}
const
RangeTime
:
React
.
FC
<
Iprops
>
=
(
props
:
Iprops
)
=>
{
const
{
containerStyle
,
rangeTime
,
onChange
,
placeholader
,
shouldGtCurrent
,
disabled
}
=
props
;
const
currentDay
=
moment
();
const
[
innerRangeTime
,
setInnerRangeTime
]
=
useState
({
startTime
:
null
,
endTime
:
null
});
useEffect
(()
=>
{
const
[
startTime
=
null
,
endTime
=
null
]
=
rangeTime
as
any
;
setInnerRangeTime
({
startTime
:
startTime
,
endTime
:
endTime
,
})
},
[
props
.
rangeTime
])
const
handleChange
=
(
date
:
Moment
|
null
,
dateString
:
string
,
mode
:
"startTime"
|
"endTime"
)
=>
{
const
newObject
=
{
...
innerRangeTime
,
[
mode
]:
date
,
}
onChange
?.([
newObject
.
startTime
as
unknown
as
Moment
,
newObject
.
endTime
as
unknown
as
Moment
])
setInnerRangeTime
(
newObject
)
}
const
getDisableDate
=
useCallback
((
current
:
Moment
,
mode
:
"startTime"
|
"endTime"
)
=>
{
const
reverseMode
=
mode
===
'startTime'
?
'endTime'
:
'startTime'
;
const
modeTime
:
Moment
|
null
=
innerRangeTime
[
reverseMode
];
// current 为当前日历上的日期, 如果返回值为true,那么表示当前日期为禁用状态
if
(
!
modeTime
)
{
if
(
shouldGtCurrent
)
{
return
current
<
currentDay
.
endOf
(
'day'
);
}
return
false
}
if
(
mode
===
'startTime'
)
{
return
shouldGtCurrent
?
(
current
<
currentDay
.
endOf
(
'day'
)
||
current
>
(
modeTime
as
Moment
).
endOf
(
'day'
))
:
current
>
(
modeTime
as
Moment
).
endOf
(
'day'
)
}
else
{
//现在的时间要大于开始的时间, true 为禁用
return
shouldGtCurrent
?
(
current
<
currentDay
.
endOf
(
'day'
)
||
current
<
(
modeTime
as
Moment
).
endOf
(
'day'
))
:
current
<
(
modeTime
as
Moment
).
endOf
(
'day'
)
}
},
[
innerRangeTime
])
return
(
<
div
className=
{
cx
(
styles
.
container
,
containerStyle
)
}
>
<
div
className=
{
styles
.
wrapFlex
}
>
<
DatePicker
style=
{
{
width
:
'100%'
}
}
value=
{
innerRangeTime
.
startTime
}
onChange=
{
(
date
:
Moment
|
null
,
dateString
:
string
)
=>
handleChange
(
date
,
dateString
,
"startTime"
)
}
disabledDate=
{
(
current
)
=>
getDisableDate
(
current
,
'startTime'
)
}
placeholder=
{
placeholader
!
[
0
]
}
disabled=
{
disabled
}
showTime
/>
</
div
>
<
span
className=
{
styles
.
splitChar
}
>
~
</
span
>
<
div
className=
{
styles
.
wrapFlex
}
>
<
DatePicker
style=
{
{
width
:
'100%'
}
}
value=
{
innerRangeTime
.
endTime
}
onChange=
{
(
date
:
Moment
|
null
,
dateString
:
string
)
=>
handleChange
(
date
,
dateString
,
"endTime"
)
}
disabledDate=
{
(
current
)
=>
getDisableDate
(
current
,
'endTime'
)
}
placeholder=
{
placeholader
!
[
1
]
}
disabled=
{
disabled
}
showTime
/>
</
div
>
</
div
>
)
}
RangeTime
.
defaultProps
=
{
containerStyle
:
{},
rangeTime
:
[],
onChange
:
null
,
placeholader
:
[
"开始时间"
,
"结束时间"
],
shouldGtCurrent
:
true
,
disabled
:
false
,
showTime
:
false
,
}
export
default
RangeTime
src/constants/index.ts
View file @
b16e219c
...
...
@@ -112,8 +112,8 @@ export enum LAYOUT_TYPE {
}
// 本地环境跳过权限校验
//
export const isDev = process.env.NODE_ENV === "development"
export
const
isDev
=
false
export
const
isDev
=
process
.
env
.
NODE_ENV
===
"development"
//
export const isDev = false
export
const
STATUS_ENUM
=
[
{
...
...
src/pages/home/components/StatisticsColumn/index.tsx
View file @
b16e219c
...
...
@@ -49,9 +49,9 @@ const StatisticsColumn = (props) => {
icon
:
totalBrand1
,
},
{
count
:
responseData
?.
toBe
Product
Valify
?.
count
||
0
,
name
:
responseData
?.
toBe
Product
Valify
?.
name
,
link
:
responseData
?.
toBe
Product
Valify
?.
link
||
null
,
count
:
responseData
?.
toBe
Brand
Valify
?.
count
||
0
,
name
:
responseData
?.
toBe
Brand
Valify
?.
name
,
link
:
responseData
?.
toBe
Brand
Valify
?.
link
||
null
,
icon
:
totalBrand2
},
]
...
...
src/pages/marketing/marketingActivitiesManagement/activePage/add/index.less
0 → 100644
View file @
b16e219c
.card {
padding: 16px;
background-color: #fff;
border-radius: 8px;
.title {
color: '#252D37';
font-size: 14px;
margin-bottom: 16px;
font-weight: 600;
}
}
src/pages/marketing/marketingActivitiesManagement/activePage/add/index.tsx
0 → 100644
View file @
b16e219c
import
{
PageHeaderWrapper
}
from
'@ant-design/pro-layout'
;
import
React
from
'react'
;
import
NiceForm
from
'@/components/NiceForm'
;
import
RangeTime
from
'@/components/RangeTime/FormilyRangeTime'
;
import
{
Button
,
Space
}
from
'antd'
import
styles
from
'./index.less'
;
import
schema
from
'./schema'
;
import
ReutrnEle
from
'@/components/ReturnEle'
;
import
{
history
}
from
'umi'
;
import
{
BgColorsOutlined
,
SaveOutlined
}
from
'@ant-design/icons'
;
import
{
createFormActions
}
from
'@formily/antd'
;
const
actions
=
createFormActions
()
const
Add
=
()
=>
{
const
onSubmit
=
(
values
:
any
)
=>
{
}
return
(
<
PageHeaderWrapper
title=
"账户详情"
onBack=
{
()
=>
history
.
goBack
()
}
backIcon=
{
<
ReutrnEle
/>
}
extra=
{
<
Space
>
<
Button
icon=
{
<
BgColorsOutlined
/>
}
>
活动页装修
</
Button
>
<
Button
icon=
{
<
SaveOutlined
/>
}
onClick=
{
()
=>
actions
.
submit
()
}
type=
"primary"
>
保存
</
Button
>
</
Space
>
}
>
<
div
className=
{
styles
.
card
}
>
<
div
className=
{
styles
.
title
}
>
基本信息
</
div
>
<
NiceForm
onSubmit=
{
onSubmit
}
schema=
{
schema
}
actions=
{
actions
}
components=
{
{
RangeTime
}
}
/>
</
div
>
</
PageHeaderWrapper
>
)
}
export
default
Add
;
src/pages/marketing/marketingActivitiesManagement/activePage/add/schema.tsx
0 → 100644
View file @
b16e219c
import
{
ISchema
}
from
"@formily/antd"
;
const
schema
:
ISchema
=
{
type
:
'object'
,
properties
:
{
layout
:
{
type
:
'object'
,
"x-component"
:
'mega-layout'
,
'x-component-props'
:
{
full
:
true
,
columns
:
2
,
grid
:
true
,
labelCol
:
4
,
wrapperCol
:
17
,
},
properties
:
{
left
:
{
type
:
'object'
,
"x-component"
:
'mega-layout'
,
"x-component-props"
:
{
labelAlign
:
'left'
},
properties
:
{
name
:
{
type
:
'string'
,
title
:
'活动页名称'
,
required
:
true
,
},
environment
:
{
type
:
'string'
,
enum
:
[],
title
:
'活动页使用环境'
,
required
:
true
,
},
template
:
{
type
:
'string'
,
enum
:
[],
title
:
'活动模板'
,
required
:
true
,
},
}
},
right
:
{
type
:
'object'
,
"x-component"
:
'mega-layout'
,
"x-component-props"
:
{
labelAlign
:
'left'
},
properties
:
{
'[startTime, endTime]'
:
{
type
:
'object'
,
title
:
'活动页有效时间'
,
"x-component"
:
'RangeTime'
,
required
:
true
,
},
mall
:
{
type
:
'string'
,
title
:
'活动页适用商城'
,
enum
:
[],
required
:
true
,
},
}
},
}
}
}
}
export
default
schema
;
src/pages/marketing/marketingActivitiesManagement/activePage/components/ActiveItem/index.less
0 → 100644
View file @
b16e219c
@marginBottom: 14px;
.section {
display: flex;
flex-direction: row;
padding: 16px;
background-color: #fff;
border-radius: 8px;
.image {
width: 168px;
height: 112px;
border-radius: 8px;
overflow: hidden;
background-color: red;
margin-right: 16px;
}
.infoContainer {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
flex: 1;
.info {
.header {
color: #303133;
font-size: 16px;
line-height: 16px;
margin-bottom: @marginBottom;
}
.tags {
margin-bottom: @marginBottom;
}
.mall {
margin-bottom: @marginBottom;
.label {
min-width: 72px;
display: inline-block;
}
}
.time {
.startTime {
margin-right: 40px;
}
}
}
}
.status {
margin-left: auto;
margin-right: 104px;
}
}
src/pages/marketing/marketingActivitiesManagement/activePage/components/ActiveItem/index.tsx
0 → 100644
View file @
b16e219c
import
StatusTag
from
'@/components/StatusTag'
;
import
{
PlayCircleOutlined
}
from
'@ant-design/icons'
;
import
{
Button
}
from
'antd'
;
import
React
from
'react'
;
import
styles
from
'./index.less'
;
/** partial 去掉 */
interface
Iprops
{
image
?:
string
,
title
?:
string
,
tags
?:
string
[],
mall
?:
string
,
startTime
?:
string
,
endTime
?:
string
,
}
const
ActiveItem
:
React
.
FC
<
Iprops
>
=
(
props
:
Iprops
)
=>
{
return
(
<
div
className=
{
styles
.
section
}
>
<
img
className=
{
styles
.
image
}
/>
<
div
className=
{
styles
.
infoContainer
}
>
<
div
className=
{
styles
.
info
}
>
<
div
className=
{
styles
.
header
}
>
9余额平台中秋节促销活动页
</
div
>
<
div
className=
{
styles
.
tags
}
>
<
StatusTag
type=
"default"
title=
"WEB中秋主题活动模板"
/>
</
div
>
<
div
className=
{
styles
.
mall
}
>
<
span
className=
{
styles
.
label
}
>
适用商城:
</
span
>
<
span
>
灵犀超时-WEB个人商城
</
span
>
</
div
>
<
div
className=
{
styles
.
time
}
>
<
span
className=
{
styles
.
startTime
}
>
有效期开始:2020-08-25 09:00:00
</
span
>
<
span
>
有效期结束:2020-08-25 09:00:00
</
span
>
</
div
>
</
div
>
<
div
className=
{
styles
.
status
}
>
<
StatusTag
type=
"success"
title=
"进行中"
/>
</
div
>
<
Button
icon=
{
<
PlayCircleOutlined
/>
}
>
已上线
</
Button
>
</
div
>
</
div
>
)
}
export
default
ActiveItem
src/pages/marketing/marketingActivitiesManagement/activePage/components/FormilyCheckBox/index.less
0 → 100644
View file @
b16e219c
.container {
display: flex;
flex-direction: column;
.checkboxItem {
margin-bottom: 2px;
.checkbox {
display: flex;
flex-direction: row;
}
&:last-of-type {
margin-bottom: 0px;
}
}
}
src/pages/marketing/marketingActivitiesManagement/activePage/components/FormilyCheckBox/index.tsx
0 → 100644
View file @
b16e219c
import
React
from
'react'
;
import
{
Checkbox
}
from
'antd'
;
import
styles
from
'./index.less'
;
type
CheckboxType
=
{
label
:
string
,
value
:
number
|
string
extra
?:
number
|
string
}
interface
Iprops
{
props
:
{
enum
:
CheckboxType
[]
},
mutators
:
{
change
:
(
params
:
number
[]
|
string
[])
=>
void
},
value
:
number
[]
|
string
[]
}
const
FormilyCheckBox
:
React
.
FC
<
Iprops
>
&
{
isFieldComponent
:
boolean
}
=
(
props
:
Iprops
)
=>
{
const
{
value
=
[],
mutators
}
=
props
;
const
componentProps
=
props
.
props
||
{};
const
enumsMap
:
CheckboxType
[]
=
componentProps
?.
enum
||
[];
const
handleChange
=
(
isChecked
:
boolean
,
_item
:
CheckboxType
)
=>
{
let
newList
:
string
[]
|
number
[]
=
[]
if
(
isChecked
)
{
newList
=
(
value
as
string
[]).
concat
(
_item
.
value
as
string
);
}
else
{
newList
=
(
value
as
string
[]).
filter
((
_row
)
=>
_row
!==
_item
.
value
)
}
mutators
.
change
(
newList
)
}
return
(
<
div
className=
{
styles
.
container
}
>
{
enumsMap
.
map
((
_item
)
=>
{
const
isChecked
=
(
value
as
string
[]).
indexOf
((
_item
as
any
).
value
)
!==
-
1
;
return
(
<
div
className=
{
styles
.
checkboxItem
}
key=
{
_item
.
value
}
>
<
Checkbox
checked=
{
isChecked
}
onChange=
{
(
e
)
=>
handleChange
(
e
.
target
.
checked
,
_item
)
}
>
<
div
className=
{
styles
.
checkbox
}
>
<
span
>
{
_item
.
label
}
</
span
>
</
div
>
</
Checkbox
>
</
div
>
)
})
}
</
div
>
)
}
FormilyCheckBox
.
isFieldComponent
=
true
;
export
default
FormilyCheckBox
src/pages/marketing/marketingActivitiesManagement/activePage/components/SearchPannel/index.tsx
0 → 100644
View file @
b16e219c
import
{
createFormActions
,
SchemaForm
,
LifeCycleTypes
}
from
'@formily/antd'
;
import
React
from
'react'
;
import
schema
from
'./schema'
;
import
VerticalLayout
from
'./layout'
;
import
FormilyCheckBox
from
'../FormilyCheckBox'
;
const
actions
=
createFormActions
()
interface
Iprops
{
onSubmit
?:
(
values
:
any
)
=>
void
,
onFormValueChange
?:
(
values
:
any
)
=>
void
}
const
SearchPannel
:
React
.
FC
<
Iprops
>
=
(
props
:
Iprops
)
=>
{
const
{
onSubmit
,
onFormValueChange
}
=
props
const
handleSubmit
=
(
values
:
any
)
=>
{
onSubmit
?.(
values
)
}
return
(
<
SchemaForm
components=
{
{
VerticalLayout
,
FormilyCheckBox
}
}
actions=
{
actions
}
schema=
{
schema
}
onSubmit=
{
handleSubmit
}
effects=
{
(
$
,
{
setFieldState
})
=>
{
$
(
LifeCycleTypes
.
ON_FORM_INPUT_CHANGE
).
subscribe
((
state
)
=>
{
onFormValueChange
?.(
state
.
values
)
})
}
}
></
SchemaForm
>
)
}
export
default
SearchPannel
src/pages/marketing/marketingActivitiesManagement/activePage/components/SearchPannel/layout.tsx
0 → 100644
View file @
b16e219c
import
React
,
{
useMemo
}
from
'react'
;
interface
Iprops
{
children
:
React
.
ReactNode
,
title
:
string
,
props
:
{
"x-component-props"
:
{
title
:
string
}
}
}
const
VerticalLayout
:
React
.
FC
<
Iprops
>
&
{
isVirtualFieldComponent
:
boolean
}
=
(
props
:
Iprops
)
=>
{
const
{
children
,
}
=
props
;
const
xComponentProps
=
props
.
props
[
"x-component-props"
]
||
{};
const
{
title
=
""
}
=
xComponentProps
;
const
styles
=
useMemo
(()
=>
({
display
:
'flex'
,
flexDirection
:
"column"
,
padding
:
'16px 16px 0px 16px'
,
}),
[])
return
(
<
div
style=
{
styles
as
any
}
>
<
div
style=
{
{
marginBottom
:
'16px'
,
color
:
"#252537"
,
fontSize
:
'14px'
,
lineHeight
:
'14px'
,
fontWeight
:
600
}
}
>
{
title
}
</
div
>
<
div
>
{
children
}
</
div
>
</
div
>
)
}
VerticalLayout
.
isVirtualFieldComponent
=
true
export
default
VerticalLayout
src/pages/marketing/marketingActivitiesManagement/activePage/components/SearchPannel/schema.tsx
0 → 100644
View file @
b16e219c
import
{
ISchema
}
from
'@formily/antd'
;
const
schema
:
ISchema
=
{
type
:
'object'
,
properties
:
{
layout
:
{
type
:
'object'
,
"x-component"
:
'mega-layout'
,
"x-component-props"
:
{
"full"
:
true
,
labelAlign
:
"top"
,
},
properties
:
{
statusLayout
:
{
type
:
'object'
,
"x-component"
:
'VerticalLayout'
,
"x-component-props"
:
{
title
:
'状态'
},
properties
:
{
status
:
{
type
:
'string'
,
title
:
''
,
"x-component"
:
'FormilyCheckBox'
,
enum
:
[
{
label
:
'待上线'
,
value
:
1
},
{
label
:
'已上线'
,
value
:
2
},
{
label
:
'进行中'
,
value
:
3
},
{
label
:
'已下线'
,
value
:
4
},
{
label
:
'已结束'
,
value
:
5
},
]
}
}
},
timeLayout
:
{
type
:
'string'
,
"x-component"
:
'VerticalLayout'
,
"x-component-props"
:
{
title
:
'有效期'
},
properties
:
{
start
:
{
title
:
'开始'
,
type
:
'date'
,
},
end
:
{
title
:
'结束:'
,
type
:
'date'
,
}
}
},
environmentLayout
:
{
type
:
'object'
,
"x-component"
:
'VerticalLayout'
,
"x-component-props"
:
{
title
:
'适用环境'
},
properties
:
{
status
:
{
type
:
'string'
,
title
:
''
,
"x-component"
:
'FormilyCheckBox'
,
enum
:
[
{
label
:
'WEB'
,
value
:
1
},
{
label
:
'APP'
,
value
:
2
},
{
label
:
'小程序'
,
value
:
3
},
{
label
:
'H5'
,
value
:
4
},
]
}
}
},
},
}
}
}
export
default
schema
src/pages/marketing/marketingActivitiesManagement/activePage/index.less
0 → 100644
View file @
b16e219c
@import '../../../../global/styles/index.less';
.page {
display: flex;
flex-direction: row;
.searchPannel {
width: 320px;
background-color: #fff;
border-radius: 8px;
}
.tablePanenl {
margin-left: @margin-md;
flex: 1;
.header {
display: flex;
flex-direction: row;
justify-content: space-between;
.search {
width: 256px;
:global {
.ant-input {
padding: 7px 11px;
border: none;
&:focus {
border-color: transparent;
}
}
.ant-input-search-button {
border-left: none;
border: none;
}
}
}
}
.table {
margin-top: @margin-md;
.tableItem {
margin-bottom: @margin-sm;
&:last-of-type {
margin-bottom: 0px;
}
}
}
.footer {
margin-top: @margin-md;
.pagination {
float: right;
}
}
}
}
src/pages/marketing/marketingActivitiesManagement/activePage/index.tsx
0 → 100644
View file @
b16e219c
import
React
,
{
useEffect
,
useMemo
,
useState
}
from
'react'
;
import
{
Card
,
Input
,
Button
,
Pagination
}
from
'antd'
;
import
SearchPannel
from
'./components/SearchPannel'
;
import
styles
from
'./index.less'
;
import
{
PlusOutlined
}
from
'@ant-design/icons'
;
import
ActiveItem
from
'./components/ActiveItem'
;
import
{
unstable_batchedUpdates
}
from
'react-dom'
;
import
{
useDebounce
}
from
'@umijs/hooks'
;
const
{
Search
}
=
Input
;
type
SearchParamsType
=
{
status
:
number
[],
}
const
ActivePage
=
()
=>
{
const
list
=
new
Array
(
10
).
fill
(
5
);
const
[
currentPage
,
setPage
]
=
useState
<
number
>
(
1
);
const
[
currentPageSize
,
setPageSize
]
=
useState
<
number
>
(
10
);
const
[
searchParams
,
setSearchParams
]
=
useState
<
SearchParamsType
|
null
>
(
null
)
const
cacheData
=
useMemo
(()
=>
({...
searchParams
,
current
:
currentPage
,
pageSize
:
currentPageSize
,
}),
[
searchParams
,
currentPage
,
currentPageSize
])
const
debouncedValue
=
useDebounce
(
cacheData
,
1500
);
const
[
loading
,
setLoading
]
=
useState
<
boolean
>
(
false
);
const
onPaginationChange
=
(
page
:
number
,
pageSize
:
number
)
=>
{
unstable_batchedUpdates
(()
=>
{
setPage
(
page
);
setPageSize
(
pageSize
)
})
}
const
onSearchChange
=
(
values
:
SearchParamsType
)
=>
{
console
.
log
(
values
);
setSearchParams
(
values
)
}
useEffect
(()
=>
{
console
.
log
(
"123123"
,
debouncedValue
);
},
[
debouncedValue
])
return
(
<
div
className=
{
styles
.
page
}
>
<
div
className=
{
styles
.
searchPannel
}
>
<
SearchPannel
onFormValueChange=
{
onSearchChange
}
/>
</
div
>
<
div
className=
{
styles
.
tablePanenl
}
>
<
div
className=
{
styles
.
header
}
>
<
div
className=
{
styles
.
search
}
>
<
Search
placeholder=
"搜索"
/>
</
div
>
<
Button
icon=
{
<
PlusOutlined
/>
}
type=
"primary"
>
新增
</
Button
>
</
div
>
<
div
className=
{
styles
.
table
}
>
{
list
.
map
((
_item
,
key
)
=>
{
return
(
<
div
className=
{
styles
.
tableItem
}
key=
{
key
}
>
<
ActiveItem
/>
</
div
>
)
})
}
</
div
>
<
div
className=
{
styles
.
footer
}
>
<
div
className=
{
styles
.
pagination
}
>
<
Pagination
showQuickJumper
total=
{
500
}
pageSize=
{
currentPageSize
}
current=
{
currentPage
}
onChange=
{
onPaginationChange
}
/>
</
div
>
</
div
>
</
div
>
</
div
>
)
}
export
default
ActivePage
;
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