forked from yoone/WEB
1
0
Fork 0
WEB/src/pages/Product/WpList/index.tsx

541 lines
14 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { PRODUCT_STATUS_ENUM } from '@/constants';
import {
productcontrollerProductbysku,
productcontrollerSearchproducts,
} from '@/servers/api/product';
import { sitecontrollerAll } from '@/servers/api/site';
import {
wpproductcontrollerGetwpproducts,
wpproductcontrollerSetconstitution,
wpproductcontrollerSyncproducts,
wpproductcontrollerUpdateproduct,
wpproductcontrollerUpdatevariation,
} from '@/servers/api/wpProduct';
import { EditOutlined } from '@ant-design/icons';
import {
ActionType,
DrawerForm,
PageContainer,
ProColumns,
ProForm,
ProFormDigit,
ProFormList,
ProFormSelect,
ProFormText,
ProTable,
} from '@ant-design/pro-components';
import { App, Button, Divider, Form } from 'antd';
import { useRef } from 'react';
const List: React.FC = () => {
const actionRef = useRef<ActionType>();
const columns: ProColumns<API.WpProductDTO>[] = [
{
title: '名称',
dataIndex: 'name',
},
{
title: '站点',
dataIndex: 'siteId',
valueType: 'select',
request: async () => {
const { data = [] } = await sitecontrollerAll();
return data.map((item) => ({
label: item.siteName,
value: item.id,
}));
},
},
{
title: 'sku',
dataIndex: 'sku',
hideInSearch: true,
},
{
title: '产品状态',
dataIndex: 'status',
valueType: 'select',
valueEnum: PRODUCT_STATUS_ENUM,
},
{
title: '常规价格',
dataIndex: 'regular_price',
hideInSearch: true,
},
{
title: '销售价格',
dataIndex: 'sale_price',
hideInSearch: true,
},
{
title: '更新时间',
dataIndex: 'updatedAt',
valueType: 'dateTime',
hideInSearch: true,
},
{
title: '创建时间',
dataIndex: 'createdAt',
valueType: 'dateTime',
hideInSearch: true,
},
{
title: '操作',
dataIndex: 'option',
valueType: 'option',
render: (_, record) => (
<>
<UpdateForm tableRef={actionRef} values={record} />
{record.type === 'simple' && record.sku ? (
<>
<Divider type="vertical" />
<SetComponent
tableRef={actionRef}
values={record}
isProduct={true}
/>
</>
) : (
<></>
)}
</>
),
},
];
const varColumns: ProColumns<API.VariationDTO>[] = [
{
title: '变体名',
dataIndex: 'name',
},
{
title: 'sku',
dataIndex: 'sku',
hideInSearch: true,
},
{
title: '常规价格',
dataIndex: 'regular_price',
hideInSearch: true,
},
{
title: '销售价格',
dataIndex: 'sale_price',
hideInSearch: true,
},
{
title: '操作',
dataIndex: 'option',
valueType: 'option',
render: (_, record) => (
<>
<UpdateVaritation tableRef={actionRef} values={record} />
{record.sku ? (
<>
<Divider type="vertical" />
<SetComponent
tableRef={actionRef}
values={record}
isProduct={false}
/>
</>
) : (
<></>
)}
</>
),
},
];
return (
<PageContainer header={{ title: 'WP产品列表' }}>
<ProTable<API.WpProductDTO>
headerTitle="查询表格"
actionRef={actionRef}
rowKey="id"
request={async (params) => {
const { data, success } = await wpproductcontrollerGetwpproducts(
params,
);
return {
total: data?.total || 0,
data: data?.items || [],
success,
};
}}
columns={columns}
toolBarRender={() => [<SyncForm tableRef={actionRef} />]}
expandable={{
rowExpandable: (record) => record.type === 'variable',
expandedRowRender: (record) => (
<ProTable<API.VariationDTO>
rowKey="id"
dataSource={record.variations}
pagination={false}
search={false}
options={false}
columns={varColumns}
/>
),
}}
/>
</PageContainer>
);
};
const SyncForm: React.FC<{
tableRef: React.MutableRefObject<ActionType | undefined>;
}> = ({ tableRef }) => {
const { message } = App.useApp();
return (
<DrawerForm<API.wpproductcontrollerSyncproductsParams>
title="同步产品"
trigger={
<Button key="syncSite" type="primary">
</Button>
}
autoFocusFirstInput
drawerProps={{
destroyOnClose: true,
}}
onFinish={async (values) => {
try {
const { success, message: errMsg } =
await wpproductcontrollerSyncproducts(values);
if (!success) {
throw new Error(errMsg);
}
message.success('同步成功');
tableRef.current?.reload();
return true;
} catch (error: any) {
message.error(error.message);
}
}}
>
<ProForm.Group>
<ProFormSelect
name="siteId"
width="lg"
label="站点"
placeholder="请选择站点"
request={async () => {
const { data = [] } = await sitecontrollerAll();
return data.map((item) => ({
label: item.siteName,
value: item.id,
}));
}}
/>
</ProForm.Group>
</DrawerForm>
);
};
const UpdateForm: React.FC<{
tableRef: React.MutableRefObject<ActionType | undefined>;
values: API.WpProductDTO;
}> = ({ tableRef, values: initialValues }) => {
const { message } = App.useApp();
return (
<DrawerForm<API.UpdateProductDTO>
title="编辑产品"
initialValues={initialValues}
trigger={
<Button type="primary">
<EditOutlined />
</Button>
}
autoFocusFirstInput
drawerProps={{
destroyOnClose: true,
}}
onFinish={async (values) => {
const { siteId, ...params } = values;
try {
const { success, message: errMsg } =
await wpproductcontrollerUpdateproduct(
{
productId: initialValues.externalProductId,
siteId,
},
params,
);
if (!success) {
throw new Error(errMsg);
}
message.success('提交成功');
tableRef.current?.reload();
return true;
} catch (error: any) {
message.error(error.message);
}
}}
>
<ProForm.Group>
<ProFormText label="名称" width="lg" name="name" />
<ProFormSelect
width="lg"
label="站点"
request={async () => {
const { data = [] } = await sitecontrollerAll();
return data.map((item) => ({
label: item.siteName,
value: item.id,
}));
}}
name="siteId"
disabled
/>
<ProFormText
name="sku"
width="lg"
label="sku"
tooltip="Example: TO-ZY-06MG-WG-S-0001"
placeholder="请输入SKU"
/>
{initialValues.type === 'simple' ? (
<>
<ProFormDigit
name="regular_price"
width="lg"
label="常规价格"
fieldProps={{
precision: 2,
}}
/>
<ProFormDigit
name="sale_price"
width="lg"
label="促销价格"
fieldProps={{
precision: 2,
}}
/>
</>
) : (
<></>
)}
</ProForm.Group>
</DrawerForm>
);
};
const UpdateVaritation: React.FC<{
tableRef: React.MutableRefObject<ActionType | undefined>;
values: API.VariationDTO;
}> = ({ tableRef, values: initialValues }) => {
const { message } = App.useApp();
return (
<DrawerForm<API.UpdateProductDTO>
title="编辑变体"
initialValues={initialValues}
trigger={
<Button type="primary">
<EditOutlined />
</Button>
}
autoFocusFirstInput
drawerProps={{
destroyOnClose: true,
}}
onFinish={async (values) => {
const { ...params } = values;
try {
const { success, message: errMsg } =
await wpproductcontrollerUpdatevariation(
{
siteId: initialValues.siteId,
productId: initialValues.externalProductId,
variationId: initialValues.externalVariationId,
},
params,
);
if (!success) {
throw new Error(errMsg);
}
message.success('提交成功');
tableRef.current?.reload();
return true;
} catch (error: any) {
message.error(error.message);
}
}}
>
<ProForm.Group>
<ProFormText label="变体名称" width="lg" name="name" />
<ProFormText
name="sku"
width="lg"
label="sku"
tooltip="Example: TO-ZY-06MG-WG-S-0001"
placeholder="请输入SKU"
/>
<ProFormDigit
name="regular_price"
width="lg"
label="常规价格"
fieldProps={{
precision: 2,
}}
/>
<ProFormDigit
name="sale_price"
width="lg"
label="促销价格"
fieldProps={{
precision: 2,
}}
/>
</ProForm.Group>
</DrawerForm>
);
};
const SetComponent: React.FC<{
tableRef: React.MutableRefObject<ActionType | undefined>;
values: API.VariationDTO | API.WpProductDTO;
isProduct: boolean;
}> = ({ tableRef, values: { id, constitution, name }, isProduct = false }) => {
const { message } = App.useApp();
const [form] = Form.useForm();
const fetchInitialValues = async () => {
const initData = await Promise.all(
constitution?.map?.(async (item) => {
const { data } = await productcontrollerProductbysku({
sku: item.sku as string,
});
return {
quantity: item.quantity,
sku: {
label: data?.name,
value: item.sku,
},
};
}) || [],
);
form.setFieldsValue({
constitution: initData,
});
};
return (
<DrawerForm<API.SetConstitutionDTO>
title={name}
form={form}
trigger={
<Button type="primary" danger={constitution?.length === 0}>
<EditOutlined />
</Button>
}
autoFocusFirstInput
drawerProps={{
destroyOnClose: true,
}}
onFinish={async ({ constitution }) => {
try {
const { success, message: errMsg } =
await wpproductcontrollerSetconstitution(
{
id,
},
{
isProduct,
constitution,
},
);
if (!success) {
throw new Error(errMsg);
}
message.success('提交成功');
tableRef.current?.reload();
return true;
} catch (error: any) {
message.error(error.message);
}
}}
onOpenChange={(visiable) => {
if (visiable) fetchInitialValues();
}}
>
<ProForm.Group>
<ProFormList<{
sku: string;
quantity: number;
}>
name="constitution"
rules={[
{
required: true,
message: '至少需要一个商品',
validator: (_, value) =>
value && value.length > 0
? Promise.resolve()
: Promise.reject('至少需要一个商品'),
},
]}
creatorButtonProps={{ children: '新增' }}
>
{(fields, idx, { remove }) => (
<div key={idx}>
<ProFormSelect
request={async ({ keyWords }) => {
if (keyWords.length < 3) return [];
try {
const { data } = await productcontrollerSearchproducts({
name: keyWords,
});
const arr =
data?.map((item) => {
return {
label: item.name,
value: item.sku,
};
}) || [];
return arr;
} catch (error) {
console.log(error);
return [];
}
}}
name="sku"
label="产品"
width="lg"
placeholder="请选择产品"
tooltip="至少输入3个字符"
fieldProps={{
showSearch: true,
filterOption: false,
}}
transform={(value) => {
return value?.value || value;
}}
debounceTime={300} // 防抖减少请求频率
rules={[{ required: true, message: '请选择产品' }]}
/>
<ProFormDigit
name="quantity"
label="数量"
placeholder="请输入数量"
rules={[{ required: true, message: '请输入数量' }]}
fieldProps={{
precision: 0,
}}
/>
<Button type="link" danger onClick={() => remove(fields.key)}>
</Button>
</div>
)}
</ProFormList>
</ProForm.Group>
</DrawerForm>
);
};
export default List;