178 lines
5.3 KiB
TypeScript
178 lines
5.3 KiB
TypeScript
import React, { useEffect, useState } from 'react';
|
|
import { message, Tag, Typography } from 'antd';
|
|
import dayjs from 'dayjs';
|
|
import XinTable from '@/components/XinTable';
|
|
import type { XinTableColumn, XinTableProps } from '@/components/XinTable/typings.ts';
|
|
import type IContainerReturn from '@/domain/iContainerReturn.ts';
|
|
import { CONTAINER_TYPE_MAP } from '@/domain/iContainerReturn.ts';
|
|
import { getStoreOptions } from '@/api/customer/store.ts';
|
|
import { Create } from '@/api/common/table.ts';
|
|
import type IStore from '@/domain/iStore.ts';
|
|
|
|
const { Title, Text } = Typography;
|
|
|
|
/**
|
|
* 回筐记录(压筐=生成账单时自动写入,只读;回筐=门店退回手动登记,删除后恢复门店待回数量)
|
|
*/
|
|
const ContainerReturnPage: React.FC = () => {
|
|
const [stores, setStores] = useState<IStore[]>([]);
|
|
|
|
useEffect(() => {
|
|
getStoreOptions().then((res) => setStores(res.data.data ?? []));
|
|
}, []);
|
|
|
|
const columns: XinTableColumn<IContainerReturn>[] = [
|
|
{
|
|
title: '门店',
|
|
dataIndex: 'store_id',
|
|
valueType: 'select',
|
|
rules: [{ required: true, message: '请选择门店' }],
|
|
fieldProps: {
|
|
options: stores.map((s) => ({ label: s.name, value: s.id })),
|
|
showSearch: true,
|
|
optionFilterProp: 'label',
|
|
},
|
|
render: (_, record) => record.store?.name ?? `门店#${record.store_id}`,
|
|
},
|
|
{
|
|
title: '类型',
|
|
dataIndex: 'type',
|
|
valueType: 'select',
|
|
hideInForm: true,
|
|
align: 'center',
|
|
fieldProps: {
|
|
options: Object.entries(CONTAINER_TYPE_MAP).map(([value, item]) => ({
|
|
value: Number(value),
|
|
label: item.text,
|
|
})),
|
|
},
|
|
render: (_, record) => {
|
|
const item = CONTAINER_TYPE_MAP[record.type ?? 0];
|
|
return <Tag color={item?.color}>{item?.text ?? '-'}</Tag>;
|
|
},
|
|
},
|
|
{
|
|
title: '关联账单',
|
|
dataIndex: 'bill_id',
|
|
hideInForm: true,
|
|
hideInSearch: true,
|
|
align: 'center',
|
|
render: (_, record) =>
|
|
record.bill ? <Text copyable={{ text: record.bill.bill_no }}>{record.bill.bill_no}</Text> : '-',
|
|
},
|
|
{
|
|
title: '周转筐数量',
|
|
dataIndex: 'box_num',
|
|
valueType: 'digit',
|
|
hideInSearch: true,
|
|
initialValue: 0,
|
|
rules: [{ required: true, message: '请输入周转筐数量' }],
|
|
fieldProps: { min: 0, precision: 0 },
|
|
align: 'center',
|
|
render: (_, record) => <Text strong>{record.box_num}</Text>,
|
|
},
|
|
{
|
|
title: '周转托盘数量',
|
|
dataIndex: 'tray_num',
|
|
valueType: 'digit',
|
|
hideInSearch: true,
|
|
initialValue: 0,
|
|
rules: [{ required: true, message: '请输入周转托盘数量' }],
|
|
fieldProps: { min: 0, precision: 0 },
|
|
align: 'center',
|
|
render: (_, record) => <Text strong>{record.tray_num}</Text>,
|
|
},
|
|
{
|
|
title: '当前待回(筐/托盘)',
|
|
key: 'pending',
|
|
hideInForm: true,
|
|
hideInSearch: true,
|
|
align: 'center',
|
|
render: (_, record) =>
|
|
record.store
|
|
? `${record.store.pending_box_num ?? 0} / ${record.store.pending_tray_num ?? 0}`
|
|
: '-',
|
|
},
|
|
{
|
|
title: '退回日期',
|
|
dataIndex: 'return_date',
|
|
valueType: 'dateRange',
|
|
hideInTable: true,
|
|
hideInForm: true,
|
|
align: 'center',
|
|
},
|
|
{
|
|
title: '退回日期',
|
|
dataIndex: 'return_date',
|
|
valueType: 'date',
|
|
hideInSearch: true,
|
|
initialValue: dayjs(),
|
|
rules: [{ required: true, message: '请选择退回日期' }],
|
|
align: 'center',
|
|
},
|
|
{
|
|
title: '操作人',
|
|
dataIndex: 'operator',
|
|
hideInForm: true,
|
|
hideInSearch: true,
|
|
align: 'center',
|
|
render: (_, record) => record.operator?.nickname ?? '-',
|
|
},
|
|
{
|
|
title: '登记时间',
|
|
dataIndex: 'created_at',
|
|
hideInForm: true,
|
|
hideInSearch: true,
|
|
align: 'center',
|
|
},
|
|
{
|
|
title: '备注',
|
|
dataIndex: 'remark',
|
|
valueType: 'textarea',
|
|
hideInSearch: true,
|
|
fieldProps: { rows: 2 },
|
|
render: (v) => v || '-',
|
|
},
|
|
];
|
|
|
|
const tableProps: XinTableProps<IContainerReturn> = {
|
|
api: '/recon/container-return',
|
|
columns,
|
|
rowKey: 'id',
|
|
accessName: 'recon.containerReturn',
|
|
// 压筐记录由账单生成,仅回筐记录可删除;均不允许编辑
|
|
editShow: false,
|
|
deleteShow: (record) => record.type === 2,
|
|
// 自定义提交:DatePicker 值为 dayjs 对象,格式化为 Y-m-d 后再提交
|
|
handleFinish: async (values) => {
|
|
await Create('/recon/container-return', {
|
|
...values,
|
|
return_date: dayjs(values.return_date).format('YYYY-MM-DD'),
|
|
});
|
|
message.success('回筐已登记');
|
|
return true;
|
|
},
|
|
formProps: {
|
|
grid: true,
|
|
colProps: { span: 12 },
|
|
rowProps: { gutter: 20 },
|
|
layout: 'vertical',
|
|
},
|
|
modalProps: { width: 640, title: '回筐登记' },
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<div className="mb-5">
|
|
<Title level={3}>回筐记录</Title>
|
|
<Text type="secondary">
|
|
生成账单时自动写入「压筐」记录并累加门店待回数量;门店退回周转筐/托盘时手动新增「回筐」登记并扣减待回,删除登记将恢复待回数量。
|
|
</Text>
|
|
</div>
|
|
<XinTable<IContainerReturn> {...tableProps} />
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default ContainerReturnPage;
|