Commit 03acb249 authored by beisir's avatar beisir

feat: 初始化服务商品改造

parent d98ff0ad
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';
const EditableContext = React.createContext<FormInstance<any> | null>(null);
interface Item {
key: string;
name: string;
age: string;
address: string;
}
interface EditableRowProps {
index: number;
}
const EditableRow: React.FC<EditableRowProps> = ({ index, ...props }) => {
// console.log('==========> index', props);
// const [form] = Form.useForm();
// console.log('==========>props', props)
return (
// <Form form={form} component={false}>
// <EditableContext.Provider value={form}>
<tr {...props} />
// </EditableContext.Provider>
// </Form>
);
};
interface EditableCellProps {
rowIndex: number;
title: React.ReactNode;
editable: boolean;
children: React.ReactNode;
dataIndex: keyof Item;
record: Item;
handleSave: (record: Item) => void;
}
const EditableCell: React.FC<EditableCellProps> = (props) => {
const {
rowIndex,
title,
editable,
children,
dataIndex,
record,
handleSave,
...restProps
} = props;
// console.log(props);
const form = useContext(EditableContext)!;
const save = async () => {
try {
console.log(rowIndex);
const { tableList } = await form.validateFields();
handleSave(tableList);
} catch (errInfo) {
console.log('Save failed:', errInfo);
}
};
const childNode = <Form.Item
style={{ margin: 0 }}
name={['tableList', rowIndex, dataIndex]}
initialValue={record[dataIndex]}
rules={[ { required: true, message: `${title} is required.` }]}>
<InputNumber onBlur={save} />
</Form.Item>
return <td {...restProps}>{childNode}</td>;
};
type EditableTableProps = Parameters<typeof Table>[0];
interface DataType {
supplyPrice: number;
commissionRate: number;
marketPrice: number;
salePrice: number;
stock: number;
productStockWarning: number;
}
type ColumnTypes = Exclude<EditableTableProps['columns'], undefined>;
const EditFormTable: React.FC = () => {
const [dataSource, setDataSource] = useState<DataType[]>([
{
supplyPrice: 100,
commissionRate: 20,
marketPrice: 32,
salePrice: 100,
stock: 100,
productStockWarning: 100,
},
{
supplyPrice: 100,
commissionRate: 20,
marketPrice: 32,
salePrice: 100,
stock: 100,
productStockWarning: 100,
}
]);
// const form = useContext(EditableContext)!;
const [form] = Form.useForm();
const [count, setCount] = useState(2);
const handleDelete = (key: React.Key) => {
const newData = dataSource.filter(item => item.key !== key);
setDataSource(newData);
};
const defaultColumns: (ColumnTypes[number] & { editable?: boolean; dataIndex: string })[] = [
{
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 = () => {
console.log(form.getFieldsValue());
// const newData: DataType = {
// key: count,
// supplyPrice: 200,
// commissionRate: 20,
// marketPrice: 32,
// salePrice: 100,
// stock: 100,
// productStockWarning: 100,
// };
// setDataSource([...dataSource, newData]);
// setCount(count + 1);
};
const handleSave = (row: DataType[]) => {
console.log('============>row', row);
// const newData = [...dataSource];
// const index = newData.findIndex(item => row.key === item.key);
// const item = newData[index];
// newData.splice(index, 1, {
// ...item,
// ...row,
// });
setDataSource([...row]);
};
const components = {
body: {
row: EditableRow,
cell: EditableCell,
},
};
// 根据这里做判断渲染表格
const columns = defaultColumns.map((col, colIndex) => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: (record: DataType, rowIndex: number) => ({
record,
rowIndex,
editable: col.editable,
dataIndex: col.dataIndex,
title: col.title,
handleSave,
}),
};
});
return (
<div>
<Button onClick={handleAdd} type="primary" style={{ marginBottom: 16 }}>
Add a row
</Button>
<Form form={form} component={false}>
<EditableContext.Provider value={form}>
<Table
pagination={false}
size="small"
components={components}
bordered
dataSource={dataSource}
rowKey={(row, rowInd) => rowInd}
columns={columns as ColumnTypes}
/>
</EditableContext.Provider>
</Form>
</div>
);
};
export default EditFormTable;
\ No newline at end of file
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
import { Button, Form, Input, Select, Space } from 'antd';
import React, { useState, forwardRef, useImperativeHandle } from 'react';
import { ConsoleSqlOutlined, MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
import { Button, Form, Input, Select, Space, Modal } from 'antd';
import React, { useState, forwardRef, useImperativeHandle, useEffect } from 'react';
import { useParams } from 'react-router-dom';
import { formItemLayout } from '../config';
import EditFormTable from './EditFormTable';
const { Option } = Select;
const areas = [{ label: 'Beijing', value: 'Beijing' }, { label: 'Shanghai', value: 'Shanghai' }];
const sights = {
Beijing: ['Tiananmen', 'Great Wall'],
Shanghai: ['Oriental Pearl', 'The Bund'],
};
interface SpecItem {
specId: number;
specName: string;
}
interface PropsType {
editData: any;
specList: Array<SpecItem>;
}
// type SightsKeys = keyof typeof sights;
const SpecificationTemplate = (props, _) => {
const { specList, label, name, selectName, specName, form } = props;
const FormPriceOrStock = forwardRef((props, ref) => {
const handleChange = (val, option) => {
const optionSpecName = option ? option.specName : null;
form.setFieldsValue({ [selectName]: optionSpecName });
};
const bundlePlusAddSpecEvent = (addCallback: () => void) => {
const specId = form.getFieldValue(name);
if (!specId) {
Modal.warning({
maskClosable: true,
title: `请先选择${label}!`,
});
return;
}
console.log(specId);
addCallback();
}
return <>
<Form.Item name={name} label={label}>
<Select
allowClear
options={specList}
style={{ width: 200 }}
fieldNames={{ label: 'specName', value: 'specId' }}
placeholder={`请选择${label}`}
showSearch
filterOption={(input, option) => option.specName.toLowerCase().indexOf(input.toLowerCase()) >= 0}
onChange={handleChange}
/>
</Form.Item>
<Form.Item name={selectName} hidden></Form.Item>
<Form.List name={specName}>
{(fields, { add, remove }) => (
<>
{fields.map((field, index) => (
<Form.Item key={field.key} noStyle shouldUpdate={(prevValues, curValues) => false}>
{() => (
<Space key={field.key} align="baseline">
<Form.Item style={{ marginLeft: 10 }} name={[field.name, specName]}
rules={[{ required: true, message: '请输入规格名称' }]}
>
<Input placeholder="请输入规格名称" />
</Form.Item>
<MinusCircleOutlined onClick={() => remove(field.name)} />
</Space>
)}
</Form.Item>
))}
{fields.length < 3 && <Form.Item noStyle>
<Button style={{ marginLeft: 10, marginBottom: 24 }} type="dashed" onClick={() => bundlePlusAddSpecEvent(add)} icon={<PlusOutlined />} />
</Form.Item>}
</>
)}
</Form.List>
</>
}
const filterSpecData = skuList => skuList.reduce((originObj, item) => {
if (item.firstSpecValue) {
originObj.firstSpecValue.push({ firstSpecValue: item.firstSpecValue });
}
if (item.secondSpecValue) {
originObj.secondSpecValue.push({ secondSpecValue: item.secondSpecValue });
}
return originObj;
}, {
firstSpecValue: [],
secondSpecValue: [],
});
const FormPriceOrStock = forwardRef((props: PropsType, ref) => {
const { specList, editData } = props;
const [form] = Form.useForm();
const [specInitValue, setSpecInitValue] = useState({
firstSpec: '',
firstSpecId: null,
firstSpecValue: [],
secondSpec: '',
secondSpecId: null,
secondSpecValue: [],
});
const onFinish = (values: any) => {
console.log('Received values of form:', values);
};
const handleChange = () => {
form.setFieldsValue({ sights: [] });
};
const onCheck = async () => {
try {
const values = await form.validateFields();
......@@ -36,113 +121,61 @@ const FormPriceOrStock = forwardRef((props, ref) => {
useImperativeHandle(ref, () => ({
onCheck,
}));
const { id } = useParams<any>();
useEffect(() => {
if (+id !== 0) {
if (!Object.keys(editData).length) return;
const { skuList } = editData;
const [oneItem] = skuList;
// 根据接口过滤数据
const { firstSpecValue, secondSpecValue } = filterSpecData(skuList);
const specData = {
firstSpec: oneItem.firstSpec,
firstSpecId: oneItem.firstSpecId,
firstSpecValue,
secondSpec: oneItem.secondSpec,
secondSpecId: oneItem.secondSpecId,
secondSpecValue,
};
form.setFieldsValue(specData);
setSpecInitValue(specData);
}
}, [id, editData]);
return (
// {...formItemLayout}
<Form
form={form}
name="dynamic_form_nest_item"
onFinish={onFinish}
autoComplete="off"
initialValues={{
area: 'Beijing',
}}
>
{/* <Form.Item name="area" label="Area" rules={[{ required: true, message: 'Missing area' }]}>
<Select options={areas} onChange={handleChange} />
</Form.Item> */}
<Form.List name="sights">
{(fields, { add, remove }) => (
<>
{fields.map(field => (
<Form.Item key={field.key} noStyle shouldUpdate={(prevValues, curValues) => false}>
{() => (
<Space key={field.key} align="baseline">
<Form.Item
label="Sight"
name={[field.name, 'sight']}
rules={[{ required: true, message: 'Missing sight' }]}
initialValues={specInitValue}
>
<Select disabled={false} style={{ width: 130 }}>
{(sights[form.getFieldValue('area')] || []).map(item => (
<Option key={item} value={item}>
{item}
</Option>
))}
</Select>
</Form.Item>
<Form.Item
label="Price"
name={[field.name, 'price']}
rules={[{ required: true, message: 'Missing price' }]}
>
<Input />
</Form.Item>
<MinusCircleOutlined onClick={() => remove(field.name)} />
</Space>
)}
</Form.Item>
))}
<Form.Item>
<Button type="dashed" onClick={() => add()} block icon={<PlusOutlined />}>
Add sights
</Button>
</Form.Item>
</>
)}
{/* {(fields, { add, remove }) => (
<>
{fields.map(field => (
<Space key={field.key} align="baseline">
<Form.Item
noStyle
shouldUpdate={(prevValues, curValues) =>
prevValues.area !== curValues.area || prevValues.sights !== curValues.sights
}
>
{() => (
<Form.Item
{...field}
label="Sight"
name={[field.name, 'sight']}
rules={[{ required: true, message: 'Missing sight' }]}
>
<Select disabled={!form.getFieldValue('area')} style={{ width: 130 }}>
{(sights[form.getFieldValue('area') as SightsKeys] || []).map(item => (
<Option key={item} value={item}>
{item}
</Option>
))}
</Select>
</Form.Item>
)}
</Form.Item>
<Form.Item
{...field}
label="Price"
name={[field.name, 'price']}
rules={[{ required: true, message: 'Missing price' }]}
>
<Input />
</Form.Item>
<MinusCircleOutlined onClick={() => remove(field.name)} />
</Space>
))}
<SpecificationTemplate
form={form}
label="一级规格"
name="firstSpecId"
selectName="firstSpec"
specName="firstSpecValue"
specList={specList}
/>
<SpecificationTemplate
form={form}
label="二级规格"
name="secondSpecId"
selectName="secondSpec"
specName="secondSpecValue"
specList={specList}
/>
<Form.Item>
<Button type="dashed" onClick={() => add()} block icon={<PlusOutlined />}>
Add sights
</Button>
</Form.Item>
</>
)} */}
</Form.List>
<Form.Item>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
<EditFormTable />
</Form>
);
});
......
......@@ -67,7 +67,8 @@ const FormRuleSetting = forwardRef((props: { editData: any }, ref) => {
imageList: editData.commonImageList,
commonImageList: editData.commonImageList,
detailImageList: editData.detailImageList,
appointment: '0', // 预约
appointment: serviceItem.appointment, // 预约
receptionVolume: serviceItem.receptionVolume, // 接待数量
});
}
}, [id, editData]);
......@@ -119,7 +120,8 @@ const FormRuleSetting = forwardRef((props: { editData: any }, ref) => {
commonImageList,
detailImageList,
appointment: '', // 预约
appointment: null, // 预约
receptionVolume: null,
}}
scrollToFirstError
>
......@@ -243,12 +245,12 @@ const FormRuleSetting = forwardRef((props: { editData: any }, ref) => {
<Form.Item name="appointment" label="预约">
<Radio.Group>
<Radio value="1"></Radio>
<Radio value="0"></Radio>
<Radio value={1}></Radio>
<Radio value={0}></Radio>
</Radio.Group>
</Form.Item>
<Form.Item
name="meiri"
name="receptionVolume"
label="每日最低接待量"
rules={[{ required: true, message: '每日最低接待量' }]}
>
......
......@@ -12,7 +12,7 @@ import FormPriceOrStock from './components/FormPriceOrStock';
import FormRuleSetting from './components/FormRuleSetting';
import FormSettlementOthers from './components/FormSettlementOthers';
import commonStyle from './common.less';
import { getProductDetail, merchantCategoryGetAll, merchantBrandList } from './service';
import { getProductDetail, merchantCategoryGetAll, merchantBrandList, merchantSpecList } from './service';
/**
* 服务商品改造-商品模块
......@@ -33,7 +33,7 @@ const ServiceGoods = options => {
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({});
......@@ -82,12 +82,18 @@ const ServiceGoods = options => {
const result = await merchantBrandList();
setBrandList(result.data || []);
};
// 获取规格列表
const getMerchantSpecList = async () => {
const result = await merchantSpecList();
setSpecList(result.data || []);
};
useEffect(() => {
(async () => {
setPageLoading(true);
await getMerchantCategory();
await getMerchantBrandList();
await getMerchantSpecList();
if (pageId !== 0) {
await getProductDetailResponse();
}
......@@ -111,7 +117,7 @@ const ServiceGoods = options => {
/>
<Title title="价格与库存" />
<FormPriceOrStock ref={stockRef} initValue={editData} />
<FormPriceOrStock ref={stockRef} specList={specList} editData={editData} />
<Title title="规则设置" />
<FormRuleSetting ref={settingRef} editData={editData} />
......
......@@ -31,3 +31,8 @@ export const merchantBrandList = () =>
request.post('/product/brand/api/merchant/list', {
prefix: goodsApi,
});
// 获取规格列表
export const merchantSpecList = () => request.post('/product/spec/api/merchant/list', {
prefix: goodsApi,
});
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