|
@@ -1,412 +1,607 @@
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
-import {watch} from "vue";
|
|
|
|
-import {useUserStore} from "@/store/modules/user";
|
|
|
|
-import {AreaCard, DashboardData} from "@/api/dashboard/types";
|
|
|
|
|
|
+import { DashboardData } from "@/api/dashboard/types";
|
|
|
|
+import {
|
|
|
|
+ AddressId,
|
|
|
|
+ Area,
|
|
|
|
+ AreaCard,
|
|
|
|
+ AreaLineData,
|
|
|
|
+ AreaParams,
|
|
|
|
+} from "@/api/areaboard/types";
|
|
import AreaDataCard from "@/views/areaboard/components/AreaDataCard.vue";
|
|
import AreaDataCard from "@/views/areaboard/components/AreaDataCard.vue";
|
|
import LiquidChart from "@/views/charts-components/LiquidChart.vue";
|
|
import LiquidChart from "@/views/charts-components/LiquidChart.vue";
|
|
import PercentBarChart from "@/views/charts-components/PercentBarChart.vue";
|
|
import PercentBarChart from "@/views/charts-components/PercentBarChart.vue";
|
|
import CircleChart from "@/views/charts-components/CircleChart.vue";
|
|
import CircleChart from "@/views/charts-components/CircleChart.vue";
|
|
-import {getDashboardData} from "@/api/dashboard";
|
|
|
|
import LineChart from "@/views/charts-components/LineChart.vue";
|
|
import LineChart from "@/views/charts-components/LineChart.vue";
|
|
import AverageBarChart from "@/views/charts-components/AverageBarChart.vue";
|
|
import AverageBarChart from "@/views/charts-components/AverageBarChart.vue";
|
|
|
|
+import { GradeList } from "@/api/grade/types";
|
|
|
|
+import { getGradeSelect } from "@/api/grade";
|
|
|
|
+import {
|
|
|
|
+ getAreaAddress,
|
|
|
|
+ getAreaBoardLines,
|
|
|
|
+ getAreaBoardPies,
|
|
|
|
+ getAreaCard,
|
|
|
|
+ getAreaSchool,
|
|
|
|
+} from "@/api/areaboard";
|
|
|
|
+import { SchoolList } from "@/api/school/types";
|
|
|
|
|
|
defineOptions({
|
|
defineOptions({
|
|
name: "DashboardArea",
|
|
name: "DashboardArea",
|
|
inheritAttrs: false,
|
|
inheritAttrs: false,
|
|
});
|
|
});
|
|
-const userStore = useUserStore();
|
|
|
|
-watch(
|
|
|
|
- () => userStore.schoolId,
|
|
|
|
- (newValue, oldValue) => {
|
|
|
|
- console.log(newValue, oldValue);
|
|
|
|
- }
|
|
|
|
-);
|
|
|
|
-
|
|
|
|
-const date = ref("");
|
|
|
|
/**
|
|
/**
|
|
- * 数据卡片
|
|
|
|
|
|
+ * 筛选条件
|
|
*/
|
|
*/
|
|
-let cards: AreaCard = reactive({
|
|
|
|
- student: 0, // 样本人数
|
|
|
|
- game: 0, // 累计训练次数
|
|
|
|
- school: 10, // 全部班级
|
|
|
|
|
|
+const address: AddressId = reactive({
|
|
|
|
+ province_id: 0,
|
|
|
|
+ city_id: 0,
|
|
|
|
+});
|
|
|
|
+const dataParams: AreaParams = reactive({
|
|
|
|
+ school_id: 0,
|
|
|
|
+ grade_id: 0,
|
|
|
|
+ start_time: Math.ceil(Date.parse("2023/1/1 00:00") / 1000),
|
|
|
|
+ end_time: Math.ceil(Date.now() / 1000),
|
|
});
|
|
});
|
|
|
|
+const datePicker = ref<number[]>([Date.parse("2023/1/1 00:00"), Date.now()]);
|
|
|
|
+const provinceData = ref<Area[]>();
|
|
|
|
+const cityData = ref<Area[]>();
|
|
|
|
+async function getAddressData(id: number) {
|
|
|
|
+ getAreaAddress(id)
|
|
|
|
+ .then(({ data }) => {
|
|
|
|
+ if (id == 0) {
|
|
|
|
+ provinceData.value = data;
|
|
|
|
+ provinceData.value.unshift({ area_id: 0, area_name: "全部省" });
|
|
|
|
+ } else {
|
|
|
|
+ cityData.value = data;
|
|
|
|
+ cityData.value.unshift({ area_id: 0, area_name: "全部市" });
|
|
|
|
+ }
|
|
|
|
+ // 重新获取学校
|
|
|
|
+ getSchoolData(address);
|
|
|
|
+ })
|
|
|
|
+ .catch((error) => {
|
|
|
|
+ console.log(error);
|
|
|
|
+ if (id == 0) {
|
|
|
|
+ provinceData.value = [{ area_id: 0, area_name: "全部省" }];
|
|
|
|
+ } else {
|
|
|
|
+ cityData.value = [{ area_id: 0, area_name: "全部市" }];
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
+//getAreaSchool
|
|
/**
|
|
/**
|
|
- * 图表数据
|
|
|
|
|
|
+ * 获取学校
|
|
*/
|
|
*/
|
|
-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;
|
|
|
|
- });
|
|
|
|
|
|
+const schoolData = ref<SchoolList[]>();
|
|
|
|
+async function getSchoolData(address: AddressId) {
|
|
|
|
+ getAreaSchool(address)
|
|
|
|
+ .then(({ data }) => {
|
|
|
|
+ schoolData.value = data;
|
|
|
|
+ schoolData.value?.unshift({ num: "", school_id: 0, name: "全部学校" });
|
|
|
|
+ })
|
|
|
|
+ .catch((error) => {
|
|
|
|
+ schoolData.value = [];
|
|
|
|
+ schoolData.value?.unshift({ num: "", school_id: 0, name: "全部学校" });
|
|
|
|
+ console.log(error);
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
+/**
|
|
|
|
+ * 班级数据
|
|
|
|
+ */
|
|
|
|
+const gradeData = ref<GradeList[]>();
|
|
|
|
+async function getGradeData(schoolId: number) {
|
|
|
|
+ getGradeSelect(schoolId)
|
|
|
|
+ .then(({ data }) => {
|
|
|
|
+ gradeData.value = data;
|
|
|
|
+ gradeData.value?.unshift({ id: 0, name: "全部班级" });
|
|
|
|
+ })
|
|
|
|
+ .catch((error) => {
|
|
|
|
+ gradeData.value = [];
|
|
|
|
+ gradeData.value?.unshift({ id: 0, name: "全部班级" });
|
|
|
|
+ console.log(error);
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
+// 改变时间
|
|
|
|
+function changeDate() {
|
|
|
|
+ dataParams.start_time = Math.ceil(datePicker.value[0] / 1000);
|
|
|
|
+ dataParams.end_time = Math.ceil(datePicker.value[1] / 1000);
|
|
|
|
+}
|
|
|
|
+/**
|
|
|
|
+ * 数据卡片
|
|
|
|
+ */
|
|
|
|
+const cardStatus = ref(false);
|
|
|
|
+const cards = ref<AreaCard>();
|
|
|
|
+async function getDataCard(schoolId: number) {
|
|
|
|
+ getAreaCard(schoolId)
|
|
|
|
+ .then(({ data }) => {
|
|
|
|
+ cards.value = data;
|
|
|
|
+ cardStatus.value = true;
|
|
|
|
+ })
|
|
|
|
+ .catch((error) => {
|
|
|
|
+ console.log(error);
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
+/**
|
|
|
|
+ * 饼图数据
|
|
|
|
+ */
|
|
|
|
+const pieStatus = ref(false);
|
|
|
|
+const pieMessage = ref("加载中...");
|
|
|
|
+const pieChartData = ref<DashboardData>();
|
|
|
|
+async function getPieChartData(params: AreaParams) {
|
|
|
|
+ pieStatus.value = false;
|
|
|
|
+ getAreaBoardPies(params)
|
|
|
|
+ .then(({ data }) => {
|
|
|
|
+ pieChartData.value = data;
|
|
|
|
+ pieStatus.value = true;
|
|
|
|
+ })
|
|
|
|
+ .catch((error) => {
|
|
|
|
+ pieStatus.value = false;
|
|
|
|
+ pieMessage.value = error.message;
|
|
|
|
+ console.log(error.message);
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
+/**
|
|
|
|
+ * 折线图数据
|
|
|
|
+ */
|
|
|
|
+const lineStatus = ref(false);
|
|
|
|
+const lineMessage = ref("加载中...");
|
|
|
|
+const lineChartData = ref<AreaLineData>();
|
|
|
|
+const averageData = ref<number[][]>();
|
|
|
|
+async function getLineChartData(params: AreaParams) {
|
|
|
|
+ lineStatus.value = false;
|
|
|
|
+ getAreaBoardLines(params)
|
|
|
|
+ .then(({ data }) => {
|
|
|
|
+ lineChartData.value = data;
|
|
|
|
+ // 柱状图
|
|
|
|
+ averageData.value = [];
|
|
|
|
+ averageData.value.push(lineChartData.value?.frontNum);
|
|
|
|
+ averageData.value.push(lineChartData.value?.afterNum);
|
|
|
|
+ lineStatus.value = true;
|
|
|
|
+ })
|
|
|
|
+ .catch((error) => {
|
|
|
|
+ lineStatus.value = false;
|
|
|
|
+ lineMessage.value = error.message;
|
|
|
|
+ console.log(error.message);
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
+/**
|
|
|
|
+ * 获取页面数据
|
|
|
|
+ */
|
|
|
|
+function getPageData() {
|
|
|
|
+ // 数据卡片
|
|
|
|
+ getDataCard(dataParams.school_id);
|
|
|
|
+ // 饼图数据
|
|
|
|
+ getPieChartData(dataParams);
|
|
|
|
+ // 折线图数据
|
|
|
|
+ getLineChartData(dataParams);
|
|
}
|
|
}
|
|
-// 数据状态:1正常,2训练次数小于3,3过期,4缺省
|
|
|
|
-const dataStatus = ref(5);
|
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
- // 图表数据
|
|
|
|
- getChartData(0);
|
|
|
|
|
|
+ // 获取省份
|
|
|
|
+ getAddressData(0);
|
|
|
|
+ cityData.value = [{ area_id: 0, area_name: "全部市" }];
|
|
|
|
+ // 获取学校
|
|
|
|
+ getSchoolData(address);
|
|
|
|
+ gradeData.value = [{ id: 0, name: "全部班级" }];
|
|
|
|
+ // 获取页面数据
|
|
|
|
+ getPageData();
|
|
});
|
|
});
|
|
-const averageData = ref([
|
|
|
|
- [5, 6, 5, 4, 3],
|
|
|
|
- [9, 10, 15, 12, 8],
|
|
|
|
-]);
|
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
<template>
|
|
<template>
|
|
<div class="area-container">
|
|
<div class="area-container">
|
|
<div class="area-top">
|
|
<div class="area-top">
|
|
- <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 class="search-box">
|
|
|
|
+ <el-select
|
|
|
|
+ v-model="address.province_id"
|
|
|
|
+ placeholder="全部省"
|
|
|
|
+ size="large"
|
|
|
|
+ @change="getAddressData(address.province_id)"
|
|
|
|
+ >
|
|
|
|
+ <el-option
|
|
|
|
+ v-for="item in provinceData"
|
|
|
|
+ :key="item.area_id"
|
|
|
|
+ :label="item.area_name"
|
|
|
|
+ :value="item.area_id"
|
|
|
|
+ />
|
|
|
|
+ </el-select>
|
|
|
|
+ <el-select
|
|
|
|
+ v-model="address.city_id"
|
|
|
|
+ placeholder="全部市"
|
|
|
|
+ size="large"
|
|
|
|
+ @change="getSchoolData(address)"
|
|
|
|
+ >
|
|
|
|
+ <el-option
|
|
|
|
+ v-for="item in cityData"
|
|
|
|
+ :key="item.area_id"
|
|
|
|
+ :label="item.area_name"
|
|
|
|
+ :value="item.area_id"
|
|
|
|
+ />
|
|
|
|
+ </el-select>
|
|
|
|
+ <div>
|
|
|
|
+ <el-date-picker
|
|
|
|
+ v-model="datePicker"
|
|
|
|
+ type="daterange"
|
|
|
|
+ size="large"
|
|
|
|
+ start-placeholder="开始日期"
|
|
|
|
+ end-placeholder="结束日期"
|
|
|
|
+ format="YYYY-MM-DD"
|
|
|
|
+ value-format="x"
|
|
|
|
+ @change="changeDate()"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ <el-button size="large" color="#4284f2" @click="getPageData()"
|
|
|
|
+ >查找</el-button
|
|
|
|
+ >
|
|
|
|
+ </div>
|
|
|
|
+ <div class="card-box">
|
|
|
|
+ <!-- 数据卡片 -->
|
|
|
|
+ <template v-if="cardStatus">
|
|
|
|
+ <AreaDataCard
|
|
|
|
+ :key="cards.toString()"
|
|
|
|
+ :schools="cards.school"
|
|
|
|
+ :games="cards.game"
|
|
|
|
+ :students="cards.student"
|
|
|
|
+ />
|
|
|
|
+ </template>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="search-box s2">
|
|
|
|
+ <el-select
|
|
|
|
+ v-model="dataParams.school_id"
|
|
|
|
+ placeholder="全部学校"
|
|
|
|
+ size="large"
|
|
|
|
+ @change="getGradeData(dataParams.school_id)"
|
|
|
|
+ >
|
|
|
|
+ <el-option
|
|
|
|
+ v-for="item in schoolData"
|
|
|
|
+ :key="item.school_id"
|
|
|
|
+ :label="item.name"
|
|
|
|
+ :value="item.school_id"
|
|
|
|
+ />
|
|
|
|
+ </el-select>
|
|
|
|
+ <el-select
|
|
|
|
+ v-model="dataParams.grade_id"
|
|
|
|
+ placeholder="全部班级"
|
|
|
|
+ size="large"
|
|
|
|
+ >
|
|
|
|
+ <el-option
|
|
|
|
+ v-for="item in gradeData"
|
|
|
|
+ :key="item.id"
|
|
|
|
+ :label="item.name"
|
|
|
|
+ :value="item.id"
|
|
|
|
+ />
|
|
|
|
+ </el-select>
|
|
|
|
+ <el-button size="large" color="#4284f2" @click="getPageData()"
|
|
|
|
+ >查找</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="pieStatus" class="item">
|
|
|
|
+ <LiquidChart
|
|
|
|
+ id="liquidChart1"
|
|
|
|
+ :key="pieChartData.frontAverage"
|
|
|
|
+ :data="
|
|
|
|
+ pieChartData.frontAverage ? pieChartData.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="pieStatus" class="item">
|
|
|
|
+ <LiquidChart
|
|
|
|
+ id="liquidChart2"
|
|
|
|
+ :key="pieChartData.afterAverage"
|
|
|
|
+ :data="
|
|
|
|
+ pieChartData.afterAverage ? pieChartData.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="pieStatus" class="item">
|
|
|
|
+ <CircleChart
|
|
|
|
+ id="circleChart1"
|
|
|
|
+ :key="pieChartData.front"
|
|
|
|
+ :data="pieChartData.front ? pieChartData.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="pieStatus" class="item">
|
|
|
|
+ <CircleChart
|
|
|
|
+ id="circleChart2"
|
|
|
|
+ :key="pieChartData.after.toString()"
|
|
|
|
+ :data="pieChartData.after ? pieChartData.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>
|
|
|
|
+ <template v-if="lineStatus">
|
|
|
|
+ <line-chart
|
|
|
|
+ id="lineChart1"
|
|
|
|
+ :data="lineChartData?.curve"
|
|
|
|
+ width="1000px"
|
|
|
|
+ height="558px"
|
|
|
|
+ />
|
|
|
|
+ </template>
|
|
|
|
+ </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 pos">学员专注力训练高专注占比分析</p>
|
|
|
|
+ <template v-if="lineStatus">
|
|
|
|
+ <AverageBarChart
|
|
|
|
+ id="averageBarChart1"
|
|
|
|
+ :key="averageData.toString()"
|
|
|
|
+ :data-sets="averageData"
|
|
|
|
+ width="520px"
|
|
|
|
+ height="520px"
|
|
|
|
+ class="chart"
|
|
|
|
+ />
|
|
|
|
+ </template>
|
|
|
|
+ <el-row :gutter="15" class="bottom">
|
|
|
|
+ <el-col :span="12">
|
|
|
|
+ <p class="l">
|
|
|
|
+ <span>训练前期全体学员</span>
|
|
|
|
+ <span>高专注占比平均值</span>
|
|
|
|
+ <b>{{ lineChartData?.frontHeight }}</b>
|
|
|
|
+ </p>
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col :span="12">
|
|
|
|
+ <p class="r">
|
|
|
|
+ <span>训练后期全体学员</span>
|
|
|
|
+ <span>高专注占比平均值</span>
|
|
|
|
+ <b>{{ lineChartData?.afterHeight }}</b>
|
|
|
|
+ </p>
|
|
|
|
+ </el-col>
|
|
|
|
+ </el-row>
|
|
|
|
+ </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="pieStatus" class="bar">
|
|
|
|
+ <PercentBarChart
|
|
|
|
+ id="barChart1"
|
|
|
|
+ :key="pieChartData.frontProportion.toString()"
|
|
|
|
+ width="400px"
|
|
|
|
+ height="500px"
|
|
|
|
+ title="全体学员初期训练专注力评分占比"
|
|
|
|
+ :percent="pieChartData.frontProportion.percentage"
|
|
|
|
+ :data="pieChartData.frontProportion.num"
|
|
|
|
+ class="chart"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col :xs="24" :sm="24" :md="12" :lg="24" :xl="12">
|
|
|
|
+ <div v-if="pieStatus" class="bar">
|
|
|
|
+ <PercentBarChart
|
|
|
|
+ id="barChart2"
|
|
|
|
+ :key="pieChartData.afterProportion.toString()"
|
|
|
|
+ width="400px"
|
|
|
|
+ height="500px"
|
|
|
|
+ title="全体学员训练近期专注力评分平均占比"
|
|
|
|
+ :percent="pieChartData.afterProportion.percentage"
|
|
|
|
+ :data="pieChartData.afterProportion.num"
|
|
|
|
+ class="chart"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ </el-col>
|
|
|
|
+ </el-row>
|
|
|
|
+ </div>
|
|
|
|
+ </el-col>
|
|
|
|
+ </el-row>
|
|
</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 pos">学员专注力训练高专注占比分析</p>
|
|
|
|
- <AverageBarChart
|
|
|
|
- id="averageBarChart1"
|
|
|
|
- :data-sets="averageData"
|
|
|
|
- width="520px"
|
|
|
|
- height="520px"
|
|
|
|
- class="chart"
|
|
|
|
- />
|
|
|
|
- <el-row :gutter="15" class="bottom">
|
|
|
|
- <el-col :span="12">
|
|
|
|
- <p class="l">
|
|
|
|
- <span>训练前期全体学员</span>
|
|
|
|
- <span>高专注占比平均值</span>
|
|
|
|
- <b>13.5</b>
|
|
|
|
- </p>
|
|
|
|
- </el-col>
|
|
|
|
- <el-col :span="12">
|
|
|
|
- <p class="r">
|
|
|
|
- <span>训练后期全体学员</span>
|
|
|
|
- <span>高专注占比平均值</span>
|
|
|
|
- <b>33.7</b>
|
|
|
|
- </p>
|
|
|
|
- </el-col>
|
|
|
|
- </el-row>
|
|
|
|
- </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>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|
|
.area-top {
|
|
.area-top {
|
|
- background: #ffffff;
|
|
|
|
|
|
+ background: #fff;
|
|
}
|
|
}
|
|
-.card-box{
|
|
|
|
- padding:0 30px 20px 30px;
|
|
|
|
|
|
+
|
|
|
|
+.card-box {
|
|
|
|
+ padding: 0 30px 20px;
|
|
}
|
|
}
|
|
|
|
+
|
|
.search-box {
|
|
.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;
|
|
|
|
- }
|
|
|
|
|
|
+ display: flex;
|
|
|
|
+ padding: 20px 55px;
|
|
|
|
+ line-height: 40px;
|
|
|
|
+
|
|
|
|
+ .el-select {
|
|
|
|
+ width: 140px;
|
|
|
|
+ margin-right: 10px;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .el-date-editor {
|
|
|
|
+ width: 300px !important;
|
|
|
|
+ margin: 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
.el-button {
|
|
.el-button {
|
|
- font-size: 16px;
|
|
|
|
- padding: 0 26px;
|
|
|
|
- margin: 0 20px;
|
|
|
|
- border-radius: 10px;
|
|
|
|
|
|
+ padding: 0 26px;
|
|
|
|
+ margin: 0 20px;
|
|
|
|
+ font-size: 16px;
|
|
|
|
+ border-radius: 10px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-:deep(.el-select),:deep(.el-date-editor) {
|
|
|
|
|
|
+
|
|
|
|
+:deep(.el-select),
|
|
|
|
+:deep(.el-date-editor) {
|
|
--el-select-input-focus-border-color: none !important;
|
|
--el-select-input-focus-border-color: none !important;
|
|
- border: 1px solid #dddddd;
|
|
|
|
- border-radius: 10px;
|
|
|
|
|
|
+
|
|
overflow: hidden;
|
|
overflow: hidden;
|
|
|
|
+ border: 1px solid #ddd;
|
|
|
|
+ border-radius: 10px;
|
|
}
|
|
}
|
|
-:deep(.search-box.s2 .el-select){
|
|
|
|
- border: none;
|
|
|
|
|
|
+
|
|
|
|
+:deep(.search-box.s2 .el-select) {
|
|
|
|
+ border: none;
|
|
}
|
|
}
|
|
|
|
+
|
|
:deep(.el-date-editor) {
|
|
:deep(.el-date-editor) {
|
|
--el-select-input-focus-border-color: none !important;
|
|
--el-select-input-focus-border-color: none !important;
|
|
}
|
|
}
|
|
|
|
+
|
|
:deep(.el-input__wrapper) {
|
|
:deep(.el-input__wrapper) {
|
|
box-shadow: none !important;
|
|
box-shadow: none !important;
|
|
}
|
|
}
|
|
|
|
+
|
|
:deep(.el-input__wrapper.is-focus) {
|
|
:deep(.el-input__wrapper.is-focus) {
|
|
box-shadow: none !important;
|
|
box-shadow: none !important;
|
|
}
|
|
}
|
|
|
|
+
|
|
:deep(.el-select:hover:not(.el-select--disabled) .el-input__wrapper) {
|
|
:deep(.el-select:hover:not(.el-select--disabled) .el-input__wrapper) {
|
|
box-shadow: none !important;
|
|
box-shadow: none !important;
|
|
}
|
|
}
|
|
-.charts-container{
|
|
|
|
|
|
+
|
|
|
|
+.charts-container {
|
|
position: relative;
|
|
position: relative;
|
|
- padding:0 30px 20px 30px;
|
|
|
|
|
|
+ padding: 0 30px 20px;
|
|
}
|
|
}
|
|
|
|
+
|
|
.charts-item {
|
|
.charts-item {
|
|
- background: #ffffff;
|
|
|
|
|
|
+ position: relative;
|
|
|
|
+ text-align: center;
|
|
|
|
+ background: #fff;
|
|
border: 1px solid #e8eaec;
|
|
border: 1px solid #e8eaec;
|
|
border-radius: 24px;
|
|
border-radius: 24px;
|
|
- text-align: center;
|
|
|
|
- position: relative;
|
|
|
|
|
|
+
|
|
.title {
|
|
.title {
|
|
- margin: 0;
|
|
|
|
- height: 78px;
|
|
|
|
- line-height: 78px;
|
|
|
|
- text-align: left;
|
|
|
|
- text-indent: 2em;
|
|
|
|
- font-size: 18px;
|
|
|
|
- &.pos{
|
|
|
|
- margin-bottom: -50px;
|
|
|
|
- }
|
|
|
|
|
|
+ height: 78px;
|
|
|
|
+ margin: 0;
|
|
|
|
+ font-size: 18px;
|
|
|
|
+ line-height: 78px;
|
|
|
|
+ text-align: left;
|
|
|
|
+ text-indent: 2em;
|
|
|
|
+
|
|
|
|
+ &.pos {
|
|
|
|
+ margin-bottom: -50px;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+
|
|
.item {
|
|
.item {
|
|
- padding-bottom: 30px;
|
|
|
|
|
|
+ padding-bottom: 30px;
|
|
}
|
|
}
|
|
|
|
+
|
|
.chart {
|
|
.chart {
|
|
- margin: 0 auto;
|
|
|
|
|
|
+ margin: 0 auto;
|
|
}
|
|
}
|
|
|
|
+
|
|
p {
|
|
p {
|
|
- margin: 0;
|
|
|
|
- line-height: 24px;
|
|
|
|
- font-size: 16px;
|
|
|
|
|
|
+ margin: 0;
|
|
|
|
+ font-size: 16px;
|
|
|
|
+ line-height: 24px;
|
|
}
|
|
}
|
|
|
|
+
|
|
.bar {
|
|
.bar {
|
|
- margin-top: 60px;
|
|
|
|
|
|
+ margin-top: 60px;
|
|
}
|
|
}
|
|
- .bottom{
|
|
|
|
- padding:0 20px 20px 20px;
|
|
|
|
- .el-col p{
|
|
|
|
- position: relative;
|
|
|
|
- box-sizing: border-box;
|
|
|
|
- white-space: nowrap;
|
|
|
|
- border-radius: 10px;
|
|
|
|
- padding:10px 20px;
|
|
|
|
- text-align: left;
|
|
|
|
- color: #ffffff;
|
|
|
|
- &.l{
|
|
|
|
- background: #f8b865;
|
|
|
|
- }
|
|
|
|
- &.r{
|
|
|
|
- background: #8877ef;
|
|
|
|
- }
|
|
|
|
- span{display: block}
|
|
|
|
- b{
|
|
|
|
- position: absolute;
|
|
|
|
- right:20px;
|
|
|
|
- top:22px;
|
|
|
|
- font-size: 26px;
|
|
|
|
- font-style: normal;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+ .bottom {
|
|
|
|
+ padding: 0 20px 20px;
|
|
|
|
+
|
|
|
|
+ .el-col p {
|
|
|
|
+ position: relative;
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
+ padding: 10px 20px;
|
|
|
|
+ color: #fff;
|
|
|
|
+ text-align: left;
|
|
|
|
+ white-space: nowrap;
|
|
|
|
+ border-radius: 10px;
|
|
|
|
+
|
|
|
|
+ &.l {
|
|
|
|
+ background: #f8b865;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ &.r {
|
|
|
|
+ background: #8877ef;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ span {
|
|
|
|
+ display: block;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ b {
|
|
|
|
+ position: absolute;
|
|
|
|
+ top: 22px;
|
|
|
|
+ right: 20px;
|
|
|
|
+ font-size: 26px;
|
|
|
|
+ font-style: normal;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+
|
|
.empty {
|
|
.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;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ 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>
|
|
</style>
|