Commit 391363ed authored by 前端-黄佳鑫's avatar 前端-黄佳鑫

feat(商家营销活动): 搭配商品选择

parent bbbe6d01
import React, { Fragment, useEffect, useState } from 'react';
import { Form, Input, Row, Col, Image, Space } from 'antd';
import React, { Fragment } from 'react';
import { Form, Input, Row, Col, Image } from 'antd';
import { DeleteOutlined } from '@ant-design/icons';
import { FormInstance } from 'antd/es/form/Form';
import style from '../../index.less';
type ListProps = {
......@@ -40,6 +41,8 @@ type RemindLayoutProps = {
}
export interface ProductLayoutProps {
/** FormInstance */
form?: FormInstance,
/** message */
remind?: RemindLayoutProps,
/** 最外层标号 */
......@@ -53,7 +56,7 @@ export interface ProductLayoutProps {
}
const ProductLayout: React.FC<ProductLayoutProps> = (props: any) => {
const { remind, index, list, onDeletion, onEntry } = props;
const { form, remind, index, list, onDeletion, onEntry } = props;
const handleChange = (e, name, _index?) => {
onEntry(name, Number(e.target.value), _index)
......@@ -97,8 +100,6 @@ const ProductLayout: React.FC<ProductLayoutProps> = (props: any) => {
</div>
<div className={style.productLayout_item_info}>品类:{_item.category}</div>
<div className={style.productLayout_item_info}>品牌:{_item.brand}L</div>
{/* <div className={style.productLayout_item_info}>品类:成品皮--&gt;牛皮--&gt;黄牛皮</div> */}
{/* <div className={style.productLayout_item_info}>品牌:{_item.brand} 颜色:红色 规格:XXL</div> */}
</Col>
</Row>
</div>
......
......@@ -19,9 +19,9 @@ type RemindLayoutProps = {
/** 列表标题 */
listTitle?: string
/** 列表label */
label?: {[key: number]: string},
label?: { [key: number]: string },
/** 提醒 */
message?: {[key: number]: string},
message?: { [key: number]: string },
}
interface ListModalLayoutProps {
......@@ -45,6 +45,8 @@ interface ListModalLayoutProps {
type ListProps = {
/** id */
id?: number,
/** skuid */
skuId?: number,
/** 商品id */
productId: number,
/** 商品名称 */
......@@ -94,7 +96,7 @@ const ListModalLayout: React.FC<ListModalLayoutProps> = (props: any) => {
if (isArray(selectRowRecord)) {
fields[idx].list = [...fields[idx].list, ...selectRowRecord.map((item: any) => {
return {
id: item.id,
skuId: item.skuId,
productId: item.productId,
productName: item.productName,
category: item.category,
......@@ -173,8 +175,19 @@ const ListModalLayout: React.FC<ListModalLayoutProps> = (props: any) => {
}
/** 选择搭配商品 */
const handleCollocation = (_index: number) => {
setIdx(_index);
const handleCollocation = (_idx: number) => {
const fields = [...dataSource];
form.resetFields()
fields.forEach((item, _index) => {
item.list.forEach((_item, __index) => {
form.setFieldsValue({
[`limitValue_${_index}`]: item.limitValue,
[`groupPrice_${_index}`]: item.groupPrice,
[`num_${_index}_${__index}`]: _item.num,
})
})
})
setIdx(_idx);
toggle(true)
}
......@@ -209,7 +222,6 @@ const ListModalLayout: React.FC<ListModalLayoutProps> = (props: any) => {
}
useEffect(() => {
console.log(value, 10086)
const fields = [...value];
fields.forEach((item, _index) => {
item.list.forEach((_item, __index) => {
......@@ -249,6 +261,7 @@ const ListModalLayout: React.FC<ListModalLayoutProps> = (props: any) => {
>
{!isEmpty(item.list) && (
<ProductLayout
form={form}
index={index}
remind={remind}
list={item.list}
......@@ -257,9 +270,16 @@ const ListModalLayout: React.FC<ListModalLayoutProps> = (props: any) => {
/>
)}
{/* 选择搭配商品 */}
{remind.name !== 'swapValue' && (
<Button type="dashed" block icon={<PlusOutlined />} onClick={() => handleCollocation(index)}>
{remind.buttonTitle}
</Button>
)}
{(remind.name === 'swapValue' && item.list.length === 0) && (
<Button type="dashed" block icon={<PlusOutlined />} onClick={() => handleCollocation(index)}>
{remind.buttonTitle}
</Button>
)}
</CollapseLayout>
</Form.Item>
))}
......
......@@ -17,6 +17,7 @@ export const remindLayout = (int, giveType?, giftType?) => {
switch(int) {
case 6:
return {
name: 'giveValue',
type: 'limitValue',
modalTitle: `设置赠品-${give}${gift}`,
buttonTitle: `添加赠送${gift}`,
......@@ -39,6 +40,7 @@ export const remindLayout = (int, giveType?, giftType?) => {
}
case 13: {
return {
name: 'swapValue',
type: 'limitValue',
modalTitle: `设置换购商品-${give}换购商品`,
buttonTitle: '添加换购商品',
......@@ -62,6 +64,7 @@ export const remindLayout = (int, giveType?, giftType?) => {
}
case 15:
return {
name: 'groupValue',
type: 'groupPrice',
modalTitle: '设置搭配商品',
buttonTitle: '选择搭配商品',
......
......@@ -16,11 +16,25 @@ const { onFormMount$ } = FormEffectHooks;
const ReadyExamineOne = () => {
const ref = useRef<any>({});
const [rowkeys, setRowKeys] = useState<Array<number>>([]);
const [submitLoading, setSubmitLoading] = useState<boolean>(false);
const fetchSubmitBatch = async () => {
setSubmitLoading(true)
await PublicApi.postMarketingMerchantActivityExamineStep1Batch({ ids: rowkeys }).then(res => {
if (res.code !== 1000) {
setSubmitLoading(false)
return
}
ref.current.reload();
setRowKeys([])
}).catch(_e => { setSubmitLoading(false) })
}
const controllerBtns = (
<Row>
<Col span={6}>
<Button
loading={submitLoading}
onClick={fetchSubmitBatch}
disabled={rowkeys.length === 0}
>
批量提交审核
......
......@@ -15,11 +15,26 @@ const { onFormMount$ } = FormEffectHooks;
const ReadyExamineTwo = () => {
const ref = useRef<any>({});
const [rowkeys, setRowKeys] = useState<Array<number>>([]);
const [submitLoading, setSubmitLoading] = useState<boolean>(false);
const fetchSubmitBatch = async () => {
setSubmitLoading(true)
await PublicApi.postMarketingMerchantActivityExamineStep2Batch({ ids: rowkeys }).then(res => {
if (res.code !== 1000) {
setSubmitLoading(false)
return
}
ref.current.reload();
setRowKeys([])
}).catch(_e => {setSubmitLoading(false)})
}
const controllerBtns = (
<Row>
<Col span={6}>
<Button
loading={submitLoading}
onClick={fetchSubmitBatch}
disabled={rowkeys.length === 0}
>
批量提交审核
......
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';
......@@ -14,11 +14,31 @@ const { onFormMount$ } = FormEffectHooks;
const ReadyLive = () => {
const ref = useRef<any>({});
const [rowkeys, setRowKeys] = useState<Array<number>>([]);
const [submitLoading, setSubmitLoading] = useState<boolean>(false);
const fetchSubmitBatch = async (id?: number) => {
let res: any = null;
if (id) {
res = await PublicApi.postMarketingMerchantActivityOnline({ id: Number(id) })
} else {
res = await PublicApi.postMarketingMerchantActivityOnlineBatch({ ids: rowkeys });
}
setSubmitLoading(true)
if (res.code !== 1000) {
setSubmitLoading(false)
return
}
setSubmitLoading(false)
ref.current.reload();
setRowKeys([])
}
const controllerBtns = (
<Row>
<Col span={6}>
<Button
loading={submitLoading}
onClick={() => fetchSubmitBatch()}
disabled={rowkeys.length === 0}
>
批量上线活动
......@@ -77,6 +97,17 @@ const ReadyLive = () => {
title: '操作',
key: 'state',
dataIndex: 'state',
render: (_text, _record) => (
<Fragment>
{_record.online && (
<Popconfirm okButtonProps={{ loading: submitLoading }} title="确定要上线活动吗?" okText="是" cancelText="否" onConfirm={() => fetchSubmitBatch(_record.id)}>
<Button type='link'>
上线活动
</Button>
</Popconfirm>
)}
</Fragment>
)
}
]
......
......@@ -14,6 +14,24 @@ const { onFormMount$ } = FormEffectHooks;
const ReadySubmit = () => {
const ref = useRef<any>({});
const [rowkeys, setRowKeys] = useState<Array<number>>([]);
const [submitLoading, setSubmitLoading] = useState<boolean>(false);
const fetchSubmitBatch = async (id?: number) => {
let res: any = null;
if (id) {
res = await PublicApi.postMarketingMerchantActivitySubmit({ id: Number(id) })
} else {
res = await PublicApi.postMarketingMerchantActivitySubmitBatch({ ids: rowkeys });
}
setSubmitLoading(true)
if (res.code !== 1000) {
setSubmitLoading(false)
return
}
setSubmitLoading(false)
ref.current.reload();
setRowKeys([])
}
const controllerBtns = (
<Row>
......@@ -27,19 +45,6 @@ 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',
......@@ -93,7 +98,7 @@ const ReadySubmit = () => {
render: (_text, _record) => (
<Fragment>
{_record.submit && (
<Popconfirm title="确定要提交吗?" okText="是" cancelText="否" onConfirm={() => fetchSubmitBatch(_record.id)}>
<Popconfirm okButtonProps={{ loading: submitLoading }} title="确定要提交吗?" okText="是" cancelText="否" onConfirm={() => fetchSubmitBatch(_record.id)}>
<Button type='link'>
提交
</Button>
......
......@@ -38,7 +38,7 @@ const avtivityTypes = [
]
const AddedMarketing = () => {
const { query: { id, signUpId }, pathname } = history.location;
const { query: { id }, pathname } = history.location;
const [path] = useState(pathname.split('/')[pathname.split('/').length - 1]);
const focus$ = useEventEmitter();
const [form] = Form.useForm();
......
import React from 'react';
import { Image, Form, Input, Popconfirm } from 'antd';
import { Image, Form, Input, Popconfirm, Button } from 'antd';
const columns_4 = ({
dataSource,
setDataSource,
handleDelete,
form,
handlCollocation,
value,
}) => {
/** 输入 */
const handleInputChange = (e, name, index) => {
......@@ -128,12 +130,23 @@ const columns_4 = ({
key: 'operation',
dataIndex: 'operation',
render: (_text, _record) => (
<>
<Popconfirm
title="是否删除?"
onConfirm={() => handleDelete(_record.skuId)}
>
<a>删除</a>
</Popconfirm>
{(value === 6) && (
<Button type='link' onClick={() => handlCollocation(_record)}>设置赠品</Button>
)}
{(value === 13) && (
<Button type='link' onClick={() => handlCollocation(_record)}>设置换购商品</Button>
)}
{(value === 15) && (
<Button type='link' onClick={() => handlCollocation(_record)}>设置搭配商品</Button>
)}
</>
)
},
]
......
import React from 'react';
import { Tooltip, Image } from 'antd';
import { QuestionCircleOutlined } from '@ant-design/icons';
import { ColumnType } from 'antd/lib/table';
import { Image, Form, Input, Popconfirm } from 'antd';
interface ColumnTypes<T> extends ColumnType<any> {
/**
* 可编辑
*/
editable?: boolean,
/**
* 操作
*/
operation?: boolean,
}
const columns_8 = () => {
const columns_8 = ({
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 (
[
{
......@@ -57,34 +67,89 @@ const columns_8 = () => {
{
title: '预售价格',
key: 'activityPrice',
dataIndex: 'activityPrice'
dataIndex: 'activityPrice',
},
{
title: '单位定金',
key: 'activityPrice',
dataIndex: 'activityPrice'
dataIndex: 'activityPrice',
},
{
title: '定金抵扣单价',
key: 'activityPrice',
dataIndex: 'activityPrice'
dataIndex: 'activityPrice',
},
{
title: '个人限购数量',
key: 'restrictNum',
dataIndex: 'restrictNum',
editable: true,
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',
editable: true,
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: '',
dataIndex: ''
key: 'operation',
dataIndex: 'operation',
render: (_text, _record) => (
<Popconfirm
title="是否删除?"
onConfirm={() => handleDelete(_record.skuId)}
>
<a>删除</a>
</Popconfirm>
)
},
]
)
......
......@@ -7,6 +7,8 @@ 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';
import ListModalLayout from '@/pages/transaction/marketingAbility/paltformSign/readySubmitExamine/components/listModalLayout';
import { remindLayout, RemindLayoutProps } from '@/pages/transaction/marketingAbility/paltformSign/readySubmitExamine/components/productListLayout/remind';
type optionProps = {
/** key */
......@@ -34,6 +36,9 @@ const ProductListLayout: React.FC<ProductListProps> = (props: any) => {
const [listModalVisible, setListModalVisible] = useState<boolean>(false);
const [dataSource, setDataSource] = useState<any[]>([]);
const [idNotInList, setIdNotInList] = useState<number[]>([]); // 排除的id集合 ,Long
const [skuId, setSkuId] = useState<number>(0); // 当前设置商品的id
const [remind, setRemind] = useState<RemindLayoutProps>({});
const [collocation, setCollocation] = useState<any[]>([]);
const handlesStFieldsValue = () => {
const params = [...dataSource];
......@@ -62,15 +67,50 @@ const ProductListLayout: React.FC<ProductListProps> = (props: any) => {
setDataSource(newData.filter(item => item.skuId !== key))
}
/** 设置搭配 */
const handlCollocation = (record: any) => {
const tableRecord: any = {...record}
if (tableRecord.goodsSubsidiaryGroupList !== undefined) {
setCollocation(tableRecord.goodsSubsidiaryGroupList)
} else {
setCollocation([])
}
setSkuId(tableRecord.skuId)
setListModalVisible(true);
console.log(record)
}
const columns = useMemo(() => {
return Columns[value]?.({ dataSource, setDataSource, handleDelete, form, setIdNotInList })
return Columns[value]?.({ dataSource, setDataSource, handleDelete, form, setIdNotInList, handlCollocation, value })
}, [value, dataSource])
const toggle = (flag: boolean) => {
const activityDefinedBO = form.getFieldValue('activityDefinedBO');
if (isEmpty(shopIdList)) {
message.warning('请选择适用商城!')
message.warning('请选择适用商城!');
return
}
if ((value === 6 || value === 13) && isEmpty(activityDefinedBO)) {
message.warning('请选择活动规则!');
return
}
if ((value === 6) && !isEmpty(activityDefinedBO) && (!activityDefinedBO.giveType || !activityDefinedBO.giftType)) {
message.warning('请选择赠送促销类型和赠品类型!');
return
}
if ((value === 13) && !isEmpty(activityDefinedBO) && !activityDefinedBO.swapType) {
message.warning('请选择换购类型!');
return
}
if (value === 6) {
setRemind(remindLayout(value, activityDefinedBO.giveType, activityDefinedBO.giftType));
}
if (value === 13) {
setRemind(remindLayout(value, activityDefinedBO.swapType));
}
if (value === 15) {
setRemind(remindLayout(value));
}
setProductVisible(flag)
}
......@@ -82,10 +122,20 @@ const ProductListLayout: React.FC<ProductListProps> = (props: any) => {
useEffect(() => {
if (activityId) {
PublicApi.getMarketingMerchantActivityDetailGoodsPage({ current: '1', pageSize: '999', activityId}).then(res => {
PublicApi.getMarketingMerchantActivityDetailGoodsPage({ current: '1', pageSize: '999', activityId }).then(res => {
if (res.code !== 1000) {
return
}
const activityDefinedBO = form.getFieldValue('activityDefinedBO');
if (value === 6) {
setRemind(remindLayout(value, activityDefinedBO.giveType, activityDefinedBO.giftType));
}
if (value === 13) {
setRemind(remindLayout(value, activityDefinedBO.swapType));
}
if (value === 15) {
setRemind(remindLayout(value));
}
form.setFieldsValue({
'productList': res.data.data
})
......@@ -99,6 +149,17 @@ const ProductListLayout: React.FC<ProductListProps> = (props: any) => {
handlesStFieldsValue()
}, [dataSource])
const handleConfirm = (params: any) => {
const fields = [...dataSource];
fields.forEach(item => {
if (item.skuId === skuId) {
item.goodsSubsidiaryGroupList = [...params]
}
})
setListModalVisible(false)
setDataSource(fields)
}
return (
<CardLayout
id="productListLayout"
......@@ -110,7 +171,7 @@ const ProductListLayout: React.FC<ProductListProps> = (props: any) => {
rules={[{ required: true, message: '请选择活动商品' }]}
>
<Table
rowKey={(record) => record.id}
rowKey={(record) => record.skuId}
columns={columns}
dataSource={dataSource}
pagination={{
......@@ -125,6 +186,19 @@ const ProductListLayout: React.FC<ProductListProps> = (props: any) => {
toggle={toggle}
onConfirm={handleSelectActiveProducts}
/>
{/* 设置搭配商品 */}
{!isEmpty(remind) && (
<ListModalLayout
title={remind.modalTitle}
remind={remind}
idNotInList={[skuId]}
shopIdList={shopIdList}
visible={listModalVisible}
onClose={() => setListModalVisible(false)}
onConfirm={handleConfirm}
value={collocation}
/>
)}
</Form.Item>
</CardLayout>
)
......
......@@ -28,7 +28,7 @@ type optionProps = {
const RulesLayout: React.FC<RulesLayoutProps> = (props: any) => {
const { focus$, form } = props;
const [option, setOption] = useState<optionProps>();
const [ladderType, setLadderType] = useState<number>(1)
const [ladderType, setLadderType] = useState<number>(1);
const handleActivityDefinedBO = (e) => {
const { value } = e.target
......
......@@ -20,20 +20,25 @@ import {
const ReadySubmitExamine = () => {
const ref = useRef<any>({});
const [rowkeys, setRowKeys] = useState<Array<number>>([]);
const [loading, setLoading] = useState<boolean>(false)
const [deleteLoading, setDeleteLoading] = useState<boolean>(false);
const [submitLoading, setSubmitLoading] = 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 });
res = await PublicApi.postMarketingMerchantActivitySubmitExamineBatch({ ids: rowkeys });
}
if (res.code === 1000) {
setSubmitLoading(true)
if (res.code !== 1000) {
setSubmitLoading(false)
return
}
setSubmitLoading(false)
ref.current.reload();
setRowKeys([])
}
}
const fetchDeleteBatch = async (id?: number) => {
let res: any = null;
......@@ -42,12 +47,12 @@ const ReadySubmitExamine = () => {
} else {
res = await PublicApi.postMarketingMerchantActivityDeleteBatch({ ids: rowkeys });
}
setLoading(true)
setDeleteLoading(true)
if (res.code !== 1000) {
setLoading(false)
setDeleteLoading(false)
return
}
setLoading(false)
setDeleteLoading(false)
ref.current.reload();
setRowKeys([])
}
......@@ -105,7 +110,7 @@ const ReadySubmitExamine = () => {
render: (_text, _record) => (
<Fragment>
{_record.submit && (
<Popconfirm title="确定要提交吗?" okText="是" cancelText="否" onConfirm={() => fetchSubmitBatch(_record.id)}>
<Popconfirm okButtonProps={{ loading: submitLoading }} title="确定要提交吗?" okText="是" cancelText="否" onConfirm={() => fetchSubmitBatch(_record.id)}>
<Button type='link'>
提交
</Button>
......@@ -113,7 +118,7 @@ const ReadySubmitExamine = () => {
)}
{_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)}>
<Popconfirm okButtonProps={{ loading: deleteLoading }} title="确定要删除吗?" okText="是" cancelText="否" onConfirm={() => fetchDeleteBatch(_record.id)}>
<Button type='link'>
删除
</Button>
......@@ -248,13 +253,15 @@ const ReadySubmitExamine = () => {
</Button>
<Button
icon={<DeleteOutlined />}
loading={loading}
loading={deleteLoading}
onClick={() => fetchDeleteBatch()}
disabled={rowkeys.length === 0}
>
批量删除
</Button>
<Button
loading={loading}
loading={submitLoading}
onClick={() => fetchSubmitBatch()}
disabled={rowkeys.length === 0}
>
批量提交审核
......
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