回筐逻辑修改

This commit is contained in:
liu
2026-08-14 23:47:49 +08:00
parent 4bdaf2a219
commit 7c3f6147ac
20 changed files with 325 additions and 342 deletions
+69 -85
View File
@@ -1,18 +1,40 @@
import React, { useEffect, useState } from 'react';
import { message, Tag, Typography } from 'antd';
import dayjs from 'dayjs';
import { Typography } from 'antd';
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;
/** 有符号数量展示:正数=压筐(橙色 +N),负数=回筐(绿色 N),0 置灰 */
const SignedNum: React.FC<{ value?: number }> = ({ value }) => {
const num = Number(value ?? 0);
if (num > 0) {
return <Text strong type="warning">+{num}</Text>;
}
if (num < 0) {
return <Text strong type="success">{num}</Text>;
}
return <Text type="secondary">0</Text>;
};
/** 有符号金额展示:正=压筐附加(橙),负=回筐抵扣(绿) */
const SignedAmount: React.FC<{ value?: string }> = ({ value }) => {
const num = Number(value ?? 0);
if (num > 0) {
return <Text strong type="warning">+¥{num.toFixed(2)}</Text>;
}
if (num < 0) {
return <Text strong type="success">-¥{Math.abs(num).toFixed(2)}</Text>;
}
return <Text type="secondary">¥0.00</Text>;
};
/**
* 回筐记录(压筐=生成账单时自动写入,只读;回筐=门店退回手动登记,删除后恢复门店待回数量
* 回筐记录(周转筐/托盘跟账单走:生成账单时自动写入完整快照,只读
* 数量正数=压筐(附加金额),负数=回筐(抵扣金额)
*/
const ContainerReturnPage: React.FC = () => {
const [stores, setStores] = useState<IStore[]>([]);
@@ -26,7 +48,7 @@ const ContainerReturnPage: React.FC = () => {
title: '门店',
dataIndex: 'store_id',
valueType: 'select',
rules: [{ required: true, message: '请选择门店' }],
hideInForm: true,
fieldProps: {
options: stores.map((s) => ({ label: s.name, value: s.id })),
showSearch: true,
@@ -34,81 +56,57 @@ const ContainerReturnPage: React.FC = () => {
},
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> : '-',
render: (_, record) => record.bill ? (
<>
<Text copyable={{ text: record.bill.bill_no }}>{record.bill.bill_no}</Text>
<div className={'text-[12px] text-[#999]'}>{record.bill.bill_date}</div>
</>
) : '-',
},
{
title: '周转筐数量',
title: '压(回)筐数量',
dataIndex: 'box_num',
valueType: 'digit',
hideInForm: true,
hideInSearch: true,
initialValue: 0,
rules: [{ required: true, message: '请输入周转筐数量' }],
fieldProps: { min: 0, precision: 0 },
align: 'center',
render: (_, record) => <Text strong>{record.box_num}</Text>,
render: (_, record) => <SignedNum value={record.box_num} />,
},
{
title: '周转托盘数量',
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}`
: '-',
render: (_, record) => <SignedNum value={record.tray_num} />,
},
{
title: '退回日期',
dataIndex: 'return_date',
valueType: 'dateRange',
hideInTable: true,
title: '筐单价',
dataIndex: 'box_price',
hideInForm: true,
hideInSearch: true,
align: 'center',
render: (_, record) => `¥${Number(record.box_price ?? 0).toFixed(2)}`,
},
{
title: '退回日期',
dataIndex: 'return_date',
valueType: 'date',
title: '托盘单价',
dataIndex: 'tray_price',
hideInForm: true,
hideInSearch: true,
initialValue: dayjs(),
rules: [{ required: true, message: '请选择退回日期' }],
align: 'center',
render: (_, record) => `¥${Number(record.tray_price ?? 0).toFixed(2)}`,
},
{
title: '抵扣(附加)金额',
dataIndex: 'amount',
hideInForm: true,
hideInSearch: true,
align: 'center',
render: (_, record) => <SignedAmount value={record.amount} />,
},
{
title: '操作人',
@@ -119,20 +117,20 @@ const ContainerReturnPage: React.FC = () => {
render: (_, record) => record.operator?.nickname ?? '-',
},
{
title: '记时间',
title: '记时间',
dataIndex: 'created_at',
valueType: 'dateRange',
hideInForm: true,
hideInTable: true,
align: 'center',
},
{
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> = {
@@ -140,25 +138,11 @@ const ContainerReturnPage: React.FC = () => {
columns,
rowKey: 'id',
accessName: 'recon.containerReturn',
// 压筐记录账单生成,仅回筐记录可删除;均不允许编辑
// 记录账单生成,只读:不新增、不编辑、不删除
addShow: false,
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: '回筐登记' },
deleteShow: false,
formProps: false,
};
return (
@@ -166,7 +150,7 @@ const ContainerReturnPage: React.FC = () => {
<div className="mb-5">
<Title level={3}></Title>
<Text type="secondary">
退/
/== 0
</Text>
</div>
<XinTable<IContainerReturn> {...tableProps} />