- 在BizProvider中新增supplierInvoice类型支持 - 添加SupplierInvoiceList组件用于显示供应商发票信息 - 为经销商显示添加市场/超市标识区分 - 更新公司支付账户模态框类型定义以支持业务值类型 - 优化订单成本列表中的公司字段显示方式 - 在订单供应商列表中新增发票上传状态显示 - 为订单供应商模态框添加开票状态逻辑处理 - 更新多个模态框的列配置以支持业务值类型 - 调整选择模态框布局大小和分页配置 - 移除支付记录列表的编辑删除功能 - 优化订单供应商选择列表的发票相关字段显示
522 lines
13 KiB
TypeScript
522 lines
13 KiB
TypeScript
import {
|
|
BizContainer,
|
|
BizValueType,
|
|
ButtonAccess,
|
|
ModeType,
|
|
} from '@/components';
|
|
import { business } from '@/services';
|
|
import { formatBankCard, formatIdCard, formatPhone } from '@/utils/format';
|
|
import { useIntl } from '@@/exports';
|
|
import { EyeInvisibleOutlined, EyeTwoTone } from '@ant-design/icons';
|
|
import { ProColumns } from '@ant-design/pro-components';
|
|
import { ProDescriptionsItemProps } from '@ant-design/pro-descriptions';
|
|
import { Button, Image, Modal, Space, Tag } from 'antd';
|
|
import React, { useState } from 'react';
|
|
|
|
interface IOrderSupplierListProps {
|
|
ghost?: boolean;
|
|
orderId?: BusinessAPI.OrderVO['orderId'];
|
|
supplierInvoiceVO?: BusinessAPI.SupplierInvoiceVO;
|
|
search?: boolean;
|
|
onValueChange?: () => void;
|
|
mode?: ModeType;
|
|
trigger?: () => React.ReactNode;
|
|
}
|
|
|
|
export default function OrderSupplierList(props: IOrderSupplierListProps) {
|
|
const {
|
|
ghost = false,
|
|
orderId,
|
|
search = true,
|
|
mode = 'page',
|
|
trigger,
|
|
onValueChange,
|
|
supplierInvoiceVO,
|
|
} = props;
|
|
const intl = useIntl();
|
|
const intlPrefix = 'orderSupplier';
|
|
|
|
const [showIdCard, setShowIdCard] = useState<Record<string, boolean>>({});
|
|
const [showBankCard, setShowBankCard] = useState<Record<string, boolean>>({});
|
|
const [showPhone, setShowPhone] = useState<Record<string, boolean>>({});
|
|
const [activeKey, setActiveKey] = useState<string>('ALL');
|
|
|
|
// 发票预览相关状态
|
|
const [invoiceVisible, setInvoiceVisible] = useState(false);
|
|
const [contractVisible, setContractVisible] = useState(false);
|
|
const [wechatQrVisible, setWechatQrVisible] = useState(false);
|
|
const [paymentVoucherVisible, setPaymentVoucherVisible] = useState(false);
|
|
const [currentRecord, setCurrentRecord] =
|
|
useState<BusinessAPI.OrderSupplierVO | null>(null);
|
|
|
|
const columns: ProColumns<BusinessAPI.OrderSupplierVO, BizValueType>[] = [
|
|
{
|
|
title: intl.formatMessage({ id: intlPrefix + '.column.order' }),
|
|
dataIndex: 'orderVO',
|
|
key: 'orderId',
|
|
valueType: 'order',
|
|
},
|
|
{
|
|
title: intl.formatMessage({ id: intlPrefix + '.column.name' }),
|
|
dataIndex: 'name',
|
|
key: 'name',
|
|
},
|
|
{
|
|
title: intl.formatMessage({ id: intlPrefix + '.column.invoiceAmount' }),
|
|
dataIndex: 'invoiceAmount',
|
|
key: 'invoiceAmount',
|
|
valueType: 'money',
|
|
search: false,
|
|
},
|
|
{
|
|
title: intl.formatMessage({ id: intlPrefix + '.column.depositAmount' }),
|
|
dataIndex: 'depositAmount',
|
|
key: 'depositAmount',
|
|
valueType: 'money',
|
|
search: false,
|
|
},
|
|
// 剩余付款金额
|
|
{
|
|
title: intl.formatMessage({
|
|
id: intlPrefix + '.column.remainingAmount',
|
|
}),
|
|
dataIndex: 'remainingAmount',
|
|
key: 'remainingAmount',
|
|
valueType: 'money',
|
|
search: false,
|
|
renderText: (_, record) => {
|
|
return record.invoiceAmount - record.depositAmount || 0;
|
|
},
|
|
},
|
|
{
|
|
title: intl.formatMessage({ id: intlPrefix + '.column.supplierInvoice' }),
|
|
dataIndex: 'supplierInvoiceVO',
|
|
key: 'supplierInvoiceId',
|
|
search: false,
|
|
valueType: 'supplierInvoice',
|
|
},
|
|
{
|
|
title: intl.formatMessage({ id: intlPrefix + '.column.invoiceUpload' }),
|
|
dataIndex: 'invoiceUpload',
|
|
key: 'invoiceUpload',
|
|
search: false,
|
|
valueType: 'switch',
|
|
render: (_, record) => (
|
|
<Tag color={record.invoiceUpload ? 'green' : 'red'}>
|
|
{record.invoiceUpload
|
|
? intl.formatMessage({
|
|
id: intlPrefix + '.column.invoiceUpload.uploaded',
|
|
})
|
|
: intl.formatMessage({
|
|
id: intlPrefix + '.column.invoiceUpload.notUploaded',
|
|
})}
|
|
</Tag>
|
|
),
|
|
},
|
|
{
|
|
title: intl.formatMessage({ id: intlPrefix + '.column.contractUpload' }),
|
|
dataIndex: 'contractUpload',
|
|
key: 'contractUpload',
|
|
search: false,
|
|
valueType: 'switch',
|
|
render: (_, record) => (
|
|
<Tag color={record.contractUpload ? 'green' : 'red'}>
|
|
{record.contractUpload
|
|
? intl.formatMessage({
|
|
id: intlPrefix + '.column.contractUpload.uploaded',
|
|
})
|
|
: intl.formatMessage({
|
|
id: intlPrefix + '.column.contractUpload.notUploaded',
|
|
})}
|
|
</Tag>
|
|
),
|
|
},
|
|
{
|
|
title: intl.formatMessage({
|
|
id: intlPrefix + '.column.idCard',
|
|
}),
|
|
dataIndex: 'idCard',
|
|
key: 'idCard',
|
|
search: false,
|
|
render: (_, record) => (
|
|
<div className="flex items-center">
|
|
<span>
|
|
{formatIdCard(record.idCard, showIdCard[record.orderSupplierId])}
|
|
</span>
|
|
<span
|
|
className="ml-2 cursor-pointer"
|
|
onClick={() => {
|
|
setShowIdCard((prev) => ({
|
|
...prev,
|
|
[record.orderSupplierId]: !prev[record.orderSupplierId],
|
|
}));
|
|
}}
|
|
>
|
|
{showIdCard[record.orderSupplierId] ? (
|
|
<EyeTwoTone />
|
|
) : (
|
|
<EyeInvisibleOutlined />
|
|
)}
|
|
</span>
|
|
</div>
|
|
),
|
|
},
|
|
{
|
|
title: intl.formatMessage({ id: intlPrefix + '.column.phone' }),
|
|
dataIndex: 'phone',
|
|
key: 'phone',
|
|
search: false,
|
|
render: (_, record) => (
|
|
<div className="flex items-center">
|
|
<span>
|
|
{formatPhone(record.phone, showPhone[record.orderSupplierId])}
|
|
</span>
|
|
<span
|
|
className="ml-2 cursor-pointer"
|
|
onClick={() => {
|
|
setShowPhone((prev) => ({
|
|
...prev,
|
|
[record.orderSupplierId]: !prev[record.orderSupplierId],
|
|
}));
|
|
}}
|
|
>
|
|
{showPhone[record.orderSupplierId] ? (
|
|
<EyeTwoTone />
|
|
) : (
|
|
<EyeInvisibleOutlined />
|
|
)}
|
|
</span>
|
|
</div>
|
|
),
|
|
},
|
|
{
|
|
title: intl.formatMessage({ id: intlPrefix + '.column.bankCard' }),
|
|
dataIndex: 'bankCard',
|
|
key: 'bankCard',
|
|
search: false,
|
|
render: (_, record) => (
|
|
<div className="flex items-center">
|
|
<span>
|
|
{formatBankCard(
|
|
record?.bankCard || '',
|
|
showBankCard[record.orderSupplierId],
|
|
)}
|
|
</span>
|
|
<span
|
|
className="ml-2 cursor-pointer"
|
|
onClick={() => {
|
|
setShowBankCard((prev) => ({
|
|
...prev,
|
|
[record.orderSupplierId]: !prev[record.orderSupplierId],
|
|
}));
|
|
}}
|
|
>
|
|
{showBankCard[record.orderSupplierId] ? (
|
|
<EyeTwoTone />
|
|
) : (
|
|
<EyeInvisibleOutlined />
|
|
)}
|
|
</span>
|
|
</div>
|
|
),
|
|
},
|
|
{
|
|
title: intl.formatMessage({ id: intlPrefix + '.column.orderCompany' }),
|
|
dataIndex: 'orderCompany',
|
|
key: 'companyId',
|
|
valueType: 'company',
|
|
},
|
|
{
|
|
title: intl.formatMessage({ id: intlPrefix + '.column.isPaid' }),
|
|
dataIndex: 'isPaid',
|
|
key: 'isPaid',
|
|
valueType: 'select',
|
|
valueEnum: {
|
|
true: {
|
|
text: intl.formatMessage({
|
|
id: intlPrefix + '.column.isPaid.paid',
|
|
}),
|
|
status: 'success',
|
|
},
|
|
false: {
|
|
text: intl.formatMessage({
|
|
id: intlPrefix + '.column.isPaid.unpaid',
|
|
}),
|
|
status: 'processing',
|
|
},
|
|
},
|
|
},
|
|
];
|
|
|
|
const detailColumns: ProDescriptionsItemProps<
|
|
BusinessAPI.OrderSupplierVO,
|
|
BizValueType
|
|
>[] = columns as ProDescriptionsItemProps<
|
|
BusinessAPI.OrderSupplierVO,
|
|
BizValueType
|
|
>[];
|
|
|
|
return (
|
|
<>
|
|
<BizContainer<
|
|
typeof business.orderSupplier,
|
|
BusinessAPI.OrderSupplierVO,
|
|
BusinessAPI.OrderSupplierPageQry
|
|
>
|
|
rowKey={'orderSupplierId'}
|
|
permission={'operation-order-supplier'}
|
|
func={business.orderSupplier}
|
|
method={'orderSupplier'}
|
|
methodUpper={'OrderSupplier'}
|
|
intlPrefix={intlPrefix}
|
|
modeType={mode}
|
|
onValueChange={onValueChange}
|
|
container={{
|
|
ghost,
|
|
}}
|
|
status={false}
|
|
page={{
|
|
fieldProps: {
|
|
bordered: true,
|
|
ghost,
|
|
//@ts-ignore
|
|
search,
|
|
params: {
|
|
...(activeKey !== 'ALL' && {
|
|
isPaid: activeKey! as any,
|
|
}),
|
|
...(supplierInvoiceVO && {
|
|
invoiceId: supplierInvoiceVO.supplierInvoiceId,
|
|
}),
|
|
poStates: ['COMPLETED'],
|
|
type: 'FARMER',
|
|
},
|
|
tableAlertOptionRender: (props) => {
|
|
return (
|
|
<Space>
|
|
<Button
|
|
key={'cancel'}
|
|
type={'link'}
|
|
onClick={() => props.onCleanSelected()}
|
|
size={'middle'}
|
|
>
|
|
取消选择
|
|
</Button>
|
|
</Space>
|
|
);
|
|
},
|
|
toolbar: {
|
|
menu: {
|
|
type: 'tab',
|
|
activeKey: activeKey,
|
|
items: [
|
|
// 全部
|
|
{
|
|
key: 'ALL',
|
|
label: intl.formatMessage({
|
|
id: intlPrefix + '.tab.all',
|
|
}),
|
|
},
|
|
// 已支付
|
|
{
|
|
key: 'true',
|
|
label: intl.formatMessage({
|
|
id: intlPrefix + '.tab.paid',
|
|
}),
|
|
},
|
|
// 未支付
|
|
{
|
|
key: 'false',
|
|
label: intl.formatMessage({
|
|
id: intlPrefix + '.tab.unpaid',
|
|
}),
|
|
},
|
|
],
|
|
onChange: (key) => {
|
|
setActiveKey(key as string);
|
|
},
|
|
},
|
|
},
|
|
},
|
|
columns,
|
|
options: (orderSupplierVO) => {
|
|
let btn = [];
|
|
if (orderSupplierVO.invoiceUpload) {
|
|
btn.push(
|
|
<ButtonAccess
|
|
permission="operation-order-supplier-view-invoice"
|
|
key="view-invoice"
|
|
type="link"
|
|
onClick={() => {
|
|
setCurrentRecord(orderSupplierVO);
|
|
setInvoiceVisible(true);
|
|
}}
|
|
>
|
|
查看发票
|
|
</ButtonAccess>,
|
|
);
|
|
}
|
|
|
|
if (orderSupplierVO.wechatQr) {
|
|
btn.push(
|
|
<ButtonAccess
|
|
permission="operation-order-supplier-view-wechat-qr-code"
|
|
key="wechat-qr-code"
|
|
type="link"
|
|
onClick={() => {
|
|
setCurrentRecord(orderSupplierVO);
|
|
setWechatQrVisible(true);
|
|
}}
|
|
>
|
|
查看微信收款码
|
|
</ButtonAccess>,
|
|
);
|
|
}
|
|
|
|
if (orderSupplierVO.contractUpload) {
|
|
btn.push(
|
|
<ButtonAccess
|
|
permission="operation-order-supplier-view-contract"
|
|
key="view-contract"
|
|
type="link"
|
|
onClick={() => {
|
|
setCurrentRecord(orderSupplierVO);
|
|
setContractVisible(true);
|
|
}}
|
|
>
|
|
查看合同
|
|
</ButtonAccess>,
|
|
);
|
|
}
|
|
|
|
if (orderSupplierVO.isPaid) {
|
|
btn.push(
|
|
<ButtonAccess
|
|
permission="operation-order-supplier-view-payment-voucher"
|
|
key="payment-voucher"
|
|
type="link"
|
|
onClick={() => {
|
|
setCurrentRecord(orderSupplierVO);
|
|
setPaymentVoucherVisible(true);
|
|
}}
|
|
>
|
|
查看付款凭证
|
|
</ButtonAccess>,
|
|
);
|
|
}
|
|
return btn;
|
|
},
|
|
}}
|
|
create={false}
|
|
update={false}
|
|
destroy={false}
|
|
detail={{
|
|
rowId: orderId,
|
|
formType: 'drawer',
|
|
columns: detailColumns,
|
|
trigger,
|
|
}}
|
|
/>
|
|
|
|
{/* 发票预览Modal */}
|
|
<Modal
|
|
title="查看发票"
|
|
open={invoiceVisible}
|
|
onCancel={() => setInvoiceVisible(false)}
|
|
footer={null}
|
|
width={800}
|
|
centered
|
|
>
|
|
{currentRecord?.invoiceImg && currentRecord.invoiceImg.length > 0 ? (
|
|
<div className="space-y-4">
|
|
{currentRecord.invoiceImg.map((item, index) => (
|
|
<div key={index} className="text-center">
|
|
<p className="mb-2">发票 {index + 1}</p>
|
|
<Image
|
|
width="100%"
|
|
height={400}
|
|
src={item.filePath}
|
|
alt={item.fileName || `发票${index + 1}`}
|
|
placeholder={<div className="text-gray-400">加载中...</div>}
|
|
/>
|
|
<p className="text-sm text-gray-500 mt-2">
|
|
{item.fileName || `发票${index + 1}`}
|
|
</p>
|
|
</div>
|
|
))}
|
|
</div>
|
|
) : (
|
|
<div className="text-center py-8 text-gray-500">暂无发票图片</div>
|
|
)}
|
|
</Modal>
|
|
|
|
{/* 合同预览Modal */}
|
|
<Modal
|
|
title="查看合同"
|
|
open={contractVisible}
|
|
onCancel={() => setContractVisible(false)}
|
|
footer={null}
|
|
width={800}
|
|
centered
|
|
>
|
|
{currentRecord?.contractImg && currentRecord.contractImg.length > 0 ? (
|
|
<div className="space-y-4">
|
|
{currentRecord.contractImg.map((item, index) => (
|
|
<div key={index} className="text-center">
|
|
<p className="mb-2">合同 {index + 1}</p>
|
|
<Image
|
|
width="100%"
|
|
height={400}
|
|
src={item.filePath}
|
|
alt={item.fileName || `合同${index + 1}`}
|
|
placeholder={<div className="text-gray-400">加载中...</div>}
|
|
/>
|
|
<p className="text-sm text-gray-500 mt-2">
|
|
{item.fileName || `合同${index + 1}`}
|
|
</p>
|
|
</div>
|
|
))}
|
|
</div>
|
|
) : (
|
|
<div className="text-center py-8 text-gray-500">暂无合同图片</div>
|
|
)}
|
|
</Modal>
|
|
|
|
{/* 微信收款码预览Modal */}
|
|
<Modal
|
|
title="查看微信收款码"
|
|
open={wechatQrVisible}
|
|
onCancel={() => setWechatQrVisible(false)}
|
|
footer={null}
|
|
width={400}
|
|
centered
|
|
>
|
|
{currentRecord?.wechatQr ? (
|
|
<div className="text-center">
|
|
<Image
|
|
width="100%"
|
|
src={currentRecord.wechatQr}
|
|
alt="微信收款码"
|
|
placeholder={<div className="text-gray-400">加载中...</div>}
|
|
/>
|
|
</div>
|
|
) : (
|
|
<div className="text-center py-8 text-gray-500">暂无微信收款码</div>
|
|
)}
|
|
</Modal>
|
|
|
|
{/* 付款凭证预览Modal */}
|
|
<Modal
|
|
title="查看付款凭证"
|
|
open={paymentVoucherVisible}
|
|
onCancel={() => setPaymentVoucherVisible(false)}
|
|
footer={null}
|
|
width={800}
|
|
centered
|
|
>
|
|
<div className="text-center py-8 text-gray-500">暂无付款凭证图片</div>
|
|
</Modal>
|
|
</>
|
|
);
|
|
}
|