index.vue 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. <script setup lang="ts">
  2. import {watch} from "vue";
  3. import {useUserStore} from "@/store/modules/user";
  4. import {getGradeList, getGradeStudents} from "@/api/grade";
  5. import {GradeItem} from "@/api/grade/types";
  6. const userStore = useUserStore();
  7. defineOptions({
  8. name: "ClassIndex",
  9. inheritAttrs: false,
  10. });
  11. /**
  12. * 班级数据
  13. */
  14. const gradeData = ref<GradeItem[]>();
  15. // 0加载中,1数据正常,2数据为空
  16. const dataStatus = ref(0);
  17. // 班级status: 0全部1未结课2已结课
  18. const gradeType = ref(0);
  19. async function getGradeItems(schoolId: number, status: number) {
  20. getGradeList(schoolId, status)
  21. .then(({data}) => {
  22. gradeData.value = data;
  23. if (gradeData.value?.length > 0) {
  24. dataStatus.value = 1;
  25. } else {
  26. dataStatus.value = 2;
  27. }
  28. })
  29. .catch((error) => {
  30. dataStatus.value = 2;
  31. console.log(error);
  32. });
  33. }
  34. // 请求班级学生数据
  35. async function getStudentList(grade: GradeItem) {
  36. getGradeStudents(grade.id)
  37. .then(({data}) => {
  38. grade.students = data;
  39. })
  40. .catch((error) => {
  41. console.log(error);
  42. });
  43. }
  44. // 改变班级状态
  45. function changeGradeType() {
  46. getGradeItems(userStore.schoolId, gradeType.value);
  47. }
  48. // 打开班级请求学生
  49. function collapseGrade(grade: GradeItem) {
  50. if (grade.count > 0) {
  51. if (!grade.students || grade.students.length === 0) {
  52. getStudentList(grade);
  53. }
  54. }
  55. }
  56. onMounted(() => {
  57. // 获取班级
  58. getGradeItems(userStore.schoolId, gradeType.value);
  59. });
  60. watch(
  61. () => userStore.schoolId,
  62. (newValue, oldValue) => {
  63. console.log("userStore.schoolId", newValue, oldValue);
  64. // 学校切换后重新加载数据
  65. getGradeItems(newValue, gradeType.value);
  66. }
  67. );
  68. </script>
  69. <template>
  70. <div class="class-container">
  71. <!-- 班级选择 -->
  72. <div class="class-select">
  73. <el-select v-model="gradeType" placeholder="全部班级" size="large" @change="changeGradeType()">
  74. <el-option key="0" label="全部班级" :value="Number(0)" />
  75. <el-option key="1" label="未结课班级" :value="Number(1)" />
  76. <el-option key="1" label="已结课班级" :value="Number(2)" />
  77. </el-select>
  78. </div>
  79. <!-- 班级折叠面板-->
  80. <template v-if="dataStatus == 1">
  81. <div v-for="grade in gradeData" :key="grade.id" class="list-collapse">
  82. <el-collapse v-model="grade.active" @change="collapseGrade(grade)">
  83. <el-collapse-item :name="grade.id" class="testtt">
  84. <template #title>
  85. <div class="title">
  86. <span class="blue mr-10">{{ grade.name }}</span>
  87. <span class="mr-10">教师:{{ grade.teacher_name || "未分配" }}</span>
  88. <span class="mr-10">班级号:{{ grade.num }}</span>
  89. <span v-if="grade.grade_status == 1" class="red">结课时间:{{ grade.grade_time }}</span>
  90. <span class="blue fr"
  91. >学生:{{ grade.count }}人
  92. <el-icon :class="grade.active && grade.active.includes(grade.id) ? 'is-active' : ''"
  93. ><CaretBottom
  94. /></el-icon>
  95. </span>
  96. </div>
  97. </template>
  98. <div>
  99. <el-table :data="grade.students" max-height="400" style="width: 100%">
  100. <el-table-column align="center" label="序号" type="index" width="80" />
  101. <el-table-column align="center" label="学生名称" prop="name" width="180" />
  102. <el-table-column align="center" label="手机号" prop="phone" width="180" />
  103. <el-table-column align="center" label="训练次数" prop="count" width="180" />
  104. <el-table-column />
  105. <!-- 无数据插槽 -->
  106. <template #empty>
  107. <div v-if="grade.count > 0">...</div>
  108. <div v-else class="empty">
  109. <img src="../../assets/empty.png" alt="数据为空" />
  110. <p>该班级还未绑定任何学生!</p>
  111. </div>
  112. </template>
  113. </el-table>
  114. </div>
  115. </el-collapse-item>
  116. </el-collapse>
  117. </div>
  118. </template>
  119. <template v-else>
  120. <div class="empty page-empty">
  121. <img src="../../assets/empty.png" alt="数据为空" />
  122. <p v-if="dataStatus == 0">加载中...</p>
  123. <template v-if="dataStatus == 2">
  124. <p v-if="gradeType == 0">您的学校还未创建任何班级!</p>
  125. <p v-if="gradeType == 1">您的学校还没有任何未结课班级!</p>
  126. <p v-if="gradeType == 2">您的学校还没有任何已结课班级!</p>
  127. </template>
  128. </div>
  129. </template>
  130. </div>
  131. </template>
  132. <style lang="scss" scoped>
  133. .class-container {
  134. position: relative;
  135. padding: 20px 30px;
  136. }
  137. .class-select {
  138. margin-bottom: 20px;
  139. .el-select {
  140. width: 160px;
  141. margin: 0;
  142. }
  143. }
  144. :deep(.el-input__wrapper) {
  145. background: #fff;
  146. border-radius: 12px;
  147. box-shadow: none !important;
  148. }
  149. /* el-select 各种边框线隐藏 **/
  150. :deep(.el-select) {
  151. --el-select-input-focus-border-color: none !important;
  152. }
  153. :deep(.el-select .el-input__wrapper.is-focus) {
  154. box-shadow: none !important;
  155. }
  156. :deep(.el-select:hover:not(.el-select--disabled) .el-input__wrapper) {
  157. box-shadow: none !important;
  158. }
  159. .page-empty {
  160. padding: 240px 0;
  161. }
  162. .list-collapse {
  163. padding: 0 32px;
  164. margin-bottom: 10px;
  165. background: #fff;
  166. border-radius: 25px;
  167. .empty {
  168. padding: 20px 0;
  169. }
  170. .title {
  171. width: 100%;
  172. font-size: 18px;
  173. span {
  174. display: inline-block;
  175. }
  176. .blue {
  177. color: #4284f2;
  178. }
  179. .red {
  180. color: #e04962;
  181. }
  182. .fr {
  183. float: right;
  184. }
  185. .el-icon {
  186. vertical-align: middle;
  187. &.is-active {
  188. transform: rotate(180deg);
  189. }
  190. }
  191. }
  192. :deep(.el-collapse),
  193. :deep(.el-collapse-item__header),
  194. :deep(.el-collapse-item__wrap) {
  195. border: none;
  196. }
  197. :deep(.el-collapse-item__arrow) {
  198. display: none;
  199. }
  200. }
  201. :deep(.el-table .el-table__header .el-table__cell .cell) {
  202. overflow: visible;
  203. white-space: nowrap;
  204. }
  205. :deep(.el-table th.el-table__cell) {
  206. background: #e9ebee;
  207. }
  208. .mobile .list-collapse {
  209. :deep(.el-collapse-item__header) {
  210. height: auto;
  211. }
  212. }
  213. </style>