ERPTurbo_Admin/packages/app-operation/src/components/Reconciliation/ReconciliationInvoiceModal.tsx
shenyifei f5feec84e3 feat(biz): 添加供应商发票功能并优化表格组件
- 在BizProvider中新增supplierInvoice类型支持
- 添加SupplierInvoiceList组件用于显示供应商发票信息
- 为经销商显示添加市场/超市标识区分
- 更新公司支付账户模态框类型定义以支持业务值类型
- 优化订单成本列表中的公司字段显示方式
- 在订单供应商列表中新增发票上传状态显示
- 为订单供应商模态框添加开票状态逻辑处理
- 更新多个模态框的列配置以支持业务值类型
- 调整选择模态框布局大小和分页配置
- 移除支付记录列表的编辑删除功能
- 优化订单供应商选择列表的发票相关字段显示
2026-01-14 11:45:56 +08:00

333 lines
8.6 KiB
TypeScript

import { BizValueType, SelectModal } from '@/components';
import { business } from '@/services';
import { formatCurrency } from '@/utils/format';
import { formatParam } from '@/utils/formatParam';
import { useIntl } from '@@/exports';
import {
ActionType,
LightFilter,
ProColumns,
} from '@ant-design/pro-components';
import { Alert, ModalProps, Row, Space, Tag } from 'antd';
import React, { useEffect, useRef, useState } from 'react';
export interface IReconciliationInvoiceModalProps extends ModalProps {
title: string;
selectedList?: BusinessAPI.ReconciliationInvoiceVO[];
onFinish: (
reconciliationInvoiceVOList: BusinessAPI.ReconciliationInvoiceVO[],
) => void;
type: 'checkbox' | 'radio' | undefined;
params?: BusinessAPI.ReconciliationInvoicePageQry;
num?: number;
tips?: string;
extraFilter?: React.ReactNode[];
extraColumns?: ProColumns<
BusinessAPI.ReconciliationInvoiceVO,
BizValueType
>[];
}
export default function ReconciliationInvoiceModal(
props: IReconciliationInvoiceModalProps,
) {
const {
title,
onFinish,
type,
selectedList,
params: initParams,
num = 10,
tips,
extraFilter = [],
extraColumns: initExtraColumns = [],
...rest
} = props;
const actionRef = useRef<ActionType>();
const sessionKey = `reconciliationInvoiceList`;
const [params, setParams] =
useState<BusinessAPI.ReconciliationInvoicePageQry>(initParams || {});
useEffect(() => {
if (initParams) {
setParams({
...params,
...initParams,
});
}
}, [initParams]);
const intl = useIntl();
const intlPrefix = 'reconciliationInvoice';
const columns: ProColumns<
BusinessAPI.ReconciliationInvoiceVO,
BizValueType
>[] = [
{
title: intl.formatMessage({
id: intlPrefix + '.column.invoiceSn',
}),
dataIndex: 'invoiceSn',
key: 'invoiceSn',
renderText: (text: string) => <span className="font-medium">{text}</span>,
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.dealer' }),
dataIndex: 'dealerVO',
key: 'dealerId',
search: false,
render: (_, record) =>
record.dealerVO?.shortName || record.dealerVO?.fullName,
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.company' }),
dataIndex: 'companyVO',
key: 'companyId',
search: false,
render: (_, record) =>
record.companyVO?.shortName || record.companyVO?.fullName,
},
{
title: intl.formatMessage({
id: intlPrefix + '.column.invoiceAmount',
}),
dataIndex: 'invoiceAmount',
key: 'invoiceAmount',
valueType: 'money',
search: false,
render: (_, record) => (
<span className="text-green-600 font-medium">
{formatCurrency(record.invoiceAmount)}
</span>
),
},
{
title: intl.formatMessage({ id: intlPrefix + '.column.invoiceDate' }),
dataIndex: 'invoiceDate',
key: 'invoiceDate',
valueType: 'dateTime',
search: false,
},
...(initExtraColumns || []),
];
function setReconciliationInvoiceVOStorage(
reconciliationInvoiceVO: BusinessAPI.ReconciliationInvoiceVO,
) {
const localReconciliationInvoiceList = localStorage.getItem(sessionKey);
const reconciliationInvoiceList = localReconciliationInvoiceList
? JSON.parse(localReconciliationInvoiceList)
: [];
reconciliationInvoiceList.forEach(
(item: BusinessAPI.ReconciliationInvoiceVO, index: number) => {
if (
item.reconciliationInvoiceId ===
reconciliationInvoiceVO.reconciliationInvoiceId
) {
reconciliationInvoiceList.splice(index, 1);
}
},
);
if (reconciliationInvoiceList.length < 5) {
reconciliationInvoiceList.unshift(reconciliationInvoiceVO);
localStorage.setItem(
sessionKey,
JSON.stringify(reconciliationInvoiceList),
);
} else {
reconciliationInvoiceList.pop();
reconciliationInvoiceList.unshift(reconciliationInvoiceVO);
localStorage.setItem(
sessionKey,
JSON.stringify(reconciliationInvoiceList),
);
}
}
return (
<SelectModal<
BusinessAPI.ReconciliationInvoiceVO,
BusinessAPI.ReconciliationInvoicePageQry
>
rowKey={'reconciliationInvoiceId'}
modalProps={{
title: title || '选择对账开票',
...rest,
destroyOnHidden: true,
afterOpenChange: (open) => {
if (!open) {
setParams({
...initParams,
});
}
},
}}
selectedList={selectedList}
tableProps={{
rowKey: 'reconciliationInvoiceId',
columns: columns,
columnsState: {
persistenceType: 'sessionStorage',
persistenceKey: 'reconciliationInvoiceModalColumnStateKey',
},
params: {
...params,
},
request: async (params, sorter, filter) => {
const { data, success, totalCount } =
await business.reconciliationInvoice.pageReconciliationInvoice({
reconciliationInvoicePageQry: formatParam<typeof params>(
params,
sorter,
filter,
),
});
return {
data: data || [],
total: totalCount,
success,
};
},
tableAlertRender: ({ selectedRowKeys, selectedRows }) => {
// selectedRows 和 selectedList 组合在一起,去重
const selectedRowsMap = new Map<
string,
BusinessAPI.ReconciliationInvoiceVO
>();
selectedRows.forEach((item: BusinessAPI.ReconciliationInvoiceVO) => {
if (item) {
if (!selectedRowsMap.has(item.reconciliationInvoiceId)) {
selectedRowsMap.set(item.reconciliationInvoiceId, item);
}
}
});
selectedList?.forEach((item: BusinessAPI.ReconciliationInvoiceVO) => {
if (!selectedRowsMap.has(item.reconciliationInvoiceId)) {
selectedRowsMap.set(item.reconciliationInvoiceId, item);
}
});
let selectedTempList: BusinessAPI.ReconciliationInvoiceVO[] = [];
selectedRowsMap.forEach(
(item: BusinessAPI.ReconciliationInvoiceVO) => {
if (selectedRowKeys.includes(item.reconciliationInvoiceId)) {
selectedTempList.push(item);
}
},
);
return (
<Space size={12}>
<span> {selectedRowKeys.length} </span>
<Space wrap={true}>
{selectedTempList?.map(
(item: BusinessAPI.ReconciliationInvoiceVO) => {
return (
item && (
<span key={item.reconciliationInvoiceId}>
{item.invoiceSn}
</span>
)
);
},
)}
</Space>
</Space>
);
},
...(tips && {
tableExtraRender: () => {
return tips && <Alert type={'info'} message={tips} />;
},
}),
...(type === 'radio' && {
tableExtraRender: () => {
const localReconciliationInvoiceList =
localStorage.getItem(sessionKey);
if (localReconciliationInvoiceList) {
const reconciliationInvoiceList = JSON.parse(
localReconciliationInvoiceList,
);
return (
<>
{tips && <Alert type={'info'} message={tips} />}
<Row gutter={16}>
{reconciliationInvoiceList.map(
(item: BusinessAPI.ReconciliationInvoiceVO) => {
return (
<Tag
style={{
cursor: 'pointer',
}}
onClick={async () => {
const { data: reconciliationInvoiceVO } =
await business.reconciliationInvoice.showReconciliationInvoice(
{
reconciliationInvoiceShowQry: {
reconciliationInvoiceId:
item.reconciliationInvoiceId,
},
},
);
if (reconciliationInvoiceVO) {
onFinish([reconciliationInvoiceVO]);
setReconciliationInvoiceVOStorage(
reconciliationInvoiceVO,
);
}
}}
key={item.reconciliationInvoiceId}
>
{item.invoiceSn}
</Tag>
);
},
)}
</Row>
</>
);
}
},
}),
actionRef: actionRef,
toolbar: {
actions: [],
filter: (
<LightFilter
onFinish={async (values) => {
setParams({
...initParams,
...values,
});
}}
>
{extraFilter}
</LightFilter>
),
search: {
placeholder: '请输入发票编码',
onSearch: async (value: string) => {
setParams({
...params,
invoiceSn: value,
});
},
},
},
}}
onFinish={(reconciliationInvoiceVOList) => {
if (type === 'radio') {
if (reconciliationInvoiceVOList.length > 0) {
setReconciliationInvoiceVOStorage(reconciliationInvoiceVOList[0]);
}
}
onFinish(reconciliationInvoiceVOList);
}}
num={num}
type={type}
/>
);
}