| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 |
- <template>
- <div class="main_container custom_container">
- <div class="page_item end_item">
- <!-- 当前在线人数 -->
- <div class="page_search">
- <div class="search_content">
- <div class="content_left">
- <div class="grade_title">当前在线人数</div>
- </div>
- </div>
- </div>
- <div class="page_jg_20"></div>
- <ul class="cardBoard">
- <li v-for="card in cardBoardList" :key="card.label">
- <div class="label">{{ card.label }}</div>
- <div class="num">{{ card.value }}</div>
- </li>
- </ul>
-
- <!-- 模块列表 -->
- <div class="page_jg_20"></div>
- <TabSearch tabType="line" :tabList="onlineTypeTablist" :defaultTabKey="defaultOnlineTypeTab">
- </TabSearch>
- <!-- 时间范围 -->
- <div class="page_jg_20"></div>
- <TabSearch tabType="box" :tabList="dateRangeTablist" :defaultTabKey="defaultDateRangeTab">
- </TabSearch>
- <!-- 图表 -->
- <div class="page_jg_20"></div>
- <div class="chart_box">
- <!-- 某段时间的 某类型 在线人数统计 -->
- <div class="chart">
- <div class="page_search">
- <div class="search_content">
- <div class="content_left">
- <div class="grade_title">{{ onLineType }}在线人数统计</div>
- </div>
- </div>
- </div>
- <LineChart reportHeight="244px" :datax="somePeriodTimeLineData.datax"
- :datay="somePeriodTimeLineData.datay" :showCheckBox="false">
- </LineChart>
- </div>
- <!-- 某一时刻的 某类型 在线人数统计 -->
- <div class="chart">
- <div class="page_search">
- <div class="search_content">
- <div class="content_left">
- <div class="grade_title">{{ onLineTime }}时 / {{ onLineType }} 在线人数统计</div>
- </div>
- </div>
- </div>
- <MultipleBarCharts :datax="someoneTimeBarData.datax" :datay="someoneTimeBarData.datay"
- :height="244">
- </MultipleBarCharts>
- </div>
- <div class="chart">
- <!-- 某个学校的当天在线人数统计 -->
- <div class="page_search">
- <div class="search_content">
- <div class="content_left">
- <div class="grade_title">{{ schoolName }} / 当天在线人数统计</div>
- </div>
- </div>
- </div>
- <TabSearch :tabList="visualizationTypeTablist" tabType="box"
- :defaultTabKey="defaultVisualizationTypeTab"
- @tabChange="(val) => HandleTabChange('visualizationType', val)">
- </TabSearch>
- <LineChart v-if="defaultVisualizationTypeTab == 'chart'" reportHeight="208px"
- :datax="someSchoolOneDayBarData.datax" :datay="someSchoolOneDayBarData.datay"
- :showCheckBox="false">
- </LineChart>
- <template v-if="defaultVisualizationTypeTab == 'table'">
- <div class="page_search">
- <div class="search_content">
- <div class="content_left"></div>
- <div class="content_right">
- <el-button class="button_refresh">导出</el-button>
- </div>
- </div>
- </div>
- <div class="page_jg_20"></div>
- <Table :tableColumns="tableColumns" :tableData="someSchoolOneDayTableData">
- </Table>
- </template>
- </div>
- </div>
- </div>
- </div>
- </template>
- <script setup lang="ts">
- import TabSearch from '@/baseComponents/TabSearch.vue';
- import Table from '@/baseComponents/Table.vue';
- import { computed, reactive, ref, onMounted } from 'vue';
- import { onlineTypeTablist, dateRangeTablist, visualizationTypeTablist } from './tabSearch';
- import { tableColumns } from './table'
- import { getHeadData, getModuleList, getChartData } from '@/api/performanceMonitor'
- import MultipleBarCharts from '@/baseComponents/MultipleBarCharts.vue';
- import LineChart from '@/baseComponents/LineChart.vue';
- // 看板数据
- const boardMsg = reactive({
- teacherOnline: 0,
- studentOnline: 0,
- scaneOnline: 0,
- examinationPaperOnline: 0,
- analysisOnline: 0
- })
- // 看板列表
- const cardBoardList = computed(() => [
- {
- label: '教师在线',
- value: boardMsg.teacherOnline
- },
- {
- label: '学生在线',
- value: boardMsg.studentOnline
- },
- {
- label: '使用扫描人数',
- value: boardMsg.scaneOnline
- },
- {
- label: '使用阅卷人数',
- value: boardMsg.examinationPaperOnline
- },
- {
- label: '使用分析人数',
- value: boardMsg.analysisOnline
- },
- ])
- // 图表数据
- const onLineType = ref('学校教师') // 在线类型
- const schoolName = ref('北京师范大学附属中学') //学校名称
- // 某段时间的 某类型 在线人数统计
- const somePeriodTimeLineData = reactive({
- datax: ['0时', '1时', '2时', '3时', '4时', '5时', '6时', '7时', '8时', '9时', '10时'],
- datay: [
- [233, 43, 56, 43, 44, 34, 5, 65, 76, 87, 853],
- ]
- })
- // 某一时刻的 某类型 在线人数统计
- const onLineTime = ref(0)
- const someoneTimeBarData = reactive({
- datax: ['北京师范大学附属中学', '师达', '交大分校', '本部高中', '本部初中'],
- datay: [233, 43, 56, 43, 44]
- })
- // 某个学校的当天在线人数统计 折线图数据
- const someSchoolOneDayBarData = reactive({
- datax: ['0时', '1时', '2时', '3时', '4时', '5时', '6时', '7时', '8时', '9时', '10时'],
- datay: [
- [233, 43, 56, 43, 44, 34, 5, 65, 76, 87, 853],
- ]
- })
- // 某个学校的当天在线人数统计 表格数据
- const someSchoolOneDayTableData = ref([
- {
- num: 1, // 如果使用 type="index",这个字段其实可以不需要
- school: '北京师范大学附属中学',
- account: 'teacher01',
- name: '白语忱',
- operationDetail: '系统登录',
- operationTime: '2026-07-14 08:22:15',
- },
- {
- num: 2,
- school: '北京师范大学附属中学',
- account: 'teacher05',
- name: '曹延熠',
- operationDetail: '系统登录',
- operationTime: '2026-07-14 10:05:12',
- },
- ])
- // 处理tab切换相关操作
- const defaultOnlineTypeTab = ref('teacherOnline') // 默认的在线类型
- const defaultDateRangeTab = ref('today') // 默认的 时间范围
- const defaultVisualizationTypeTab = ref('chart') // 默认的 某个学校的当天在线人数 的可视化展示类型
- const HandleTabChange = (type: string, val: string) => {
- switch (type) {
- case 'visualizationType':
- defaultVisualizationTypeTab.value = val
- break
- }
- }
- // 获取头部数据
- const fetchHeadData = async () => {
- try {
- const res = await getHeadData()
- const data = res.data || res
- boardMsg.teacherOnline = data.teacherLoginNum ?? 0
- boardMsg.studentOnline = data.studentLoginNum ?? 0
- boardMsg.scaneOnline = data.scannedNum ?? 0
- boardMsg.examinationPaperOnline = data.markingNum ?? 0
- boardMsg.analysisOnline = data.reportNum ?? 0
- } catch (err) {
- console.error('getHeadData 请求失败:', err)
- }
- }
- // 获取模块列表
- const fetchModuleList = async () => {
- try {
- const res = await getModuleList()
- // console.log('getModuleList 响应数据:', res)
- const data = res.data || res
- // 筛选"在线"相关的模块,映射为 tabList 格式
- const onlineList = (data || []).map((item: any) => ({
- key: String(item.code),
- label: item.name
- }))
- if (onlineList.length) {
- onlineTypeTablist.value = onlineList
- defaultOnlineTypeTab.value = onlineList[0].key
- }
- } catch (err) {
- console.error('getModuleList 请求失败:', err)
- }
- }
- // 获取图表数据
- const fetchChartData = async () => {
- try {
- const res = await getChartData({
- schoolId: 0,
- timeType: 0,
- moduleCode: 0,
- startTime: '',
- endTime: '',
- })
- // console.log('getChartData 响应数据:', res)
- const data = res.data || res
- if (data) {
-
- // somePeriodTimeLineData.datax = data.map((item: any) => item.xname)
- // somePeriodTimeLineData.datay = data.map((item: any) => item.count)
- // somePeriodTimeLineData.datax = data.xname
- // somePeriodTimeLineData.datay = data.count
- }
- } catch (err) {
- console.error('getChartData 请求失败:', err)
- }
- }
- onMounted(() => {
- fetchHeadData()
- fetchModuleList()
- fetchChartData()
- })
- </script>
- <style lang="scss" scoped>
- .cardBoard {
- display: grid;
- grid-template-columns: repeat(5, 1fr);
- gap: 20px;
- li {
- background-color: #f2f2f2;
- padding: 20px;
- border-radius: 8px;
- .label {
- font-size: 16px;
- }
- .num {
- font-size: 34px;
- font-weight: 600;
- }
- }
- }
- .chart_box {
- display: flex;
- flex-direction: column;
- gap: 10px;
- .chart {
- border: 1px solid #dcdfe6;
- min-height: 320px;
- padding: 20px;
- }
- }
- </style>
|