|
@@ -1,6 +1,14 @@
|
|
|
<script setup lang="ts">
|
|
|
-import { watch } from "vue";
|
|
|
-import { useUserStore } from "@/store/modules/user";
|
|
|
+import {watch} from "vue";
|
|
|
+import {useUserStore} from "@/store/modules/user";
|
|
|
+import {AreaCard, DashboardData} from "@/api/dashboard/types";
|
|
|
+import AreaDataCard from "@/views/areaboard/components/AreaDataCard.vue";
|
|
|
+import LiquidChart from "@/views/charts-components/LiquidChart.vue";
|
|
|
+import PercentBarChart from "@/views/charts-components/PercentBarChart.vue";
|
|
|
+import CircleChart from "@/views/charts-components/CircleChart.vue";
|
|
|
+import {getDashboardData} from "@/api/dashboard";
|
|
|
+import LineChart from "@/views/charts-components/LineChart.vue";
|
|
|
+import AverageBarChart from "@/views/charts-components/AverageBarChart.vue";
|
|
|
|
|
|
defineOptions({
|
|
|
name: "DashboardArea",
|
|
@@ -15,28 +23,345 @@ watch(
|
|
|
);
|
|
|
|
|
|
const date = ref("");
|
|
|
+/**
|
|
|
+ * 数据卡片
|
|
|
+ */
|
|
|
+let cards: AreaCard = reactive({
|
|
|
+ student: 0, // 样本人数
|
|
|
+ game: 0, // 累计训练次数
|
|
|
+ school: 10, // 全部班级
|
|
|
+});
|
|
|
+/**
|
|
|
+ * 图表数据
|
|
|
+ */
|
|
|
+const chartStatus = ref(false);
|
|
|
+let chartData: DashboardData = reactive({
|
|
|
+ frontAverage: 0, // 初期专注力估值
|
|
|
+ afterAverage: 0, // 近期专注力估值
|
|
|
+ front: 0, // 初期50分以上的占比
|
|
|
+ after: 0, // 近期50分以上的占比
|
|
|
+ frontProportion: { num: [], percentage: [] }, // 初期分期占比分析
|
|
|
+ afterProportion: { num: [], percentage: [] }, // 近期分期占比分析
|
|
|
+});
|
|
|
+async function getChartData(gradeId: number) {
|
|
|
+ getDashboardData(gradeId)
|
|
|
+ .then(({ data }) => {
|
|
|
+ chartData = <DashboardData>{ ...data };
|
|
|
+ if (chartData.frontAverage > 0) {
|
|
|
+ chartStatus.value = true;
|
|
|
+ dataStatus.value = 1;
|
|
|
+ } else {
|
|
|
+ dataStatus.value = 2;
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch((error) => {
|
|
|
+ console.log(error.toString());
|
|
|
+ dataStatus.value = 2;
|
|
|
+ });
|
|
|
+}
|
|
|
+// 数据状态:1正常,2训练次数小于3,3过期,4缺省
|
|
|
+const dataStatus = ref(5);
|
|
|
+onMounted(() => {
|
|
|
+ // 图表数据
|
|
|
+ getChartData(0);
|
|
|
+});
|
|
|
+const indicatorsData = ref([
|
|
|
+ [50, 60, 55, 64.5],
|
|
|
+ [55, 90, 70, 82.5],
|
|
|
+]);
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
<div class="area-container">
|
|
|
<div class="area-top">
|
|
|
- <el-date-picker
|
|
|
- v-model="date"
|
|
|
- type="daterange"
|
|
|
- start-placeholder="开始日期"
|
|
|
- end-placeholder="结束日期"
|
|
|
- :default-value="[new Date(2023, 6, 1), new Date(2030, 10, 1)]"
|
|
|
- />
|
|
|
+ <div class="search-box">
|
|
|
+ <el-select placeholder="全部省" size="large">
|
|
|
+ <el-option key="0" label="全部省" :value="Number(0)" />
|
|
|
+ <el-option key="1" label="省1" :value="Number(1)" />
|
|
|
+ <el-option key="1" label="省2" :value="Number(2)" />
|
|
|
+ </el-select>
|
|
|
+ <el-select placeholder="全部市" size="large">
|
|
|
+ <el-option key="0" label="全部市" :value="Number(0)" />
|
|
|
+ <el-option key="1" label="市1" :value="Number(1)" />
|
|
|
+ <el-option key="1" label="市2" :value="Number(2)" />
|
|
|
+ </el-select>
|
|
|
+ <el-select placeholder="全龄" size="large">
|
|
|
+ <el-option key="0" label="全龄" :value="Number(0)" />
|
|
|
+ <el-option key="1" label="1岁" :value="Number(1)" />
|
|
|
+ <el-option key="1" label="2岁" :value="Number(2)" />
|
|
|
+ </el-select>
|
|
|
+ <div>
|
|
|
+ <el-date-picker
|
|
|
+ v-model="date"
|
|
|
+ type="daterange"
|
|
|
+ size="large"
|
|
|
+ start-placeholder="开始日期"
|
|
|
+ end-placeholder="结束日期"
|
|
|
+ :default-value="[new Date(2023, 6, 1), new Date(2030, 10, 1)]"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <el-button size="large" type="primary">查找</el-button>
|
|
|
+ </div>
|
|
|
+ <div class="card-box">
|
|
|
+ <AreaDataCard :schools="cards.school" :games="cards.game" :students="cards.student"/>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
+ <div class="search-box s2">
|
|
|
+ <el-select placeholder="全部省" size="large">
|
|
|
+ <el-option key="0" label="全部省" :value="Number(0)" />
|
|
|
+ <el-option key="1" label="省1" :value="Number(1)" />
|
|
|
+ <el-option key="1" label="省2" :value="Number(2)" />
|
|
|
+ </el-select>
|
|
|
+ <el-select placeholder="全部市" size="large">
|
|
|
+ <el-option key="0" label="全部市" :value="Number(0)" />
|
|
|
+ <el-option key="1" label="市1" :value="Number(1)" />
|
|
|
+ <el-option key="1" label="市2" :value="Number(2)" />
|
|
|
+ </el-select>
|
|
|
+ <el-select placeholder="全龄" size="large">
|
|
|
+ <el-option key="0" label="全龄" :value="Number(0)" />
|
|
|
+ <el-option key="1" label="1岁" :value="Number(1)" />
|
|
|
+ <el-option key="1" label="2岁" :value="Number(2)" />
|
|
|
+ </el-select>
|
|
|
+ <el-button size="large" type="primary">查找</el-button>
|
|
|
+ </div>
|
|
|
+ <!-- Echarts 图表 -->
|
|
|
+ <div class="charts-container">
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :md="24" :lg="12" :xl="8">
|
|
|
+ <div class="charts-item">
|
|
|
+ <p class="title">学员专注力平均值整体对比分析</p>
|
|
|
+ <el-row justify="space-between">
|
|
|
+ <el-col :xs="24" :sm="12">
|
|
|
+ <div v-if="chartStatus" class="item">
|
|
|
+ <LiquidChart
|
|
|
+ id="liquidChart1"
|
|
|
+ :key="chartData.frontAverage"
|
|
|
+ :data="chartData.frontAverage ? chartData.frontAverage : 0"
|
|
|
+ height="200px"
|
|
|
+ width="200px"
|
|
|
+ color="#3a7fc2"
|
|
|
+ bg-color="#accded"
|
|
|
+ class="chart"
|
|
|
+ />
|
|
|
+ <p>全体学员初期</p>
|
|
|
+ <p>专注力评估均值</p>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :xs="24" :sm="12">
|
|
|
+ <div v-if="chartStatus" class="item">
|
|
|
+ <LiquidChart
|
|
|
+ id="liquidChart2"
|
|
|
+ :key="chartData.afterAverage"
|
|
|
+ :data="chartData.afterAverage ? chartData.afterAverage : 0"
|
|
|
+ height="200px"
|
|
|
+ width="200px"
|
|
|
+ color="#5563ac"
|
|
|
+ bg-color="#cacce6"
|
|
|
+ class="chart"
|
|
|
+ />
|
|
|
+ <p>全体学员训练近期</p>
|
|
|
+ <p>专注力评估均值</p>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-row justify="space-between">
|
|
|
+ <el-col :xs="24" :sm="12">
|
|
|
+ <div v-if="chartStatus" class="item">
|
|
|
+ <CircleChart
|
|
|
+ id="circleChart1"
|
|
|
+ :key="chartData.front"
|
|
|
+ :data="chartData.front ? chartData.front : 0"
|
|
|
+ height="200px"
|
|
|
+ width="200px"
|
|
|
+ color="#3a7fc2"
|
|
|
+ bg-color="#e4e7f4"
|
|
|
+ font-color="#3a7fc2"
|
|
|
+ font-size="30px"
|
|
|
+ :round-cap="Boolean(true)"
|
|
|
+ />
|
|
|
+ <p>初期训练</p>
|
|
|
+ <p>专注力50以上人数比例</p>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :xs="24" :sm="12">
|
|
|
+ <div v-if="chartStatus" class="item">
|
|
|
+ <CircleChart
|
|
|
+ id="circleChart2"
|
|
|
+ :key="chartData.after.toString()"
|
|
|
+ :data="chartData.after ? chartData.after : 0"
|
|
|
+ height="200px"
|
|
|
+ width="200px"
|
|
|
+ color="#5563ac"
|
|
|
+ bg-color="#e4e7f4"
|
|
|
+ font-color="#5563ac"
|
|
|
+ font-size="30px"
|
|
|
+ :round-cap="Boolean(true)"
|
|
|
+ />
|
|
|
+ <p>近期训练</p>
|
|
|
+ <p>专注力50以上人数比例</p>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <!-- 学员专注力评分分级占比分析 -->
|
|
|
+ <el-col :md="24" :lg="12" :xl="16">
|
|
|
+ <div class="charts-item">
|
|
|
+ <p class="title">样本每次训练专注力评分均值整体变化曲线</p>
|
|
|
+ <line-chart id="lineChart1" width="1000px" height="558px"/>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+ <div class="charts-container">
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :md="24" :lg="12" :xl="8">
|
|
|
+ <div class="charts-item">
|
|
|
+ <p class="title">学员专注力训练高专注占比分析</p>
|
|
|
+ <AverageBarChart
|
|
|
+ id="averageBarChart1"
|
|
|
+ :data-sets="indicatorsData"
|
|
|
+ width="400px"
|
|
|
+ height="300px"
|
|
|
+ class="chart"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <!-- 学员专注力评分分级占比分析 -->
|
|
|
+ <el-col :md="24" :lg="12" :xl="16">
|
|
|
+ <div class="charts-item">
|
|
|
+ <p class="title">学员专注力评分分级占比分析</p>
|
|
|
+ <el-row justify="space-between">
|
|
|
+ <el-col :xs="24" :sm="24" :md="12" :lg="24" :xl="12">
|
|
|
+ <div v-if="chartStatus" class="bar">
|
|
|
+ <PercentBarChart
|
|
|
+ id="barChart1"
|
|
|
+ :key="chartData.frontProportion.toString()"
|
|
|
+ width="400px"
|
|
|
+ height="500px"
|
|
|
+ title="全体学员初期训练专注力评分占比"
|
|
|
+ :percent="chartData.frontProportion.percentage"
|
|
|
+ :data="chartData.frontProportion.num"
|
|
|
+ class="chart"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :xs="24" :sm="24" :md="12" :lg="24" :xl="12">
|
|
|
+ <div v-if="chartStatus" class="bar">
|
|
|
+ <PercentBarChart
|
|
|
+ id="barChart2"
|
|
|
+ :key="chartData.afterProportion.toString()"
|
|
|
+ width="400px"
|
|
|
+ height="500px"
|
|
|
+ title="全体学员训练近期专注力评分平均占比"
|
|
|
+ :percent="chartData.afterProportion.percentage"
|
|
|
+ :data="chartData.afterProportion.num"
|
|
|
+ class="chart"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
-.area-container {
|
|
|
+.area-top {
|
|
|
+ background: #ffffff;
|
|
|
+}
|
|
|
+.card-box{
|
|
|
+ padding:0 30px 20px 30px;
|
|
|
+}
|
|
|
+.search-box {
|
|
|
+ display: flex;
|
|
|
+ line-height: 40px;
|
|
|
+ padding: 20px 55px 20px 55px;
|
|
|
+ .el-select{
|
|
|
+ width: 140px;
|
|
|
+ margin-right: 10px;
|
|
|
+ }
|
|
|
+ .el-date-editor{
|
|
|
+ width:300px !important;
|
|
|
+ margin: 0;
|
|
|
+ }
|
|
|
+ .el-button {
|
|
|
+ font-size: 16px;
|
|
|
+ padding: 0 26px;
|
|
|
+ margin: 0 20px;
|
|
|
+ border-radius: 10px;
|
|
|
+ }
|
|
|
+}
|
|
|
+:deep(.el-select),:deep(.el-date-editor) {
|
|
|
+ --el-select-input-focus-border-color: none !important;
|
|
|
+ border: 1px solid #dddddd;
|
|
|
+ border-radius: 10px;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+:deep(.search-box.s2 .el-select){
|
|
|
+ border: none;
|
|
|
+}
|
|
|
+:deep(.el-date-editor) {
|
|
|
+ --el-select-input-focus-border-color: none !important;
|
|
|
+}
|
|
|
+:deep(.el-input__wrapper) {
|
|
|
+ box-shadow: none !important;
|
|
|
+}
|
|
|
+:deep(.el-input__wrapper.is-focus) {
|
|
|
+ box-shadow: none !important;
|
|
|
+}
|
|
|
+:deep(.el-select:hover:not(.el-select--disabled) .el-input__wrapper) {
|
|
|
+ box-shadow: none !important;
|
|
|
+}
|
|
|
+.charts-container{
|
|
|
position: relative;
|
|
|
- padding: 30px;
|
|
|
+ padding:0 30px 20px 30px;
|
|
|
}
|
|
|
-.area-top {
|
|
|
+.charts-item {
|
|
|
background: #ffffff;
|
|
|
+ border: 1px solid #e8eaec;
|
|
|
+ border-radius: 24px;
|
|
|
+ text-align: center;
|
|
|
+ position: relative;
|
|
|
+ .title {
|
|
|
+ margin: 0;
|
|
|
+ height: 78px;
|
|
|
+ line-height: 78px;
|
|
|
+ text-align: left;
|
|
|
+ text-indent: 2em;
|
|
|
+ font-size: 18px;
|
|
|
+ }
|
|
|
+ .item {
|
|
|
+ padding-bottom: 30px;
|
|
|
+ }
|
|
|
+ .chart {
|
|
|
+ margin: 0 auto;
|
|
|
+ }
|
|
|
+ p {
|
|
|
+ margin: 0;
|
|
|
+ line-height: 24px;
|
|
|
+ font-size: 16px;
|
|
|
+ }
|
|
|
+ .bar {
|
|
|
+ margin-top: 60px;
|
|
|
+ }
|
|
|
+ .empty {
|
|
|
+ box-sizing: border-box;
|
|
|
+ height: 400px;
|
|
|
+ padding-top: 200px;
|
|
|
+ text-align: center;
|
|
|
+ background-image: url("../../assets/empty.png");
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-position: center 30%;
|
|
|
+ p {
|
|
|
+ font-size: 14px;
|
|
|
+ color: #a1a1a1;
|
|
|
+ &.red {
|
|
|
+ color: #e04962;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
</style>
|