hookehuyr

feat(签到): 添加小作业列表功能支持

在教师API中添加获取小作业列表接口
更新签到详情页和日历组件以支持小作业筛选
修改任务详情接口返回小作业列表数据
1 /* 1 /*
2 * @Date: 2025-06-06 09:26:16 2 * @Date: 2025-06-06 09:26:16
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-12-01 14:06:29 4 + * @LastEditTime: 2025-12-11 14:43:44
5 * @FilePath: /mlaj/src/api/checkin.js 5 * @FilePath: /mlaj/src/api/checkin.js
6 * @Description: 签到模块相关接口 6 * @Description: 签到模块相关接口
7 */ 7 */
...@@ -35,7 +35,8 @@ export const getTaskListAPI = (params) => fn(fetch.get(Api.GET_TASK_LIST, param ...@@ -35,7 +35,8 @@ export const getTaskListAPI = (params) => fn(fetch.get(Api.GET_TASK_LIST, param
35 * @description: 获取作业详情 35 * @description: 获取作业详情
36 * @param: i 作业id 36 * @param: i 作业id
37 * @param: month 月份 37 * @param: month 月份
38 - * @returns data: { id 作业id, title 作业名称, note 作业描述, frequency 交作业的频次, cycle 交作业的周期 {0=本周期 | 30=每月 | 7=每周 | 1=每日}, attachment_type 上传附件的类型 [text=文本 image=图片 video=视频 audio=音频], begin_date 开始时间, end_date 结束时间, task_type 任务类型 [checkin=签到 | file=上传附件], is_gray 作业是否应该置灰, my_checkin_dates 我在日历中打过卡的日期, target_number 打卡的目标数量, checkin_number 已经打卡的数量, checkin_avatars 最后打卡的10个人的头像 } 38 + * @param: subtask_id 小作业ID
39 + * @returns data: { id 作业id, title 作业名称, note 作业描述, frequency 交作业的频次, cycle 交作业的周期 {0=本周期 | 30=每月 | 7=每周 | 1=每日}, attachment_type 上传附件的类型 [text=文本 image=图片 video=视频 audio=音频], begin_date 开始时间, end_date 结束时间, task_type 任务类型 [checkin=签到 | file=上传附件], is_gray 作业是否应该置灰, my_checkin_dates 我在日历中打过卡的日期, target_number 打卡的目标数量, checkin_number 已经打卡的数量, checkin_avatars 最后打卡的10个人的头像, subtask_list 小作业列表 [{id,title,cycle,frequency,attachment_type,begin_date,end_date,is_finish}] }
39 */ 40 */
40 export const getTaskDetailAPI = (params) => fn(fetch.get(Api.GET_TASK_DETAIL, params)) 41 export const getTaskDetailAPI = (params) => fn(fetch.get(Api.GET_TASK_DETAIL, params))
41 42
......
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-12-01 14:13:18 4 + * @LastEditTime: 2025-12-11 15:08:04
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 TEACHER_LIST_TASK: '/srv/?a=task&t=teacher_list', 14 TEACHER_LIST_TASK: '/srv/?a=task&t=teacher_list',
15 TEACHER_DETAIL_TASK: '/srv/?a=task&t=teacher_detail', 15 TEACHER_DETAIL_TASK: '/srv/?a=task&t=teacher_detail',
16 + TEACHER_SUBTASK_LIST: '/srv/?a=subtask&t=list',
16 STUDENT_LIST: '/srv/?a=user&t=student_list', 17 STUDENT_LIST: '/srv/?a=user&t=student_list',
17 STUDENT_DETAIL: '/srv/?a=user&t=student_detail', 18 STUDENT_DETAIL: '/srv/?a=user&t=student_detail',
18 STUDENT_STAT: '/srv/?a=user&t=student_stat', 19 STUDENT_STAT: '/srv/?a=user&t=student_stat',
...@@ -99,6 +100,13 @@ export const getTeacherTaskListAPI = (params) => fn(fetch.get(Api.TEACHER_LIST_T ...@@ -99,6 +100,13 @@ export const getTeacherTaskListAPI = (params) => fn(fetch.get(Api.TEACHER_LIST_T
99 export const getTeacherTaskDetailAPI = (params) => fn(fetch.get(Api.TEACHER_DETAIL_TASK, params)) 100 export const getTeacherTaskDetailAPI = (params) => fn(fetch.get(Api.TEACHER_DETAIL_TASK, params))
100 101
101 /** 102 /**
103 + * 获取小作业列表
104 + * @param {*} task_id 大作业ID
105 + * @returns {Object} data [{id,title,cycle,frequency,attachment_type,begin_date,end_date,is_finish}]
106 + */
107 +export const getTeacherSubtaskListAPI = (params) => fn(fetch.get(Api.TEACHER_SUBTASK_LIST, params))
108 +
109 +/**
102 * 获取学员列表 110 * 获取学员列表
103 * @param {*} grade_id 年级ID 111 * @param {*} grade_id 年级ID
104 * @param {*} class_id 班级ID 112 * @param {*} class_id 班级ID
......
1 <!-- 1 <!--
2 * @Date: 2025-01-25 15:34:17 2 * @Date: 2025-01-25 15:34:17
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-12-11 13:55:33 4 + * @LastEditTime: 2025-12-11 15:01:51
5 * @FilePath: /mlaj/src/components/ui/CollapsibleCalendar.vue 5 * @FilePath: /mlaj/src/components/ui/CollapsibleCalendar.vue
6 * @Description: 可折叠日历组件 6 * @Description: 可折叠日历组件
7 --> 7 -->
...@@ -86,7 +86,7 @@ ...@@ -86,7 +86,7 @@
86 :style="{ minHeight: '30%', maxHeight: '80%', width: '100%' }" 86 :style="{ minHeight: '30%', maxHeight: '80%', width: '100%' }"
87 > 87 >
88 <van-picker 88 <van-picker
89 - title="作业选择" 89 + title="作业选择"
90 :columns="courseColumns" 90 :columns="courseColumns"
91 @confirm="onConfirmCourse" 91 @confirm="onConfirmCourse"
92 @cancel="showCoursePicker = false" 92 @cancel="showCoursePicker = false"
...@@ -113,6 +113,10 @@ const props = defineProps({ ...@@ -113,6 +113,10 @@ const props = defineProps({
113 modelValue: { 113 modelValue: {
114 type: [String, Date], 114 type: [String, Date],
115 default: null 115 default: null
116 + },
117 + subtaskList: {
118 + type: Array,
119 + default: () => []
116 } 120 }
117 }) 121 })
118 122
...@@ -127,14 +131,15 @@ const currentDate = ref(props.modelValue || new Date()) ...@@ -127,14 +131,15 @@ const currentDate = ref(props.modelValue || new Date())
127 // 作业筛选相关 131 // 作业筛选相关
128 const showCoursePicker = ref(false) 132 const showCoursePicker = ref(false)
129 const selectedCourseText = ref('全部作业') 133 const selectedCourseText = ref('全部作业')
130 -const courseColumns = [ 134 +const courseColumns = computed(() => {
131 - { text: '全部作业', value: '' }, 135 + return [
132 - { text: '语文语文语文语文语文语文数学英语化学化学化学化学英语', value: 'chinese' }, 136 + { text: '全部作业', value: '' },
133 - { text: '数学', value: 'math' }, 137 + ...props.subtaskList.map(item => ({
134 - { text: '英语', value: 'english' }, 138 + text: item.title,
135 - { text: '物理', value: 'physics' }, 139 + value: item.id
136 - { text: '化学', value: 'chemistry' } 140 + }))
137 -] 141 + ]
142 +})
138 143
139 const openCoursePicker = () => { 144 const openCoursePicker = () => {
140 showCoursePicker.value = true 145 showCoursePicker.value = true
......
...@@ -190,7 +190,7 @@ ...@@ -190,7 +190,7 @@
190 import { ref, computed, onMounted, nextTick, reactive } from 'vue' 190 import { ref, computed, onMounted, nextTick, reactive } from 'vue'
191 import { useRoute, useRouter } from 'vue-router' 191 import { useRoute, useRouter } from 'vue-router'
192 import { getTaskDetailAPI, getUploadTaskInfoAPI } from "@/api/checkin" 192 import { getTaskDetailAPI, getUploadTaskInfoAPI } from "@/api/checkin"
193 -import { getTeacherFindSettingsAPI } from '@/api/teacher' 193 +import { getTeacherFindSettingsAPI, getTeacherSubtaskListAPI } from '@/api/teacher'
194 import { useTitle } from '@vueuse/core' 194 import { useTitle } from '@vueuse/core'
195 import { useCheckin } from '@/composables/useCheckin' 195 import { useCheckin } from '@/composables/useCheckin'
196 import AudioPlayer from '@/components/ui/AudioPlayer.vue' 196 import AudioPlayer from '@/components/ui/AudioPlayer.vue'
...@@ -233,11 +233,7 @@ const taskType = computed(() => route.query.task_type) ...@@ -233,11 +233,7 @@ const taskType = computed(() => route.query.task_type)
233 const showTaskPicker = ref(false) 233 const showTaskPicker = ref(false)
234 const selectedTaskText = ref('') 234 const selectedTaskText = ref('')
235 const selectedTaskValue = ref('') 235 const selectedTaskValue = ref('')
236 -const taskOptions = [ 236 +const taskOptions = [{ text: '全部作业', value: '' }]
237 - { text: '作业一:基础练习', value: 'task1' },
238 - { text: '作业二:进阶挑战', value: 'task2' },
239 - { text: '作业三:综合应用', value: 'task3' },
240 -]
241 237
242 const onConfirmTask = ({ selectedOptions }) => { 238 const onConfirmTask = ({ selectedOptions }) => {
243 const option = selectedOptions[0] 239 const option = selectedOptions[0]
...@@ -787,6 +783,16 @@ onMounted(async () => { ...@@ -787,6 +783,16 @@ onMounted(async () => {
787 getTaskDetail(dayjs().format('YYYY-MM')); 783 getTaskDetail(dayjs().format('YYYY-MM'));
788 } 784 }
789 785
786 + // 获取小作业列表
787 + const subtask_list = await getTeacherSubtaskListAPI({ task_id: route.query.id })
788 + if (subtask_list.code) {
789 + taskOptions.value = [...taskOptions.value, ...subtask_list.data.map(item => ({
790 + text: item.title,
791 + value: item.id
792 + }))
793 + ]
794 + }
795 +
790 // 初始化编辑数据 796 // 初始化编辑数据
791 await initEditData() 797 await initEditData()
792 }) 798 })
......
1 <!-- 1 <!--
2 * @Date: 2025-05-29 15:34:17 2 * @Date: 2025-05-29 15:34:17
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-12-11 13:46:21 4 + * @LastEditTime: 2025-12-11 15:19:52
5 * @FilePath: /mlaj/src/views/checkin/IndexCheckInPage.vue 5 * @FilePath: /mlaj/src/views/checkin/IndexCheckInPage.vue
6 * @Description: 文件描述 6 * @Description: 文件描述
7 --> 7 -->
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
14 ref="calendarRef" 14 ref="calendarRef"
15 :title="taskDetail.title" 15 :title="taskDetail.title"
16 :formatter="formatter" 16 :formatter="formatter"
17 + :subtask-list="taskDetail.subtask_list"
17 v-model="selectedDate" 18 v-model="selectedDate"
18 @select="onSelectDay" 19 @select="onSelectDay"
19 @click-subtitle="onClickSubtitle" 20 @click-subtitle="onClickSubtitle"
...@@ -535,15 +536,17 @@ const onPanelChange = ({ date }) => { ...@@ -535,15 +536,17 @@ const onPanelChange = ({ date }) => {
535 getTaskDetail(dayjs(date).format('YYYY-MM')); 536 getTaskDetail(dayjs(date).format('YYYY-MM'));
536 } 537 }
537 538
538 -const selectedCourseText = ref('')
539 -
540 /** 539 /**
541 * 处理作业选择事件 540 * 处理作业选择事件
542 * @param {string} course - 选中的作业 541 * @param {string} course - 选中的作业
543 */ 542 */
543 +const selectedSubtaskId = ref('')
544 +
544 const onSelectCourse = (course) => { 545 const onSelectCourse = (course) => {
545 - selectedCourseText.value = course.text; 546 + selectedSubtaskId.value = course;
546 console.warn('选中的作业:', course); 547 console.warn('选中的作业:', course);
548 + // 切换作业后, 刷新当前日期的打卡详情
549 + getTaskDetail(dayjs(selectedDate.value).format('YYYY-MM'));
547 } 550 }
548 551
549 /** 552 /**
...@@ -719,7 +722,7 @@ const isPatchCheckin = ref(false); ...@@ -719,7 +722,7 @@ const isPatchCheckin = ref(false);
719 const attachmentTypeOptions = ref([]); 722 const attachmentTypeOptions = ref([]);
720 723
721 const getTaskDetail = async (month) => { 724 const getTaskDetail = async (month) => {
722 - const { code, data } = await getTaskDetailAPI({ i: route.query.id, month }); 725 + const { code, data } = await getTaskDetailAPI({ i: route.query.id, month, subtask_id: selectedSubtaskId.value });
723 if (code) { 726 if (code) {
724 taskDetail.value = data; 727 taskDetail.value = data;
725 progress1.value = ((data.checkin_number/data.target_number)*100).toFixed(1); // 计算进度条百分比 728 progress1.value = ((data.checkin_number/data.target_number)*100).toFixed(1); // 计算进度条百分比
......