From 6a68772179bdb8a19bb6c0dfd8903e6dd26e4954 Mon Sep 17 00:00:00 2001 From: sunhonglei Date: Wed, 5 Mar 2025 18:51:28 +0800 Subject: [PATCH] =?UTF-8?q?=E8=80=83=E8=AF=95=E7=BB=9F=E8=AE=A1=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../examination/src/api/exam-online/index.tsx | 7 +- .../src/components/contentMain/index.js | 5 +- .../compoents/ExamStatisticsPage.tsx | 276 ++++++++++++++++++ .../src/views/exam-online/exam-statistics.tsx | 35 +++ .../examination/src/views/slider/menu.tsx | 6 +- 5 files changed, 325 insertions(+), 4 deletions(-) create mode 100644 packages/examination/src/views/exam-online/compoents/ExamStatisticsPage.tsx create mode 100644 packages/examination/src/views/exam-online/exam-statistics.tsx diff --git a/packages/examination/src/api/exam-online/index.tsx b/packages/examination/src/api/exam-online/index.tsx index ded6520..c7e5e47 100644 --- a/packages/examination/src/api/exam-online/index.tsx +++ b/packages/examination/src/api/exam-online/index.tsx @@ -77,4 +77,9 @@ export const paperStatusCheck = async () => { export const paperDeleteCheck = async () => { const response = await axios.get('/ex/exam-schedule/paperDeleteCheck'); return response.data; -}; \ No newline at end of file +}; +// 考试统计初期化 +export const examStatisticsInit = async () => { + const response = await axios.get('/ex/exam-statistics/init'); + return response.data; +}; diff --git a/packages/examination/src/components/contentMain/index.js b/packages/examination/src/components/contentMain/index.js index ec1481c..4238688 100644 --- a/packages/examination/src/components/contentMain/index.js +++ b/packages/examination/src/components/contentMain/index.js @@ -22,8 +22,8 @@ import Store from 'views/store_manage'; // 店铺管理 import DemoList from 'views/demo/demoList'; import ExamSchedule from "views/exam-online/exam-schedule"; import ExamAdd from "../../views/exam-online/exam-add"; -import ExamEdit from "../../views/exam-online/exam-edit"; // demo list - +import ExamEdit from "../../views/exam-online/exam-edit"; +import ExamStatistics from "../../views/exam-online/exam-statistics"; import Customer from 'views/statistical/list'; import CustomerDetail from 'views/statistical/detail'; import ExamDetail from "../../views/exam-online/exam-detail"; @@ -48,6 +48,7 @@ class ContentMain extends Component { + diff --git a/packages/examination/src/views/exam-online/compoents/ExamStatisticsPage.tsx b/packages/examination/src/views/exam-online/compoents/ExamStatisticsPage.tsx new file mode 100644 index 0000000..4f3c639 --- /dev/null +++ b/packages/examination/src/views/exam-online/compoents/ExamStatisticsPage.tsx @@ -0,0 +1,276 @@ +import React, { useEffect, useState, useRef } from 'react'; +import { Row, Col, Select, Table, Card } from 'antd'; +import ReactECharts from 'echarts-for-react'; +import {examStatisticsInit, getIndustryList} from "api/exam-online/index"; // 修改接口为获取带详情的试卷列表 + +const { Option } = Select; + +const examTableColumns = [ + { + title: '考试次数', + dataIndex: 'examTimes', + key: 'examTimes', + }, + { + title: '参与人数', + dataIndex: 'participants', + key: 'participants', + }, + { + title: '平均用时(分钟)', + dataIndex: 'averageTime', + key: 'averageTime', + }, + { + title: '合格率', + dataIndex: 'passRate', + key: 'passRate', + }, +]; +type initData = { + questionCount: number; + paperCount: number; + examCount: number; + industryDimensionData: { value: number; name: string }[]; + aqServiceDimensionData: { value: number; name: string }[]; + examTableData: { + key: string; + examTimes: number; + participants: number; + averageTime: number; + passRate: string; + }[]; + scoreDistributionData: { value: number; name: string }[]; + paperDistributionData: { value: number; name: string }[]; +}; +// 模拟题型占比数据 +const questionTypeDistributionData = [ + { value: 25, name: '选择题' }, + { value: 25, name: '填空题' }, + { value: 25, name: '判断题' }, + { value: 25, name: '简答题' }, +]; + +const Dashboard: React.FC = () => { + const industrySelectRef = useRef(null); + + // 定义状态来存储从后台获取的数据 + const [questionCount, setQuestionCount] = useState(0); + const [paperCount, setPaperCount] = useState(0); + const [examCount, setExamCount] = useState(0); + const [industryOptions, setIndustryOptions] = useState<{ value: string; label: string }[]>([]); + const [industryDimensionData, setIndustryDimensionData] = useState<{ value: number; name: string }[]>([]); + const [aqServiceDimensionData, setAqServiceDimensionData] = useState<{ value: number; name: string }[]>([]); + const [examTableData, setExamTableData] = useState<{ + key: string; + examTimes: number; + participants: number; + averageTime: number; + passRate: string; + }[]>([]); + const [scoreDistributionData, setScoreDistributionData] = useState<{ value: number; name: string }[]>([]); + const [paperDistributionData, setPaperDistributionData] = useState<{ value: number; name: string }[]>([]); + + // 新增状态来控制显示的数据 + const [showIndustryDimension, setShowIndustryDimension] = useState(true); + const [showAQServiceDimension, setShowAQServiceDimension] = useState(true); + + useEffect(() => { + // 模拟从后台获取数据 + const fetchData = async () => { + try { + // 获取监管行业列表 + const industryResponse = await getIndustryList(); + setIndustryOptions(industryResponse.map((item: any) => ({ value: item.industry_id, label: item.industry_name }))); + // 这里可以替换为实际的 API 请求 + const response:initData = await examStatisticsInit(); + // 更新状态 + setQuestionCount(response.questionCount); + setPaperCount(response.paperCount); + setExamCount(response.examCount); + + setIndustryDimensionData(response.industryDimensionData); + setAqServiceDimensionData(response.aqServiceDimensionData); + setExamTableData(response.examTableData); + setScoreDistributionData(response.scoreDistributionData); + setPaperDistributionData(response.paperDistributionData); + } catch (error) { + console.error('数据获取失败:', error); + } + }; + + fetchData(); + }, []); + + useEffect(() => { + // 可以在这里添加下拉框选择变化的监听逻辑 + if (industrySelectRef.current) { + industrySelectRef.current.addEventListener('change', () => { + // 处理选择变化逻辑 + }); + } + }, []); + + const handleSelectChange = (value: string) => { + console.log('Selected value:', value); + if (value === '') { + // 选择“全部” + setShowIndustryDimension(true); + setShowAQServiceDimension(true); + } else { + // 选择其他选项 + setShowIndustryDimension(false); + setShowAQServiceDimension(false); + } + }; + + // 环状图配置项生成函数 + const getRingChartOption = (data: { value: number; name: string }[]) => ({ + tooltip: { + trigger: 'item', + formatter: '{a}
{b}: {c} ({d}%)', + }, + legend: { + orient: 'vertical', + right: 10, + top: 'center', + data: data.map(item => item.name), + }, + series: [ + { + name: '占比', + type: 'pie', + radius: ['30%', '50%'], // 设置为环状图 + center: ['40%', '50%'], + data, + }, + ], + }); + const getPieChartOption = (data: { value: number; name: string }[]) => ({ + tooltip: { + trigger: 'item', + formatter: '{a}
{b}: {c} ({d}%)', + }, + legend: { + orient: 'vertical', + right: 10, + top: 'center', + data: data.map(item => item.name), + }, + series: [ + { + name: '占比', + type: 'pie', + radius: '50%', + center: ['40%', '50%'], + data, + }, + ], + }); + + return ( +
+ {/* 第一行:试题数、试卷数、考试次数 */} + + +
+

试题{questionCount}条

+
+ + +
+

试卷{paperCount}套

+
+ + +
+

考试{examCount}次

+
+ +
+ + {/* 下面分为左右两部分 */} + + {/* 左半区:题库情况 */} + + + 题库情况 + + 监管行业: + + +
+ )} + > + {/* 监管行业维度统计环状图 */} + {showIndustryDimension && ( +
+

监管行业维度统计

+ +
+ )} + {!showIndustryDimension && ( +
+

AQ 服务类型维度统计

+ +
+ )} +
+ {/* AQ 服务类型维度统计环状图 */} + {showAQServiceDimension && ( +
+

AQ 服务类型维度统计

+ +
+ )} + {!showAQServiceDimension && ( +
+

题型占比

+ +
+ )} + + + {/* 右半区:考试情况和试卷情况 */} + + {/* 考试情况 */} + + 考试情况 + {('详情>>')} + + )} + > + {/* 考试情况表格 */} + + + + {/* 试卷情况环状图 */} + + 试卷情况 + {('详情>>')} + + )} + style={{ marginTop: 20 }} + > + + + + + + ); +}; + +export default Dashboard; \ No newline at end of file diff --git a/packages/examination/src/views/exam-online/exam-statistics.tsx b/packages/examination/src/views/exam-online/exam-statistics.tsx new file mode 100644 index 0000000..649ea38 --- /dev/null +++ b/packages/examination/src/views/exam-online/exam-statistics.tsx @@ -0,0 +1,35 @@ +import React, { Component } from "react"; +import Dashboard from "./compoents/ExamStatisticsPage"; + +interface States { + resData: any + visible: boolean + title: string + current: any +} + +class ExamStatistics extends Component { + constructor(props: any) { + super(props); + this.state = { + resData: undefined, + visible: false, + title: '新增公告', + current: {} + } + } + + componentDidMount() { + // this.getList() + } + + render() { + return ( +
+ +
+ ) + } +} + +export default ExamStatistics; \ No newline at end of file diff --git a/packages/examination/src/views/slider/menu.tsx b/packages/examination/src/views/slider/menu.tsx index 85094c7..fb143a5 100644 --- a/packages/examination/src/views/slider/menu.tsx +++ b/packages/examination/src/views/slider/menu.tsx @@ -26,11 +26,15 @@ const menuList = [ { title: '线上考试', key: 'exam-online', - // icon: 'icon-peizhi', + icon: 'icon-peizhi', subs: [ { title: '考试安排', key: 'exam-schedule', + }, + { + title: '考试统计', + key: 'exam-statistics', } ] },