forked from yoone/WEB
1
0
Fork 0
WEB/src/pages/Stock/PurchaseOrder/index.tsx

683 lines
20 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 { Purchase_Order_STATUS_ENUM } from '@/constants';
import { productcontrollerSearchproducts } from '@/servers/api/product';
import {
stockcontrollerCreatepurchaseorder,
stockcontrollerDelpurchaseorder,
stockcontrollerGetallstockpoints,
stockcontrollerGetpurchaseorders,
stockcontrollerReceivepurchaseorder,
stockcontrollerUpdatepurchaseorder,
} from '@/servers/api/stock';
import { EditOutlined, PlusOutlined } from '@ant-design/icons';
import {
ActionType,
DrawerForm,
PageContainer,
ProColumns,
ProForm,
ProFormDatePicker,
ProFormDependency,
ProFormDigit,
ProFormList,
ProFormSelect,
ProFormText,
ProFormTextArea,
ProTable,
} from '@ant-design/pro-components';
import { App, Button, Divider, Form, Popconfirm } from 'antd';
import { useRef } from 'react';
const PurchaseOrderPage: React.FC = () => {
const { message } = App.useApp();
const actionRef = useRef<ActionType>();
const columns: ProColumns<API.PurchaseOrderDTO>[] = [
{
title: '订单编号',
dataIndex: 'orderNumber',
},
{
title: '仓库',
dataIndex: 'stockPointName',
hideInSearch: true,
},
{
title: '状态',
dataIndex: 'status',
valueType: 'select',
valueEnum: Purchase_Order_STATUS_ENUM,
hideInSearch: true,
},
{
title: '预计到货时间',
dataIndex: 'expectedArrivalTime',
valueType: 'dateTime',
hideInSearch: true,
},
{
title: '数量',
hideInSearch: true,
render(_, record) {
return record.items.reduce((cur, next) => {
return cur + next.quantity;
}, 0);
},
},
{
title: '备注',
dataIndex: 'note',
hideInSearch: true,
},
{
title: '更新时间',
dataIndex: 'updatedAt',
valueType: 'dateTime',
hideInSearch: true,
},
{
title: '创建时间',
dataIndex: 'createdAt',
valueType: 'dateTime',
hideInSearch: true,
},
{
title: '操作',
dataIndex: 'option',
valueType: 'option',
render: (_, record) => (
<>
{record.status !== 'received' && (
<UpdateForm tableRef={actionRef} values={record} />
)}
{record.status === 'draft' ? (
<>
<Divider type="vertical" />
<Popconfirm
title="删除"
description="确认删除?"
onConfirm={async () => {
try {
const { success, message: errMsg } =
await stockcontrollerDelpurchaseorder({
id: record.id as number,
});
if (!success) {
throw new Error(errMsg);
}
actionRef.current?.reload();
} catch (error: any) {
message.error(error.message);
}
}}
>
<Button type="primary" danger>
</Button>
</Popconfirm>
</>
) : record.status === 'submitted' ? (
<>
<Divider type="vertical" />
<Popconfirm
title="入库"
description="确认已到达?"
onConfirm={async () => {
try {
const { success, message: errMsg } =
await stockcontrollerReceivepurchaseorder({
id: record.id as number,
});
if (!success) {
throw new Error(errMsg);
}
actionRef.current?.reload();
} catch (error: any) {
message.error(error.message);
}
}}
>
<Button type="primary"></Button>
</Popconfirm>
</>
) : (
<DetailForm tableRef={actionRef} values={record} />
)}
</>
),
},
];
return (
<PageContainer ghost>
<ProTable<API.PurchaseOrderDTO>
headerTitle="查询表格"
actionRef={actionRef}
rowKey="id"
request={async (params) => {
const { data, success } = await stockcontrollerGetpurchaseorders(
params,
);
return {
total: data?.total || 0,
data: data?.items || [],
success,
};
}}
columns={columns}
toolBarRender={() => [<CreateForm tableRef={actionRef} />]}
/>
</PageContainer>
);
};
const CreateForm: React.FC<{
tableRef: React.MutableRefObject<ActionType | undefined>;
}> = ({ tableRef }) => {
const { message } = App.useApp();
const [form] = Form.useForm();
return (
<DrawerForm<API.CreatePurchaseOrderDTO>
title="新建"
trigger={
<Button type="primary">
<PlusOutlined />
</Button>
}
form={form}
autoFocusFirstInput
layout="vertical"
drawerProps={{
destroyOnClose: true,
}}
onFinish={async (values) => {
try {
const { success, message: errMsg } =
await stockcontrollerCreatepurchaseorder(values);
if (!success) {
throw new Error(errMsg);
}
tableRef.current?.reload();
message.success('提交成功');
return true;
} catch (error: any) {
message.error(error.message);
}
}}
>
<ProFormSelect
request={async () => {
try {
const { data } = await stockcontrollerGetallstockpoints();
return (
data?.map((item) => {
return {
label: item.name,
value: item.id,
};
}) || []
);
} catch (error) {
return [];
}
}}
name="stockPointId"
label="仓库"
width="lg"
placeholder="请选择仓库"
rules={[{ required: true, message: '请选择仓库' }]}
/>
<ProFormSelect
name={'status'}
label="状态"
placeholder={'请选择状态'}
valueEnum={Purchase_Order_STATUS_ENUM}
width={'lg'}
rules={[{ required: true, message: '请选择状态' }]}
/>
<ProFormTextArea label="备注" name="note" width={'lg'} />
<ProFormDatePicker
name="expectedArrivalTime"
label="预计到货时间"
placeholder={'请选择预计到货时间'}
width={'lg'}
rules={[{ required: true, message: '请选择预计到货时间' }]}
/>
<ProFormDependency name={['items']}>
{({ items }) => {
return '数量:' + items?.reduce((acc, cur) => acc + cur.quantity, 0);
}}
</ProFormDependency>
<ProFormList<API.PurchaseOrderItem>
name="items"
label="产品"
rules={[
{
required: true,
message: '至少需要一个商品',
validator: (_, value) =>
value && value.length > 0
? Promise.resolve()
: Promise.reject('至少需要一个商品'),
},
]}
creatorButtonProps={{ children: '新增', size: 'large' }}
wrapperCol={{ span: 24 }}
>
{(fields, idx, { remove }) => (
<div key={idx}>
<ProFormSelect
request={async ({ keyWords }) => {
if (keyWords.length < 3) return [];
try {
const { data } = await productcontrollerSearchproducts({
name: keyWords,
});
return (
data?.map((item) => {
return {
label: item.name,
value: item.sku,
};
}) || []
);
} catch (error) {
return [];
}
}}
name="productSku"
label={'产品' + (idx + 1)}
width="lg"
placeholder="请选择产品"
tooltip="至少输入3个字符"
fieldProps={{
showSearch: true,
filterOption: false,
}}
transform={(value) => {
return value?.value || value;
}}
debounceTime={300} // 防抖减少请求频率
rules={[{ required: true, message: '请选择产品' }]}
onChange={(_, option) => {
form.setFieldValue(
['items', fields.key, 'productName'],
option.title,
);
}}
/>
<ProFormText name={'productName'} label="产品名称" hidden={true} />
<ProFormDigit
name="quantity"
label="数量"
placeholder="请输入数量"
rules={[{ required: true, message: '请输入数量' }]}
fieldProps={{
precision: 0,
}}
/>
<ProFormDigit
name="price"
label="价格"
placeholder="请输入价格"
rules={[{ required: true, message: '请输入价格' }]}
fieldProps={{
precision: 2,
}}
/>
<Button type="link" danger onClick={() => remove(fields.key)}>
</Button>
</div>
)}
</ProFormList>
</DrawerForm>
);
};
const UpdateForm: React.FC<{
tableRef: React.MutableRefObject<ActionType | undefined>;
values: API.UpdatePurchaseOrderDTO & {
id: number;
};
}> = ({ tableRef, values }) => {
const { message } = App.useApp();
const [form] = Form.useForm();
const initialValues = {
...values,
items: values?.items?.map((item: API.PurchaseOrderItem) => ({
...item,
productSku: {
label: item.productName,
value: item.productSku,
},
})),
};
return (
<DrawerForm<API.UpdatePurchaseOrderDTO>
title="编辑"
form={form}
initialValues={initialValues}
trigger={
<Button type="primary">
<EditOutlined />
</Button>
}
autoFocusFirstInput
drawerProps={{
destroyOnClose: true,
}}
onFinish={async (values) => {
try {
const { success, message: errMsg } =
await stockcontrollerUpdatepurchaseorder(
{ id: initialValues.id },
values,
);
if (!success) {
throw new Error(errMsg);
}
message.success('提交成功');
tableRef.current?.reload();
return true;
} catch (error: any) {
message.error(error.message);
}
}}
>
<ProForm.Group>
<ProFormSelect
request={async () => {
try {
const { data } = await stockcontrollerGetallstockpoints();
return (
data?.map((item) => {
return {
label: item.name,
value: item.id,
};
}) || []
);
} catch (error) {
return [];
}
}}
name="stockPointId"
label="仓库"
width="lg"
placeholder="请选择仓库"
rules={[{ required: true, message: '请选择仓库' }]}
/>
<ProFormSelect
name={'status'}
label="状态"
placeholder={'请选择状态'}
valueEnum={Purchase_Order_STATUS_ENUM}
width={'lg'}
rules={[{ required: true, message: '请选择状态' }]}
/>
<ProFormDatePicker
name="expectedArrivalTime"
label="预计到货时间"
placeholder={'请选择预计到货时间'}
width={'lg'}
rules={[{ required: true, message: '请选择预计到货时间' }]}
/>
<ProFormTextArea label="备注" name="note" width={'lg'} />
<ProFormDependency name={['items']}>
{({ items }) => {
return (
'数量:' + items?.reduce((acc, cur) => acc + cur.quantity, 0)
);
}}
</ProFormDependency>
<ProFormList<API.PurchaseOrderItem>
name="items"
rules={[
{
required: true,
message: '至少需要一个商品',
validator: (_, value) =>
value && value.length > 0
? Promise.resolve()
: Promise.reject('至少需要一个商品'),
},
]}
creatorButtonProps={{ children: '新增', size: 'large' }}
wrapperCol={{ span: 24 }}
>
{(fields, idx, { remove }) => (
<div key={idx}>
<ProFormSelect
request={async ({ keyWords }) => {
if (keyWords.length < 3) return [];
try {
const { data } = await productcontrollerSearchproducts({
name: keyWords,
});
return (
data?.map((item) => {
return {
label: item.name,
value: item.sku,
};
}) || []
);
} catch (error) {
return [];
}
}}
name="productSku"
label="产品"
width="lg"
placeholder="请选择产品"
tooltip="至少输入3个字符"
fieldProps={{
showSearch: true,
filterOption: false,
}}
transform={(value) => {
return value?.value || value;
}}
debounceTime={300} // 防抖减少请求频率
rules={[{ required: true, message: '请选择产品' }]}
onChange={(_, option) => {
form.setFieldValue(
['items', fields.key, 'productName'],
option?.title,
);
}}
/>
<ProFormText name="productName" label="产品名称" hidden={true} />
<ProFormDigit
name="quantity"
label="数量"
placeholder="请输入数量"
rules={[{ required: true, message: '请输入数量' }]}
fieldProps={{
precision: 0,
}}
/>
<ProFormDigit
name="price"
label="价格"
placeholder="请输入价格"
rules={[{ required: true, message: '请输入价格' }]}
fieldProps={{
precision: 2,
}}
/>
<Button type="link" danger onClick={() => remove(fields.key)}>
</Button>
</div>
)}
</ProFormList>
</ProForm.Group>
</DrawerForm>
);
};
const DetailForm: React.FC<{
tableRef: React.MutableRefObject<ActionType | undefined>;
values: API.UpdatePurchaseOrderDTO & {
id: number;
};
}> = ({ tableRef, values }) => {
const { message } = App.useApp();
const [form] = Form.useForm();
const initialValues = {
...values,
items: values?.items?.map((item: API.PurchaseOrderItem) => ({
...item,
productSku: {
label: item.productName,
value: item.productSku,
},
})),
};
return (
<DrawerForm<API.UpdatePurchaseOrderDTO>
title="详情"
form={form}
initialValues={initialValues}
trigger={<Button type="primary"></Button>}
autoFocusFirstInput
drawerProps={{
destroyOnClose: true,
}}
readonly={true}
layout="vertical"
>
<ProFormSelect
request={async () => {
try {
const { data } = await stockcontrollerGetallstockpoints();
return (
data?.map((item) => {
return {
label: item.name,
value: item.id,
};
}) || []
);
} catch (error) {
return [];
}
}}
name="stockPointId"
label="仓库"
width="lg"
placeholder="请选择仓库"
rules={[{ required: true, message: '请选择仓库' }]}
/>
<ProFormText
name="orderNumber"
label="订单编号"
placeholder="请输入订单编号"
width={'lg'}
rules={[{ required: true, message: '请输入订单编号' }]}
/>
<ProFormSelect
name={'status'}
label="状态"
placeholder={'请选择状态'}
valueEnum={Purchase_Order_STATUS_ENUM}
width={'lg'}
rules={[{ required: true, message: '请选择状态' }]}
/>
<ProFormDatePicker
name="expectedArrivalTime"
label="预计到货时间"
placeholder={'请选择预计到货时间'}
width={'lg'}
rules={[{ required: true, message: '请选择预计到货时间' }]}
/>
<ProFormTextArea label="备注" name="note" width={'lg'} />
<ProFormList<API.PurchaseOrderItem>
name="items"
rules={[
{
required: true,
message: '至少需要一个商品',
validator: (_, value) =>
value && value.length > 0
? Promise.resolve()
: Promise.reject('至少需要一个商品'),
},
]}
creatorButtonProps={{ children: '新增', size: 'large' }}
wrapperCol={{ span: 24 }}
>
{(fields, idx, { remove }) => (
<div key={idx}>
<ProForm.Group>
<ProFormSelect
request={async ({ keyWords }) => {
if (keyWords.length < 3) return [];
try {
const { data } = await productcontrollerSearchproducts({
name: keyWords,
});
return (
data?.map((item) => {
return {
label: item.name,
value: item.sku,
};
}) || []
);
} catch (error) {
return [];
}
}}
name="productSku"
label="产品"
width="lg"
placeholder="请选择产品"
tooltip="至少输入3个字符"
fieldProps={{
showSearch: true,
filterOption: false,
}}
transform={(value) => {
return value?.value || value;
}}
debounceTime={300} // 防抖减少请求频率
rules={[{ required: true, message: '请选择产品' }]}
onChange={(_, option) => {
form.setFieldValue(
['items', fields.key, 'productName'],
option?.title,
);
}}
/>
<ProFormText name="productName" label="产品名称" hidden={true} />
<ProFormDigit
name="quantity"
label="数量"
placeholder="请输入数量"
rules={[{ required: true, message: '请输入数量' }]}
fieldProps={{
precision: 0,
}}
/>
<ProFormDigit
name="price"
label="价格"
placeholder="请输入价格"
rules={[{ required: true, message: '请输入价格' }]}
fieldProps={{
precision: 2,
}}
/>
</ProForm.Group>
</div>
)}
</ProFormList>
</DrawerForm>
);
};
export default PurchaseOrderPage;