Files
fe_supplier_frontend/src/pages/index/index.tsx

199 lines
6.4 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 { Card, Row, Col, Spin, message } from 'antd';
import { Column, Pie, Bar } from '@ant-design/charts';
import {
getYearcountNum,
getAccessTypeCountNum,
getSupplierTypeCountNum,
getAccessFlowCountNum, // 第四个接口
getSupplierAuditCountNum // 第五个接口
} from './servers';
type YearCountItem = { updateYear: string; countNum: string; };
type AccessTypeItem = { accessTypeText: string; countNum: string; };
type SupplierTypeItem = { supplierTypeCn: string; countNum: string; };
const HomeDashboard: React.FC = () => {
const [yearData, setYearData] = useState<any[]>([]);
const [accessTypeData, setAccessTypeData] = useState<any[]>([]);
const [supplierTypeData, setSupplierTypeData] = useState<any[]>([]);
const [accessFlowData, setAccessFlowData] = useState<any[]>([]);
const [supplierAuditData, setSupplierAuditData] = useState<any[]>([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
setLoading(true);
Promise.all([
getYearcountNum(),
getAccessTypeCountNum(),
getSupplierTypeCountNum(),
getAccessFlowCountNum(),
getSupplierAuditCountNum(),
])
.then(([yearRes, accessTypeRes, supplierTypeRes, accessFlowRes, supplierAuditRes]) => {
// 1. 年度注册供应商数量
if (yearRes.code === 200 && Array.isArray(yearRes.data)) {
// 支持多年度,兼容数据
setYearData((yearRes.data || []).map((item: YearCountItem) => ({
year: item.updateYear,
count: Number(item.countNum),
})));
} else message.error('获取年度注册统计失败');
// 2. 准入类别统计
if (accessTypeRes.code === 200 && Array.isArray(accessTypeRes.data)) {
setAccessTypeData((accessTypeRes.data || []).map((item: AccessTypeItem) => ({
type: item.accessTypeText,
count: Number(item.countNum),
})));
} else message.error('获取准入类别统计失败');
// 3. 供应商身份类别统计
if (supplierTypeRes.code === 200 && Array.isArray(supplierTypeRes.data)) {
setSupplierTypeData((supplierTypeRes.data || []).map((item: SupplierTypeItem) => ({
type: item.supplierTypeCn,
count: Number(item.countNum),
})));
} else message.error('获取身份类别统计失败');
// 4. 准入流程进度统计
if (accessFlowRes.code === 200 && accessFlowRes.data) {
const flow = accessFlowRes.data;
setAccessFlowData([
{ status: '未开始', count: flow.noStartNum || 0 },
{ status: '进行中', count: flow.doingNum || 0 },
{ status: '待审核', count: flow.auditNum || 0 },
{ status: '已完成', count: flow.completeNum || 0 },
]);
} else message.error('获取准入流程统计失败');
// 5. 供应商审核进度统计
if (supplierAuditRes.code === 200 && supplierAuditRes.data) {
const flow = supplierAuditRes.data;
setSupplierAuditData([
{ status: '未开始', count: flow.noStartNum || 0 },
{ status: '进行中', count: flow.doingNum || 0 },
{ status: '待审核', count: flow.auditNum || 0 },
{ status: '已完成', count: flow.completeNum || 0 },
]);
} else message.error('获取供应商审核统计失败');
})
.catch(() => message.error('统计数据获取失败'))
.finally(() => setLoading(false));
}, []);
// 图表配置
const yearConfig = {
data: yearData,
xField: 'year',
yField: 'count',
label: {
// content 是函数,用于显示内容
content: (originData: any) => originData.count,
style: { fill: '#fff' }
},
xAxis: { title: { text: '年份' } },
yAxis: { title: { text: '注册供应商数量' } },
height: 260,
autoFit: true,
};
const accessTypeConfig = {
appendPadding: 10,
data: accessTypeData,
angleField: 'count',
colorField: 'type',
radius: 1,
label: {
type: 'spider',
content: '{name}{value}'
// 可选: style: { fontSize: 12 }
},
legend: { position: 'right' as const }, // 保证类型推断正确
height: 260,
};
const supplierTypeConfig = {
data: supplierTypeData,
xField: 'count',
yField: 'type',
seriesField: 'type',
label: {
position: 'right' as const, // 保证是字面量类型
content: (data: any) => data.count,
style: { fill: '#333' }
},
legend: false as const,
height: 260,
autoFit: true,
};
// 准入流程 & 审核进度 用 Pie 或 Bar 都可以
const accessFlowConfig = {
appendPadding: 10,
data: accessFlowData,
angleField: 'count',
colorField: 'status',
radius: 1,
label: {
type: 'spider',
content: '{name}{value}',
},
legend: { position: 'right' as const },
height: 260,
};
const supplierAuditConfig = {
appendPadding: 10,
data: supplierAuditData,
angleField: 'count',
colorField: 'status',
radius: 1,
label: {
type: 'spider',
content: '{name}{value}'
},
legend: { position: 'right' as const },
height: 260,
};
return (
<>
<Spin spinning={loading}>
<Row gutter={[24, 24]}>
{/* 第一行3图 */}
<Col xs={24} sm={24} md={8}>
<Card title="每年注册供应商数量" bordered={false}>
<Column {...yearConfig} />
</Card>
</Col>
<Col xs={24} sm={12} md={8}>
<Card title="准入类别统计" bordered={false}>
<Pie {...accessTypeConfig} />
</Card>
</Col>
<Col xs={24} sm={12} md={8}>
<Card title="供应商身份类别统计" bordered={false}>
<Bar {...supplierTypeConfig} />
</Card>
</Col>
{/* 第二行2图 */}
<Col xs={24} sm={12} md={12}>
<Card title="准入流程进度统计" bordered={false}>
<Pie {...accessFlowConfig} />
</Card>
</Col>
<Col xs={24} sm={12} md={12}>
<Card title="供应商审核进度统计" bordered={false}>
<Pie {...supplierAuditConfig} />
</Card>
</Col>
</Row>
</Spin>
</>
);
};
export default HomeDashboard;