feat(teacher): 添加学员学习数据统计功能
添加新的API接口和学生详情页面的统计数据显示功能 移除测试成绩显示并调整出勤率和作业完成率的布局
Showing
2 changed files
with
51 additions
and
22 deletions
| 1 | /* | 1 | /* |
| 2 | * @Date: 2025-06-23 11:46:21 | 2 | * @Date: 2025-06-23 11:46:21 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-06-27 09:55:12 | 4 | + * @LastEditTime: 2025-06-27 14:04:05 |
| 5 | * @FilePath: /mlaj/src/api/teacher.js | 5 | * @FilePath: /mlaj/src/api/teacher.js |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | */ | 7 | */ |
| ... | @@ -13,6 +13,7 @@ const Api = { | ... | @@ -13,6 +13,7 @@ const Api = { |
| 13 | TEACHER_ADD_TASK: '/srv/?a=task&t=teacher_add', | 13 | TEACHER_ADD_TASK: '/srv/?a=task&t=teacher_add', |
| 14 | STUDENT_LIST: '/srv/?a=user&t=student_list', | 14 | STUDENT_LIST: '/srv/?a=user&t=student_list', |
| 15 | STUDENT_DETAIL: '/srv/?a=user&t=student_detail', | 15 | STUDENT_DETAIL: '/srv/?a=user&t=student_detail', |
| 16 | + STUDENT_STAT: '/srv/?a=user&t=student_stat', | ||
| 16 | STUDENT_CHECKIN_LIST: '/srv/?a=checkin&t=student_checkin_list', | 17 | STUDENT_CHECKIN_LIST: '/srv/?a=checkin&t=student_checkin_list', |
| 17 | STUDENT_UPLOAD_LIST: '/srv/?a=checkin&t=student_upload_list', | 18 | STUDENT_UPLOAD_LIST: '/srv/?a=checkin&t=student_upload_list', |
| 18 | STUDENT_CHECKIN_FEEDBACK_LIST: '/srv/?a=feedback&t=list', | 19 | STUDENT_CHECKIN_FEEDBACK_LIST: '/srv/?a=feedback&t=list', |
| ... | @@ -114,3 +115,11 @@ export const addCheckinFeedbackAPI = (params) => fn(fetch.post(Api.ADD_CHECKIN_F | ... | @@ -114,3 +115,11 @@ export const addCheckinFeedbackAPI = (params) => fn(fetch.post(Api.ADD_CHECKIN_F |
| 114 | * @returns {Object} data { id } | 115 | * @returns {Object} data { id } |
| 115 | */ | 116 | */ |
| 116 | export const delCheckinFeedbackAPI = (params) => fn(fetch.post(Api.DEL_CHECKIN_FEEDBACK, params)) | 117 | export const delCheckinFeedbackAPI = (params) => fn(fetch.post(Api.DEL_CHECKIN_FEEDBACK, params)) |
| 118 | + | ||
| 119 | +/** | ||
| 120 | + * 学员学习数据 | ||
| 121 | + * @param {*} i 学员ID | ||
| 122 | + * @param {*} group_id 课程ID | ||
| 123 | + * @returns {Object} data { need_checkin_count, real_checkin_count, need_upload_count, real_upload_count } | ||
| 124 | + */ | ||
| 125 | +export const getStudentStatAPI = (params) => fn(fetch.post(Api.STUDENT_STAT, params)) | ... | ... |
| ... | @@ -2,7 +2,7 @@ | ... | @@ -2,7 +2,7 @@ |
| 2 | * @Author: hookehuyr hookehuyr@gmail.com | 2 | * @Author: hookehuyr hookehuyr@gmail.com |
| 3 | * @Date: 2025-06-19 17:12:19 | 3 | * @Date: 2025-06-19 17:12:19 |
| 4 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 4 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 5 | - * @LastEditTime: 2025-06-27 10:49:01 | 5 | + * @LastEditTime: 2025-06-27 14:39:13 |
| 6 | * @FilePath: /mlaj/src/views/teacher/studentPage.vue | 6 | * @FilePath: /mlaj/src/views/teacher/studentPage.vue |
| 7 | * @Description: 学生详情页面 | 7 | * @Description: 学生详情页面 |
| 8 | --> | 8 | --> |
| ... | @@ -57,35 +57,35 @@ | ... | @@ -57,35 +57,35 @@ |
| 57 | <div class="mt-2"> | 57 | <div class="mt-2"> |
| 58 | <van-row> | 58 | <van-row> |
| 59 | <!-- 出勤率 --> | 59 | <!-- 出勤率 --> |
| 60 | - <van-col span="8"> | 60 | + <van-col span="12"> |
| 61 | <div class="bg-white p-4 text-center"> | 61 | <div class="bg-white p-4 text-center"> |
| 62 | <div class="relative w-16 h-16 mx-auto mb-2"> | 62 | <div class="relative w-16 h-16 mx-auto mb-2"> |
| 63 | - <van-circle v-model:current-rate="studentStats.attendanceRate" :rate="studentStats.attendanceRate" | 63 | + <van-circle v-model:current-rate="checkinCount" :rate="checkinCount" |
| 64 | - :speed="100" :text="studentStats.attendanceRate + '%'" stroke-width="70" color="#10b981" size="64" /> | 64 | + :text="`${checkinCountText}`" stroke-width="70" color="#10b981" size="64" /> |
| 65 | </div> | 65 | </div> |
| 66 | <div class="text-sm text-gray-600">出勤率</div> | 66 | <div class="text-sm text-gray-600">出勤率</div> |
| 67 | </div> | 67 | </div> |
| 68 | </van-col> | 68 | </van-col> |
| 69 | <!-- 作业完成率 --> | 69 | <!-- 作业完成率 --> |
| 70 | - <van-col span="8"> | 70 | + <van-col span="12"> |
| 71 | <div class="bg-white p-4 text-center"> | 71 | <div class="bg-white p-4 text-center"> |
| 72 | <div class="relative w-16 h-16 mx-auto mb-2"> | 72 | <div class="relative w-16 h-16 mx-auto mb-2"> |
| 73 | - <van-circle v-model:current-rate="studentStats.homeworkRate" :rate="studentStats.homeworkRate" | 73 | + <van-circle v-model:current-rate="uploadCount" :rate="uploadCount" |
| 74 | - :speed="100" :text="studentStats.homeworkRate + '%'" stroke-width="70" color="#3b82f6" size="64" /> | 74 | + :text="`${uploadCountText}`" stroke-width="70" color="#3b82f6" size="64" /> |
| 75 | </div> | 75 | </div> |
| 76 | <div class="text-sm text-gray-600">作业完成率</div> | 76 | <div class="text-sm text-gray-600">作业完成率</div> |
| 77 | </div> | 77 | </div> |
| 78 | </van-col> | 78 | </van-col> |
| 79 | <!-- 测验成绩 --> | 79 | <!-- 测验成绩 --> |
| 80 | - <van-col span="8"> | 80 | + <!-- <van-col span="8"> |
| 81 | <div class="bg-white p-4 text-center"> | 81 | <div class="bg-white p-4 text-center"> |
| 82 | <div class="relative w-16 h-16 mx-auto mb-2"> | 82 | <div class="relative w-16 h-16 mx-auto mb-2"> |
| 83 | <van-circle v-model:current-rate="studentStats.testScore" :rate="studentStats.testScore" :speed="100" | 83 | <van-circle v-model:current-rate="studentStats.testScore" :rate="studentStats.testScore" :speed="100" |
| 84 | - :text="studentStats.testScore + '%'" stroke-width="70" color="#f59e0b" size="64" /> | 84 | + :text="`${studentStats.testScore}%`" stroke-width="70" color="#f59e0b" size="64" /> |
| 85 | </div> | 85 | </div> |
| 86 | <div class="text-sm text-gray-600">测验成绩</div> | 86 | <div class="text-sm text-gray-600">测验成绩</div> |
| 87 | </div> | 87 | </div> |
| 88 | - </van-col> | 88 | + </van-col> --> |
| 89 | </van-row> | 89 | </van-row> |
| 90 | </div> | 90 | </div> |
| 91 | 91 | ||
| ... | @@ -381,7 +381,7 @@ import { useTitle } from '@vueuse/core'; | ... | @@ -381,7 +381,7 @@ import { useTitle } from '@vueuse/core'; |
| 381 | import dayjs from 'dayjs'; | 381 | import dayjs from 'dayjs'; |
| 382 | 382 | ||
| 383 | import { getCheckinTeacherListAPI, delUploadTaskInfoAPI, likeUploadTaskInfoAPI, dislikeUploadTaskInfoAPI } from "@/api/checkin"; | 383 | import { getCheckinTeacherListAPI, delUploadTaskInfoAPI, likeUploadTaskInfoAPI, dislikeUploadTaskInfoAPI } from "@/api/checkin"; |
| 384 | -import { getStudentDetailAPI, getStudentCheckinListAPI, getStudentUploadListAPI, getCheckinFeedbackListAPI, addCheckinFeedbackAPI, delCheckinFeedbackAPI } from "@/api/teacher"; | 384 | +import { getStudentDetailAPI, getStudentCheckinListAPI, getStudentUploadListAPI, getCheckinFeedbackListAPI, addCheckinFeedbackAPI, delCheckinFeedbackAPI, getStudentStatAPI } from "@/api/teacher"; |
| 385 | 385 | ||
| 386 | 386 | ||
| 387 | const router = useRouter() | 387 | const router = useRouter() |
| ... | @@ -398,13 +398,6 @@ const studentInfo = ref({}) | ... | @@ -398,13 +398,6 @@ const studentInfo = ref({}) |
| 398 | // 选中的课程列表(默认选中第一个课程) | 398 | // 选中的课程列表(默认选中第一个课程) |
| 399 | const selectedCourses = ref([]) | 399 | const selectedCourses = ref([]) |
| 400 | 400 | ||
| 401 | -// 统计数据 | ||
| 402 | -const studentStats = ref({ | ||
| 403 | - attendanceRate: 92, | ||
| 404 | - homeworkRate: 88, | ||
| 405 | - testScore: 85 | ||
| 406 | -}) | ||
| 407 | - | ||
| 408 | // 当前选中的标签页 | 401 | // 当前选中的标签页 |
| 409 | const activeTab = ref('homework') | 402 | const activeTab = ref('homework') |
| 410 | 403 | ||
| ... | @@ -517,6 +510,8 @@ const toggleCourseSelection = (course) => { | ... | @@ -517,6 +510,8 @@ const toggleCourseSelection = (course) => { |
| 517 | resetAndReload() | 510 | resetAndReload() |
| 518 | resetAndReloadRecords() | 511 | resetAndReloadRecords() |
| 519 | resetAndReloadEvaluations() | 512 | resetAndReloadEvaluations() |
| 513 | + // 重新获取统计数据以匹配当前选中的课程 | ||
| 514 | + getStatList() | ||
| 520 | } | 515 | } |
| 521 | 516 | ||
| 522 | // 状态选项 | 517 | // 状态选项 |
| ... | @@ -678,15 +673,18 @@ onMounted(async () => { | ... | @@ -678,15 +673,18 @@ onMounted(async () => { |
| 678 | 673 | ||
| 679 | // 这里可以根据studentId调用API获取学生详细信息 | 674 | // 这里可以根据studentId调用API获取学生详细信息 |
| 680 | await loadStudentData(studentId) | 675 | await loadStudentData(studentId) |
| 676 | + // 加载统计数据 | ||
| 677 | + await getStatList() | ||
| 681 | 678 | ||
| 682 | // 加载作业记录 | 679 | // 加载作业记录 |
| 683 | - onLoad() | 680 | + await onLoad() |
| 684 | 681 | ||
| 685 | // 加载签到记录 | 682 | // 加载签到记录 |
| 686 | - onRecordLoad() | 683 | + await onRecordLoad() |
| 687 | 684 | ||
| 688 | // 加载班主任点评 | 685 | // 加载班主任点评 |
| 689 | - onEvaluationLoad() | 686 | + await onEvaluationLoad() |
| 687 | + | ||
| 690 | }) | 688 | }) |
| 691 | 689 | ||
| 692 | /** | 690 | /** |
| ... | @@ -1026,6 +1024,28 @@ const resetAndReloadEvaluations = () => { | ... | @@ -1026,6 +1024,28 @@ const resetAndReloadEvaluations = () => { |
| 1026 | evaluationLoading.value = true; | 1024 | evaluationLoading.value = true; |
| 1027 | onEvaluationLoad(); | 1025 | onEvaluationLoad(); |
| 1028 | } | 1026 | } |
| 1027 | + | ||
| 1028 | +// 统计数据 | ||
| 1029 | +const checkinCount = ref(0); | ||
| 1030 | +const checkinCountText = computed(() => checkinCount.value.toFixed(1) + '%'); | ||
| 1031 | +const uploadCount = ref(0); | ||
| 1032 | +const uploadCountText = computed(() => uploadCount.value.toFixed(1) + '%'); | ||
| 1033 | + | ||
| 1034 | +const getStatList = async () => { | ||
| 1035 | + try { | ||
| 1036 | + const { code, data } = await getStudentStatAPI({ | ||
| 1037 | + i: route.params.id, | ||
| 1038 | + group_id: selectedCourses.value.length ? selectedCourses.value[0]['id'] : '', | ||
| 1039 | + }) | ||
| 1040 | + | ||
| 1041 | + if (code) { | ||
| 1042 | + checkinCount.value = data.real_checkin_count/data.need_checkin_count * 100; | ||
| 1043 | + uploadCount.value = data.real_upload_count/data.need_upload_count * 100; | ||
| 1044 | + } | ||
| 1045 | + } catch (error) { | ||
| 1046 | + console.error('获取统计数据失败:', error); | ||
| 1047 | + } | ||
| 1048 | +} | ||
| 1029 | </script> | 1049 | </script> |
| 1030 | 1050 | ||
| 1031 | <style lang="less"> | 1051 | <style lang="less"> | ... | ... |
-
Please register or login to post a comment