2024-03-15 03:07:18 +00:00
|
|
|
<template>
|
2024-04-28 02:34:21 +00:00
|
|
|
<div class="app-container">
|
2024-04-30 07:51:19 +00:00
|
|
|
<div class="item header">
|
|
|
|
<el-card>
|
|
|
|
<div class="card-header">
|
2024-05-08 06:00:09 +00:00
|
|
|
<ul>
|
|
|
|
<li><img :src="userStore.avatar" />{{ getGreeting() }}</li>
|
|
|
|
<li>
|
|
|
|
<el-button round>
|
|
|
|
<router-link target="_blank" to="/bigScreen">
|
|
|
|
<el-icon>
|
|
|
|
<FullScreen />
|
|
|
|
</el-icon><span>可视大屏</span>
|
|
|
|
</router-link>
|
|
|
|
</el-button>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
</el-card>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="item">
|
|
|
|
<el-card style="height: 200px;">
|
|
|
|
<template #header>
|
|
|
|
<div class="card-header">
|
|
|
|
<span>总用户数</span>
|
2024-04-30 07:51:19 +00:00
|
|
|
</div>
|
2024-05-08 06:00:09 +00:00
|
|
|
</template>
|
2024-04-30 07:51:19 +00:00
|
|
|
|
2024-05-08 06:00:09 +00:00
|
|
|
<div class="card-content">
|
2024-05-08 09:11:11 +00:00
|
|
|
<span class="font-num">{{ userNum }}</span>
|
2024-05-08 06:00:09 +00:00
|
|
|
</div>
|
|
|
|
</el-card>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="item">
|
|
|
|
<el-card style="height: 200px;">
|
|
|
|
<template #header>
|
|
|
|
<div class="card-header">
|
|
|
|
<span>总测评数</span>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<div class="card-content">
|
2024-05-08 09:11:11 +00:00
|
|
|
<span class="font-num">{{ evaluationNum }}</span>
|
2024-05-08 06:00:09 +00:00
|
|
|
</div>
|
|
|
|
</el-card>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="item">
|
|
|
|
<el-card style="height: 200px;">
|
|
|
|
<template #header>
|
|
|
|
<div class="card-header">
|
|
|
|
<span>总预警数</span>
|
2024-04-30 07:51:19 +00:00
|
|
|
</div>
|
2024-05-08 06:00:09 +00:00
|
|
|
</template>
|
|
|
|
|
|
|
|
<div class="card-content">
|
2024-05-08 09:11:11 +00:00
|
|
|
<span class="font-num">{{ warnNum }}</span>
|
2024-04-30 07:51:19 +00:00
|
|
|
</div>
|
|
|
|
</el-card>
|
|
|
|
</div>
|
2024-05-08 06:00:09 +00:00
|
|
|
|
|
|
|
<div class="item">
|
2024-04-30 07:51:19 +00:00
|
|
|
<el-card style="height: 200px;">
|
|
|
|
<template #header>
|
|
|
|
<div class="card-header">
|
2024-05-08 06:00:09 +00:00
|
|
|
<span>总干预数</span>
|
2024-04-30 07:51:19 +00:00
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<div class="card-content">
|
2024-05-08 09:11:11 +00:00
|
|
|
<span class="font-num">{{ interveneNum }}</span>
|
2024-04-30 07:51:19 +00:00
|
|
|
</div>
|
|
|
|
</el-card>
|
|
|
|
</div>
|
|
|
|
|
2024-05-08 06:00:09 +00:00
|
|
|
<div class="item item-chart">
|
|
|
|
<div>
|
|
|
|
<v-chart :option="leftPieOption" autoresize />
|
|
|
|
</div>
|
|
|
|
<div>
|
|
|
|
<v-chart :option="centerBarOption" autoresize />
|
|
|
|
</div>
|
|
|
|
<div>
|
|
|
|
<v-chart :option="rightBarOption" autoresize />
|
|
|
|
</div>
|
2024-04-30 07:51:19 +00:00
|
|
|
</div>
|
2024-03-15 03:07:18 +00:00
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script setup name="Index" lang="ts">
|
2024-05-08 09:11:11 +00:00
|
|
|
import { getUserNum, getEvaluationNum, getWarnNum, getInterveneNum, getWarn4All, getPublishNum, getGrade } from '@/api/index'
|
|
|
|
|
2024-04-30 07:51:19 +00:00
|
|
|
import * as echarts from 'echarts';
|
|
|
|
import { use } from 'echarts/core'
|
|
|
|
import { CanvasRenderer } from "echarts/renderers";
|
|
|
|
import { PieChart, BarChart, LineChart } from "echarts/charts";
|
2024-05-08 09:11:11 +00:00
|
|
|
import { TitleComponent, TooltipComponent, LegendComponent, ToolboxComponent, GridComponent, VisualMapComponent } from "echarts/components";
|
2024-04-30 07:51:19 +00:00
|
|
|
import VChart from 'vue-echarts'
|
|
|
|
|
|
|
|
import useUserStore from '@/store/modules/user';
|
|
|
|
const userStore = useUserStore();
|
|
|
|
|
|
|
|
use([
|
|
|
|
CanvasRenderer,
|
|
|
|
PieChart,
|
|
|
|
BarChart,
|
|
|
|
LineChart,
|
|
|
|
TitleComponent,
|
|
|
|
TooltipComponent,
|
|
|
|
LegendComponent,
|
|
|
|
ToolboxComponent,
|
2024-05-08 09:11:11 +00:00
|
|
|
GridComponent,
|
|
|
|
VisualMapComponent
|
2024-04-30 07:51:19 +00:00
|
|
|
]);
|
|
|
|
|
2024-05-08 06:00:09 +00:00
|
|
|
function getGreeting() {
|
|
|
|
// 获取当前时间
|
|
|
|
let timeNow = new Date();
|
|
|
|
// 获取当前小时
|
|
|
|
let hours = timeNow.getHours();
|
|
|
|
// 设置默认文字
|
|
|
|
let state = ``;
|
|
|
|
// 判断当前时间段
|
|
|
|
if (hours >= 0 && hours <= 10) {
|
|
|
|
state = `早上好, ${userStore.nickname}`;
|
|
|
|
} else if (hours > 10 && hours <= 14) {
|
|
|
|
state = `中午好, ${userStore.nickname}`;
|
|
|
|
} else if (hours > 14 && hours <= 18) {
|
|
|
|
state = `下午好, ${userStore.nickname}`;
|
|
|
|
} else if (hours > 18 && hours <= 24) {
|
|
|
|
state = `晚上好, ${userStore.nickname}`;
|
|
|
|
}
|
|
|
|
return state;
|
|
|
|
}
|
2024-03-15 03:07:18 +00:00
|
|
|
|
2024-05-08 06:00:09 +00:00
|
|
|
const leftPieOption = ref({
|
2024-04-30 07:51:19 +00:00
|
|
|
title: {
|
2024-05-08 06:00:09 +00:00
|
|
|
text: '预警统计',
|
|
|
|
subtext: '严重度',
|
|
|
|
x: 'center',
|
|
|
|
y: '40%',
|
|
|
|
textStyle: {
|
|
|
|
color: '#95989D',
|
|
|
|
fontSize: 20,
|
|
|
|
lineHeight: 10,
|
|
|
|
},
|
|
|
|
subtextStyle: {
|
|
|
|
color: '#95989D',
|
|
|
|
fontSize: 16,
|
|
|
|
lineHeight: 10,
|
|
|
|
},
|
2024-04-30 07:51:19 +00:00
|
|
|
},
|
|
|
|
tooltip: {
|
2024-05-08 06:00:09 +00:00
|
|
|
trigger: 'item',
|
|
|
|
formatter: "{b} : {c} ({d}%)"
|
2024-04-30 07:51:19 +00:00
|
|
|
},
|
2024-05-08 06:00:09 +00:00
|
|
|
|
|
|
|
visualMap: {
|
|
|
|
show: false,
|
|
|
|
min: 500,
|
|
|
|
max: 600,
|
|
|
|
inRange: {
|
|
|
|
//colorLightness: [0, 1]
|
|
|
|
}
|
|
|
|
},
|
|
|
|
series: [{
|
|
|
|
name: '访问来源',
|
|
|
|
type: 'pie',
|
|
|
|
radius: ['50%', '70%'],
|
|
|
|
center: ['50%', '50%'],
|
|
|
|
color: ['rgb(131,249,103)', '#FBFE27', '#FE5050', '#1DB7E5'], //'#FBFE27','rgb(11,228,96)','#FE5050'
|
2024-05-08 09:11:11 +00:00
|
|
|
data: [],
|
2024-05-08 06:00:09 +00:00
|
|
|
roseType: 'radius',
|
|
|
|
label: {
|
|
|
|
normal: {
|
2024-05-08 09:11:11 +00:00
|
|
|
formatter: ['{c|{c}人}', '{b|{b}}'].join('\n'),
|
2024-05-08 06:00:09 +00:00
|
|
|
rich: {
|
|
|
|
c: {
|
|
|
|
color: '#95989D',
|
|
|
|
fontSize: 20,
|
|
|
|
fontWeight: 'bold',
|
|
|
|
lineHeight: 5
|
|
|
|
},
|
|
|
|
b: {
|
|
|
|
color: '#95989D',
|
|
|
|
fontSize: 14,
|
|
|
|
height: 44
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
},
|
|
|
|
labelLine: {
|
|
|
|
normal: {
|
|
|
|
lineStyle: {
|
|
|
|
color: 'rgb(98,137,169)',
|
|
|
|
},
|
|
|
|
smooth: 0.2,
|
|
|
|
length: 10,
|
|
|
|
length2: 20,
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}]
|
|
|
|
})
|
|
|
|
|
2024-05-08 09:11:11 +00:00
|
|
|
async function getWarn4AllData() {
|
|
|
|
const res = await getWarn4All()
|
|
|
|
|
|
|
|
const data = [
|
|
|
|
{ name: '未见异常', value: res.data.noneNum },
|
|
|
|
{ name: '低风险', value: res.data.lowNum },
|
|
|
|
{ name: '中风险', value: res.data.middleNum },
|
|
|
|
{ name: '高风险', value: res.data.highNum },
|
|
|
|
{ name: '重大风险', value: res.data.majorNum }
|
|
|
|
]
|
|
|
|
|
|
|
|
leftPieOption.value.series[0].data = data
|
|
|
|
}
|
|
|
|
|
2024-05-08 06:00:09 +00:00
|
|
|
const centerBarOption = ref({
|
|
|
|
title: {
|
|
|
|
text: '年级统计',
|
|
|
|
x: 'right',
|
|
|
|
y: '1%',
|
|
|
|
textStyle: {
|
|
|
|
color: '#95989D',
|
|
|
|
fontSize: 20,
|
|
|
|
lineHeight: 10,
|
|
|
|
}
|
|
|
|
},
|
|
|
|
tooltip: {
|
|
|
|
trigger: 'axis',
|
|
|
|
axisPointer: { // 坐标轴指示器,坐标轴触发有效
|
|
|
|
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
|
|
|
}
|
|
|
|
},
|
|
|
|
legend: {
|
2024-05-08 09:11:11 +00:00
|
|
|
data: ['发布数', '测评数'],
|
2024-05-08 06:00:09 +00:00
|
|
|
right: 'center',
|
|
|
|
top: 0,
|
|
|
|
textStyle: {
|
|
|
|
color: "#95989D"
|
|
|
|
},
|
|
|
|
itemWidth: 12,
|
|
|
|
itemHeight: 10,
|
|
|
|
// itemGap: 35
|
|
|
|
},
|
|
|
|
grid: {
|
|
|
|
left: '0',
|
|
|
|
right: '20',
|
|
|
|
bottom: '0',
|
|
|
|
top: '15%',
|
|
|
|
containLabel: true
|
|
|
|
},
|
|
|
|
xAxis: {
|
|
|
|
type: 'category',
|
2024-05-08 09:11:11 +00:00
|
|
|
data: [],
|
2024-05-08 06:00:09 +00:00
|
|
|
axisLine: {
|
|
|
|
lineStyle: {
|
|
|
|
color: '#95989D'
|
|
|
|
}
|
|
|
|
},
|
|
|
|
axisLabel: {
|
|
|
|
//rotate:-90,
|
|
|
|
formatter: function (value: any) { return value.split("").join("\n"); },
|
|
|
|
textStyle: {
|
|
|
|
color: '#95989D',
|
|
|
|
fontSize: 14,
|
|
|
|
},
|
|
|
|
lineStyle: {
|
|
|
|
color: '#95989D',
|
2024-04-30 07:51:19 +00:00
|
|
|
}
|
|
|
|
}
|
2024-05-08 06:00:09 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
yAxis: {
|
|
|
|
type: 'value',
|
|
|
|
splitNumber: 4,
|
|
|
|
axisTick: { show: false },
|
|
|
|
splitLine: {
|
|
|
|
show: true,
|
|
|
|
lineStyle: {
|
|
|
|
color: '#95989D'
|
|
|
|
}
|
|
|
|
},
|
|
|
|
axisLabel: {
|
|
|
|
textStyle: {
|
|
|
|
color: '#95989D',
|
|
|
|
fontSize: 14,
|
|
|
|
}
|
|
|
|
},
|
|
|
|
axisLine: { show: false },
|
|
|
|
},
|
|
|
|
|
2024-05-08 09:11:11 +00:00
|
|
|
series: [
|
2024-04-30 07:51:19 +00:00
|
|
|
]
|
|
|
|
})
|
2024-05-08 06:00:09 +00:00
|
|
|
|
2024-05-08 09:11:11 +00:00
|
|
|
async function getGradeData() {
|
|
|
|
const res = await getGrade()
|
|
|
|
let xAxisData: any[] = []
|
|
|
|
let seriesPublishData: any[] = []
|
|
|
|
let seriesEvaluationData: any[] = []
|
|
|
|
|
|
|
|
res.data.forEach((v: any) => {
|
|
|
|
xAxisData.push(v.name)
|
|
|
|
seriesPublishData.push(v.value)
|
|
|
|
seriesEvaluationData.push(v.spareValue)
|
|
|
|
});
|
|
|
|
|
|
|
|
const seriesData = [{ name: '发布数', data: seriesPublishData, type: 'bar' }, { name: '测评数', data: seriesEvaluationData, type: 'bar' }]
|
|
|
|
centerBarOption.value.xAxis.data = xAxisData
|
|
|
|
centerBarOption.value.series = seriesData
|
|
|
|
}
|
|
|
|
|
2024-05-08 06:00:09 +00:00
|
|
|
const rightBarOption = ref({
|
|
|
|
title: {
|
2024-05-08 09:11:11 +00:00
|
|
|
text: '量表使用统计',
|
|
|
|
x: 'right',
|
2024-05-08 06:00:09 +00:00
|
|
|
y: '1%',
|
|
|
|
textStyle: {
|
|
|
|
color: '#95989D',
|
|
|
|
fontSize: 20,
|
|
|
|
lineHeight: 10,
|
|
|
|
}
|
|
|
|
},
|
2024-05-08 09:11:11 +00:00
|
|
|
tooltip: {
|
|
|
|
trigger: 'axis',
|
|
|
|
axisPointer: {
|
|
|
|
type: 'shadow'
|
|
|
|
}
|
|
|
|
},
|
2024-05-08 06:00:09 +00:00
|
|
|
grid: {
|
2024-05-08 09:11:11 +00:00
|
|
|
left: '3%',
|
|
|
|
right: '4%',
|
|
|
|
bottom: '3%',
|
2024-05-08 06:00:09 +00:00
|
|
|
containLabel: true
|
|
|
|
},
|
2024-05-08 09:11:11 +00:00
|
|
|
xAxis: {
|
|
|
|
type: 'value',
|
|
|
|
boundaryGap: [0, 0.01]
|
|
|
|
},
|
|
|
|
yAxis: {
|
|
|
|
type: 'category',
|
|
|
|
data: []
|
|
|
|
},
|
|
|
|
series: [
|
|
|
|
|
|
|
|
]
|
|
|
|
})
|
2024-05-08 06:00:09 +00:00
|
|
|
|
2024-05-08 09:11:11 +00:00
|
|
|
async function getPublishNumData() {
|
|
|
|
const res = await getPublishNum()
|
|
|
|
let yAxisData: any[] = []
|
|
|
|
let data: any[] = []
|
|
|
|
res.data.forEach((v: any) => {
|
|
|
|
yAxisData.push(v.name)
|
|
|
|
data.push(v.value)
|
|
|
|
});
|
|
|
|
|
|
|
|
const seriesData = [{ name: '量表使用次数', data: data, type: 'bar' }]
|
|
|
|
rightBarOption.value.yAxis.data = yAxisData
|
|
|
|
rightBarOption.value.series = seriesData
|
|
|
|
}
|
2024-05-08 06:00:09 +00:00
|
|
|
|
2024-05-08 09:11:11 +00:00
|
|
|
const userNum = ref(0)
|
|
|
|
async function getUserNumData() {
|
|
|
|
const res = await getUserNum()
|
|
|
|
userNum.value = res.data
|
|
|
|
}
|
|
|
|
|
|
|
|
const evaluationNum = ref(0)
|
|
|
|
async function getEvaluationNumData() {
|
|
|
|
const res = await getEvaluationNum()
|
|
|
|
evaluationNum.value = res.data
|
|
|
|
}
|
|
|
|
|
|
|
|
const warnNum = ref(0)
|
|
|
|
async function getWarnNumData() {
|
|
|
|
const res = await getWarnNum()
|
|
|
|
warnNum.value = res.data
|
|
|
|
}
|
|
|
|
|
|
|
|
const interveneNum = ref(0)
|
|
|
|
async function getInterveneNumData() {
|
|
|
|
const res = await getInterveneNum()
|
|
|
|
interveneNum.value = res.data
|
|
|
|
}
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
getUserNumData()
|
|
|
|
getEvaluationNumData()
|
|
|
|
getWarnNumData()
|
|
|
|
getInterveneNumData()
|
|
|
|
getPublishNumData()
|
|
|
|
|
|
|
|
getWarn4AllData()
|
|
|
|
getGradeData()
|
|
|
|
})
|
2024-05-08 06:00:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
// import { initWebSocket } from '@/utils/websocket';
|
|
|
|
|
|
|
|
// onMounted(() => {
|
|
|
|
// let protocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://'
|
|
|
|
// initWebSocket(protocol + window.location.host + import.meta.env.VITE_APP_BASE_API + "/resource/websocket");
|
|
|
|
// });
|
2024-03-15 03:07:18 +00:00
|
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
2024-05-08 09:11:11 +00:00
|
|
|
/* 声明字体*/
|
|
|
|
@font-face {
|
|
|
|
font-family: electronicFont;
|
|
|
|
src: url('@/assets/font/DS-DIGIT.TTF');
|
|
|
|
}
|
|
|
|
|
|
|
|
.font-num {
|
|
|
|
font-size: 80px;
|
|
|
|
color: #FE5050;
|
|
|
|
text-align: center;
|
|
|
|
font-family: 'electronicFont';
|
|
|
|
}
|
|
|
|
|
2024-04-28 02:34:21 +00:00
|
|
|
.app-container {
|
2024-04-30 07:51:19 +00:00
|
|
|
width: 100%;
|
2024-04-28 02:34:21 +00:00
|
|
|
height: calc(100vh - 85px);
|
2024-04-30 07:51:19 +00:00
|
|
|
display: grid;
|
|
|
|
grid-template-columns: repeat(4, 1fr);
|
|
|
|
grid-template-rows: 150px 200px 1fr;
|
2024-05-08 09:11:11 +00:00
|
|
|
gap: 5px;
|
2024-04-30 07:51:19 +00:00
|
|
|
background-color: #F3F3F3;
|
|
|
|
|
|
|
|
ul {
|
|
|
|
list-style-type: none;
|
|
|
|
}
|
|
|
|
|
|
|
|
.header {
|
|
|
|
grid-column: 1 / 5;
|
|
|
|
|
|
|
|
.card-header {
|
2024-05-08 06:00:09 +00:00
|
|
|
ul {
|
|
|
|
width: 100%;
|
2024-04-30 07:51:19 +00:00
|
|
|
display: flex;
|
2024-05-08 06:00:09 +00:00
|
|
|
justify-content: space-between;
|
2024-04-30 07:51:19 +00:00
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
img {
|
|
|
|
height: 80px;
|
|
|
|
border-radius: 50%;
|
|
|
|
margin-right: 20px;
|
2024-05-08 06:00:09 +00:00
|
|
|
vertical-align: middle;
|
2024-04-30 07:51:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.item-chart {
|
2024-05-08 06:00:09 +00:00
|
|
|
margin-top: 6px;
|
|
|
|
grid-column: 1 / 5;
|
|
|
|
display: flex;
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
|
|
div {
|
|
|
|
flex: 0 1 33%;
|
|
|
|
background-color: #fff;
|
|
|
|
padding: 20px 0;
|
|
|
|
}
|
2024-04-30 07:51:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
.item {
|
|
|
|
.card-header {
|
|
|
|
display: flex;
|
|
|
|
justify-content: space-between;
|
2024-05-08 09:11:11 +00:00
|
|
|
align-items: center;
|
2024-04-30 07:51:19 +00:00
|
|
|
color: #95989D;
|
|
|
|
font-size: 16px;
|
2024-05-08 09:11:11 +00:00
|
|
|
font-weight: bold;
|
|
|
|
}
|
|
|
|
|
|
|
|
.card-content {
|
|
|
|
display: flex;
|
|
|
|
justify-content: center;
|
|
|
|
align-items: center;
|
2024-04-30 07:51:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
.card-item-1 {
|
|
|
|
display: flex;
|
|
|
|
justify-content: space-between;
|
|
|
|
font-size: 20px;
|
|
|
|
padding: 20px 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
.card-item-2 {
|
|
|
|
display: flex;
|
|
|
|
justify-content: space-between;
|
|
|
|
font-size: 18px;
|
|
|
|
color: #95989D;
|
|
|
|
padding: 10px 0;
|
|
|
|
margin-left: -10px;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2024-03-15 03:07:18 +00:00
|
|
|
}
|
|
|
|
</style>
|