Selaa lähdekoodia

build: 缺省页面信息提示

chaooo 2 vuotta sitten
vanhempi
commit
46690ba796

+ 2 - 2
src/api/dashboard/index.ts

@@ -15,10 +15,10 @@ export function getDashboardTop(id: number): AxiosPromise<DashboardCard> {
 /**
  * 获取首页图表数据
  */
-export function getDashboardData(id: number): AxiosPromise<DashboardData> {
+export function getDashboardData(school_id: number, grade_id: number): AxiosPromise<DashboardData> {
   return request({
     url: "/board/v1/bottom",
     method: "get",
-    params: { grade_id: id },
+    params: { school_id: school_id, grade_id: grade_id},
   });
 }

+ 13 - 5
src/components/Pagination/index.vue

@@ -14,8 +14,8 @@
 </template>
 
 <script setup lang="ts">
-import { computed, PropType } from "vue";
-import { scrollTo } from "@/utils/scroll-to";
+import {PropType} from "vue";
+import {scrollTo} from "@/utils/scroll-to";
 
 const props = defineProps({
   total: {
@@ -34,7 +34,7 @@ const props = defineProps({
   pageSizes: {
     type: Array as PropType<number[]>,
     default() {
-      return [10, 20, 30, 50];
+      return [10, 12, 20, 24, 30, 50];
     },
   },
   layout: {
@@ -79,10 +79,18 @@ function handleCurrentChange(val: number) {
 
 <style lang="scss" scoped>
 .pagination {
-  padding: 12px;
-
+	margin-top: 3rem;
+  padding: 1rem;
+	color:#474b59;
   &.hidden {
     display: none;
   }
 }
+:deep(.el-input){
+	border: 1px solid #dddcdd;
+	border-radius: 5px;
+}
+:deep(.el-pagination){
+	justify-content: center;
+}
 </style>

+ 18 - 0
src/styles/reset.scss

@@ -80,3 +80,21 @@ div:focus {
   display: block;
   clear: both;
 }
+.empty {
+  box-sizing: border-box;
+  padding:30px 0;
+  text-align: center;
+  line-height:1.5rem;
+  //background-image: url("../assets/empty.png");
+  //background-repeat: no-repeat;
+  //background-position: center center;
+  //position: relative;
+  p {
+	margin:0;
+	font-size: 14px;
+	color: #a1a1a1;
+	&.red {
+	  color: #e04962;
+	}
+  }
+}

+ 17 - 32
src/utils/index.ts

@@ -1,39 +1,24 @@
 /**
- * Check if an element has a class
- * @param {HTMLElement} ele
- * @param {string} cls
- * @returns {boolean}
- */
-export function hasClass(ele: HTMLElement, cls: string) {
-  return !!ele.className.match(new RegExp("(\\s|^)" + cls + "(\\s|$)"));
-}
-
-/**
- * Add class to element
- * @param {HTMLElement} ele
- * @param {string} cls
- */
-export function addClass(ele: HTMLElement, cls: string) {
-  if (!hasClass(ele, cls)) ele.className += " " + cls;
-}
-
-/**
- * Remove class from element
- * @param {HTMLElement} ele
- * @param {string} cls
+ * @param {string} path
+ * @returns {Boolean}
  */
-export function removeClass(ele: HTMLElement, cls: string) {
-  if (hasClass(ele, cls)) {
-    const reg = new RegExp("(\\s|^)" + cls + "(\\s|$)");
-    ele.className = ele.className.replace(reg, " ");
-  }
+export function isExternal(path: string) {
+	return /^(https?:|http?:|mailto:|tel:)/.test(path);
 }
 
 /**
- * @param {string} path
- * @returns {Boolean}
+ * 获取URL参数值
+ * @param name URL参数名称
  */
-export function isExternal(path: string) {
-  const isExternal = /^(https?:|http?:|mailto:|tel:)/.test(path);
-  return isExternal;
+function getUrlParam(name:string) {
+	let value = "";
+	const paramsStr = window.location.href.split('?')[1];
+	const paramArr = paramsStr.split('&');
+	paramArr.some((item) => {
+		if(item.includes(name)){
+			value = item.split("=")[1] || "";
+			return;
+		}
+	});
+	return value;
 }

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

@@ -65,28 +65,28 @@ let chartData: DashboardData = reactive({
   frontProportion: { num: [], percentage: [] }, // 初期分期占比分析
   afterProportion: { num: [], percentage: [] }, // 近期分期占比分析
 });
-async function getChartData(gradeId: number) {
-  getDashboardData(gradeId)
+async function getChartData(schoolId:number, gradeId: number) {
+  getDashboardData(schoolId, 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;
+			dataStatus.value = 5;
+			dataMessage.value = error.message;
+      console.log(error.message);
     });
 }
-// 数据状态:1正常,2训练次数小于3,3过期,4缺省
+// 数据状态:1正常,2训练次数小于3,3过期,4缺省,5接口直接返回缺省信息error.message
 const dataStatus = ref(5);
+const dataMessage = ref("加载中...");
 // 改变班级重新加载图表数据
 function changeGrade() {
   dataStatus.value = 5;
-  getChartData(gradeId.value);
+  getChartData(userStore.schoolId, gradeId.value);
 }
 onMounted(() => {
   // 获取班级
@@ -94,7 +94,7 @@ onMounted(() => {
   // 数据卡片
   getDataCard(userStore.schoolId);
   // 图表数据
-  getChartData(gradeId.value);
+  getChartData(userStore.schoolId, gradeId.value);
 });
 watch(
   () => userStore.schoolId,
@@ -105,7 +105,7 @@ watch(
     dataStatus.value = 5;
     getGradeData(newValue);
     getDataCard(newValue);
-    getChartData(0);
+    getChartData(newValue,0);
   }
 );
 </script>
@@ -260,36 +260,38 @@ watch(
       <el-col :md="24" :lg="8">
         <div class="charts-item">
           <p class="title">学员专注力平均值整体对比分析</p>
-          <div v-if="dataStatus == 2" class="empty">
-            <p>筛选条件的学生人群训练3次以上才能进行训练数据分析,</p>
-            <p>当前训练数据不足以进行数据分析!</p>
-          </div>
-          <div v-if="dataStatus == 3" class="empty">
-            <p class="red">合作已过期,无法进行数据看板的查看!</p>
-          </div>
-          <div v-if="dataStatus == 4" class="empty">
-            <p>您的学校还没有任何训练数据!</p>
-          </div>
+<!--          <div v-if="dataStatus == 2" class="empty">-->
+<!--            <p>筛选条件的学生人群训练3次以上才能进行训练数据分析,</p>-->
+<!--            <p>当前训练数据不足以进行数据分析!</p>-->
+<!--          </div>-->
+<!--          <div v-if="dataStatus == 3" class="empty">-->
+<!--            <p class="red">合作已过期,无法进行数据看板的查看!</p>-->
+<!--          </div>-->
+<!--          <div v-if="dataStatus == 4" class="empty">-->
+<!--            <p>您的学校还没有任何训练数据!</p>-->
+<!--          </div>-->
           <div v-if="dataStatus == 5" class="empty">
-            <p>加载中...</p>
+						<img src="../../assets/empty.png" alt="数据为空">
+            <p>{{ dataMessage }}</p>
           </div>
         </div>
       </el-col>
       <el-col :md="24" :lg="16">
         <div class="charts-item">
           <p class="title">学员专注力评分分级占比分析</p>
-          <div v-if="dataStatus == 2" class="empty">
-            <p>筛选条件的学生人群训练3次以上才能进行训练数据分析,</p>
-            <p>当前训练数据不足以进行数据分析!</p>
-          </div>
-          <div v-if="dataStatus == 3" class="empty">
-            <p class="red">合作已过期,无法进行数据看板的查看!</p>
-          </div>
-          <div v-if="dataStatus == 4" class="empty">
-            <p>您的学校还没有任何训练数据!</p>
-          </div>
+<!--          <div v-if="dataStatus == 2" class="empty">-->
+<!--            <p>筛选条件的学生人群训练3次以上才能进行训练数据分析,</p>-->
+<!--            <p>当前训练数据不足以进行数据分析!</p>-->
+<!--          </div>-->
+<!--          <div v-if="dataStatus == 3" class="empty">-->
+<!--            <p class="red">合作已过期,无法进行数据看板的查看!</p>-->
+<!--          </div>-->
+<!--          <div v-if="dataStatus == 4" class="empty">-->
+<!--            <p>您的学校还没有任何训练数据!</p>-->
+<!--          </div>-->
           <div v-if="dataStatus == 5" class="empty">
-            <p>加载中...</p>
+						<img src="../../assets/empty.png" alt="数据为空">
+            <p>{{ dataMessage }}</p>
           </div>
         </div>
       </el-col>
@@ -367,20 +369,7 @@ watch(
     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;
-      }
-    }
+    padding: 200px 0;
   }
 }
 </style>

+ 90 - 61
src/views/grade/index.vue

@@ -14,14 +14,18 @@ defineOptions({
  * 班级数据
  */
 const gradeData = ref<GradeItem[]>();
+// 0加载中,1数据正常,2数据为空
+const dataStatus = ref(0);
 // 班级status: 0全部1未结课2已结课
-let gradeStatus = ref(0);
+const gradeType = ref(0);
 async function getGradeItems(schoolId: number, status: number) {
   getGradeList(schoolId, status)
     .then(({ data }) => {
       gradeData.value = data;
+			dataStatus.value = 1;
     })
     .catch((error) => {
+			dataStatus.value = 2;
       console.log(error);
     });
 }
@@ -36,8 +40,8 @@ async function getStudentList(grade: GradeItem) {
     });
 }
 // 改变班级状态
-function changeStatus() {
-  getGradeItems(userStore.schoolId, gradeStatus.value);
+function changeGradeType() {
+  getGradeItems(userStore.schoolId, gradeType.value);
 }
 // 打开班级请求学生
 function collapseGrade(grade: GradeItem) {
@@ -47,14 +51,14 @@ function collapseGrade(grade: GradeItem) {
 }
 onMounted(() => {
   // 获取班级
-  getGradeItems(userStore.schoolId, gradeStatus.value);
+  getGradeItems(userStore.schoolId, gradeType.value);
 });
 watch(
   () => userStore.schoolId,
   (newValue, oldValue) => {
     console.log("userStore.schoolId", newValue, oldValue);
     // 学校切换后重新加载数据
-    getGradeItems(newValue, gradeStatus.value);
+    getGradeItems(newValue, gradeType.value);
   }
 );
 </script>
@@ -64,10 +68,10 @@ watch(
     <!-- 班级选择 -->
     <div class="class-select">
       <el-select
-        v-model="gradeStatus"
+        v-model="gradeType"
         placeholder="全部班级"
         size="large"
-        @change="changeStatus()"
+        @change="changeGradeType()"
       >
         <el-option key="0" label="全部班级" :value="Number(0)" />
         <el-option key="1" label="未结课班级" :value="Number(1)" />
@@ -75,66 +79,85 @@ watch(
       </el-select>
     </div>
     <!-- 班级折叠面板-->
-    <div v-for="grade in gradeData" :key="grade.id" class="list-collapse">
-      <el-collapse v-model="grade.active" @change="collapseGrade(grade)">
-        <el-collapse-item :name="grade.id">
-          <template #title>
-            <div class="title">
-              <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"
-                >学生:{{ grade.count }}人
+		<template v-if="dataStatus == 1">
+			<div v-for="grade in gradeData" :key="grade.id" class="list-collapse">
+				<el-collapse v-model="grade.active" @change="collapseGrade(grade)">
+					<el-collapse-item :name="grade.id">
+						<template #title>
+							<div class="title">
+								<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"
+								>学生:{{ grade.count }}人
                 <el-icon
-                  :class="
+										:class="
                     grade.active && grade.active.includes(grade.id)
                       ? 'is-active'
                       : ''
                   "
-                  ><CaretBottom
-                /></el-icon>
+								><CaretBottom/></el-icon>
               </span>
-            </div>
-          </template>
-          <div>
-            <el-table
-              :data="grade.students"
-              max-height="400"
-              style="width: 100%"
-            >
-              <el-table-column
-                type="index"
-                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="count"
-                label="训练次数"
-                width="180"
-                align="center"
-              />
-              <el-table-column />
-            </el-table>
-          </div>
-        </el-collapse-item>
-      </el-collapse>
-    </div>
+							</div>
+						</template>
+						<div>
+							<el-table
+									:data="grade.students"
+									max-height="400"
+									style="width: 100%"
+							>
+								<el-table-column
+										type="index"
+										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="count"
+										label="训练次数"
+										width="180"
+										align="center"
+								/>
+								<el-table-column />
+								<!-- 无数据插槽 -->
+								<template #empty>
+									<div class="empty">
+										<img src="../../assets/empty.png" alt="数据为空">
+										<p>该班级还未绑定任何学生!</p>
+									</div>
+								</template>
+							</el-table>
+						</div>
+					</el-collapse-item>
+				</el-collapse>
+			</div>
+		</template>
+		<template v-else>
+			<div class="empty page-empty">
+				<img src="../../assets/empty.png" alt="数据为空">
+				<p v-if="dataStatus == 0">加载中...</p>
+				<template v-if="dataStatus == 2">
+					<p v-if="gradeType==0">您的学校还未创建任何班级!</p>
+					<p v-if="gradeType==1">您的学校还没有任何未结课班级!</p>
+					<p v-if="gradeType==2">您的学校还没有任何已结课班级!</p>
+				</template>
+			</div>
+		</template>
   </div>
 </template>
 
@@ -167,11 +190,17 @@ watch(
 :deep(.el-select:hover:not(.el-select--disabled) .el-input__wrapper) {
   box-shadow: none !important;
 }
+.page-empty{
+	padding:240px 0;
+}
 .list-collapse {
   background: #ffffff;
   border-radius: 25px;
   padding: 0 32px;
   margin-bottom: 10px;
+	.empty{
+		padding:20px 0;
+	}
   .title {
     width: 100%;
     font-size: 18px;

+ 36 - 17
src/views/student/index.vue

@@ -31,39 +31,48 @@ async function getGradeData(schoolId: number) {
 /**
  * 学生数据
  */
+const studentSearch:StudentParams = reactive({
+	school_id: userStore.schoolId,
+	grade_id: 0,
+	search: "",
+	page_no: 1,
+	page_size: 12,
+});
+// 0加载中,1数据正常,2数据为空
+const dataStatus = ref(0);
 const studentCount = ref(0);
 const studentData = ref<StudentItem[]>();
-let keywords = ref("");
-async function getStudentData() {
-	const studentSearch:StudentParams = {
-		school_id: userStore.schoolId,
-		grade_id: gradeId.value,
-		search: keywords.value,
-		page_no: 0,
-		page_size: 12
-	}
+async function getStudentData(schoolId) {
+	studentSearch.school_id = schoolId;
 	getStudentLists(studentSearch)
 		.then(({ data }) => {
 			const {count, lists} = data;
 			studentCount.value = count;
 			studentData.value = lists;
+			dataStatus.value = 1;
 		})
 		.catch((error) => {
+			dataStatus.value = 2;
 			console.log(error);
 		});
 }
+function getStudentSearch(){
+	getStudentData(userStore.schoolId);
+}
 onMounted(() => {
 	// 获取班级
 	getGradeData(userStore.schoolId);
 	// 获取学生数据
-	getStudentData();
+	getStudentData(userStore.schoolId);
 });
 watch(
 	() => userStore.schoolId,
 	(newValue) => {
 		// 学校切换后重新加载数据
-		gradeId.value = 0;
+		studentSearch.grade_id = 0;
+		studentSearch.search = "";
 		getGradeData(newValue);
+		getStudentData(userStore.schoolId);
 	}
 );
 </script>
@@ -72,7 +81,7 @@ watch(
   <div class="student-container">
     <!-- 学生查找 -->
     <div class="student-search">
-			<el-select v-model="gradeId" placeholder="全部班级" size="large">
+			<el-select v-model="studentSearch.grade_id" placeholder="全部班级" size="large">
 				<el-option
 						v-for="item in gradeData"
 						:key="item.id"
@@ -81,11 +90,11 @@ watch(
 				/>
 			</el-select>
       <el-input
-        v-model="keywords"
+        v-model="studentSearch.search"
         size="large"
         placeholder="请输入学生名称或手机号码"
       />
-      <el-button size="large" type="primary" @click="getStudentData()">查找</el-button>
+      <el-button size="large" type="primary" @click="getStudentSearch()">查找</el-button>
       <span>共<b>{{ studentCount }}</b>人</span>
     </div>
     <!-- 学生数据 -->
@@ -98,17 +107,27 @@ watch(
         <el-table-column prop="create_time" label="注册时间" align="center" />
         <el-table-column prop="count" label="训练次数" align="center" />
         <el-table-column />
-        <el-table-column label="操作" align="center">
-          <router-link to="/student/result" class="table-btn">训练效果分析</router-link>
+        <el-table-column label="操作" align="center" >
+					<template #default="scope">
+						<router-link :to="'/student/result?id='+scope.row.id" class="table-btn">训练效果分析</router-link>
+					</template>
         </el-table-column>
 				<!-- 无数据插槽 -->
 				<template #empty>
 					<div class="empty">
 						<img src="../../assets/empty.png" alt="数据为空">
-						<p>未查询到学生数据,请更换查询条件重新查找!</p>
+						<p v-if="dataStatus == 0">加载中...</p>
+						<p v-if="dataStatus == 2">暂时还没有任何学生绑定学校!</p>
 					</div>
 				</template>
       </el-table>
+			<pagination
+					v-if="studentCount > 0"
+					v-model:total="studentCount"
+					v-model:page="studentSearch.page_no"
+					v-model:limit="studentSearch.page_size"
+					@pagination="getStudentSearch()"
+			/>
     </div>
   </div>
 </template>

+ 14 - 2
src/views/teacher/index.vue

@@ -14,6 +14,8 @@ defineOptions({
  * 班级数据
  */
 const teacherData = ref<TeacherItem[]>();
+// 0加载中,1数据正常,2数据为空
+const dataStatus = ref(0);
 // 教师数量
 let teacherCount = ref(0);
 // 用于搜索的教师名称或手机号
@@ -25,8 +27,10 @@ async function getTeacherData(schoolId: number, keyword: string) {
       const temp: TeacherList = data;
       teacherData.value = temp.lists;
       teacherCount.value = temp.count;
+			dataStatus.value = 1;
     })
     .catch((error) => {
+			dataStatus.value = 2;
       console.log(error);
     });
 }
@@ -97,6 +101,7 @@ watch(
         >人</span
       >
     </div>
+		<template v-if="dataStatus == 1">
     <!-- 折叠面板-->
     <div v-for="teacher in teacherData" :key="teacher.id" class="list-collapse">
       <el-collapse v-model="teacher.active" @change="collapseTeacher(teacher)">
@@ -113,8 +118,7 @@ watch(
                       ? 'is-active'
                       : ''
                   "
-                  ><CaretBottom
-                /></el-icon>
+                  ><CaretBottom/></el-icon>
               </span>
             </div>
           </template>
@@ -232,6 +236,14 @@ watch(
         </el-collapse-item>
       </el-collapse>
     </div>
+		</template>
+		<template v-else>
+			<div class="empty page-empty">
+				<img src="../../assets/empty.png" alt="数据为空">
+				<p v-if="dataStatus == 0">加载中...</p>
+				<p v-if="dataStatus == 2">暂时还没有任何教师注册绑定学校!</p>
+			</div>
+		</template>
   </div>
 </template>