ERPTurbo_Admin/packages/app-operation/src/components/Order/PurchaseOrderModal.tsx
shenyifei 3e24b86326 feat(order): 新增采购单相关组件及功能
- 新增 PurchaseOrderFormItem、PurchaseOrderModal 等采购单表单项组件
- 在 OrderCostList 和 OrderSupplierList 中集成采购单选择功能
- 新增 OrderRebateList 返利列表组件
- 实现采购单数据的展示与选择逻辑
- 添加采购单相关的搜索和筛选字段
- 支持采购单详情查看及关联数据显示
- 优化订单成本列表的创建表单结构
- 增加表格行选择和批量操作功能
- 完善采购单状态标签显示及样式处理
2025-12-19 17:30:08 +08:00

355 lines
9.2 KiB
TypeScript

import { business } from '@/services';
import { formatParam } from '@/utils/formatParam';
import { pagination } from '@/utils/pagination';
import { useIntl } from '@@/exports';
import {
ActionType,
LightFilter,
ProColumns,
ProFormSelect,
} from '@ant-design/pro-components';
import { SelectModal } from '@chageable/components';
import { Alert, ModalProps, Row, Space, Tag } from 'antd';
import React, { useEffect, useRef, useState } from 'react';
export interface IPurchaseOrderModalProps extends ModalProps {
title: string;
selectedList?: BusinessAPI.PurchaseOrderVO[];
onFinish: (purchaseOrderVOList: BusinessAPI.PurchaseOrderVO[]) => void;
type: 'checkbox' | 'radio' | undefined;
params?: BusinessAPI.DealerPageQry;
num?: number;
tips?: string;
extraFilter?: React.ReactNode[];
extraColumns?: ProColumns<BusinessAPI.PurchaseOrderVO>[];
}
export default function PurchaseOrderModal(props: IPurchaseOrderModalProps) {
const {
title,
onFinish,
type,
selectedList,
params: initParams,
num = 10,
tips,
extraFilter = [],
extraColumns: initExtraColumns = [],
...rest
} = props;
const actionRef = useRef<ActionType>();
const sessionKey = `purchaseOrderList`;
const intl = useIntl();
const intlPrefix = 'purchaseOrder';
const [params, setParams] = useState<BusinessAPI.DealerPageQry>(
initParams || {},
);
useEffect(() => {
if (initParams) {
setParams({
...params,
...initParams,
});
}
}, [initParams]);
const columns: ProColumns<BusinessAPI.PurchaseOrderVO>[] = [
{
title: intl.formatMessage({ id: intlPrefix + '.column.orderSn' }),
dataIndex: 'orderSn',
key: 'orderSn',
renderText: (text: string) => <span className="font-medium">{text}</span>,
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.origin' }),
dataIndex: ['orderVehicle', 'origin'],
search: false,
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.destination' }),
dataIndex: ['orderVehicle', 'destination'],
search: false,
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.dealerName' }),
dataIndex: ['orderVehicle', 'dealerName'],
key: 'dealerName',
search: false,
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.vehicleNo' }),
dataIndex: ['orderVehicle', 'vehicleNo'],
key: 'vehicleNo',
search: false,
render: (_, record) => {
return record.orderVehicle?.vehicleNo
? '第' + record.orderVehicle?.vehicleNo + '车'
: '-';
},
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.plate' }),
dataIndex: ['orderVehicle', 'plate'],
key: 'plate',
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.driver' }),
dataIndex: ['orderVehicle', 'driver'],
key: 'driver',
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.phone' }),
dataIndex: ['orderVehicle', 'phone'],
key: 'phone',
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.state' }),
dataIndex: 'state',
key: 'state',
valueType: 'select',
render: (_, record) => {
const stateText = intl.formatMessage({
id: `${intlPrefix}.column.state.${record.state?.toLowerCase() || 'unknown'}`,
});
let color = 'default';
switch (record.state) {
case 'DRAFT':
color = 'default';
break;
case 'WAITING_AUDIT':
color = 'processing';
break;
case 'COMPLETED':
color = 'success';
break;
case 'REJECTED':
color = 'error';
break;
default:
color = 'default';
}
return <Tag color={color}>{stateText}</Tag>;
},
},
...(initExtraColumns || []),
];
function setDealerVOStorage(purchaseOrderVO: BusinessAPI.PurchaseOrderVO) {
const localPurchaseOrderList = localStorage.getItem(sessionKey);
const purchaseOrderList = localPurchaseOrderList
? JSON.parse(localPurchaseOrderList)
: [];
purchaseOrderList.forEach(
(item: BusinessAPI.PurchaseOrderVO, index: number) => {
if (item.orderId === purchaseOrderVO.orderId) {
purchaseOrderList.splice(index, 1);
}
},
);
if (purchaseOrderList.length < 5) {
purchaseOrderList.unshift(purchaseOrderVO);
localStorage.setItem(sessionKey, JSON.stringify(purchaseOrderList));
} else {
purchaseOrderList.pop();
purchaseOrderList.unshift(purchaseOrderVO);
localStorage.setItem(sessionKey, JSON.stringify(purchaseOrderList));
}
}
return (
<SelectModal<BusinessAPI.PurchaseOrderVO, BusinessAPI.PurchaseOrderPageQry>
rowKey={'orderId'}
modalProps={{
title: title || '选择采购单',
...rest,
destroyOnHidden: true,
afterOpenChange: (open) => {
if (!open) {
setParams({
...initParams,
});
}
},
}}
selectedList={selectedList}
tableProps={{
rowKey: 'orderId',
columns: columns,
columnsState: {
persistenceType: 'sessionStorage',
persistenceKey: 'purchaseOrderModalColumnStateKey',
},
params: {
...params,
},
request: async (params, sorter, filter) => {
const { data, success, totalCount } =
await business.purchaseOrder.pagePurchaseOrder({
purchaseOrderPageQry: formatParam<typeof params>(
params,
sorter,
filter,
),
});
return {
data: data || [],
total: totalCount,
success,
};
},
pagination: {
...pagination(),
position: ['bottomRight'],
},
tableAlertRender: ({ selectedRowKeys, selectedRows }) => {
// selectedRows 和 selectedList 组合在一起,去重,
const selectedRowsMap = new Map<
string,
BusinessAPI.PurchaseOrderVO
>();
selectedRows.forEach((item: BusinessAPI.PurchaseOrderVO) => {
if (item) {
if (!selectedRowsMap.has(item.orderId)) {
selectedRowsMap.set(item.orderId, item);
}
}
});
selectedList?.forEach((item: BusinessAPI.PurchaseOrderVO) => {
if (!selectedRowsMap.has(item.orderId)) {
selectedRowsMap.set(item.orderId, item);
}
});
let selectedTempList: BusinessAPI.PurchaseOrderVO[] = [];
selectedRowsMap.forEach((item: BusinessAPI.PurchaseOrderVO) => {
if (selectedRowKeys.includes(item.orderId)) {
selectedTempList.push(item);
}
});
return (
<Space size={12}>
<span> {selectedRowKeys.length} </span>
<Space wrap={true}>
{selectedTempList?.map((item: BusinessAPI.PurchaseOrderVO) => {
return item && <span key={item.orderId}>{item.orderSn}</span>;
})}
</Space>
</Space>
);
},
...(tips && {
tableExtraRender: () => {
return tips && <Alert type={'info'} message={tips} />;
},
}),
...(type === 'radio' && {
tableExtraRender: () => {
const localDealerList = localStorage.getItem(sessionKey);
if (localDealerList) {
const dealerList = JSON.parse(localDealerList);
return (
<>
{tips && <Alert type={'info'} message={tips} />}
<Row gutter={16}>
{dealerList.map((item: BusinessAPI.PurchaseOrderVO) => {
return (
<Tag
style={{
cursor: 'pointer',
}}
onClick={async () => {
const { data: purchaseOrderVO } =
await business.purchaseOrder.showPurchaseOrder({
purchaseOrderShowQry: {
orderId: item.orderId,
},
});
if (purchaseOrderVO) {
onFinish([purchaseOrderVO]);
setDealerVOStorage(purchaseOrderVO);
}
}}
key={item.orderId}
>
{item.orderSn}
</Tag>
);
})}
</Row>
</>
);
}
},
}),
actionRef: actionRef,
toolbar: {
filter: (
<LightFilter
onFinish={async (values) => {
setParams({
...initParams,
...values,
});
}}
>
{extraFilter}
<ProFormSelect
label={'采购单状态'}
name={'state'}
placeholder={'请选择采购单状态'}
valueEnum={{
DRAFT: intl.formatMessage({
id: intlPrefix + '.column.state.draft',
}),
WAITING_AUDIT: intl.formatMessage({
id: intlPrefix + '.column.state.waiting_audit',
}),
COMPLETED: intl.formatMessage({
id: intlPrefix + '.column.state.completed',
}),
REJECTED: intl.formatMessage({
id: intlPrefix + '.column.state.rejected',
}),
CLOSED: intl.formatMessage({
id: intlPrefix + '.column.state.closed',
}),
}}
fieldProps={{
showSearch: true,
allowClear: true,
autoClearSearchValue: true,
}}
/>
</LightFilter>
),
search: {
placeholder: '请输入采购单编号',
onSearch: async (value: string) => {
setParams({
...params,
//@ts-ignore
orderSn: value,
});
},
},
},
}}
onFinish={(dealerVOList) => {
if (type === 'radio') {
if (dealerVOList.length > 0) {
setDealerVOStorage(dealerVOList[0]);
}
}
onFinish(dealerVOList);
}}
num={num}
type={type}
/>
);
}