Merge remote-tracking branch 'origin/main'

main
hujunpeng 4 months ago
commit 079c6c5a2b
  1. 5
      packages/examination/src/api/exam-online/index.tsx
  2. 5
      packages/examination/src/components/contentMain/index.js
  3. 276
      packages/examination/src/views/exam-online/compoents/ExamStatisticsPage.tsx
  4. 35
      packages/examination/src/views/exam-online/exam-statistics.tsx
  5. 6
      packages/examination/src/views/slider/menu.tsx

@ -78,3 +78,8 @@ export const paperDeleteCheck = async () => {
const response = await axios.get('/ex/exam-schedule/paperDeleteCheck'); const response = await axios.get('/ex/exam-schedule/paperDeleteCheck');
return response.data; return response.data;
}; };
// 考试统计初期化
export const examStatisticsInit = async () => {
const response = await axios.get('/ex/exam-statistics/init');
return response.data;
};

@ -22,8 +22,8 @@ import Store from 'views/store_manage'; // 店铺管理
import DemoList from 'views/demo/demoList'; import DemoList from 'views/demo/demoList';
import ExamSchedule from "views/exam-online/exam-schedule"; import ExamSchedule from "views/exam-online/exam-schedule";
import ExamAdd from "../../views/exam-online/exam-add"; 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 Customer from 'views/statistical/list';
import CustomerDetail from 'views/statistical/detail'; import CustomerDetail from 'views/statistical/detail';
import ExamDetail from "../../views/exam-online/exam-detail"; import ExamDetail from "../../views/exam-online/exam-detail";
@ -55,6 +55,7 @@ class ContentMain extends Component {
<Route exact path='/exam-add' component={ ExamAdd }/> <Route exact path='/exam-add' component={ ExamAdd }/>
<Route exact path='/exam-edit' component={ ExamEdit }/> <Route exact path='/exam-edit' component={ ExamEdit }/>
<Route exact path='/exam-detail' component={ ExamDetail }/> <Route exact path='/exam-detail' component={ ExamDetail }/>
<Route exact path='/exam-statistics' component={ ExamStatistics }/>
<Route exact path='/questionList' component={ QuestionList }/> <Route exact path='/questionList' component={ QuestionList }/>
<Route exact path='/questionAdd' component={ QuestionAdd }/> <Route exact path='/questionAdd' component={ QuestionAdd }/>
<Route exact path='/questionUp' component={ QuestionUp }/> <Route exact path='/questionUp' component={ QuestionUp }/>

@ -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<HTMLSelectElement>(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} <br/>{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} <br/>{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 (
<div style={{ padding: 20 }}>
{/* 第一行:试题数、试卷数、考试次数 */}
<Row gutter={16}>
<Col span={8}>
<div style={{ textAlign: 'center', background: '#DCE4F8', height: 60 }}>
<p>{questionCount}</p>
</div>
</Col>
<Col span={8}>
<div style={{ textAlign: 'center', background: '#DCE4F8', height: 60 }}>
<p>{paperCount}</p>
</div>
</Col>
<Col span={8}>
<div style={{ textAlign: 'center', background: '#DCE4F8', height: 60 }}>
<p>{examCount}</p>
</div>
</Col>
</Row>
{/* 下面分为左右两部分 */}
<Row gutter={16} style={{ marginTop: 20 }}>
{/* 左半区:题库情况 */}
<Col span={12}>
<Card
title={(
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span></span>
<span>
<Select placeholder="请选择监管行业" onChange={handleSelectChange} style={{ width: 180 }} defaultValue="">
<Option key="" value=""></Option>
{industryOptions.map(option => (
<Option key={option.value} value={option.value}>
{option.label}
</Option>
))}
</Select>
</span>
</div>
)}
>
{/* 监管行业维度统计环状图 */}
{showIndustryDimension && (
<div style={{ marginBottom: 20 }}>
<h3></h3>
<ReactECharts option={getRingChartOption(industryDimensionData)} />
</div>
)}
{!showIndustryDimension && (
<div style={{ marginBottom: 20 }}>
<h3>AQ </h3>
<ReactECharts option={getRingChartOption(aqServiceDimensionData)} />
</div>
)}
<hr style={{ border: '1px solid #e8e8e8', marginBottom: 20 }} />
{/* AQ 服务类型维度统计环状图 */}
{showAQServiceDimension && (
<div>
<h3>AQ </h3>
<ReactECharts option={getRingChartOption(aqServiceDimensionData)} />
</div>
)}
{!showAQServiceDimension && (
<div>
<h3></h3>
<ReactECharts option={getRingChartOption(questionTypeDistributionData)} />
</div>
)}
</Card>
</Col>
{/* 右半区:考试情况和试卷情况 */}
<Col span={12}>
{/* 考试情况 */}
<Card
title={(
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span></span>
<a>{('详情>>')}</a>
</div>
)}
>
{/* 考试情况表格 */}
<Table columns={examTableColumns} dataSource={examTableData} pagination={false} />
<ReactECharts option={getPieChartOption(scoreDistributionData)} />
</Card>
{/* 试卷情况环状图 */}
<Card
title={(
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span></span>
<a>{('详情>>')}</a>
</div>
)}
style={{ marginTop: 20 }}
>
<ReactECharts option={getRingChartOption(paperDistributionData)} />
</Card>
</Col>
</Row>
</div>
);
};
export default Dashboard;

@ -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<any, States> {
constructor(props: any) {
super(props);
this.state = {
resData: undefined,
visible: false,
title: '新增公告',
current: {}
}
}
componentDidMount() {
// this.getList()
}
render() {
return (
<div className="container">
<Dashboard />
</div>
)
}
}
export default ExamStatistics;

@ -26,11 +26,15 @@ const menuList = [
{ {
title: '线上考试', title: '线上考试',
key: 'exam-online', key: 'exam-online',
// icon: 'icon-peizhi', icon: 'icon-peizhi',
subs: [ subs: [
{ {
title: '考试安排', title: '考试安排',
key: 'exam-schedule', key: 'exam-schedule',
},
{
title: '考试统计',
key: 'exam-statistics',
} }
] ]
}, },

Loading…
Cancel
Save