mental-health-web/src/views/index.vue

507 lines
10 KiB
Vue
Raw Normal View History

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>