ソースを参照

build: 班级管理

chaooo 2 年 前
コミット
22f3a5bb73

+ 29 - 5
src/api/school/index.ts

@@ -1,23 +1,47 @@
 import request from "@/utils/request";
 import { AxiosPromise } from "axios";
-import { SchoolList, GradeList } from "./types";
+import { SchoolList, GradeList, GradeItem, StudentList } from "./types";
 
 /**
  * 获取学校列表
  */
-export function getSchoolList(): AxiosPromise<SchoolList[]> {
+export function getSchoolSelect(): AxiosPromise<SchoolList[]> {
   return request({
     url: "/board/v1/schools",
     method: "get",
   });
 }
 /**
- * 获取班级列表
+ * 获取班级列表(班级select下拉列表)
  */
-export function getGradeList(id: number): AxiosPromise<GradeList[]> {
+export function getGradeSelect(id: number): AxiosPromise<GradeList[]> {
   return request({
-    url: "/board/v1/grade",
+    url: "/board/v1/choose-grade",
     method: "get",
     params: { school_id: id },
   });
 }
+/**
+ * 班级管理
+ * status: 0全部1未结课2已结课
+ */
+export function getGradeList(
+  id: number,
+  status: number
+): AxiosPromise<GradeItem[]> {
+  return request({
+    url: "/board/v1/grade",
+    method: "get",
+    params: { school_id: id, status: status },
+  });
+}
+/**
+ * 班级管理-学生列表
+ */
+export function getGradeStudents(id: number): AxiosPromise<StudentList[]> {
+  return request({
+    url: "/board/v1/students",
+    method: "get",
+    params: { grade_id: id },
+  });
+}

+ 41 - 7
src/api/school/types.ts

@@ -2,21 +2,55 @@
  * 学校列表
  */
 export interface SchoolList {
-  /** 学校id */
+  // 学校id
   school_id: number;
-  /** 学校名称 */
+  // 学校名称
   name: string;
-  /** 学校号 */
+  // 学校号
   num: string;
 }
 /**
  * 班级列表
  */
 export interface GradeList {
-  /** 班级id */
+  // 班级id
   id: number;
-  // /** 学校id */
-  // school_id: number;
-  /** 学校名称 */
+  // 班级名称
   name: string;
 }
+/**
+ * 班级数据
+ */
+export interface GradeItem {
+  // 班级id
+  id: number;
+  // 班级名称
+  name: string;
+  // 0未结课1已结课
+  grade_status: number;
+  // 班级号
+  num: string;
+  // 学生数量
+  count: number;
+  // 教师名称
+  teacher_name: string;
+  // 结课时间
+  grade_time: string;
+  // 折叠面板使用
+  active: number;
+  // 学生列表
+  students: StudentList[];
+}
+/**
+ * 学生列表
+ */
+export interface StudentList {
+  // 学生id
+  id: number;
+  // 学生名称
+  name: string;
+  // 电话号码
+  phone: number;
+  // 训练次数
+  count: number;
+}

+ 2 - 2
src/layout/components/Navbar.vue

@@ -5,7 +5,7 @@ import { useAppStore } from "@/store/modules/app";
 import { useTagsViewStore } from "@/store/modules/tagsView";
 import { useUserStore } from "@/store/modules/user";
 import { SchoolList } from "@/api/school/types";
-import { getSchoolList } from "@/api/school";
+import { getSchoolSelect } from "@/api/school";
 import { watch } from "vue";
 import SvgIcon from "@/components/SvgIcon/index.vue";
 import { CaretBottom } from "@element-plus/icons-vue";
@@ -52,7 +52,7 @@ const schoolData = ref<SchoolList[]>();
 const schoolId = ref(0);
 const schoolNum = ref("");
 async function getSchoolData() {
-  getSchoolList()
+  getSchoolSelect()
     .then(({ data }) => {
       schoolData.value = data;
       if (schoolId.value == 0) {

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

@@ -53,12 +53,7 @@ export const useUserStore = defineStore("user", () => {
     nickname.value = data.name;
     phone.value = data.phone;
     schoolNum.value = data.num;
-    // todo: 接口写好后需要修改
-    if (data.role) {
-      role.value = data.role;
-    } else {
-      role.value = "SCHOOL";
-    }
+    role.value = data.role;
     perms.value = data.perms;
     return role.value;
   }

+ 29 - 46
src/views/dashboard/index.vue

@@ -7,9 +7,10 @@ import { GradeList } from "@/api/school/types";
 import { watch } from "vue";
 import { useUserStore } from "@/store/modules/user";
 import { CaretBottom } from "@element-plus/icons-vue";
-import { getGradeList } from "@/api/school";
+import { getGradeSelect } from "@/api/school";
 import { getDashboardData, getDashboardTop } from "@/api/dashboard";
 import { DashboardCard, DashboardData } from "@/api/dashboard/types";
+
 const userStore = useUserStore();
 defineOptions({
   name: "DashboardIndex",
@@ -18,26 +19,17 @@ defineOptions({
 /**
  * 数据卡片
  */
-const cards: DashboardCard = reactive({
-  grade: 0,
-  teacher: 0,
-  student: 0,
-  equipment: 0,
-  game: 0,
+let cards: DashboardCard = reactive({
+  grade: 0, // 全部班级
+  teacher: 0, // 全部教师
+  student: 0, // 全部学生
+  equipment: 0, // 设备套数
+  game: 0, // 累计训练次数
 });
 async function getDataCard(schoolId: number) {
   getDashboardTop(schoolId)
     .then(({ data }) => {
-      // 全部班级
-      cards.grade = data.grade;
-      // 全部教师
-      cards.teacher = data.teacher;
-      // 全部学生
-      cards.student = data.student;
-      // 设备套数
-      cards.equipment = data.equipment;
-      // 累计训练次数
-      cards.game = data.game;
+      cards = <DashboardCard>{ ...data };
     })
     .catch((error) => {
       console.log(error);
@@ -50,11 +42,10 @@ const gradeData = ref<GradeList[]>();
 // 班级编号
 let gradeId = ref(0);
 async function getGradeData(schoolId: number) {
-  getGradeList(schoolId)
+  getGradeSelect(schoolId)
     .then(({ data }) => {
       data.unshift({ id: 0, name: "全部班级" });
       gradeData.value = data;
-      //console.log(gradeData.value)
     })
     .catch((error) => {
       console.log(error);
@@ -64,32 +55,24 @@ async function getGradeData(schoolId: number) {
  * 图表数据
  */
 const chartStatus = ref(false);
-const chartData: DashboardData = reactive({
-  frontAverage: 0,
-  afterAverage: 0,
-  front: 0,
-  after: 0,
-  frontProportion: { num: [], percentage: [] },
-  afterProportion: { num: [], percentage: [] },
+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.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;
-      dataStatus.value = 1;
-      // console.log(data);
+      chartData = <DashboardData>{ ...data };
+      if (chartData.frontAverage > 0) {
+        chartStatus.value = true;
+        dataStatus.value = 1;
+      } else {
+        dataStatus.value = 2;
+      }
     })
     .catch((error) => {
       console.log(error.toString());
@@ -98,6 +81,11 @@ async function getChartData(gradeId: number) {
 }
 // 数据状态:1正常,2训练次数小于3,3过期,4缺省
 const dataStatus = ref(5);
+// 改变班级重新加载图表数据
+function changeGrade() {
+  dataStatus.value = 5;
+  getChartData(gradeId.value);
+}
 onMounted(() => {
   // 获取班级
   getGradeData(userStore.schoolId);
@@ -118,11 +106,6 @@ watch(
     getChartData(0);
   }
 );
-// 改变班级重新加载图表数据
-function changeGrade() {
-  dataStatus.value = 5;
-  getChartData(gradeId.value);
-}
 </script>
 
 <template>

+ 64 - 185
src/views/grade/index.vue

@@ -1,137 +1,62 @@
 <script setup lang="ts">
-import { GradeList } from "@/api/school/types";
+import { GradeItem } from "@/api/school/types";
+import { watch } from "vue";
+import { useUserStore } from "@/store/modules/user";
+import { CaretBottom } from "@element-plus/icons-vue";
+import { getGradeList, getGradeStudents } from "@/api/school";
 
 defineOptions({
   name: "ClassIndex",
   inheritAttrs: false,
 });
-import { watch } from "vue";
-import { useUserStore } from "@/store/modules/user";
-import { CaretBottom } from "@element-plus/icons-vue";
-import { getGradeList } from "@/api/school";
 const userStore = useUserStore();
-watch(
-  () => userStore.schoolId,
-  (newValue, oldValue) => {
-    //console.log(newValue, oldValue);
-    getGradeData(newValue);
-  }
-);
 /**
  * 班级数据
  */
-const gradeData = ref<GradeList[]>();
-// 班级编号
-let gradeId = ref(0);
-async function getGradeData(schoolId: number) {
-  getGradeList(schoolId)
+const gradeData = ref<GradeItem[]>();
+// 班级status: 0全部1未结课2已结课
+let gradeStatus = ref(0);
+async function getGradeItems(schoolId: number, status: number) {
+  getGradeList(schoolId, status)
     .then(({ data }) => {
       gradeData.value = data;
-      if (gradeId.value == 0) {
-        gradeId.value = data[0].id;
-      }
     })
     .catch((error) => {
       console.log(error);
     });
 }
+// 请求班级学生数据
+async function getStudentList(grade: GradeItem) {
+  getGradeStudents(grade.id)
+    .then(({ data }) => {
+      grade.students = data;
+    })
+    .catch((error) => {
+      console.log(error);
+    });
+}
+// 改变班级状态
+function changeStatus() {
+  getGradeItems(userStore.schoolId, gradeStatus.value);
+}
+// 打开班级请求学生
+function changeGrade(grade: GradeItem) {
+  if (!grade.students || grade.students.length === 0) {
+    getStudentList(grade);
+  }
+}
 onMounted(() => {
-  getGradeData(userStore.schoolId);
+  // 获取班级
+  getGradeItems(userStore.schoolId, gradeStatus.value);
 });
-// 折叠面板active
-const activeItem = ref();
-const tableData = ref<any>([
-  {
-    number: 1,
-    name: "TomTomTom",
-    phone: 1566666666,
-    times: 12,
-  },
-  {
-    number: 2,
-    name: "TomTomTom",
-    phone: 1566666666,
-    times: 12,
-  },
-  {
-    number: 3,
-    name: "TomTomTom",
-    phone: 1566666666,
-    times: 12,
-  },
-  {
-    number: 1,
-    name: "TomTomTom",
-    phone: 1566666666,
-    times: 12,
-  },
-  {
-    number: 2,
-    name: "TomTomTom",
-    phone: 1566666666,
-    times: 12,
-  },
-  {
-    number: 3,
-    name: "TomTomTom",
-    phone: 1566666666,
-    times: 12,
-  },
-  {
-    number: 1,
-    name: "TomTomTom",
-    phone: 1566666666,
-    times: 12,
-  },
-  {
-    number: 2,
-    name: "TomTomTom",
-    phone: 1566666666,
-    times: 12,
-  },
-  {
-    number: 3,
-    name: "TomTomTom",
-    phone: 1566666666,
-    times: 12,
-  },
-  {
-    number: 1,
-    name: "TomTomTom",
-    phone: 1566666666,
-    times: 12,
-  },
-  {
-    number: 2,
-    name: "TomTomTom",
-    phone: 1566666666,
-    times: 12,
-  },
-  {
-    number: 3,
-    name: "TomTomTom",
-    phone: 1566666666,
-    times: 12,
-  },
-  {
-    number: 1,
-    name: "TomTomTom",
-    phone: 1566666666,
-    times: 12,
-  },
-  {
-    number: 2,
-    name: "TomTomTom",
-    phone: 1566666666,
-    times: 12,
-  },
-  {
-    number: 3,
-    name: "TomTomTom",
-    phone: 1566666666,
-    times: 12,
-  },
-]);
+watch(
+  () => userStore.schoolId,
+  (newValue, oldValue) => {
+    console.log("userStore.schoolId", newValue, oldValue);
+    // 学校切换后重新加载数据
+    getGradeItems(newValue, gradeStatus.value);
+  }
+);
 </script>
 
 <template>
@@ -139,86 +64,36 @@ const tableData = ref<any>([
     <!-- 班级选择 -->
     <div class="class-select">
       <el-select
-        v-model="gradeId"
+        v-model="gradeStatus"
         placeholder="全部班级"
         size="large"
         :suffix-icon="CaretBottom"
+        @change="changeStatus()"
       >
-        <el-option
-          v-for="item in gradeData"
-          :key="item.id"
-          :label="item.name"
-          :value="item.id"
-        />
+        <el-option key="0" label="全部班级" :value="Number(0)" />
+        <el-option key="1" label="未结课班级" :value="Number(1)" />
+        <el-option key="1" label="已结课班级" :value="Number(2)" />
       </el-select>
     </div>
     <!-- 班级折叠面板-->
-    <div class="list-collapse">
-      <el-collapse v-model="activeItem">
+    <div v-for="grade in gradeData" :key="grade.id" class="list-collapse">
+      <el-collapse v-model="grade.active" @change="changeGrade(grade)">
         <el-collapse-item name="1">
           <template #title>
             <div class="title">
-              <span class="blue mr-10">向日葵小班</span>
-              <span class="mr-10">教师:松阪老师</span>
-              <span>班级号:C 2208 887829</span>
-              <span class="red ml-10">结课时间:2023-08-11</span>
-              <span class="blue fr"
-                >学生:12人
-                <el-icon
-                  :class="
-                    activeItem && activeItem.includes('1') ? 'is-active' : ''
-                  "
-                  ><CaretBottom
-                /></el-icon>
-              </span>
-            </div>
-          </template>
-          <div>
-            <el-table :data="tableData" height="400" style="width: 100%">
-              <el-table-column
-                prop="number"
-                label="序号"
-                width="80"
-                align="center"
-              />
-              <el-table-column
-                prop="name"
-                label="学生名称"
-                width="180"
-                align="center"
-              />
-              <el-table-column
-                prop="phone"
-                label="手机号"
-                width="180"
-                align="center"
-              />
-              <el-table-column
-                prop="times"
-                label="训练次数"
-                width="180"
-                align="center"
-              />
-              <el-table-column />
-            </el-table>
-          </div>
-        </el-collapse-item>
-      </el-collapse>
-    </div>
-    <div class="list-collapse">
-      <el-collapse v-model="activeItem">
-        <el-collapse-item name="2">
-          <template #title>
-            <div class="title">
-              <span class="blue mr-10">向日葵小班</span>
-              <span class="mr-10">教师:松阪老师</span>
-              <span>班级号:C 2208 887829</span>
-              <span class="red ml-10">结课时间:2023-08-11</span>
+              <span class="blue mr-10">{{ grade.name }}</span>
+              <span class="mr-10">教师:{{ grade.teacher_name }}</span>
+              <span>班级号:{{ grade.num }}</span>
+              <span v-if="grade.grade_status == 1" class="red ml-10"
+                >结课时间:{{ grade.grade_time }}</span
+              >
               <span class="blue fr"
-                >学生:12
+                >学生:{{ grade.count }}人
                 <el-icon
                   :class="
-                    activeItem && activeItem.includes('2') ? 'is-active' : ''
+                    grade.active && grade.active.includes('1')
+                      ? 'is-active'
+                      : ''
                   "
                   ><CaretBottom
                 /></el-icon>
@@ -226,9 +101,13 @@ const tableData = ref<any>([
             </div>
           </template>
           <div>
-            <el-table :data="tableData" height="400" style="width: 100%">
+            <el-table
+              :data="grade.students"
+              max-height="400"
+              style="width: 100%"
+            >
               <el-table-column
-                prop="number"
+                type="index"
                 label="序号"
                 width="80"
                 align="center"
@@ -246,7 +125,7 @@ const tableData = ref<any>([
                 align="center"
               />
               <el-table-column
-                prop="times"
+                prop="count"
                 label="训练次数"
                 width="180"
                 align="center"