Files
fe_supplier_frontend/src/pages/supplierEvaluateManage/supplierEvaluateResult/supplierEvaluateResultInfo.tsx
2025-07-03 10:21:55 +08:00

301 lines
9.3 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, { useState, useEffect } from 'react';
import {
Card,
Form,
Input,
Select,
Button,
Table,
Space,
Row,
Col,
Tooltip,
message,
} from 'antd';
import type { TablePaginationConfig } from 'antd';
import {
SearchOutlined,
DeleteOutlined,
ArrowLeftOutlined,
} from '@ant-design/icons';
import { history, useLocation, useIntl } from 'umi';
import { getEvaluateSupplierList, getAllEvaluateRules } from '@/servers/api/supplierEvaluate';
const { Option } = Select;
const SupplierEvaluateResultInfo: React.FC = () => {
const intl = useIntl();
const location = useLocation<{ record: SupplierEvaluateResult.EvaluateTaskItem }>();
const [loading, setLoading] = useState<boolean>(false);
const [form] = Form.useForm();
const [resultData, setResultData] = useState<SupplierEvaluateResult.EvaluateSupplierItem[]>([]);
const [pagination, setPagination] = useState<TablePaginationConfig>({
current: 1,
pageSize: 10,
total: 0,
showSizeChanger: true,
showQuickJumper: true,
showTotal: (total) => intl.formatMessage(
{ id: 'supplierEvaluateResult.pagination.total' },
{ total }
),
});
const [searchParams, setSearchParams] =
useState<SupplierEvaluateResult.EvaluateSupplierSearchParams>({});
const [parentRecord, setParentRecord] = useState<SupplierEvaluateResult.EvaluateTaskItem | null>(
null,
);
const [evaluateRules, setEvaluateRules] = useState<SupplierEvaluateRuleManage.EvaluateRuleItem[]>([]);
// 获取上级页面传递的数据
useEffect(() => {
if (location.state?.record) {
setParentRecord(location.state.record);
}
}, [location]);
// 获取评价规则列表
const fetchEvaluateRules = async () => {
try {
const response = await getAllEvaluateRules();
if (response.success && response.data) {
setEvaluateRules(response.data);
} else {
message.error(response.message || intl.formatMessage({ id: 'supplierEvaluateResult.message.fetchRulesFailed' }));
}
} catch (error) {
console.error('获取评价规则列表失败:', error);
message.error(intl.formatMessage({ id: 'supplierEvaluateResult.message.fetchRulesFailed' }));
}
};
// 首次加载获取评价规则列表
useEffect(() => {
fetchEvaluateRules();
}, []);
// 获取评价结果详情列表
const fetchResultDetailList = async (
current = 1,
pageSize = 10,
params: SupplierEvaluateResult.EvaluateSupplierSearchParams = searchParams,
) => {
// 确保有评价任务ID
if (!parentRecord?.id) {
message.error(intl.formatMessage({ id: 'supplierEvaluateResult.message.missingTaskId' }));
return;
}
// 更新搜索参数状态
if (params !== searchParams) {
setSearchParams(params);
}
setLoading(true);
try {
// 构建请求参数
const requestParams: SupplierEvaluateResult.EvaluateSupplierRequest = {
basePageRequest: {
pageNo: current,
pageSize: pageSize,
},
evaluateTaskId: parentRecord.id,
};
// 添加搜索条件
if (params.supplierName) {
requestParams.supplierName = params.supplierName;
}
if (params.levelName) {
requestParams.levelName = params.levelName;
}
// 调用接口获取数据
const response = await getEvaluateSupplierList(requestParams);
if (response.data && response.success) {
const { records, total, current: currentPage, size } = response.data;
// 处理数据增加表格需要的key属性
const formattedData = records.map(record => ({
...record,
key: record.id,
}));
setResultData(formattedData);
setPagination({
...pagination,
current: currentPage,
pageSize: size,
total,
});
} else {
message.error(response.message || intl.formatMessage({ id: 'supplierEvaluateResult.message.fetchDetailFailed' }));
}
} catch (error) {
console.error('获取评价结果详情列表失败:', error);
message.error(intl.formatMessage({ id: 'supplierEvaluateResult.message.fetchDetailFailed' }));
} finally {
setLoading(false);
}
};
// 首次加载获取数据
useEffect(() => {
if (parentRecord?.id) {
fetchResultDetailList(pagination.current, pagination.pageSize, {});
}
}, [parentRecord]);
// 处理表格分页变化
const handleTableChange = (newPagination: TablePaginationConfig) => {
fetchResultDetailList(newPagination.current, newPagination.pageSize, searchParams);
};
// 处理搜索
const handleSearch = (values: any) => {
fetchResultDetailList(1, pagination.pageSize, values);
};
// 处理重置
const handleReset = () => {
form.resetFields();
fetchResultDetailList(1, pagination.pageSize, {});
};
// 返回上一页
const handleBack = () => {
history.goBack();
};
// 查看得分明细
const handleViewScoreDetail = (record: SupplierEvaluateResult.EvaluateSupplierItem) => {
history.push({
pathname: 'supplierEvaluateResultScoreDetail',
state: { record, parentRecord }
});
};
// 查看打分情况
const handleViewScoring = (record: SupplierEvaluateResult.EvaluateSupplierItem) => {
history.push({
pathname: 'supplierEvaluateResultScoreByList',
state: { record, parentRecord }
});
};
const columns = [
{
title: intl.formatMessage({ id: 'supplierEvaluateResult.column.index' }),
render: (_: any, __: SupplierEvaluateResult.EvaluateSupplierItem, index: number) =>
(pagination.current! - 1) * pagination.pageSize! + index + 1,
width: 80,
},
{
title: intl.formatMessage({ id: 'supplierEvaluateResult.column.supplierName' }),
dataIndex: 'supplierName',
key: 'supplierName',
width: 200,
ellipsis: {
showTitle: false,
},
render: (supplierName: string) => (
<Tooltip placement="topLeft" title={supplierName}>
{supplierName}
</Tooltip>
),
},
{
title: intl.formatMessage({ id: 'supplierEvaluateResult.column.categoryName' }),
dataIndex: 'categoryName',
key: 'categoryName',
width: 120,
},
{
title: intl.formatMessage({ id: 'supplierEvaluateResult.column.reviewScore' }),
dataIndex: 'reviewScore',
key: 'reviewScore',
width: 100
},
{
title: intl.formatMessage({ id: 'supplierEvaluateResult.column.levelName' }),
dataIndex: 'levelName',
key: 'levelName',
width: 100,
align: 'center' as const
},
{
title: intl.formatMessage({ id: 'supplierEvaluateResult.column.action' }),
key: 'action',
width: 180,
align: 'center' as const,
render: (_: unknown, record: SupplierEvaluateResult.EvaluateSupplierItem) => (
<Space size="middle">
<Button
type="link"
onClick={() => handleViewScoreDetail(record)}
>
{intl.formatMessage({ id: 'supplierEvaluateResult.button.scoreDetail' })}
</Button>
<Button type="link" onClick={() => handleViewScoring(record)}>
{intl.formatMessage({ id: 'supplierEvaluateResult.button.scoringStatus' })}
</Button>
</Space>
),
},
];
return (
<div className="common-container">
<div className="filter-action-row">
<Form form={form} layout="inline" onFinish={handleSearch} className="filter-form">
<Form.Item name="supplierName" label={intl.formatMessage({ id: 'supplierEvaluateResult.form.supplierName' })}>
<Input placeholder={intl.formatMessage({ id: 'supplierEvaluateResult.form.placeholder.supplierName' })} allowClear />
</Form.Item>
<Form.Item name="levelName" label={intl.formatMessage({ id: 'supplierEvaluateResult.form.levelName' })}>
<Select
placeholder={intl.formatMessage({ id: 'supplierEvaluateResult.form.placeholder.levelName' })}
allowClear
style={{ width: 150 }}
>
{evaluateRules.map((rule) => (
<Option key={rule.id} value={rule.levelName}>
{rule.levelName}
</Option>
))}
</Select>
</Form.Item>
<Form.Item className="filter-btns">
<Button type="primary" icon={<SearchOutlined />} onClick={() => form.submit()}>
{intl.formatMessage({ id: 'supplierEvaluateResult.button.search' })}
</Button>
<Button type="primary" danger icon={<DeleteOutlined />} onClick={handleReset}>
{intl.formatMessage({ id: 'supplierEvaluateResult.button.reset' })}
</Button>
</Form.Item>
</Form>
<div className="right-buttons">
<Button type="link" icon={<ArrowLeftOutlined />} onClick={handleBack}>
{intl.formatMessage({ id: 'supplierEvaluateResult.button.back' })}
</Button>
</div>
</div>
<div className="content-area">
<Table
columns={columns}
dataSource={resultData}
pagination={pagination}
loading={loading}
onChange={handleTableChange}
scroll={{ x: 1100 }}
/>
</div>
</div>
);
};
export default SupplierEvaluateResultInfo;