ソースを参照

build: 首页数据调试part1

chaooo 2 年 前
コミット
7b5ad2e2c7

+ 24 - 0
src/api/dashboard/index.ts

@@ -0,0 +1,24 @@
+import request from "@/utils/request";
+import { AxiosPromise } from "axios";
+import { DashboardCard, DashboardData } from "./types";
+
+/**
+ * 获取学校列表
+ */
+export function getDashboardTop(id: number): AxiosPromise<DashboardCard> {
+  return request({
+    url: "/board/v1/top",
+    method: "get",
+    params: { school_id: id },
+  });
+}
+/**
+ * 获取班级列表
+ */
+export function getDashboardData(id: number): AxiosPromise<DashboardData> {
+  return request({
+    url: "/board/v1/bottom",
+    method: "get",
+    params: { grade_id: id },
+  });
+}

+ 31 - 0
src/api/dashboard/types.ts

@@ -0,0 +1,31 @@
+/**
+ * 首页顶部数据
+ */
+export interface DashboardCard {
+  grade: number;
+  teacher: number;
+  student: number;
+  equipment: number;
+  game: number;
+}
+/**
+ * 初期分期占比分析
+ */
+interface Proportion {
+  num: number[];
+  percentage: number[];
+}
+export interface DashboardData {
+  // 初期专注力估值
+  frontAverage: number;
+  // 近期专注力估值
+  afterAverage: number;
+  // 初期50分以上的占比
+  front: number;
+  // 近期50分以上的占比
+  after: number;
+  // 初期分期占比分析
+  frontProportion: Proportion;
+  // 近期分期占比分析
+  afterProportion: Proportion;
+}

+ 2 - 0
src/api/school/types.ts

@@ -6,6 +6,8 @@ export interface SchoolList {
   school_id: number;
   /** 学校名称 */
   name: string;
+  /** 学校号 */
+  num: string;
 }
 /**
  * 班级列表

BIN
src/assets/login/avatar.png


+ 14 - 5
src/layout/components/Navbar.vue

@@ -9,7 +9,6 @@ import { getSchoolList } from "@/api/school";
 import { watch } from "vue";
 import SvgIcon from "@/components/SvgIcon/index.vue";
 import { CaretBottom } from "@element-plus/icons-vue";
-
 const appStore = useAppStore();
 const tagsViewStore = useTagsViewStore();
 const userStore = useUserStore();
@@ -51,13 +50,15 @@ function logout() {
  */
 const schoolData = ref<SchoolList[]>();
 const schoolId = ref(0);
+const schoolNum = ref("");
 async function getSchoolData() {
   getSchoolList()
     .then(({ data }) => {
       schoolData.value = data;
       if (schoolId.value == 0) {
         schoolId.value = data[0].school_id;
-        userStore.changeSchool(schoolId.value);
+        schoolNum.value = data[0].num;
+        userStore.changeSchool(schoolId.value, schoolNum.value);
       }
     })
     .catch((error) => {
@@ -70,8 +71,15 @@ onMounted(() => {
 watch(
   () => schoolId.value,
   (newValue, oldValue) => {
-    // console.log("schoolNumber", newValue, oldValue);
-    userStore.changeSchool(newValue);
+    let num;
+    schoolData.value?.some((school) => {
+      if (newValue == school.school_id) {
+        num = school.num;
+        return true;
+      }
+    });
+    //console.log("school", newValue, num);
+    userStore.changeSchool(newValue, num);
   }
 );
 </script>
@@ -117,8 +125,9 @@ watch(
       </div>
       <!-- 用户头像 -->
       <div class="avatar-container">
+        <span>学校编码:{{ userStore.schoolNum }}</span>
         <span class="spl">|</span>
-        <img src="" alt="头像" />
+        <img src="../../assets/login/avatar.png" alt="头像" />
         <span class="">{{ userStore.nickname + " " + userStore.phone }}</span>
         <span @click="logout"
           ><svg-icon icon-class="exit" color="#006eff" size="20px"

+ 5 - 1
src/store/modules/user.ts

@@ -10,6 +10,7 @@ export const useUserStore = defineStore("user", () => {
   const token = useStorage("accessToken", "");
   const userInfo = useStorage("userInfo", "");
   const schoolId = useStorage("schoolId", 0);
+  const schoolNum = useStorage("schoolNum", "");
   const routeStatus = ref(false);
   const nickname = ref("");
   const phone = ref("");
@@ -51,6 +52,7 @@ export const useUserStore = defineStore("user", () => {
     token.value = data.token;
     nickname.value = data.name;
     phone.value = data.phone;
+    schoolNum.value = data.num;
     // todo: 接口写好后需要修改
     if (data.role) {
       role.value = data.role;
@@ -88,8 +90,9 @@ export const useUserStore = defineStore("user", () => {
   }
 
   // 切换学校
-  function changeSchool(id: number) {
+  function changeSchool(id: number, num: string) {
     schoolId.value = id;
+    schoolNum.value = num;
   }
 
   // 路由加载后设置
@@ -101,6 +104,7 @@ export const useUserStore = defineStore("user", () => {
     token,
     routeStatus,
     schoolId,
+    schoolNum,
     nickname,
     phone,
     role,

+ 2 - 2
src/views/charts-components/PercentBarChart.vue

@@ -31,12 +31,12 @@ const props = defineProps({
   // percent:[5,5,65,10,10]
   percent: {
     type: Array,
-    default: [] as Array<number>,
+    default: [0, 0, 0, 0, 0] as Array<number>,
   },
   // data:[1,2,13,2,2]
   data: {
     type: Array,
-    default: [] as Array<number>,
+    default: [0, 0, 0, 0, 0] as Array<number>,
   },
 });
 

+ 21 - 10
src/views/class/index.vue

@@ -8,25 +8,36 @@ defineOptions({
 import { watch } from "vue";
 import { useUserStore } from "@/store/modules/user";
 import { CaretBottom } from "@element-plus/icons-vue";
+import { getClassList } from "@/api/school";
 const userStore = useUserStore();
 watch(
   () => userStore.schoolId,
   (newValue, oldValue) => {
-    console.log(newValue, oldValue);
+    //console.log(newValue, oldValue);
+    getClassData(newValue);
   }
 );
 /**
  * 班级数据
  */
+const classData = ref<ClassList[]>();
 // 班级编号
-let classNumber = ref(0);
-const classData = ref<ClassList[]>([
-  {
-    id: 0,
-    school_id: 0,
-    name: "全部班级",
-  },
-]);
+let classId = ref(0);
+async function getClassData(schoolId) {
+  getClassList(schoolId)
+    .then(({ data }) => {
+      classData.value = data;
+      if (classId.value == 0) {
+        classId.value = data[0].id;
+      }
+    })
+    .catch((error) => {
+      console.log(error);
+    });
+}
+onMounted(() => {
+  getClassData(userStore.schoolId);
+});
 // 折叠面板active
 const activeItem = ref();
 const tableData = ref<any>([
@@ -128,7 +139,7 @@ const tableData = ref<any>([
     <!-- 班级选择 -->
     <div class="class-select">
       <el-select
-        v-model="classNumber"
+        v-model="classId"
         placeholder="全部班级"
         size="large"
         :suffix-icon="CaretBottom"

+ 3 - 3
src/views/dashboard/components/DataCard.vue

@@ -32,7 +32,7 @@ const props = defineProps({
 // 卡片数字动效
 function countNumber(number) {
   return useTransition(number, {
-    duration: 5000,
+    duration: 2000,
     transition: TransitionPresets.easeOutExpo,
   });
 }
@@ -51,8 +51,8 @@ const equipmentCountOutput = countNumber(equipmentCount);
 // 累计训练次数
 const trainingCount = ref(0);
 const trainingCountOutput = countNumber(trainingCount);
-
-onMounted(() => {
+// 监听数据变化
+watchEffect(() => {
   classCount.value = <number>props.classes;
   teacherCount.value = <number>props.teachers;
   studentCount.value = <number>props.students;

+ 113 - 55
src/views/dashboard/index.vue

@@ -13,6 +13,9 @@ import { ClassList, SchoolList } from "@/api/school/types";
 import { watch } from "vue";
 import { useUserStore } from "@/store/modules/user";
 import { CaretBottom } from "@element-plus/icons-vue";
+import { getClassList } from "@/api/school";
+import { getDashboardData, getDashboardTop } from "@/api/dashboard";
+import { DashboardCard, DashboardData } from "@/api/dashboard/types";
 const userStore = useUserStore();
 watch(
   () => userStore.schoolId,
@@ -24,66 +27,115 @@ watch(
 /**
  * 数据卡片
  */
-// 全部班级
-const classCount = 3000;
-// 全部教师
-const teacherCount = 5000;
-// 全部学生
-const studentCount = 6000;
-// 设备套数
-const equipmentCount = 50;
-// 累计训练次数
-const trainingCount = 2000;
+const cards: DashboardCard = reactive({});
+async function getDataCard(schoolId) {
+  getDashboardTop(schoolId)
+    .then(({ data }) => {
+      // 全部班级
+      cards.grade = data.grade;
+      // 全部教师
+      cards.teacher = data.teacher;
+      // 全部学生
+      cards.student = data.student;
+      // 设备套数
+      cards.equipment = data.equipment;
+      // 累计训练次数
+      cards.game = data.game;
+    })
+    .catch((error) => {
+      console.log(error);
+    });
+}
 /**
  * 班级数据
  */
+const classData = ref<ClassList[]>();
 // 班级编号
-let classNumber = ref(0);
-const classData = ref<ClassList[]>([
-  {
-    id: 0,
-    school_id: 0,
-    name: "全部班级",
-  },
-]);
-// function queryClassList() {
-// 	getClassList().then(({ data }) => {
-//		classData.value.concat(data);
-// 	});
-// }
-watch(
-  () => classNumber,
-  (newValue, oldValue) => {
-    console.log("userStore.schoolId", newValue, oldValue);
-    // 班级切换后重新加载班级数据
-  }
-);
-// 数据状态:1正常,2训练次数小于3,3过期,4缺省
-const dataStatus = ref(1);
+let classId = ref(0);
+async function getClassData(schoolId) {
+  getClassList(schoolId)
+    .then(({ data }) => {
+      data.unshift({ id: 0, name: "全部班级" });
+      classData.value = data;
+      //console.log(classData.value)
+    })
+    .catch((error) => {
+      console.log(error);
+    });
+}
+/**
+ * 图表数据
+ */
+const chartStatus = ref(false);
+const chartData: DashboardData = reactive({
+  // 初期专注力估值
+  frontAverage: 0,
+  // 近期专注力估值
+  afterAverage: 0,
+  // 初期50分以上的占比
+  front: 0,
+  // 近期50分以上的占比
+  after: 0,
+  // // 初期分期占比分析
+  // frontProportion: Proportion;
+  // // 近期分期占比分析
+  // afterProportion: Proportion;
+});
+async function getChartData(classId) {
+  getDashboardData(classId)
+    .then(({ data }) => {
+      // 初期专注力估值
+      chartData.frontAverage = data.frontAverage;
+      // 近期专注力估值
+      chartData.afterAverage = data.afterAverage;
+      // 初期50分以上的占比
+      chartData.front = data.front;
+      // 近期50分以上的占比
+      chartData.after = data.after;
+      // 初期分期占比分析
+      chartData.frontProportion = data.frontProportion;
+      // 近期分期占比分析
+      chartData.afterProportion = data.afterProportion;
+      chartStatus.value = true;
+      console.log(data);
+    })
+    .catch((error) => {
+      console.log(error);
+    });
+}
+
 onMounted(() => {
-  //queryClassList();
+  // 获取班级
+  getClassData(userStore.schoolId);
+  // 数据卡片
+  getDataCard(userStore.schoolId);
+  // 图表数据
+  getChartData(classId.value);
 });
 
+// 数据状态:1正常,2训练次数小于3,3过期,4缺省
+const dataStatus = ref(1);
 
-const percentData = [5,5,65,10,10];
-const percentNumber = [1,2,13,2,2];
+const percentData = [5, 5, 65, 10, 10];
+const percentNumber = [1, 2, 13, 2, 2];
 </script>
 
 <template>
   <div class="dashboard-container">
     <!-- 数据卡片 -->
     <DataCard
-      :classes="classCount"
-      :teachers="teacherCount"
-      :students="studentCount"
-      :equipments="equipmentCount"
-      :trainings="trainingCount"
+      :key="cards"
+      :classes="cards.grade"
+      :teachers="cards.teacher"
+      :students="cards.student"
+      :equipments="cards.equipment"
+      :trainings="cards.game"
     />
 
     <!-- 班级选择 及 案例展示 -->
     <div class="class-select clear">
       <el-select
-        v-model="classNumber"
+        v-model="classId"
         placeholder="全部班级"
         size="large"
         :suffix-icon="CaretBottom"
@@ -105,10 +157,11 @@ const percentNumber = [1,2,13,2,2];
           <p class="title">学员专注力平均值整体对比分析</p>
           <el-row justify="space-between">
             <el-col :xs="24" :sm="12">
-              <div class="item">
+              <div v-if="chartStatus" class="item">
                 <LiquidChart
                   id="liquidChart1"
-                  data="37.5"
+                  :key="chartData.frontAverage"
+                  :data="chartData.frontAverage ? chartData.frontAverage : 0"
                   height="200px"
                   width="200px"
                   color="#3a7fc2"
@@ -120,10 +173,11 @@ const percentNumber = [1,2,13,2,2];
               </div>
             </el-col>
             <el-col :xs="24" :sm="12">
-              <div class="item">
+              <div v-if="chartStatus" class="item">
                 <LiquidChart
                   id="liquidChart2"
-                  data="57.6"
+                  :key="chartData.afterAverage"
+                  :data="chartData.afterAverage ? chartData.afterAverage : 0"
                   height="200px"
                   width="200px"
                   color="#5563ac"
@@ -137,10 +191,11 @@ const percentNumber = [1,2,13,2,2];
           </el-row>
           <el-row justify="space-between">
             <el-col :xs="24" :sm="12">
-              <div class="item">
+              <div v-if="chartStatus" class="item">
                 <CircleChart
                   id="circleChart1"
-                  data="37.5"
+                  :key="chartData.front"
+                  :data="chartData.front ? chartData.front : 0"
                   height="200px"
                   width="200px"
                   color="#3a7fc2"
@@ -154,10 +209,11 @@ const percentNumber = [1,2,13,2,2];
               </div>
             </el-col>
             <el-col :xs="24" :sm="12">
-              <div class="item">
+              <div v-if="chartStatus" class="item">
                 <CircleChart
                   id="circleChart2"
-                  data="57.6"
+                  :key="chartData.after"
+                  :data="chartData.after ? chartData.after : 0"
                   height="200px"
                   width="200px"
                   color="#5563ac"
@@ -179,27 +235,29 @@ const percentNumber = [1,2,13,2,2];
           <p class="title">学员专注力评分分级占比分析</p>
           <el-row justify="space-between">
             <el-col :xs="24" :sm="24" :md="12" :lg="24" :xl="12">
-              <div class="bar">
+              <div v-if="chartStatus" class="bar">
                 <PercentBarChart
                   id="barChart1"
+                  :key="chartData.frontProportion"
                   width="400px"
                   height="500px"
                   title="全体学员初期训练专注力评分占比"
-                  :percent="percentData"
-                  :data="percentNumber"
+                  :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 class="bar">
+              <div v-if="chartStatus" class="bar">
                 <PercentBarChart
                   id="barChart2"
+                  :key="chartData.afterProportion"
                   width="400px"
                   height="500px"
                   title="全体学员训练近期专注力评分平均占比"
-									:percent="percentData"
-									:data="percentNumber"
+                  :percent="chartData.afterProportion.percentage"
+                  :data="chartData.afterProportion.num"
                   class="chart"
                 />
               </div>