Files
fe_supplier_frontend/src/pages/supplier/admission/admissionManagement/components/ResultModal.tsx
2025-07-02 16:18:03 +08:00

240 lines
7.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useEffect, useState } from 'react';
import { Modal, Table, Button, Select, Spin, message } from 'antd';
import { reviewInfoData } from '../services';
import { connect } from 'umi';
interface ResultModalProps {
visible: boolean;
record?: { id?: string;[key: string]: any } | null;
onCancel: () => void;
dispatch: any;
}
// 只读备注弹窗
const RemarkViewModal: React.FC<{
visible: boolean;
onCancel: () => void;
remark: string;
file?: any;
}> = ({ visible, onCancel, remark, file, }) => (
<Modal
visible={visible}
title="备注信息"
footer={null}
onCancel={onCancel}
destroyOnClose
>
<div>
<div style={{ marginBottom: 12 }}>
<b></b>{remark || '无'}
</div>
{file && file.fileUrl && (
<div>
<b></b>
<a href={file.fileUrl} target="_blank" rel="noopener noreferrer">
{file.fileName}
</a>
</div>
)}
</div>
</Modal>
);
const ResultModal: React.FC<ResultModalProps> = ({
visible,
record,
onCancel,
dispatch
}) => {
const [loading, setLoading] = useState(false);
const [suppliers, setSuppliers] = useState<any[]>([]);
const [items, setItems] = useState<any[]>([]);
const [groupSummaryResult, setGroupSummaryResult] = useState<{ [k: string]: '0' | '1' | undefined }>({});
// 查看备注弹窗
const [remarkModal, setRemarkModal] = useState({ open: false, remark: '', file: undefined as any });
// 拉取数据
useEffect(() => {
if (visible && record?.id) {
setLoading(true);
reviewInfoData({ id: record.id })
.then((res: any) => {
const supplierList = res?.data || [];
setSuppliers(supplierList);
// 所有项,取第一家公司
const allItems = (supplierList[0]?.coscoAccessItemList || []);
// 非summary项
setItems(allItems.filter((item: any) => item.itemType !== 'summary'));
// summary 行初始化
const summaryMap: { [k: string]: '0' | '1' | undefined } = {};
supplierList.forEach((sup: any) => {
// summary 行
const summaryItem = (sup.coscoAccessItemList || []).find((i: any) => i.itemType === 'summary');
console.log(summaryItem, 'summaryItem');
summaryMap[sup.supplierId] = summaryItem.coscoAccessUserItemList[0]?.reviewResult;
});
setGroupSummaryResult(summaryMap);
})
.finally(() => setLoading(false));
} else if (!visible) {
setSuppliers([]);
setItems([]);
setGroupSummaryResult({});
}
}, [visible, record]);
// 构造二级表头
const columns: any[] = [
{
title: '评审项',
dataIndex: 'itemName',
key: 'itemName',
width: 180,
fixed: 'left',
},
...suppliers.map(sup => {
// 当前公司所有人员所有非summary项取 coscoAccessUserItemList 多个)
const reviewerSet = new Set<string>();
(sup.coscoAccessItemList || []).forEach((item: any) => {
if (item.itemType !== 'summary' && Array.isArray(item.coscoAccessUserItemList)) {
item.coscoAccessUserItemList.forEach((u: any) => {
reviewerSet.add(u.reviewBy);
});
}
});
const reviewers = Array.from(reviewerSet);
console.log(sup, 'sup');
return {
title: (
<div>
<a
onClick={() => {
dispatch({
type: 'globalModal/show',
payload: {
id: sup.supplierId,
},
});
}}
>
{sup.supplierName}
</a>
</div>
),
children: reviewers.map((reviewBy: string) => ({
title: reviewBy,
dataIndex: `${sup.supplierId}_${reviewBy}`,
key: `${sup.supplierId}_${reviewBy}`,
width: 100,
align: 'center',
render: (_: any, row: any) => {
// 在sup.coscoAccessItemList里找该itemName下该人员
const item = (sup.coscoAccessItemList || []).find((it: any) => it.itemName === row.itemName && it.itemType !== 'summary');
if (!item) return null;
const userItem = (item.coscoAccessUserItemList || []).find((u: any) => u.reviewBy === reviewBy);
if (!userItem) return null;
return (
<div>
{userItem.reviewResult === '0'
? <span style={{ color: '#52c41a' }}></span>
: userItem.reviewResult === '1'
? <span style={{ color: '#f5222d' }}></span>
: ''}
{userItem.remark && (
<Button type="link" size="small" onClick={() =>
setRemarkModal({ open: true, remark: userItem.remark, file: userItem.coscoAccessTtemAttachments })
}></Button>
)}
</div>
);
}
}))
}
})
];
// 组装表格行数据
const tableData = items.map(item => {
const row: any = {
key: item.id,
itemName: item.itemName
};
suppliers.forEach(sup => {
// 每个人员一格
const reviewerSet = new Set<string>();
(sup.coscoAccessItemList || []).forEach((it: any) => {
if (it.itemType !== 'summary' && Array.isArray(it.coscoAccessUserItemList)) {
it.coscoAccessUserItemList.forEach((u: any) => {
reviewerSet.add(u.reviewBy);
});
}
});
const reviewers = Array.from(reviewerSet);
reviewers.forEach((reviewBy: string) => {
row[`${sup.supplierId}_${reviewBy}`] = null; // 具体显示用render
});
});
return row;
});
// summary 行
const summaryRow = (
<Table.Summary.Row>
<Table.Summary.Cell index={-1}></Table.Summary.Cell>
{suppliers.map((sup, index) => {
// 统计reviewer个数
const reviewerSet = new Set<string>();
(sup.coscoAccessItemList || []).forEach((item: any) => {
if (item.itemType !== 'summary' && Array.isArray(item.coscoAccessUserItemList)) {
item.coscoAccessUserItemList.forEach((u: any) => {
reviewerSet.add(u.reviewBy);
});
}
});
const colSpan = reviewerSet.size || 1;
return (
<Table.Summary.Cell index={index} key={sup.supplierId} colSpan={colSpan} align="center">
<span style={{ color: groupSummaryResult[sup.supplierId] === '0' ? '#52c41a' : '#f5222d' }}> {groupSummaryResult[sup.supplierId] === '0' ? '合格' : '不合格'}</span>
</Table.Summary.Cell>
)
})}
</Table.Summary.Row>
);
return (
<Modal
title="查看评审结果"
visible={visible}
onCancel={onCancel}
footer={[
<Button key="cancel" onClick={onCancel}> </Button>,
]}
width={1000}
bodyStyle={{ maxHeight: '60vh', overflowY: 'auto' }}
centered
destroyOnClose
>
<Spin spinning={loading}>
<Table
columns={columns}
dataSource={tableData}
pagination={false}
bordered
summary={() => summaryRow}
scroll={{ x: 300 * suppliers.length + 200 }}
/>
</Spin>
<RemarkViewModal
visible={remarkModal.open}
onCancel={() => setRemarkModal({ open: false, remark: '', file: undefined })}
remark={remarkModal.remark}
file={remarkModal.file}
/>
</Modal>
);
};
export default connect()(ResultModal);