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

689 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 { productcontrollerSearchproducts } from '@/servers/api/product';
import {
stockcontrollerCanceltransfer,
stockcontrollerCreatetransfer,
stockcontrollerGetallstockpoints,
stockcontrollerGettransfers,
stockcontrollerLosttransfer,
stockcontrollerReceivetransfer,
stockcontrollerUpdatetransfer,
} 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 TransferPage: React.FC = () => {
const { message } = App.useApp();
const actionRef = useRef<ActionType>();
const columns: ProColumns[] = [
{
title: '订单编号',
dataIndex: 'orderNumber',
},
{
title: '源仓库',
dataIndex: 'sourceStockPointName',
hideInSearch: true,
},
{
title: '目标仓库',
dataIndex: 'destStockPointName',
hideInSearch: true,
},
{
title: '状态',
dataIndex: 'status',
hideInSearch: true,
render(_, record) {
if (record.isLost) return '已丢失';
if (record.isCancel) return '已取消';
if (record.isArrived) return '已到达';
return '运输中';
},
},
{
title: '数量',
hideInSearch: true,
render(_, record) {
return record.items.reduce((cur, next) => {
return cur + next.quantity;
}, 0);
},
},
{
title: '备注',
dataIndex: 'note',
hideInSearch: true,
},
{
title: '到货时间',
dataIndex: 'arriveAt',
valueType: 'dateTime',
hideInSearch: true,
},
{
title: '发货时间',
dataIndex: 'sendAt',
valueType: 'dateTime',
hideInSearch: true,
},
{
title: '操作',
dataIndex: 'option',
valueType: 'option',
render: (_, record) => (
<>
{!record.isCancel && !record.isArrived && !record.isLost ? (
<>
<UpdateForm tableRef={actionRef} values={record} />
<Divider type="vertical" />
<Popconfirm
title="入库"
description="确认已到达?"
onConfirm={async () => {
try {
const { success, message: errMsg } =
await stockcontrollerReceivetransfer({
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>
<Divider type="vertical" />
<Popconfirm
title="丢失"
description="确认该批货已丢失?"
onConfirm={async () => {
try {
const { success, message: errMsg } =
await stockcontrollerLosttransfer({
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>
<Divider type="vertical" />
<Popconfirm
title="取消"
description="确认取消?"
onConfirm={async () => {
try {
const { success, message: errMsg } =
await stockcontrollerCanceltransfer({
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>
</>
) : (
<DetailForm tableRef={actionRef} values={record} />
)}
</>
),
},
];
return (
<PageContainer ghost>
<ProTable
headerTitle="查询表格"
actionRef={actionRef}
rowKey="id"
request={async (params) => {
const { data, success } = await stockcontrollerGettransfers(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
title="新建"
trigger={
<Button type="primary">
<PlusOutlined />
</Button>
}
form={form}
autoFocusFirstInput
layout="vertical"
drawerProps={{
destroyOnClose: true,
}}
onFinish={async (values) => {
try {
console.log(values);
const { success, message: errMsg } =
await stockcontrollerCreatetransfer(values);
if (!success) {
throw new Error(errMsg);
}
tableRef.current?.reload();
message.success('提交成功');
return true;
} catch (error: any) {
message.error(error.message);
}
}}
>
<ProFormDatePicker
name="sendAt"
label="发货时间"
rules={[{ required: true, message: '请选择发货时间' }]}
/>
<ProFormSelect
request={async () => {
try {
const { data } = await stockcontrollerGetallstockpoints();
return (
data?.map((item) => {
return {
label: item.name,
value: item.id,
};
}) || []
);
} catch (error) {
return [];
}
}}
name="sourceStockPointId"
label="源仓库"
width="lg"
placeholder="请选择仓库"
rules={[{ required: true, message: '请选择源仓库' }]}
/>
<ProFormSelect
request={async () => {
try {
const { data } = await stockcontrollerGetallstockpoints();
return (
data?.map((item) => {
return {
label: item.name,
value: item.id,
};
}) || []
);
} catch (error) {
return [];
}
}}
name="destStockPointId"
label="目标仓库"
width="lg"
placeholder="请选择仓库"
rules={[{ required: true, message: '请选择源目标仓库' }]}
/>
<ProFormTextArea name="note" label="备注" />
<ProFormDependency name={['items']}>
{({ items }) => {
return '数量:' + items?.reduce((acc, cur) => acc + cur.quantity, 0);
}}
</ProFormDependency>
<ProFormList
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,
}}
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,
}}
/>
</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 stockcontrollerUpdatetransfer(
{ id: initialValues.id },
values,
);
if (!success) {
throw new Error(errMsg);
}
message.success('提交成功');
tableRef.current?.reload();
return true;
} catch (error: any) {
message.error(error.message);
}
}}
>
<ProFormSelect
readonly
request={async () => {
try {
const { data } = await stockcontrollerGetallstockpoints();
return (
data?.map((item) => {
return {
label: item.name,
value: item.id,
};
}) || []
);
} catch (error) {
return [];
}
}}
name="sourceStockPointId"
label="源仓库"
width="lg"
placeholder="请选择仓库"
rules={[{ required: true, message: '请选择源仓库' }]}
/>
<ProFormSelect
request={async () => {
try {
const { data } = await stockcontrollerGetallstockpoints();
return (
data?.map((item) => {
return {
label: item.name,
value: item.id,
};
}) || []
);
} catch (error) {
return [];
}
}}
name="destStockPointId"
label="目标仓库"
width="lg"
placeholder="请选择仓库"
rules={[{ required: true, message: '请选择源目标仓库' }]}
/>
<ProFormTextArea name="note" label="备注" />
<ProFormDependency name={['items']}>
{({ items }) => {
return '数量:' + items?.reduce((acc, cur) => acc + cur.quantity, 0);
}}
</ProFormDependency>
<ProFormList
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,
}}
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,
}}
/>
</div>
)}
</ProFormList>
</DrawerForm>
);
};
const DetailForm: React.FC<{
tableRef: React.MutableRefObject<ActionType | undefined>;
values: Record<string, any>;
}> = ({ tableRef, values }) => {
const { message } = App.useApp();
const [form] = Form.useForm();
const initialValues = {
...values,
items: values?.items?.map(
(item: { productName: string; productSku: string }) => ({
...item,
productSku: {
label: item.productName,
value: item.productSku,
},
}),
),
};
return (
<DrawerForm
title="详情"
form={form}
initialValues={initialValues}
trigger={<Button type="primary"></Button>}
autoFocusFirstInput
drawerProps={{
destroyOnClose: true,
}}
readonly={true}
layout="vertical"
>
<ProFormText
name="orderNumber"
label="订单编号"
placeholder="请输入订单编号"
width={'lg'}
rules={[{ required: true, message: '请输入订单编号' }]}
/>
<ProFormSelect
request={async () => {
try {
const { data } = await stockcontrollerGetallstockpoints();
return (
data?.map((item) => {
return {
label: item.name,
value: item.id,
};
}) || []
);
} catch (error) {
return [];
}
}}
name="sourceStockPointId"
label="源仓库"
width="lg"
placeholder="请选择仓库"
rules={[{ required: true, message: '请选择源仓库' }]}
/>
<ProFormSelect
request={async () => {
try {
const { data } = await stockcontrollerGetallstockpoints();
return (
data?.map((item) => {
return {
label: item.name,
value: item.id,
};
}) || []
);
} catch (error) {
return [];
}
}}
name="destStockPointId"
label="目标仓库"
width="lg"
placeholder="请选择仓库"
rules={[{ required: true, message: '请选择源目标仓库' }]}
/>
<ProFormTextArea name="note" label="备注" />
<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,
}}
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,
}}
/>
</ProForm.Group>
</div>
)}
</ProFormList>
</DrawerForm>
);
};
export default TransferPage;