Commit a0d2fee9 authored by beisir's avatar beisir

fix: 批量设置

parent 8a5a0130
import { InputNumber, InputRef } from 'antd';
import { Button, Form, Input, Popconfirm, Table } from 'antd';
import type { FormInstance } from 'antd/es/form';
import React, { useContext, useEffect, useRef, useState } from 'react';
import React, { useContext, useEffect, useRef, useState, forwardRef, useImperativeHandle } from 'react';
const EditableContext = React.createContext<FormInstance<any> | null>(null);
interface DataType {
rowSpanCount?: number;
supplyPrice: number;
commissionRate: number;
marketPrice: number;
salePrice: number;
stock: number;
productStockWarning: number;
}
interface PropType {
initData: any[];
defaultColumns: any[];
setTableData: (item: DataType[]) => {};
};
interface Item {
key: string;
......@@ -26,15 +37,7 @@ interface EditableCellProps {
interface EditableRowProps {
index: number;
}
interface DataType {
rowSpanCount?: number;
supplyPrice: number;
commissionRate: number;
marketPrice: number;
salePrice: number;
stock: number;
productStockWarning: number;
}
type EditableTableProps = Parameters<typeof Table>[0];
type ColumnTypes = Exclude<EditableTableProps['columns'], undefined>;
......@@ -74,16 +77,15 @@ const EditableCell: React.FC<EditableCellProps> = (props) => {
};
let childNode = children;
if (editable) {
// if (editable) {
childNode = <Form.Item
style={{ margin: 0 }}
name={['tableList', rowIndex, dataIndex]}
// initialValue={record[dataIndex]}
rules={[{ required: true, message: `${title} is required.` }]}>
<InputNumber onBlur={save} />
{editable ?<InputNumber onBlur={save} /> : children[1]}
</Form.Item>
}
// }
return <td {...restProps}>{childNode}</td>;
};
......@@ -91,9 +93,9 @@ const EditableCell: React.FC<EditableCellProps> = (props) => {
const EditFormTable = (props: PropType) => {
const EditFormTable = forwardRef((props: PropType, ref) => {
const { initData } = props;
const { initData, defaultColumns, setTableData } = props;
// console.log(initData);
const [dataSource, setDataSource] = useState<DataType[]>([]);
const [form] = Form.useForm();
......@@ -108,48 +110,6 @@ const EditFormTable = (props: PropType) => {
setDataSource(initData);
}, [initData])
const defaultColumns: (ColumnTypes[number] & { editable?: boolean; dataIndex: string })[] = [
{
title: '一级规格',
dataIndex: 'firstSpecValue',
},
{
title: '二级规格',
dataIndex: 'secondSpecValue',
},
{
title: '供货价',
dataIndex: 'supplyPrice',
editable: true,
},
{
title: '佣金费率',
dataIndex: 'commissionRate',
editable: true,
},
{
title: '市场价',
dataIndex: 'marketPrice',
editable: true,
},
{
title: '销售价',
dataIndex: 'salePrice',
editable: true,
},
{
title: '库存',
dataIndex: 'stock',
editable: true,
},
{
title: '库存预警阈值',
dataIndex: 'productStockWarning',
editable: true,
},
];
const handleAdd = async () => {
try {
const { tableList } = await form.validateFields();
......@@ -168,8 +128,25 @@ const EditFormTable = (props: PropType) => {
// ...item,
// ...row,
// });
setDataSource([...row]);
setTableData([...row]);
};
const onCheck = async () => {
try {
const values = await form.validateFields();
return values;
} catch (errorInfo) {
return null;
}
};
useImperativeHandle(ref, () => ({
onCheck,
form,
}));
// 根据这里做判断渲染表格
const columns = defaultColumns.map((col, colIndex) => {
// if (!col.editable) {
......@@ -201,9 +178,6 @@ const EditFormTable = (props: PropType) => {
return (
<div>
<Button onClick={handleAdd} type="primary" style={{ marginBottom: 16 }}>
Add a row
</Button>
<Form form={form} scrollToFirstError component={false}>
<EditableContext.Provider value={form}>
<Table
......@@ -221,9 +195,10 @@ const EditFormTable = (props: PropType) => {
columns={columns as ColumnTypes}
/>
</EditableContext.Provider>
<Button onClick={handleAdd} type="primary" style={{ marginBottom: 16 }}>Add a row</Button>
</Form>
</div>
);
};
});
export default EditFormTable;
\ No newline at end of file
import { ConsoleSqlOutlined, MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
import { Button, Form, Input, Select, Space, Modal, notification } from 'antd';
import React, { useState, forwardRef, useImperativeHandle, useEffect } from 'react';
import { Button, Form, Input, Select, Space, Modal, InputNumber, notification } from 'antd';
import React, { useState, forwardRef, useImperativeHandle, useRef, useEffect, useContext } from 'react';
import { useParams } from 'react-router-dom';
import { formItemLayout } from '../config';
import { formItemLayout, StaticColumns } from '../config';
import EditFormTable from './EditFormTable';
import { createProductData } from '../utils';
import { createProductData, cleanArray } from '../utils';
import { ServiceContext } from '../context';
import { ColumnTypes } from '../type';
const { Option } = Select;
interface SpecItem {
......@@ -28,24 +30,31 @@ const validatorSpecValue = (value, list, index, specName) => {
return checkList.length;
};
const isRepeatProduct = (list, message) => {
const isRepeat = [...new Set(list)].length !== list.length;
if (isRepeat) {
notification.warning({ message });
}
return isRepeat;
};
const SpecificationTemplate = (props, _) => {
const { specList, label, name, selectName, specName, form, specDataList } = props;
const {
form,
name,
label,
specName,
specList,
selectName,
onChange = () => {},
specDataList,
} = props;
const customer = useContext(ServiceContext);
console.log('==============>specDataList', specDataList);
const handleChange = (val, option) => {
const optionSpecName = option ? option.specName : null;
form.setFieldsValue({ [selectName]: optionSpecName });
// onChange();
};
const inputOnblurEvent = () => {
// onChange();
}
const bundlePlusAddSpecEvent = (addCallback: () => void) => {
console.log(name);
const specId = form.getFieldValue(name);
if (!specId) {
Modal.warning({
......@@ -54,14 +63,20 @@ const SpecificationTemplate = (props, _) => {
});
return;
}
console.log(specId);
addCallback();
// inputOnblurEvent();
};
const bundlePlusRemoveSpecEvent = (removeCallback, fieldName) => {
removeCallback(fieldName)
// inputOnblurEvent();
}
return (
<>
<Form.Item name={name} label={label}>
<Select
disabled={customer.isEdit}
allowClear
options={specList}
style={{ width: 200 }}
......@@ -78,16 +93,6 @@ const SpecificationTemplate = (props, _) => {
<Form.List name={specName}>
{(fields, { add, remove }) => (
<>
{/* {fields.map((field, index) => (
<Space key={field.key} align="baseline">
<Form.Item style={{ marginLeft: 10 }} name={[index]}
rules={[{ required: true, message: '请输入规格名称' }]}
>
<Input placeholder="请输入规格名称" />
</Form.Item>
<MinusCircleOutlined onClick={() => remove(field.name)} />
</Space>
))} */}
{fields.map((field, index) => (
<Form.Item key={field.key} noStyle shouldUpdate={(prevValues, curValues) => false}>
{() => (
......@@ -109,11 +114,12 @@ const SpecificationTemplate = (props, _) => {
>
<Input
disabled={specDataList[index] && specDataList[index].id}
onBlur={inputOnblurEvent}
placeholder="请输入规格名称"
/>
</Form.Item>
{!(specDataList[index] && specDataList[index].id) && (
<MinusCircleOutlined onClick={() => remove(field.name)} />
<MinusCircleOutlined onClick={() => bundlePlusRemoveSpecEvent(remove, field.name)} />
)}
</Space>
)}
......@@ -144,6 +150,8 @@ const originItems = {
secondDuplicate: [],
};
// 编辑回显示时只获取用到的数据
const filterItem = skuItem => {
const { imageList, serviceItem, ...argsItem } = skuItem;
argsItem.disabled = true;
......@@ -152,10 +160,8 @@ const filterItem = skuItem => {
const filterSpecData = skuList =>
skuList.reduce((orgin, skuItem) => {
// console.log(item);
const item = filterItem(skuItem);
const { firstSpecValue, secondSpecValue } = item;
if (firstSpecValue && !orgin.firstDuplicate.includes(firstSpecValue)) {
orgin.firstSpecValue.push(item);
orgin.firstDuplicate.push(firstSpecValue);
......@@ -164,31 +170,45 @@ const filterSpecData = skuList =>
orgin.secondSpecValue.push(item);
orgin.secondDuplicate.push(secondSpecValue);
}
// orgin.dataSource.push({
// id: item.id,
// firstSpec: item.firstSpec,
// firstSpecId: item.firstSpecId,
// firstSpecValue: item.firstSpecValue,
// secondSpec: item.secondSpec,
// secondSpecId: item.secondSpecId,
// secondSpecValue: item.secondSpecValue,
// commissionRate: item.commissionRate,
// supplyPrice: item.supplyPrice, // 供货价
// marketPrice: item.marketPrice,
// salePrice: item.salePrice,
// stock: item.stock,
// productStockWarning: item.productStockWarning,
// });
return orgin;
}, originItems);
const createTableData = () => {};
const CreateBatchFormItems = ({ batchChange, editRef, defaultColumns }) => {
const customer = useContext(ServiceContext);
const formItems = defaultColumns
.filter(item => !item.role || item?.role.includes(customer.productType))
.map((item, index) => (
<Form.Item
noStyle
key={item.dataIndex}
name={['batchItem', item.dataIndex]}
initialValue={null}>
<InputNumber placeholder={item.title} />
</Form.Item>
));
console.log(formItems.length);
// const batchEvent = () => {
// const batchItem = form.getFieldValue('batchItem');
// console.log(batchItem);
// // editRef.current.form.setFieldsValue({
// // });
// }
return <>
{formItems.length && <Space style={{ marginBottom: 20 }}>
{formItems.concat(<Button key="batch" type="primary" onClick={batchChange}>批量设置</Button>)}
</Space>}
</>;
};
const FormPriceOrStock = forwardRef((props: PropsType, ref) => {
const { specList, editData } = props;
console.log('============>000000000000', props);
const editRef = useRef(null);
const customer = useContext(ServiceContext);
const [form] = Form.useForm();
const [specInitValue, setSpecInitValue] = useState({
firstSpec: '',
......@@ -199,44 +219,9 @@ const FormPriceOrStock = forwardRef((props: PropsType, ref) => {
secondSpecValue: [],
});
const [defaultColumns, setDefaultColumns] = useState([]);
const [tableData, setTableData] = useState([]);
const onFinish = (values: any) => {
console.log(values);
// const values = form.getFieldsValue();
// const { firstValues = [], secondValues = [], firstSpecId, secondSpecId } = values;
// if ([fisrtIsRepeat, secondIsRepeat].includes(true)) {
// setTableData([]);
// return;
// }
const cleanValues = {
firstValues: values.firstSpecValue,
secondValues: values.secondSpecValue,
firstSpecId: values.firstSpecId,
secondSpecId: values.secondSpecId,
};
const newData = createProductData(cleanValues);
// console.log('=============>生成商品数据', newData);
setTableData(newData);
// // const columnsData = createProductColumns(cleanValues, newData);
// form.resetFields('tableArray', []);
// setColumns(columnsData);
// setProductData(newData);
// console.log(newData);
// console.log(columnsData);
if (!values.firstSpecId && !values.firstSpecId) {
// 如果两个都没有选择默认生成一条数据
// Modal.warning({
// maskClosable: true,
// title: '请先选择规格分类!',
// });
}
};
const onCheck = async () => {
try {
const values = await form.validateFields();
......@@ -246,12 +231,77 @@ const FormPriceOrStock = forwardRef((props: PropsType, ref) => {
}
};
const CreateColumnsEvent = specData => {
const columsData = [];
if (specData.firstSpec && specData.firstSpecValue.length) {
columsData.push({
title: specData.firstSpec,
dataIndex: 'firstSpecValue',
role: [],
});
}
if (specData.secondSpec && specData.secondSpecValue.length) {
columsData.push({
title: specData.secondSpec,
dataIndex: 'secondSpecValue',
role: [],
});
}
if (!columsData.length) {
return;
}
const dynamicColumns: (ColumnTypes[number] & { editable?: boolean; dataIndex: string })[] = [
...columsData,
...StaticColumns,
];
setDefaultColumns(dynamicColumns);
}
const onFinish = async () => {
try {
const values = await form.validateFields();
CreateColumnsEvent(values);
const cleanValues = {
firstValues: cleanArray(values.firstSpecValue),
secondValues: cleanArray(values.secondSpecValue),
firstSpecId: values.firstSpecId,
secondSpecId: values.secondSpecId,
};
const newData = createProductData(cleanValues);
setTableData(newData);
} catch (error) {
console.log(error);
}
};
const batchChange = () => {
const batchItem = form.getFieldValue('batchItem')
const batchItemKey = Object.keys(batchItem);
const resetObject = tableData.map((item, index) => {
console.log(item);
batchItemKey.forEach(key => {
item[key] = batchItem[key] || null;
// reset[`tableList[${index}]['${key}']`] = batchItem[key] || null;
});
return item;
});
setTableData(resetObject);
console.log(resetObject);
// editRef.current.form.setFieldsValue(resetObject);
// form.setFieldsValue(resetObject);
}
useImperativeHandle(ref, () => ({
onCheck,
}));
const { id } = useParams<any>();
useEffect(() => {
if (+id !== 0) {
if (customer.isEdit) {
if (!Object.keys(editData).length) return;
const { skuList } = editData;
const [oneItem] = skuList;
......@@ -267,22 +317,22 @@ const FormPriceOrStock = forwardRef((props: PropsType, ref) => {
};
form.setFieldsValue(specData); // 设置规格数据
setSpecInitValue(specData); // 缓存规格数据
setTableData([...dataSource]);
onFinish(); // 触发生成表格
}
}, [id, editData]);
}, [customer.isEdit, editData]);
return (
// {...formItemLayout}
return (
<Form
form={form}
name="dynamic_form_nest_item"
onFinish={onFinish}
// onFinish={onFinish}
autoComplete="off"
initialValues={specInitValue}
>
<SpecificationTemplate
form={form}
onChange={onFinish}
label="一级规格"
name="firstSpecId"
selectName="firstSpec"
......@@ -292,6 +342,7 @@ const FormPriceOrStock = forwardRef((props: PropsType, ref) => {
/>
<SpecificationTemplate
form={form}
onChange={onFinish}
label="二级规格"
name="secondSpecId"
selectName="secondSpec"
......@@ -299,14 +350,13 @@ const FormPriceOrStock = forwardRef((props: PropsType, ref) => {
specList={specList}
specDataList={specInitValue.secondSpecValue}
/>
<Form.Item>
<Button type="primary" htmlType="submit">
<div style={{ display: 'flex', justifyContent: 'center', marginBottom: 20 }}>
<Button type="primary" onClick={onFinish}>
生成商品信息
</Button>
</Form.Item>
<EditFormTable initData={tableData} />
</div>
<CreateBatchFormItems batchChange={batchChange} editRef={editRef} defaultColumns={defaultColumns} />
<EditFormTable ref={editRef} defaultColumns={defaultColumns} setTableData={setTableData} initData={tableData} />
</Form>
);
});
......
......@@ -64,3 +64,36 @@ export const WeeksList = [
value: 7,
},
];
export const StaticColumns = [{
title: '供货价',
dataIndex: 'supplyPrice',
editable: true,
},
{
title: '佣金费率',
dataIndex: 'commissionRate',
editable: true,
role: [],
},
{
title: '市场价',
dataIndex: 'marketPrice',
editable: true,
},
{
title: '销售价',
dataIndex: 'salePrice',
editable: true,
},
{
title: '库存',
dataIndex: 'stock',
editable: true,
},
{
title: '库存预警阈值',
dataIndex: 'productStockWarning',
editable: true,
role: [],
}];
import React, { useState, useRef, useEffect } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { Spin, Button } from 'antd';
import { ConsoleSqlOutlined } from '@ant-design/icons';
// import { getAppChannelAllList } from '@/services/common';
import { Title, WrapperContainer } from './components/CommonTemplate';
import { TaskTypeSelect } from './components/TaskTypeSelect';
import { Task } from './type';
......@@ -28,30 +25,19 @@ import { ServiceContext } from './context';
const ServiceGoods = options => {
const pageId = +options.match.params.id; // pageId: 0-新增,1-修改,2-查看
const ref = useRef();
const basicRef = useRef(null);
const stockRef = useRef(null);
const settingRef = useRef(null);
const settleOtrRef = useRef(null);
const [isEdit, setIsEdit] = useState(false);
const [productType, setProductType] = useState(1);
const [pageLoading, setPageLoading] = useState(false);
const [isEdit, setIsEdit] = useState(false); // 是否是编辑状态
const [productType, setProductType] = useState(1); // 商品状态
const [pageLoading, setPageLoading] = useState(false); // 页面加载状态
const [categoryList, setCategoryList] = useState([]); // 获取三级类目
const [brandList, setBrandList] = useState([]); // 获取商品牌
const [specList, setSpecList] = useState([]); // 规格列表
const [examLoading, setExamLoading] = useState(false);
const [channelAllList, setChannelAllList] = useState({});
const [editData, setEditData] = useState({});
// const refreshTable = () => {
// ref.current.reload();
// };
const [editData, setEditData] = useState({}); // 编辑保存数据
// useEffect(() => {
// getChannelAllList();
// }, []);
// const onReset = () => {};
const productChange = (task: Task): void => {
setProductType(task.type);
};
......@@ -66,6 +52,7 @@ const ServiceGoods = options => {
console.log(resuslt);
};
// 编辑回显详情数据
const getProductDetailResponse = async () => {
try {
const res = await getProductDetail(pageId);
......@@ -112,7 +99,7 @@ const ServiceGoods = options => {
<Spin tip="正在加载..." spinning={pageLoading} delay={100}>
<PageHeaderWrapper className={commonStyle.header}>
<WrapperContainer>
<ServiceContext.Provider value={{ pageId, isEdit }}>
<ServiceContext.Provider value={{ pageId, isEdit, productType }}>
<Title title="商品类型" />
<TaskTypeSelect productType={productType} onChange={productChange} />
......
import { Button, Form, Input, Popconfirm, Table } from 'antd';
export interface Task {
name: string;
type: number;
desc: string;
}
interface EditableRowProps {
index: number;
}
export type EditableTableProps = Parameters<typeof Table>[0];
export type ColumnTypes = Exclude<EditableTableProps['columns'], undefined>;
......@@ -16,8 +16,6 @@ const createInitProduct = (skuItem, isCreate) => {
return skuItem;
}
return {
// firstSpecValue: '',
// secondSpecValue: '',
weight: null,
productStockWarning: null,
marketPrice: null,
......@@ -29,8 +27,6 @@ const createInitProduct = (skuItem, isCreate) => {
};
const initData = {
// firstSpecValue: '',
// secondSpecValue: '',
weight: null,
productStockWarning: null,
marketPrice: null,
......@@ -42,8 +38,6 @@ const initData = {
const createSecondProduct = (secondSpecList, initItem, secondSpec, dataSource, callback) => {
secondSpecList.forEach(secondItem => {
console.log('============>', Object.keys(secondItem));
const specSecond =
Object.keys(secondItem).length < 2
? {
......@@ -83,7 +77,6 @@ export const createProductData = ({ firstValues, secondValues, firstSpecId, seco
dataSource.push(specFirst);
});
} else if (secondValues.length) {
// const childData = createInitProduct();
createSecondProduct(secondValues, initData, secondSpecId, dataSource);
} else {
const specFirst = createInitProduct();
......
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