commit
079c6c5a2b
5 changed files with 325 additions and 4 deletions
@ -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; |
Loading…
Reference in new issue