Commit 3ad16da4 authored by 前端-黄佳鑫's avatar 前端-黄佳鑫

feat(商家营销活动管理): 页面接口接入

parent dd70f367
......@@ -40,7 +40,7 @@ export const selfManagementRoute = [
},
{
/** 修改营销活动 */
path: '/memberCenter/marketingAbility/selfManagement/readySubmitExamine/modify',
path: '/memberCenter/marketingAbility/selfManagement/readySubmitExamine/edit',
name: '修改营销活动',
component: '@/pages/transaction/marketingAbility/selfManagement/readySubmitExamine/add',
hideInMenu: true,
......
......@@ -19,7 +19,7 @@ export interface IProps {
visible: boolean,
data?: any,
id: number,
modalType: 'audit' | 'abandon' | 'date' | 'next' | 'key' | 'discard' | 'planAudit' | 'billBack' | 'merkeingAudit',
modalType: 'audit' | 'abandon' | 'date' | 'next' | 'key' | 'discard' | 'planAudit' | 'billBack' | 'merkeingAudit' | 'marketing',
onCancel?: () => void,
onOk?: () => void,
fetch?: () => Promise<unknown>,
......@@ -77,6 +77,18 @@ const ModalOperate: React.FC<IProps> = (props: any) => {
})
}
if (modalType === 'marketing') {
onFieldChange$('isPass').subscribe(({ value }) => {
setFieldState('opinion', state => {
if (value == 1) {
state.visible = false
} else {
state.visible = true
}
})
})
}
if (modalType === 'date') {
onFieldChange$('checkbox').subscribe(({ value }) => {
if (value && value.length > 0) {
......@@ -96,6 +108,8 @@ const ModalOperate: React.FC<IProps> = (props: any) => {
switch (modalType) {
case 'audit':
case 'planAudit':
case 'merkeingAudit':
case 'marketing':
return '审核不通过原因';
case 'billBack':
return '退回原因';
......@@ -215,6 +229,18 @@ const ModalOperate: React.FC<IProps> = (props: any) => {
x-component="Radio"
x-component-props={{}}
/>
case 'marketing':
return <Field
enum={
[
{ label: '审核通过', value: 1 },
{ label: '审核不通过', value: 0 }
]}
name='isPass'
required
x-component="Radio"
x-component-props={{}}
/>
}
}
......@@ -258,6 +284,9 @@ const ModalOperate: React.FC<IProps> = (props: any) => {
} else if (modalType === 'merkeingAudit') {
params.agree = value.agree;
params.reason = value.reason;
} else if (modalType === 'marketing') {
params.isPass = value.isPass;
params.opinion = value.opinion;
} else {
params.password = value.password;
}
......@@ -281,6 +310,8 @@ const ModalOperate: React.FC<IProps> = (props: any) => {
return 'auditOpinion';
case 'planAudit':
return 'cause'
case 'marketing':
return 'opinion'
default:
return 'reason'
}
......@@ -315,10 +346,11 @@ const ModalOperate: React.FC<IProps> = (props: any) => {
state: 1,
status: 1,
agree: 1,
isPass: 1,
}}
>
{modalNode()}
{(modalType === 'audit' || modalType === 'abandon' || modalType === 'discard' || modalType === 'planAudit' || modalType === 'billBack' || modalType === 'merkeingAudit')
{(modalType === 'audit' || modalType === 'abandon' || modalType === 'discard' || modalType === 'planAudit' || modalType === 'billBack' || modalType === 'merkeingAudit' || modalType === 'marketing')
&& (<Field
title={modalText()}
name={causeName(modalType)}
......
......@@ -3,19 +3,22 @@
align-items: center;
h5 { margin-bottom: 2em; }
.label {
flex: 0 0 25%;
flex: 0 0 84.66px;
color: #909399;
}
.content {
flex: 0 0 70%;
display: flex;
display: inline-block;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
.selector {
width: 68px;
min-width: 68px;
height: 32px;
color: #252D37;
background: #FAFBFC;
text-align: center;
line-height: 32px;
padding: 0px 4px;
}
}
}
......
......@@ -14,7 +14,9 @@ interface ActivityUserLayoutProps {
/** 适用用户 */
isFlag?: boolean,
/** 数据回显 */
dataScoure?: any
dataScoure?: any,
/** 适用用户 */
allUsers?: any[],
}
const PIC_MAP = {
......@@ -25,7 +27,7 @@ const PIC_MAP = {
};
const ActivityUserLayout: React.FC<ActivityUserLayoutProps> = (props: any) => {
const { title, isFlag, dataScoure } = props;
const { title, isFlag, dataScoure, allUsers } = props;
const [data, setData] = useState<any>({});
const [memberLevelList, setMemberLevelList] = useState<any[]>([]);
......@@ -41,26 +43,43 @@ const ActivityUserLayout: React.FC<ActivityUserLayoutProps> = (props: any) => {
title={title}
>
<Row gutter={[8, 8]}>
<Col span={8}>
<div className={style.cell}>
<h5 className={style.label}>适用用户: </h5>
<h5 className={style.content}>
<Space>
{data.newMember && <div className={style.selector}>新会员(平台会员)</div>}
{data.oldMember && <div className={style.selector}>老会员(平台会员)</div>}
</Space>
</h5>
</div>
<div className={style.cell}>
<h5 className={style.label}>适用用户角色: </h5>
<h5 className={style.content}>
<Space>
{data.enterpriseMember && <div className={style.selector}>企业会员</div>}
{data.personalMember && <div className={style.selector}>个人会员</div>}
</Space>
</h5>
</div>
</Col>
{!isEmpty(allUsers) ?
allUsers.map((item, i) => (
<Col span={24} key={`allUsers_${i}`}>
<div className={style.cell}>
<h5 className={style.label}>{item.title}: </h5>
<h5 className={style.content}>
<Space>
{item.value.filter(_item => _item.key !== 0).map((_item, _i) => (
<div className={style.selector} key={`_item_${_i}`}>{_item.name}</div>
))}
</Space>
</h5>
</div>
</Col>
))
: (
<Col span={24}>
<div className={style.cell}>
<h5 className={style.label}>适用用户: </h5>
<h5 className={style.content}>
<Space>
{data.newMember && <div className={style.selector}>新会员(平台会员)</div>}
{data.oldMember && <div className={style.selector}>老会员(平台会员)</div>}
</Space>
</h5>
</div>
<div className={style.cell}>
<h5 className={style.label}>适用用户角色: </h5>
<h5 className={style.content}>
<Space>
{data.enterpriseMember && <div className={style.selector}>企业会员</div>}
{data.personalMember && <div className={style.selector}>个人会员</div>}
</Space>
</h5>
</div>
</Col>
)}
</Row>
{!isFlag && (
<Row gutter={[24, 24]}>
......
......@@ -24,8 +24,8 @@ const CollocationLayout: React.FC<CollocationLayoutProps> = (props: any) => {
const columns: ColumnType<any>[] = [
{
title: 'SKUID',
key: 'id',
dataIndex: 'id',
key: 'skuId',
dataIndex: 'skuId',
},
{
title: '商品名称',
......@@ -67,7 +67,7 @@ const CollocationLayout: React.FC<CollocationLayoutProps> = (props: any) => {
totalCount: data.totalCount,
data: data.data.map(item => {
return {
id: item.id,
skuId: item.id,
productId: item.commodityId,
productName: item.name,
category: item.customerCategoryName,
......@@ -90,7 +90,7 @@ const CollocationLayout: React.FC<CollocationLayoutProps> = (props: any) => {
const productList = rowRecord.map(item => {
return {
id: item.id,
skuId: item.id,
skuId: item.skuId,
productImgUrl: item.productImgUrl,
productId: item.productId,
productName: item.productName,
......@@ -118,9 +118,9 @@ const CollocationLayout: React.FC<CollocationLayoutProps> = (props: any) => {
columns={columns}
mode="checkbox"
tableProps={{
rowKey: 'id',
rowKey: 'skuId',
}}
customKey="id"
customKey="skuId"
onClose={() => toggle(false)}
onOk={handleOk}
effects={($, actions) => {
......
export const _data = {
id: 1,
activityId: 888,
activityName: '自建营销活动管理',
marketingNo: 'XJBX888888',
externalState: 5,
externalStateName: '已结束',
interiorState: 5,
interiorStateName: '已结束',
activityType: 1,
orderModal: '询价报价下单',
membersName: '温州龙昌手袋有限公司',
creationTime: 1624603001552,
activityStartTime: 1624603001552,
activityEndTime: 1624603001552,
externalLogStates: [
{
isExecute: 1,
operationalProcess: "提交营销活动",
roleName: "供应商",
state: 1,
stateName: null,
},
{
isExecute: 0,
operationalProcess: "审核营销活动",
roleName: "平台",
state: 1,
stateName: null,
},
{
isExecute: 0,
operationalProcess: "上线营销活动",
roleName: "供应商",
state: 1,
stateName: null,
},
],
externalLogs: [
{
auditOpinion: "",
createMemberId: 20,
createMemberRoleId: 11,
createTime: 1624600139800,
id: 1,
operation: "提交营销活动",
purchaseInquiryId: 956,
roleName: "供应商",
state: 2,
stateName: "待平台审核",
},
{
auditOpinion: "同意",
createMemberId: 20,
createMemberRoleId: 11,
createTime: 1624600139800,
id: 2,
operation: "审核营销活动",
purchaseInquiryId: 956,
roleName: "平台",
state: 2,
stateName: "待上线活动",
},
],
interiorLogStates: [
{
isExecute: 1,
operationalProcess: "提交营销活动",
roleName: "新增营销活动",
state: 1,
stateName: null,
},
{
isExecute: 0,
operationalProcess: "审核营销活动",
roleName: "审核营销活动(一级)",
state: 1,
stateName: null,
},
{
isExecute: 0,
operationalProcess: "审核营销活动(二级)",
roleName: "运营总监",
state: 1,
stateName: null,
},
{
isExecute: 0,
operationalProcess: "提交营销活动",
roleName: "运营人员",
state: 1,
stateName: null,
},
],
interiorLogs: [
{
auditOpinion: "",
createMemberId: 20,
createRoleId: 11,
createTime: 1624600137942,
department: "运营人员",
id: 3968,
memberId: null,
memberRoleId: null,
operation: "新增营销活动",
position: "运营部",
purchaseInquiryId: 956,
roleName: "张三",
state: 1,
stateName: "待审核(一级)",
step: 1,
},
],
}
......@@ -3,7 +3,6 @@ import { Button } from 'antd';
import { history } from 'umi';
import { Context } from '@/pages/transaction/components/detailLayout/components/context';
import PeripheralLayout from '@/pages/transaction/components/detailLayout';
import { _data } from './data';
import ProgressLayout from '@/pages/transaction/components/detailLayout/components/progressLayout';
import GeneralLayout from '@/pages/transaction/components/detailLayout/components/generalLayout';
import RecordLyout from '@/pages/transaction/components/detailLayout/components/recordLyout';
......@@ -31,7 +30,7 @@ const TABLINK = [
]
const DetialLayout = () => {
const { query: { activityId, signUpId }, pathname } = history.location;
const { query: { id }, pathname } = history.location;
const [path] = useState(pathname.split('/')[pathname.split('/').length - 1]);
const [pathPci] = useState(pathname.split('/')[pathname.split('/').length - 2]);
const [visible, setVisible] = useState<boolean>(false)
......@@ -41,14 +40,13 @@ const DetialLayout = () => {
const [dataSource, setDataSource] = useState<any>({});
const [basicEffect, setBasicEffect] = useState<any>([]);
const [generalEffect, setGeneralEffect] = useState<any>([]);
const [allUsers, setAllusers] = useState<any[]>([])
const handleBasicEffect = (data: any) => {
setBasicEffect([
{
col: [
{ label: '活动ID', extra: data.id },
{ label: '活动名称', extra: data.activityName },
{ label: '外部状态', extra: data.outerStatusName },
{ label: '内部状态', extra: data.innerStatusName },
]
......@@ -56,14 +54,15 @@ const DetialLayout = () => {
{
col: [
{ label: '活动类型', extra: data.activityTypeName },
{ label: '活动参与类型', extra: data.activitySignUpTypeName },
{ label: '活动开始时间', extra: format(data.startTime) },
{ label: '活动结束时间', extra: format(data.endTime) },
{ label: '活动名称', extra: data.activityName },
{ label: '会员名称', extra: data.activitySignUpTypeName },
]
},
{
col: [
{ label: '要求报名时间', extra: <>{format(data.signUpStartTime)}~{format(data.signUpEndTime)}</> },
{ label: '活动开始时间', extra: format(data.startTime) },
{ label: '活动结束时间', extra: format(data.endTime) },
{ label: '创建时间', extra: format(data.createTime) },
]
},
])
......@@ -76,13 +75,16 @@ const DetialLayout = () => {
}
const fetchDataSource = useCallback(async () => {
await PublicApi.getMarketingMerchantActivityDetail({ activityId }).then((res: any) => {
await PublicApi.getMarketingMerchantActivityDetail({ id }).then((res: any) => {
if (res.code !== 1000) {
return
}
let { data } = res;
let externalLogStates: any = []
data.outerTaskStepList.forEach((item: any) => {
let externalLogStates: any = [];
let interiorLogStates: any = [];
let externalLogs: any = [];
let interiorLogs: any = [];
data.outerTaskList.forEach((item: any) => {
externalLogStates.push({
state: item.step,
stateName: null,
......@@ -91,16 +93,83 @@ const DetialLayout = () => {
roleName: item.roleName,
})
})
data.innerTaskList.forEach((item: any) => {
interiorLogStates.push({
state: item.step,
stateName: null,
isExecute: item.isExecute,
operationalProcess: item.taskName,
roleName: item.roleName,
})
})
data.outerRecordDOList.forEach((item: any) => {
externalLogs.push({
auditOpinion: item.opinion,
createMemberId: item.memberId,
createRoleId: item.needPlanId,
createTime: item.operateTime,
department: item.department,
stateName: item.statusName,
id: item.id,
memberId: null,
memberRoleId: null,
operation: item.operate,
position: item.jobTitle,
purchaseInquiryId: null,
roleName: item.operator,
state: item.step + 1,
step: item.step,
})
})
data.innerRecordDOList.forEach((item: any) => {
interiorLogs.push({
auditOpinion: item.opinion,
createMemberId: item.memberId,
createRoleId: item.needPlanId,
createTime: item.operateTime,
department: item.department,
stateName: item.statusName,
id: item.id,
memberId: null,
memberRoleId: null,
operation: item.operate,
position: item.jobTitle,
purchaseInquiryId: null,
roleName: item.operator,
state: item.step + 1,
step: item.step,
})
})
data.externalLogStates = externalLogStates;
data.interiorLogStates = interiorLogStates;
data.externalLogs = externalLogs;
data.interiorLogs = interiorLogs;
setAllusers([
{
title: '适用用户',
value: [{
key: data.newUser,
name: '新用户(不包含会员)'
},{
key: data.oldUser,
name: '老用户(不包含会员)'
},{
key: data.newMember,
name: '新会员(仅会员用户)'
},{
key: data.oldMember,
name: '老会员(仅会员用户)'
}]
}
])
setDataSource(data);
handleBasicEffect(data)
handleGeneralEffect(data.activityDefinedBO, data.activityType)
}).catch(() => { })
}).catch(() => {})
}, [])
useEffect(() => {
fetchDataSource();
// handleGeneralEffect(_data);
}, [])
const columns = useMemo(() => {
......@@ -111,10 +180,10 @@ const DetialLayout = () => {
let fetchSoure: any = null;
switch (pathPci) {
case 'readyExamineOne':
fetchSoure = PublicApi.postMarketingPlatformActivitySignupExamineStep1
fetchSoure = PublicApi.postMarketingMerchantActivityExamineStep1
break;
case 'readyExamineTwo':
fetchSoure = PublicApi.postMarketingPlatformActivitySignupExamineStep2
fetchSoure = PublicApi.postMarketingMerchantActivityExamineStep2
break;
}
return fetchSoure
......@@ -152,12 +221,12 @@ const DetialLayout = () => {
/>
<ListLayout
anchor="activityProductLayout"
ids={signUpId !== 'null' && { signUpId }}
ids={id !== 'null' && { activityId: id }}
title="活动商品"
fetch={PublicApi.getMarketingMerchantActivityDetailGoodPage}
fetch={PublicApi.getMarketingMerchantActivityDetailGoodsPage}
columns={columns}
/>
<ActivityUserLayout dataScoure={dataSource} />
<ActivityUserLayout dataScoure={dataSource} allUsers={allUsers} />
<DemandLayout storeList={dataSource.shopList} />
<RecordLyout />
</Fragment>
......@@ -165,9 +234,9 @@ const DetialLayout = () => {
/>
{/* 审核 */}
<ModalOperate
id={signUpId}
id={id}
title="单据审核"
modalType="merkeingAudit"
modalType="marketing"
visible={visible}
fetch={fetchLink()}
onCancel={() => setVisible(false)}
......
import React, { useRef, useState } from 'react';
import { Button, Row, Col } from 'antd'
import { history } from 'umi';
import TableLayout from '@/pages/transaction/components/tableLayout'
import { ColumnType } from 'antd/lib/table';
import EyePreview from '@/components/EyePreview';
......
import React, { useRef, useState } from 'react';
import { Button, Row, Col } from 'antd'
import React, { Fragment, useRef, useState } from 'react';
import { Button, Row, Col, Popconfirm } from 'antd'
import TableLayout from '@/pages/transaction/components/tableLayout'
import { ColumnType } from 'antd/lib/table';
import EyePreview from '@/components/EyePreview';
......@@ -27,6 +27,19 @@ const ReadySubmit = () => {
</Row>
)
const fetchSubmitBatch = async (id?: number) => {
let res: any = null;
if (id) {
res = await PublicApi.postMarketingMerchantActivitySubmit({ id: Number(id) })
} else {
// res = await PublicApi.postPurchasePurchaseInquirySubmitBatch({ ids: rowkeys });
}
if (res.code === 1000) {
ref.current.reload();
setRowKeys([])
}
}
const columns: ColumnType<any>[] = [
{
title: '活动ID',
......@@ -77,6 +90,17 @@ const ReadySubmit = () => {
title: '操作',
key: 'state',
dataIndex: 'state',
render: (_text, _record) => (
<Fragment>
{_record.submit && (
<Popconfirm title="确定要提交吗?" okText="是" cancelText="否" onConfirm={() => fetchSubmitBatch(_record.id)}>
<Button type='link'>
提交
</Button>
</Popconfirm>
)}
</Fragment>
)
}
]
......
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import { Form, Button } from 'antd';
import { history } from 'umi';
import { useEventEmitter } from '@umijs/hooks';
......@@ -7,8 +7,10 @@ import PeripheralLayout from '@/pages/transaction/components/detailLayout';
import BasicInfoLayout from './components/basicInfoLayout';
import RulesLayout from './components/rulesLayout';
import ShopLayout from './components/shopLayout';
import ProductListLayout from '../../paltformSign/readySubmitExamine/components/productListLayout';
import ProductListLayout from './components/productListLayout';
import PartakeUserLayout from './components/partakeUserLayout';
import moment from 'moment';
import { PublicApi } from '@/services/api';
const layout: any = {
colon: false,
......@@ -16,37 +18,51 @@ const layout: any = {
labelAlign: "left"
};
const avtivityTypes = [
{ lable: '特价促销', value: 1 },
{ lable: '直降促销', value: 2 },
{ lable: '折价促销', value: 3 },
{ lable: '满量促销', value: 4 },
{ lable: '满额促销', value: 5 },
{ lable: '赠送促销', value: 6 },
{ lable: '多件促销', value: 7 },
{ lable: '组合促销', value: 8 },
{ lable: '拼团', value: 9 },
{ lable: '抽奖', value: 10 },
{ lable: '砍价', value: 11 },
{ lable: '秒杀', value: 12 },
{ lable: '换购', value: 13 },
{ lable: '预售', value: 14 },
{ lable: '套餐', value: 15 },
{ lable: '试用', value: 16 },
]
const AddedMarketing = () => {
const { query: { activityId, signUpId } } = history.location;
const { query: { id, signUpId }, pathname } = history.location;
const [path] = useState(pathname.split('/')[pathname.split('/').length - 1]);
const focus$ = useEventEmitter();
const [form] = Form.useForm();
const [unsaved, setUnsaved] = useState<boolean>(false);
const [loading, setLoading] = useState<boolean>(false);
const [shopList, setShopList] = useState<any[]>([]);
const [dataSource, setDataSource] = useState<any>({});
const [productList, setProductList] = useState<any[]>([]);
const [shopIdList, setShopIdList] = useState<number[]>([]);
const [memberLevelList, setMemberLevelList] = useState<any[]>([]);
const [memberType, setMemberType] = useState<any[]>([]);
const [activityId, setActivityId] = useState<number>();
const handleGetShopList = (mall) => {
console.log(mall, 10086)
const shopList = mall.filter(item => item.checked)
const checkedList = mall.filter(item => item.checked);
const checkedShop = checkedList.map(item => {
return {
shopId: item.id,
shopName: item.name,
logo: item.logoUrl,
}
})
form.setFieldsValue({
"shopList": shopList.map(item => {
return {
shopId: item.id,
shopName: item.name,
logo: item.logoUrl,
}
})
"shopList": checkedShop
})
}
const handleGetDataSoure = (e) => {
if (!unsaved) {
setUnsaved(true)
}
setProductList([...e])
setShopIdList(checkedShop.map(item => { return item.shopId }));
}
const handleGetLevel = (levels) => {
......@@ -66,21 +82,84 @@ const AddedMarketing = () => {
setMemberLevelList([...list])
}
const handleSubmit = () => {
form.validateFields().then(res => {
const params: any = {
activityType: res.activityType,
activityDefinedBO: res.activityDefinedBO,
activityName: res.activityName,
startTime: Number(moment(res.startTime).format('x')),
endTime: Number(moment(res.endTime).format('x')),
newUser: (res.allUser.includes(1) ? 1 : 0),
oldUser: (res.allUser.includes(2) ? 1 : 0),
newMember: (res.allUser.includes(3) ? 1 : 0),
oldMember: (res.allUser.includes(4) ? 1 : 0),
memberLevelList,
shopList: res.shopList,
productList: res.productList
}
setLoading(true)
path !== 'add' && (params.id = id);
const fieldApi = (path === 'add' ? PublicApi.postMarketingMerchantActivitySave : PublicApi.postMarketingMerchantActivityUpdate)
fieldApi(params).then(res => {
if (res.code !== 1000) {
setLoading(false)
return
}
setUnsaved(false);
history.goBack();
}).catch(_e => { setLoading(false) })
})
}
useEffect(() => {
if (id) {
PublicApi.getMarketingMerchantActivityDetail({ id }).then(res => {
if (res.code !== 1000) {
return
}
const { data } = res;
const option: any = avtivityTypes.filter(item => item.value === data.activityType).map(_item => {
return {
value: _item.value,
children: _item.lable,
}
})[0]
focus$.emit(option)
form.setFieldsValue({
allUser: [data.newUser && 1, data.oldUser && 2, data.newMember && 3, data.oldMember && 4],
activityDefinedBO: data.activityDefinedBO,
activityName: data.activityName,
activityType: data.activityType,
shopList: data.shopList,
startTime: moment(data.startTime),
endTime: moment(data.endTime),
memberLevelList: data.memberLevelList.map(item => { return item.memberLevelId })
})
setActivityId(data.id);
setShopIdList(data.shopList.map(item => { return item.shopId }));
setShopList(data.shopList)
setMemberType([data.newUser && 1, data.oldUser && 2, data.newMember && 3, data.oldMember && 4])
}).catch(_e => { })
}
}, [id])
return (
<PeripheralLayout
detail='新增营销活动'
tabLink={[
{ id: 'basicInfoLayout', title: '基本信息' },
{ id: 'rulesLayout', title: '活动规则' },
{ id: 'shopLayout', title: '适用商城' },
{ id: 'activityProductLayout', title: '活动商品' },
{ id: 'partakeUserLayout', title: '参与用户' },
{ id: 'shopLayout', title: '适用商城' },
]}
effect={
<Button
loading={loading}
icon={<SaveOutlined />}
type="primary"
onClick={handleSubmit}
>
保存
</Button>
......@@ -93,9 +172,9 @@ const AddedMarketing = () => {
>
<BasicInfoLayout form={form} focus$={focus$} />
<RulesLayout form={form} focus$={focus$} />
<ProductListLayout signUpId={signUpId !== 'null' && signUpId} data={dataSource} getDataSource={handleGetDataSoure} />
<PartakeUserLayout onGetLevel={handleGetLevel} onSetLevel={memberLevelList} setMemberType={memberType} />
<ShopLayout onGetShopList={handleGetShopList} onSetShopList={shopList} />
<ProductListLayout activityId={activityId} form={form} focus$={focus$} shopIdList={shopIdList} />
<PartakeUserLayout onGetLevel={handleGetLevel} onSetLevel={memberLevelList} setMemberType={memberType} />
</Form>
}
/>
......
......@@ -58,6 +58,12 @@ const PartakeUserLayout: React.FC<PartakeUserLayoutProps> = (props: any) => {
}
}, [user])
useEffect(() => {
if (!isEmpty(setMemberType)) {
setUser(setMemberType.filter(_item => _item !== 1 && _item !== 2))
}
}, [setMemberType])
const handleLevelConfig = (e) => {
const data = [...levelConfig]
onGetLevel(data.filter(item => e.includes(item.id)))
......
import React from 'react';
import { Tooltip, Image, Form, Input, Popconfirm } from 'antd';
import { QuestionCircleOutlined } from '@ant-design/icons';
const columns_1 = ({
dataSource,
setDataSource,
handleDelete,
form,
}) => {
/** 输入 */
const handleInputChange = (e, name, index) => {
const { value } = e.target;
const params = [...dataSource];
const newData = params.map((_item, _i) => {
if (_i === index) {
return {
..._item,
[name]: Number(value)
}
}
return _item
})
form.setFieldsValue({
'productList': newData
})
setDataSource(newData)
}
return (
[
{
title: 'skuId',
key: 'skuId',
dataIndex: 'skuId'
},
{
title: '商品图片',
key: 'productImgUrl',
dataIndex: 'productImgUrl',
render: (text) => <Image width={32} height={32} src={text} />
},
{
title: '商品名称',
key: 'productName',
dataIndex: 'productName'
},
{
title: '品类',
key: 'category',
dataIndex: 'category'
},
{
title: '品牌',
key: 'brand',
dataIndex: 'brand'
},
{
title: '单位',
key: 'unit',
dataIndex: 'unit'
},
{
title: '商品价格',
key: 'price',
dataIndex: 'price',
render: (text) => `¥${Number(text).toFixed(2)}`
},
{
title: <Tooltip placement="top" title="活动价格表示商城直接以该商品的活动价格进行销售">
活动价格 <QuestionCircleOutlined />
</Tooltip>,
key: 'activityPrice',
dataIndex: 'activityPrice',
render: (_text, _record, index) => (
<Form.Item
style={{ marginBottom: 0 }}
initialValue={_text}
name={`activityPrice_${index}`}
rules={[{
required: true, validator: (_rule, value) => {
const pattern = /^(\-)?\d+(\.\d{1,4})?$/;
if (!value) {
return Promise.reject(new Error('请输入活动价格'));
}
if (!pattern.test(value) || (Number(value) >= Number(_record.price))) {
return Promise.reject(new Error('必须大于0且小于商品价格'));
}
return Promise.resolve();
}
}]}
>
<Input style={{ width: '112px' }} addonBefore="¥" onPressEnter={(e) => handleInputChange(e, 'activityPrice', index)} onBlur={(e) => handleInputChange(e, 'activityPrice', index)} />
</Form.Item>
)
},
{
title: '个人限购数量',
key: 'restrictNum',
dataIndex: 'restrictNum',
render: (_text, _record, index) => (
<Form.Item
style={{ marginBottom: 0 }}
initialValue={_text}
name={`restrictNum_${index}`}
dependencies={[`restrictTotalNum_${index}`]}
rules={[{
required: true,
message: '请输入个人限购数量'
},
({ getFieldValue }) => ({
validator: (_rule, value) => {
const pattern = /^(\-)?\d+(\.\d{1,3})?$/;
const restrictTotalNum = getFieldValue(`restrictTotalNum_${index}`);
if (!pattern.test(value) || !(Number(value) < Number(restrictTotalNum))) {
return Promise.reject(new Error('必须大于0且小于活动限购总数量'));
}
return Promise.resolve();
},
})
]}
>
<Input style={{ width: '112px' }} onPressEnter={(e) => handleInputChange(e, 'restrictNum', index)} onBlur={(e) => handleInputChange(e, 'restrictNum', index)} />
</Form.Item>
)
},
{
title: '活动限购总数量',
key: 'restrictTotalNum',
dataIndex: 'restrictTotalNum',
render: (_text, _record, index) => (
<Form.Item
style={{ marginBottom: 0 }}
initialValue={_text}
name={`restrictTotalNum_${index}`}
rules={[{
required: true,
message: '请输入活动限购总数量'
},
({ getFieldValue }) => ({
validator: (_rule, value) => {
const pattern = /^(\-)?\d+(\.\d{1,3})?$/;
const restrictNum = getFieldValue(`restrictNum_${index}`);
if (!pattern.test(value) || !(Number(value) > Number(restrictNum))) {
return Promise.reject(new Error('必须大于0且大于个人限购数量'));
}
return Promise.resolve();
}
})
]}
>
<Input style={{ width: '112px' }} onPressEnter={(e) => handleInputChange(e, 'restrictTotalNum', index)} onBlur={(e) => handleInputChange(e, 'restrictTotalNum', index)} />
</Form.Item>
)
},
{
title: '操作',
key: 'operation',
dataIndex: 'operation',
render: (_text, _record) => (
<Popconfirm
title="是否删除?"
onConfirm={() => handleDelete(_record.skuId)}
>
<a>删除</a>
</Popconfirm>
)
},
]
)
}
export default columns_1
import React from 'react';
import { Tooltip, Image, Form, Input, Popconfirm } from 'antd';
import { QuestionCircleOutlined } from '@ant-design/icons';
const columns_2 = ({
dataSource,
setDataSource,
handleDelete,
form,
}) => {
const sumTotal = (price, num) => {
return (Number(price) - Number(num))
}
/** 输入 */
const handleInputChange = (e, name, index) => {
const { value } = e.target;
const params = [...dataSource];
const newData = params.map((_item, _i) => {
if (_i === index) {
if (name === 'plummetPrice') {
return {
..._item,
[name]: Number(value),
'activityPrice': sumTotal(_item.price, value)
}
} else {
return {
..._item,
[name]: Number(value)
}
}
}
return _item
})
form.setFieldsValue({
'productList': newData
})
setDataSource(newData)
}
return (
[
{
title: 'skuId',
key: 'skuId',
dataIndex: 'skuId'
},
{
title: '商品图片',
key: 'productImgUrl',
dataIndex: 'productImgUrl',
render: (text) => <Image width={32} height={32} src={text} />
},
{
title: '商品名称',
key: 'productName',
dataIndex: 'productName'
},
{
title: '品类',
key: 'category',
dataIndex: 'category'
},
{
title: '品牌',
key: 'brand',
dataIndex: 'brand'
},
{
title: '单位',
key: 'unit',
dataIndex: 'unit'
},
{
title: '商品价格',
key: 'price',
dataIndex: 'price',
render: (text) => `¥${Number(text).toFixed(2)}`
},
{
title: <Tooltip placement="top" title="直降价格为商品价格的直降价格,如原价每件¥20.00的商品,每件降价¥2.00,则直降价格输入框中输入 ¥2.00">
直降价格 <QuestionCircleOutlined />
</Tooltip>,
key: 'plummetPrice',
dataIndex: 'plummetPrice',
render: (_text, _record, index) => (
<Form.Item
style={{ marginBottom: 0 }}
initialValue={_text}
name={`plummetPrice_${index}`}
rules={[{
required: true, validator: (_rule, value) => {
const pattern = /^(\-)?\d+(\.\d{1,4})?$/;
if (!value) {
return Promise.reject(new Error('请输入活动价格'));
}
if (!pattern.test(value) || (Number(value) >= Number(_record.price))) {
return Promise.reject(new Error('必须大于0且小于商品价格'));
}
return Promise.resolve();
}
}]}
>
<Input style={{ width: '112px' }} addonBefore="¥" onPressEnter={(e) => handleInputChange(e, 'plummetPrice', index)} onBlur={(e) => handleInputChange(e, 'plummetPrice', index)} />
</Form.Item>
)
},
{
title: '活动价格',
key: 'activityPrice',
dataIndex: 'activityPrice',
render: (text) => text ? `¥${Number(text).toFixed(2)}` : `¥0`
},
{
title: '个人限购数量',
key: 'restrictNum',
dataIndex: 'restrictNum',
render: (_text, _record, index) => (
<Form.Item
style={{ marginBottom: 0 }}
initialValue={_text}
name={`restrictNum_${index}`}
dependencies={[`restrictTotalNum_${index}`]}
rules={[{
required: true,
message: '请输入个人限购数量'
},
({ getFieldValue }) => ({
validator: (_rule, value) => {
const pattern = /^(\-)?\d+(\.\d{1,3})?$/;
const restrictTotalNum = getFieldValue(`restrictTotalNum_${index}`);
if (!pattern.test(value) || !(Number(value) < Number(restrictTotalNum))) {
return Promise.reject(new Error('必须大于0且小于活动限购总数量'));
}
return Promise.resolve();
},
})
]}
>
<Input style={{ width: '112px' }} onPressEnter={(e) => handleInputChange(e, 'restrictNum', index)} onBlur={(e) => handleInputChange(e, 'restrictNum', index)} />
</Form.Item>
)
},
{
title: '活动限购总数量',
key: 'restrictTotalNum',
dataIndex: 'restrictTotalNum',
render: (_text, _record, index) => (
<Form.Item
style={{ marginBottom: 0 }}
initialValue={_text}
name={`restrictTotalNum_${index}`}
rules={[{
required: true,
message: '请输入活动限购总数量'
},
({ getFieldValue }) => ({
validator: (_rule, value) => {
const pattern = /^(\-)?\d+(\.\d{1,3})?$/;
const restrictNum = getFieldValue(`restrictNum_${index}`);
if (!pattern.test(value) || !(Number(value) > Number(restrictNum))) {
return Promise.reject(new Error('必须大于0且大于个人限购数量'));
}
return Promise.resolve();
}
})
]}
>
<Input style={{ width: '112px' }} onPressEnter={(e) => handleInputChange(e, 'restrictTotalNum', index)} onBlur={(e) => handleInputChange(e, 'restrictTotalNum', index)} />
</Form.Item>
)
},
{
title: '操作',
key: 'operation',
dataIndex: 'operation',
render: (_text, _record) => (
<Popconfirm
title="是否删除?"
onConfirm={() => handleDelete(_record.skuId)}
>
<a>删除</a>
</Popconfirm>
)
},
]
)
}
export default columns_2
import React from 'react';
import { Tooltip, Image, Form, Input, Popconfirm } from 'antd';
import { QuestionCircleOutlined } from '@ant-design/icons';
const columns_3 = ({
dataSource,
setDataSource,
handleDelete,
form,
}) => {
/** 输入 */
const handleInputChange = (e, name, index) => {
const { value } = e.target;
const params = [...dataSource];
const newData = params.map((_item, _i) => {
if (_i === index) {
if (name === 'discount') {
return {
..._item,
[name]: Number(value),
'activityPrice': Number(_item.price) * (Number(value)) / 100,
}
} else {
return {
..._item,
[name]: Number(value)
}
}
}
return _item
})
form.setFieldsValue({
'productList': newData
})
setDataSource(newData)
}
return (
[
{
title: 'skuId',
key: 'skuId',
dataIndex: 'skuId'
},
{
title: '商品图片',
key: 'productImgUrl',
dataIndex: 'productImgUrl',
render: (text) => <Image width={32} height={32} src={text} />
},
{
title: '商品名称',
key: 'productName',
dataIndex: 'productName'
},
{
title: '品类',
key: 'category',
dataIndex: 'category'
},
{
title: '品牌',
key: 'brand',
dataIndex: 'brand'
},
{
title: '单位',
key: 'unit',
dataIndex: 'unit'
},
{
title: '商品价格',
key: 'price',
dataIndex: 'price',
render: (text) => `¥${Number(text).toFixed(2)}`
},
{
title: <Tooltip placement="top" title="折扣为商品价格的折扣,输入数字,如85折,输入85,9折输入90">
折扣 <QuestionCircleOutlined />
</Tooltip>,
key: 'discount',
dataIndex: 'discount',
render: (_text, _record, index) => (
<Form.Item
style={{ marginBottom: 0 }}
initialValue={_text}
name={`discount_${index}`}
rules={[{
required: true,
message: '请输入折扣'
},
() => ({
validator: (_rule, value) => {
const pattern = /^(\-)?\d+(\.\d{1,3})?$/;
if (!pattern.test(value)) {
return Promise.reject(new Error('折扣必须大于0'));
}
return Promise.resolve();
},
})
]}
>
<Input style={{ width: '112px' }} addonAfter="折" onPressEnter={(e) => handleInputChange(e, 'discount', index)} onBlur={(e) => handleInputChange(e, 'discount', index)} />
</Form.Item>
)
},
{
title: '活动价格',
key: 'activityPrice',
dataIndex: 'activityPrice',
render: (text) => text ? `¥${Number(text).toFixed(2)}` : `¥0`
},
{
title: '个人限购数量',
key: 'restrictNum',
dataIndex: 'restrictNum',
render: (_text, _record, index) => (
<Form.Item
style={{ marginBottom: 0 }}
initialValue={_text}
name={`restrictNum_${index}`}
dependencies={[`restrictTotalNum_${index}`]}
rules={[{
required: true,
message: '请输入个人限购数量'
},
({ getFieldValue }) => ({
validator: (_rule, value) => {
const pattern = /^(\-)?\d+(\.\d{1,3})?$/;
const restrictTotalNum = getFieldValue(`restrictTotalNum_${index}`);
if (!pattern.test(value) || !(Number(value) < Number(restrictTotalNum))) {
return Promise.reject(new Error('必须大于0且小于活动限购总数量'));
}
return Promise.resolve();
},
})
]}
>
<Input style={{ width: '112px' }} onPressEnter={(e) => handleInputChange(e, 'restrictNum', index)} onBlur={(e) => handleInputChange(e, 'restrictNum', index)} />
</Form.Item>
)
},
{
title: '活动限购总数量',
key: 'restrictTotalNum',
dataIndex: 'restrictTotalNum',
render: (_text, _record, index) => (
<Form.Item
style={{ marginBottom: 0 }}
initialValue={_text}
name={`restrictTotalNum_${index}`}
rules={[{
required: true,
message: '请输入活动限购总数量'
},
({ getFieldValue }) => ({
validator: (_rule, value) => {
const pattern = /^(\-)?\d+(\.\d{1,3})?$/;
const restrictNum = getFieldValue(`restrictNum_${index}`);
if (!pattern.test(value) || !(Number(value) > Number(restrictNum))) {
return Promise.reject(new Error('必须大于0且大于个人限购数量'));
}
return Promise.resolve();
}
})
]}
>
<Input style={{ width: '112px' }} onPressEnter={(e) => handleInputChange(e, 'restrictTotalNum', index)} onBlur={(e) => handleInputChange(e, 'restrictTotalNum', index)} />
</Form.Item>
)
},
{
title: '操作',
key: 'operation',
dataIndex: 'operation',
render: (_text, _record) => (
<Popconfirm
title="是否删除?"
onConfirm={() => handleDelete(_record.skuId)}
>
<a>删除</a>
</Popconfirm>
)
},
]
)
}
export default columns_3
import React from 'react';
import { Image, Form, Input, Popconfirm } from 'antd';
const columns_4 = ({
dataSource,
setDataSource,
handleDelete,
form,
}) => {
/** 输入 */
const handleInputChange = (e, name, index) => {
const { value } = e.target;
const params = [...dataSource];
const newData = params.map((_item, _i) => {
if (_i === index) {
return {
..._item,
[name]: Number(value)
}
}
return _item
})
form.setFieldsValue({
'productList': newData
})
setDataSource(newData)
}
return (
[
{
title: 'skuId',
key: 'skuId',
dataIndex: 'skuId'
},
{
title: '商品图片',
key: 'productImgUrl',
dataIndex: 'productImgUrl',
render: (text) => <Image width={32} height={32} src={text} />
},
{
title: '商品名称',
key: 'productName',
dataIndex: 'productName'
},
{
title: '品类',
key: 'category',
dataIndex: 'category'
},
{
title: '品牌',
key: 'brand',
dataIndex: 'brand'
},
{
title: '单位',
key: 'unit',
dataIndex: 'unit'
},
{
title: '商品价格',
key: 'price',
dataIndex: 'price',
render: (text) => `¥${Number(text).toFixed(2)}`
},
{
title: '个人限购数量',
key: 'restrictNum',
dataIndex: 'restrictNum',
render: (_text, _record, index) => (
<Form.Item
style={{ marginBottom: 0 }}
initialValue={_text}
name={`restrictNum_${index}`}
dependencies={[`restrictTotalNum_${index}`]}
rules={[{
required: true,
message: '请输入个人限购数量'
},
({ getFieldValue }) => ({
validator: (_rule, value) => {
const pattern = /^(\-)?\d+(\.\d{1,3})?$/;
const restrictTotalNum = getFieldValue(`restrictTotalNum_${index}`);
if (!pattern.test(value) || !(Number(value) < Number(restrictTotalNum))) {
return Promise.reject(new Error('必须大于0且小于活动限购总数量'));
}
return Promise.resolve();
},
})
]}
>
<Input style={{ width: '112px' }} onPressEnter={(e) => handleInputChange(e, 'restrictNum', index)} onBlur={(e) => handleInputChange(e, 'restrictNum', index)} />
</Form.Item>
)
},
{
title: '活动限购总数量',
key: 'restrictTotalNum',
dataIndex: 'restrictTotalNum',
render: (_text, _record, index) => (
<Form.Item
style={{ marginBottom: 0 }}
initialValue={_text}
name={`restrictTotalNum_${index}`}
rules={[{
required: true,
message: '请输入活动限购总数量'
},
({ getFieldValue }) => ({
validator: (_rule, value) => {
const pattern = /^(\-)?\d+(\.\d{1,3})?$/;
const restrictNum = getFieldValue(`restrictNum_${index}`);
if (!pattern.test(value) || !(Number(value) > Number(restrictNum))) {
return Promise.reject(new Error('必须大于0且大于个人限购数量'));
}
return Promise.resolve();
}
})
]}
>
<Input style={{ width: '112px' }} onPressEnter={(e) => handleInputChange(e, 'restrictTotalNum', index)} onBlur={(e) => handleInputChange(e, 'restrictTotalNum', index)} />
</Form.Item>
)
},
{
title: '操作',
key: 'operation',
dataIndex: 'operation',
render: (_text, _record) => (
<Popconfirm
title="是否删除?"
onConfirm={() => handleDelete(_record.skuId)}
>
<a>删除</a>
</Popconfirm>
)
},
]
)
}
export default columns_4
import React from 'react';
import { Image, Form, Input, Popconfirm } from 'antd';
const columns_5 = ({
dataSource,
setDataSource,
handleDelete,
form,
}) => {
/** 输入 */
const handleInputChange = (e, name, index) => {
const { value } = e.target;
const params = [...dataSource];
const newData = params.map((_item, _i) => {
if (_i === index) {
return {
..._item,
[name]: Number(value)
}
}
return _item
})
form.setFieldsValue({
'productList': newData
})
setDataSource(newData)
}
return (
[
{
title: 'skuId',
key: 'skuId',
dataIndex: 'skuId'
},
{
title: '商品图片',
key: 'productImgUrl',
dataIndex: 'productImgUrl',
render: (text) => <Image width={32} height={32} src={text} />
},
{
title: '商品名称',
key: 'productName',
dataIndex: 'productName'
},
{
title: '品类',
key: 'category',
dataIndex: 'category'
},
{
title: '品牌',
key: 'brand',
dataIndex: 'brand'
},
{
title: '单位',
key: 'unit',
dataIndex: 'unit'
},
{
title: '商品价格',
key: 'price',
dataIndex: 'price',
render: (text) => `¥${Number(text).toFixed(2)}`
},
{
title: '团购价格',
key: 'activityPrice',
dataIndex: 'activityPrice',
render: (_text, _record, index) => (
<Form.Item
style={{ marginBottom: 0 }}
initialValue={_text}
name={`activityPrice_${index}`}
rules={[{
required: true, validator: (_rule, value) => {
const pattern = /^(\-)?\d+(\.\d{1,3})?$/;
if (!value) {
return Promise.reject(new Error('请输入团购价格'));
}
if (!pattern.test(value) || (Number(value) >= Number(_record.price))) {
return Promise.reject(new Error('必须大于0且小于商品价格'));
}
return Promise.resolve();
}
}]}
>
<Input style={{ width: '112px' }} addonBefore="¥" onPressEnter={(e) => handleInputChange(e, 'activityPrice', index)} onBlur={(e) => handleInputChange(e, 'activityPrice', index)} />
</Form.Item>
)
},
{
title: '个人限购数量',
key: 'restrictNum',
dataIndex: 'restrictNum',
render: (_text, _record, index) => (
<Form.Item
style={{ marginBottom: 0 }}
initialValue={_text}
name={`restrictNum_${index}`}
dependencies={[`restrictTotalNum_${index}`]}
rules={[{
required: true,
message: '请输入个人限购数量'
},
({ getFieldValue }) => ({
validator: (_rule, value) => {
const pattern = /^(\-)?\d+(\.\d{1,3})?$/;
const restrictTotalNum = getFieldValue(`restrictTotalNum_${index}`);
if (!pattern.test(value) || !(Number(value) < Number(restrictTotalNum))) {
return Promise.reject(new Error('必须大于0且小于活动限购总数量'));
}
return Promise.resolve();
},
})
]}
>
<Input style={{ width: '112px' }} onPressEnter={(e) => handleInputChange(e, 'restrictNum', index)} onBlur={(e) => handleInputChange(e, 'restrictNum', index)} />
</Form.Item>
)
},
{
title: '活动限购总数量',
key: 'restrictTotalNum',
dataIndex: 'restrictTotalNum',
render: (_text, _record, index) => (
<Form.Item
style={{ marginBottom: 0 }}
initialValue={_text}
name={`restrictTotalNum_${index}`}
rules={[{
required: true,
message: '请输入活动限购总数量'
},
({ getFieldValue }) => ({
validator: (_rule, value) => {
const pattern = /^(\-)?\d+(\.\d{1,3})?$/;
const restrictNum = getFieldValue(`restrictNum_${index}`);
if (!pattern.test(value) || !(Number(value) > Number(restrictNum))) {
return Promise.reject(new Error('必须大于0且大于个人限购数量'));
}
return Promise.resolve();
}
})
]}
>
<Input style={{ width: '112px' }} onPressEnter={(e) => handleInputChange(e, 'restrictTotalNum', index)} onBlur={(e) => handleInputChange(e, 'restrictTotalNum', index)} />
</Form.Item>
)
},
{
title: '操作',
key: 'operation',
dataIndex: 'operation',
render: (_text, _record) => (
<Popconfirm
title="是否删除?"
onConfirm={() => handleDelete(_record.skuId)}
>
<a>删除</a>
</Popconfirm>
)
},
]
)
}
export default columns_5
import React from 'react';
import { Tooltip, Image, Form, Input, Popconfirm } from 'antd';
import { QuestionCircleOutlined } from '@ant-design/icons';
const columns_6 = ({
dataSource,
setDataSource,
handleDelete,
form,
}) => {
/** 输入 */
const handleInputChange = (e, name, index) => {
const { value } = e.target;
const params = [...dataSource];
const newData = params.map((_item, _i) => {
if (_i === index) {
return {
..._item,
[name]: Number(value)
}
}
return _item
})
form.setFieldsValue({
'productList': newData
})
setDataSource(newData)
}
return (
[
{
title: 'skuId',
key: 'skuId',
dataIndex: 'skuId'
},
{
title: '商品图片',
key: 'productImgUrl',
dataIndex: 'productImgUrl',
render: (text) => <Image width={32} height={32} src={text} />
},
{
title: '商品名称',
key: 'productName',
dataIndex: 'productName'
},
{
title: '品类',
key: 'category',
dataIndex: 'category'
},
{
title: '品牌',
key: 'brand',
dataIndex: 'brand'
},
{
title: '单位',
key: 'unit',
dataIndex: 'unit'
},
{
title: '商品价格',
key: 'price',
dataIndex: 'price',
render: (text) => `¥${Number(text).toFixed(2)}`
},
{
title: <Tooltip placement="top" title="第一个用户帮砍价时的起始价格">
起始价格 <QuestionCircleOutlined />
</Tooltip>,
key: 'plummetPrice',
dataIndex: 'plummetPrice',
render: (_text, _record, index) => (
<Form.Item
style={{ marginBottom: 0 }}
initialValue={_text}
name={`plummetPrice_${index}`}
rules={[{
required: true, validator: (_rule, value) => {
const pattern = /^(\-)?\d+(\.\d{1,4})?$/;
if (!value) {
return Promise.reject(new Error('请输入起始价格'));
}
if (!pattern.test(value)) {
return Promise.reject(new Error('最多保留4位小数'));
}
if ((Number(value) > Number(_record.price))) {
return Promise.reject(new Error('必须大于0且小于等于商品价格'));
}
return Promise.resolve();
}
}]}
>
<Input style={{ width: '112px' }} addonBefore="¥" onPressEnter={(e) => handleInputChange(e, 'plummetPrice', index)} onBlur={(e) => handleInputChange(e, 'plummetPrice', index)} />
</Form.Item>
)
},
{
title: <Tooltip placement="top" title="砍价过程中最后一次砍价不能超过砍价底价">
砍价底价 <QuestionCircleOutlined />
</Tooltip>,
key: 'activityPrice',
dataIndex: 'activityPrice',
render: (_text, _record, index) => (
<Form.Item
style={{ marginBottom: 0 }}
initialValue={_text}
name={`activityPrice_${index}`}
rules={[{
required: true,
message: '请输入砍价底价'
},
({ getFieldValue }) => ({
validator: (_rule, value) => {
const pattern = /^(\-)?\d+(\.\d{1,4})?$/;
const plummetPrice = getFieldValue(`plummetPrice_${index}`);
if (!pattern.test(value)) {
return Promise.reject(new Error('最多保留4位小数'));
}
if (!(Number(value) < Number(plummetPrice))) {
return Promise.reject(new Error('必须大于0且小于起始价格'));
}
return Promise.resolve();
},
})
]}
>
<Input style={{ width: '112px' }} addonBefore="¥" onPressEnter={(e) => handleInputChange(e, 'activityPrice', index)} onBlur={(e) => handleInputChange(e, 'activityPrice', index)} />
</Form.Item>
)
},
{
title: '个人限购数量',
key: 'restrictNum',
dataIndex: 'restrictNum',
render: (_text, _record, index) => (
<Form.Item
style={{ marginBottom: 0 }}
initialValue={_text}
name={`restrictNum_${index}`}
dependencies={[`restrictTotalNum_${index}`]}
rules={[{
required: true,
message: '请输入个人限购数量'
},
({ getFieldValue }) => ({
validator: (_rule, value) => {
const pattern = /^(\-)?\d+(\.\d{1,3})?$/;
const restrictTotalNum = getFieldValue(`restrictTotalNum_${index}`);
if (!pattern.test(value) || !(Number(value) < Number(restrictTotalNum))) {
return Promise.reject(new Error('必须大于0且小于活动限购总数量'));
}
return Promise.resolve();
},
})
]}
>
<Input style={{ width: '112px' }} onPressEnter={(e) => handleInputChange(e, 'restrictNum', index)} onBlur={(e) => handleInputChange(e, 'restrictNum', index)} />
</Form.Item>
)
},
{
title: '活动限购总数量',
key: 'restrictTotalNum',
dataIndex: 'restrictTotalNum',
render: (_text, _record, index) => (
<Form.Item
style={{ marginBottom: 0 }}
initialValue={_text}
name={`restrictTotalNum_${index}`}
rules={[{
required: true,
message: '请输入活动限购总数量'
},
({ getFieldValue }) => ({
validator: (_rule, value) => {
const pattern = /^(\-)?\d+(\.\d{1,3})?$/;
const restrictNum = getFieldValue(`restrictNum_${index}`);
if (!pattern.test(value) || !(Number(value) > Number(restrictNum))) {
return Promise.reject(new Error('必须大于0且大于个人限购数量'));
}
return Promise.resolve();
}
})
]}
>
<Input style={{ width: '112px' }} onPressEnter={(e) => handleInputChange(e, 'restrictTotalNum', index)} onBlur={(e) => handleInputChange(e, 'restrictTotalNum', index)} />
</Form.Item>
)
},
{
title: '操作',
key: 'operation',
dataIndex: 'operation',
render: (_text, _record) => (
<Popconfirm
title="是否删除?"
onConfirm={() => handleDelete(_record.skuId)}
>
<a>删除</a>
</Popconfirm>
)
},
]
)
}
export default columns_6
import React from 'react';
import { Tooltip, Image, Form, Input, Popconfirm } from 'antd';
import { QuestionCircleOutlined } from '@ant-design/icons';
const columns_7 = ({
dataSource,
setDataSource,
handleDelete,
form,
}) => {
/** 输入 */
const handleInputChange = (e, name, index) => {
const { value } = e.target;
const params = [...dataSource];
const newData = params.map((_item, _i) => {
if (_i === index) {
return {
..._item,
[name]: Number(value)
}
}
return _item
})
form.setFieldsValue({
'productList': newData
})
setDataSource(newData)
}
return (
[
{
title: 'skuId',
key: 'skuId',
dataIndex: 'skuId'
},
{
title: '商品图片',
key: 'productImgUrl',
dataIndex: 'productImgUrl',
render: (text) => <Image width={32} height={32} src={text} />
},
{
title: '商品名称',
key: 'productName',
dataIndex: 'productName'
},
{
title: '品类',
key: 'category',
dataIndex: 'category'
},
{
title: '品牌',
key: 'brand',
dataIndex: 'brand'
},
{
title: '单位',
key: 'unit',
dataIndex: 'unit'
},
{
title: '商品价格',
key: 'price',
dataIndex: 'price',
render: (text) => `¥${Number(text).toFixed(2)}`
},
{
title: <Tooltip placement="top" title="秒杀价格表示在秒杀时间段内商城直接以该商品的秒杀价格进行销售">
秒杀价格 <QuestionCircleOutlined />
</Tooltip>,
key: 'activityPrice',
dataIndex: 'activityPrice',
render: (_text, _record, index) => (
<Form.Item
style={{ marginBottom: 0 }}
initialValue={_text}
name={`activityPrice_${index}`}
rules={[{
required: true,
message: '请输入秒杀价格'
},
({ getFieldValue }) => ({
validator: (_rule, value) => {
const pattern = /^(\-)?\d+(\.\d{1,4})?$/;
if (!pattern.test(value)) {
return Promise.reject(new Error('最多保留4位小数'));
}
if ((Number(value) > Number(_record.price))) {
return Promise.reject(new Error('必须大于0且小于等于商品价格'));
}
return Promise.resolve();
},
})
]}
>
<Input style={{ width: '112px' }} addonBefore="¥" onPressEnter={(e) => handleInputChange(e, 'activityPrice', index)} onBlur={(e) => handleInputChange(e, 'activityPrice', index)} />
</Form.Item>
)
},
{
title: '个人限购数量',
key: 'restrictNum',
dataIndex: 'restrictNum',
render: (_text, _record, index) => (
<Form.Item
style={{ marginBottom: 0 }}
initialValue={_text}
name={`restrictNum_${index}`}
dependencies={[`restrictTotalNum_${index}`]}
rules={[{
required: true,
message: '请输入个人限购数量'
},
({ getFieldValue }) => ({
validator: (_rule, value) => {
const pattern = /^(\-)?\d+(\.\d{1,3})?$/;
const restrictTotalNum = getFieldValue(`restrictTotalNum_${index}`);
if (!pattern.test(value) || !(Number(value) < Number(restrictTotalNum))) {
return Promise.reject(new Error('必须大于0且小于活动限购总数量'));
}
return Promise.resolve();
},
})
]}
>
<Input style={{ width: '112px' }} onPressEnter={(e) => handleInputChange(e, 'restrictNum', index)} onBlur={(e) => handleInputChange(e, 'restrictNum', index)} />
</Form.Item>
)
},
{
title: '活动限购总数量',
key: 'restrictTotalNum',
dataIndex: 'restrictTotalNum',
render: (_text, _record, index) => (
<Form.Item
style={{ marginBottom: 0 }}
initialValue={_text}
name={`restrictTotalNum_${index}`}
rules={[{
required: true,
message: '请输入活动限购总数量'
},
({ getFieldValue }) => ({
validator: (_rule, value) => {
const pattern = /^(\-)?\d+(\.\d{1,3})?$/;
const restrictNum = getFieldValue(`restrictNum_${index}`);
if (!pattern.test(value) || !(Number(value) > Number(restrictNum))) {
return Promise.reject(new Error('必须大于0且大于个人限购数量'));
}
return Promise.resolve();
}
})
]}
>
<Input style={{ width: '112px' }} onPressEnter={(e) => handleInputChange(e, 'restrictTotalNum', index)} onBlur={(e) => handleInputChange(e, 'restrictTotalNum', index)} />
</Form.Item>
)
},
{
title: '操作',
key: 'operation',
dataIndex: 'operation',
render: (_text, _record) => (
<Popconfirm
title="是否删除?"
onConfirm={() => handleDelete(_record.skuId)}
>
<a>删除</a>
</Popconfirm>
)
},
]
)
}
export default columns_7
import React from 'react';
import { Tooltip, Image } from 'antd';
import { QuestionCircleOutlined } from '@ant-design/icons';
import { ColumnType } from 'antd/lib/table';
interface ColumnTypes<T> extends ColumnType<any> {
/**
* 可编辑
*/
editable?: boolean,
/**
* 操作
*/
operation?: boolean,
}
const columns_8 = () => {
return (
[
{
title: 'skuId',
key: 'skuId',
dataIndex: 'skuId'
},
{
title: '商品图片',
key: 'productImgUrl',
dataIndex: 'productImgUrl',
render: (text) => <Image width={32} height={32} src={text} />
},
{
title: '商品名称',
key: 'productName',
dataIndex: 'productName'
},
{
title: '品类',
key: 'category',
dataIndex: 'category'
},
{
title: '品牌',
key: 'brand',
dataIndex: 'brand'
},
{
title: '单位',
key: 'unit',
dataIndex: 'unit'
},
{
title: '商品价格',
key: 'price',
dataIndex: 'price',
render: (text) => `¥${Number(text).toFixed(2)}`
},
{
title: '预售价格',
key: 'activityPrice',
dataIndex: 'activityPrice'
},
{
title: '单位定金',
key: 'activityPrice',
dataIndex: 'activityPrice'
},
{
title: '定金抵扣单价',
key: 'activityPrice',
dataIndex: 'activityPrice'
},
{
title: '个人限购数量',
key: 'restrictNum',
dataIndex: 'restrictNum',
editable: true,
},
{
title: '活动限购总数量',
key: 'restrictTotalNum',
dataIndex: 'restrictTotalNum',
editable: true,
},
{
title: '操作',
key: '',
dataIndex: ''
},
]
)
}
export default columns_8
import columns_1 from './columns_1';
import columns_2 from './columns_2';
import columns_3 from './columns_3';
import columns_4 from './columns_4';
import columns_5 from './columns_4';
import columns_6 from './columns_4';
import columns_7 from './columns_4';
import columns_8 from './columns_4';
import columns_9 from './columns_5';
import columns_11 from './columns_6';
import columns_12 from './columns_7';
import columns_13 from './columns_4';
import columns_14 from './columns_8';
import columns_15 from './columns_4';
import columns_16 from './columns_4';
export const Columns = {
1: columns_1,
2: columns_2,
3: columns_3,
4: columns_4,
5: columns_5,
6: columns_6,
7: columns_7,
8: columns_8,
9: columns_9,
11: columns_11,
12: columns_12,
13: columns_13,
14: columns_14,
15: columns_15,
16: columns_16,
}
import React, { useEffect, useMemo, useState } from 'react';
import { Button, message, Table, Form, FormInstance } from 'antd';
import { Columns } from './columns';
import { EventEmitter } from '@umijs/hooks/lib/useEventEmitter'
import CardLayout from '../card';
import { PlusOutlined } from '@ant-design/icons';
import { isEmpty } from 'lodash';
import CollocationLayout from '@/pages/transaction/marketingAbility/paltformSign/readySubmitExamine/components/collocationLayout';
import { PublicApi } from '@/services/api';
type optionProps = {
/** key */
key?: string | number,
/** value */
value?: number,
/** children */
children?: string,
}
interface ProductListProps {
/** 活动id */
activityId?: number,
form?: FormInstance,
/** umi-hooks */
focus$?: EventEmitter<void>,
/** 适用商城 */
shopIdList?: number[],
}
const ProductListLayout: React.FC<ProductListProps> = (props: any) => {
const { activityId, form, focus$, shopIdList } = props;
const [value, setValue] = useState<number>(1);
const [productVisible, setProductVisible] = useState<boolean>(false);
const [listModalVisible, setListModalVisible] = useState<boolean>(false);
const [dataSource, setDataSource] = useState<any[]>([]);
const [idNotInList, setIdNotInList] = useState<number[]>([]); // 排除的id集合 ,Long
const handlesStFieldsValue = () => {
const params = [...dataSource];
params.forEach((_item, _i) => {
form.setFieldsValue({
[`plummetPrice_${_i}`]: _item.plummetPrice,
[`activityPrice_${_i}`]: _item.activityPrice,
[`restrictNum_${_i}`]: _item.restrictNum,
[`restrictTotalNum_${_i}`]: _item.restrictTotalNum,
})
})
}
focus$ && focus$.useSubscription((val: optionProps) => {
setValue(val.value)
setDataSource([])
});
/** 删除一个 */
const handleDelete = (key) => {
const newData = [...dataSource];
form.setFieldsValue({
'productList': newData.filter(item => item.skuId !== key)
})
setIdNotInList(idNotInList.filter(item => item !== key));
setDataSource(newData.filter(item => item.skuId !== key))
}
const columns = useMemo(() => {
return Columns[value]?.({ dataSource, setDataSource, handleDelete, form, setIdNotInList })
}, [value, dataSource])
const toggle = (flag: boolean) => {
if (isEmpty(shopIdList)) {
message.warning('请选择适用商城!')
return
}
setProductVisible(flag)
}
const handleSelectActiveProducts = (params) => {
setDataSource([...dataSource, ...params]);
setIdNotInList([...idNotInList, ...params.map(item => item.skuId)])
toggle(false);
}
useEffect(() => {
if (activityId) {
PublicApi.getMarketingMerchantActivityDetailGoodsPage({ current: '1', pageSize: '999', activityId}).then(res => {
if (res.code !== 1000) {
return
}
form.setFieldsValue({
'productList': res.data.data
})
setDataSource(res.data.data)
setIdNotInList([...idNotInList, ...res.data.data.map(item => item.skuId)])
})
}
}, [activityId])
useEffect(() => {
handlesStFieldsValue()
}, [dataSource])
return (
<CardLayout
id="productListLayout"
title="活动商品"
>
<Button style={{ marginBottom: '16px' }} block type="dashed" icon={<PlusOutlined />} onClick={() => toggle(true)} >选择活动商品</Button>
<Form.Item
name='productList'
rules={[{ required: true, message: '请选择活动商品' }]}
>
<Table
rowKey={(record) => record.id}
columns={columns}
dataSource={dataSource}
pagination={{
size: 'small',
}}
/>
{/* 选择活动商品 */}
<CollocationLayout
visible={productVisible}
idNotInList={idNotInList}
shopIdList={shopIdList}
toggle={toggle}
onConfirm={handleSelectActiveProducts}
/>
</Form.Item>
</CardLayout>
)
}
export default ProductListLayout;
......@@ -37,6 +37,7 @@ const RulesLayout: React.FC<RulesLayoutProps> = (props: any) => {
focus$.useSubscription((val: optionProps) => {
setOption(val);
form.resetFields(['activityDefinedBO']);
});
/** 叠加活动类型 */
......
import React, { useRef, useState } from 'react';
import React, { Fragment, useRef, useState } from 'react';
import { history } from 'umi';
import { Button, Row, Col, Space, Popconfirm } from 'antd';
import TableLayout from '@/pages/transaction/components/tableLayout'
......@@ -22,6 +22,36 @@ const ReadySubmitExamine = () => {
const [rowkeys, setRowKeys] = useState<Array<number>>([]);
const [loading, setLoading] = useState<boolean>(false)
const fetchSubmitBatch = async (id?: number) => {
let res: any = null;
if (id) {
res = await PublicApi.postMarketingMerchantActivitySubmitExamine({ id: Number(id) })
} else {
// res = await PublicApi.postPurchasePurchaseInquirySubmitBatch({ ids: rowkeys });
}
if (res.code === 1000) {
ref.current.reload();
setRowKeys([])
}
}
const fetchDeleteBatch = async (id?: number) => {
let res: any = null;
if (id) {
res = await PublicApi.postMarketingMerchantActivityDelete({ id });
} else {
res = await PublicApi.postMarketingMerchantActivityDeleteBatch({ ids: rowkeys });
}
setLoading(true)
if (res.code !== 1000) {
setLoading(false)
return
}
setLoading(false)
ref.current.reload();
setRowKeys([])
}
const columns: ColumnType<any>[] = [
{
title: '活动ID',
......@@ -72,6 +102,25 @@ const ReadySubmitExamine = () => {
title: '操作',
key: 'state',
dataIndex: 'state',
render: (_text, _record) => (
<Fragment>
{_record.submit && (
<Popconfirm title="确定要提交吗?" okText="是" cancelText="否" onConfirm={() => fetchSubmitBatch(_record.id)}>
<Button type='link'>
提交
</Button>
</Popconfirm>
)}
{_record.update && (<Button type='link' onClick={() => history.push(`/memberCenter/marketingAbility/selfManagement/readySubmitExamine/edit?id=${_record.id}`)}>修改</Button>)}
{_record.delete && (
<Popconfirm title="确定要删除吗?" okText="是" cancelText="否" onConfirm={() => fetchDeleteBatch(_record.id)}>
<Button type='link'>
删除
</Button>
</Popconfirm>
)}
</Fragment>
)
}
]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment