增加首页图表

This commit is contained in:
孙景学
2025-07-22 15:26:17 +08:00
parent c57f3b74f5
commit 6a71041400
4 changed files with 251 additions and 7 deletions

View File

@ -55,6 +55,7 @@
"not ie <= 10"
],
"dependencies": {
"@ant-design/charts": "^1.2.11",
"@ant-design/icons": "4.6.2",
"@ant-design/pro-card": "1.11.8",
"@ant-design/pro-descriptions": "1.7.0",

View File

@ -1,7 +1,193 @@
import React, { useState } from 'react';
import './index.less';
const IndexPage: React.FC = () => {
return <div></div>;
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 IndexPage;
export default HomeDashboard;

View File

@ -0,0 +1,55 @@
import request from '@/utils/request';
/**
*
* @param params
* @returns
* 统计每年注册的供应商数量
*/
export const getYearcountNum = () => request.get(`/homeStatistics/getYearcountNum`);
/**
*
* @param params
* @returns
* 统计准入类别数量
*/
export const getAccessTypeCountNum = () => request.get(`/homeStatistics/getAccessTypeCountNum`);
/**
*
* @param params
* @returns
* 统计供应商身份类别数量
*/
export const getSupplierTypeCountNum = () => request.get(`/homeStatistics/getSupplierTypeCountNum`);
/**
*
* @param params
* @returns
* 未启动数量
* private Integer noStartNum;
* 进行中数量
* private Integer doingNum;
* 完成数量
* private Integer completeNum;
*/
export const getSupplierAuditCountNum = () => request.get(`/homeStatistics/getAnnualrviewCountNum`);
/**
*
* @param params
* @returns
* 评价任务数量查询 getAccessFlowCountNum getSupplierAuditCountNum
* 未启动数量
* private Integer noStartNum;
* 进行中数量
* private Integer doingNum;
* 审核中数量
* private Integer auditNum;
* 完成数量
* private Integer completeNum;
*/
export const getAccessFlowCountNum = () => request.get(`/homeStatistics/getEvaluateCountNum`);

View File

@ -218,9 +218,11 @@ const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ vi
});
} else {
// 供应商符合性审查
if(values.supplierCompliance) {
finalPayload.coscoAccessWorkAttachments = values.supplierCompliance[0].response;
finalPayload.coscoAccessWorkAttachments.fileUrl = values.supplierCompliance[0].response.url;
}
}
const res = await add(finalPayload);
if (res?.success) {
message.success('创建成功');