hookehuyr

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

在教师API中添加获取小作业列表接口
更新签到详情页和日历组件以支持小作业筛选
修改任务详情接口返回小作业列表数据
/*
* @Date: 2025-06-06 09:26:16
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-12-01 14:06:29
* @LastEditTime: 2025-12-11 14:43:44
* @FilePath: /mlaj/src/api/checkin.js
* @Description: 签到模块相关接口
*/
......@@ -35,7 +35,8 @@ export const getTaskListAPI = (params) => fn(fetch.get(Api.GET_TASK_LIST, param
* @description: 获取作业详情
* @param: i 作业id
* @param: month 月份
* @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个人的头像 }
* @param: subtask_id 小作业ID
* @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}] }
*/
export const getTaskDetailAPI = (params) => fn(fetch.get(Api.GET_TASK_DETAIL, params))
......
/*
* @Date: 2025-06-23 11:46:21
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-12-01 14:13:18
* @LastEditTime: 2025-12-11 15:08:04
* @FilePath: /mlaj/src/api/teacher.js
* @Description: 文件描述
*/
......@@ -13,6 +13,7 @@ const Api = {
TEACHER_ADD_TASK: '/srv/?a=task&t=teacher_add',
TEACHER_LIST_TASK: '/srv/?a=task&t=teacher_list',
TEACHER_DETAIL_TASK: '/srv/?a=task&t=teacher_detail',
TEACHER_SUBTASK_LIST: '/srv/?a=subtask&t=list',
STUDENT_LIST: '/srv/?a=user&t=student_list',
STUDENT_DETAIL: '/srv/?a=user&t=student_detail',
STUDENT_STAT: '/srv/?a=user&t=student_stat',
......@@ -99,6 +100,13 @@ export const getTeacherTaskListAPI = (params) => fn(fetch.get(Api.TEACHER_LIST_T
export const getTeacherTaskDetailAPI = (params) => fn(fetch.get(Api.TEACHER_DETAIL_TASK, params))
/**
* 获取小作业列表
* @param {*} task_id 大作业ID
* @returns {Object} data [{id,title,cycle,frequency,attachment_type,begin_date,end_date,is_finish}]
*/
export const getTeacherSubtaskListAPI = (params) => fn(fetch.get(Api.TEACHER_SUBTASK_LIST, params))
/**
* 获取学员列表
* @param {*} grade_id 年级ID
* @param {*} class_id 班级ID
......
<!--
* @Date: 2025-01-25 15:34:17
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-12-11 13:55:33
* @LastEditTime: 2025-12-11 15:01:51
* @FilePath: /mlaj/src/components/ui/CollapsibleCalendar.vue
* @Description: 可折叠日历组件
-->
......@@ -86,7 +86,7 @@
:style="{ minHeight: '30%', maxHeight: '80%', width: '100%' }"
>
<van-picker
title="作业选择"
title="作业选择"
:columns="courseColumns"
@confirm="onConfirmCourse"
@cancel="showCoursePicker = false"
......@@ -113,6 +113,10 @@ const props = defineProps({
modelValue: {
type: [String, Date],
default: null
},
subtaskList: {
type: Array,
default: () => []
}
})
......@@ -127,14 +131,15 @@ const currentDate = ref(props.modelValue || new Date())
// 作业筛选相关
const showCoursePicker = ref(false)
const selectedCourseText = ref('全部作业')
const courseColumns = [
{ text: '全部作业', value: '' },
{ text: '语文语文语文语文语文语文数学英语化学化学化学化学英语', value: 'chinese' },
{ text: '数学', value: 'math' },
{ text: '英语', value: 'english' },
{ text: '物理', value: 'physics' },
{ text: '化学', value: 'chemistry' }
]
const courseColumns = computed(() => {
return [
{ text: '全部作业', value: '' },
...props.subtaskList.map(item => ({
text: item.title,
value: item.id
}))
]
})
const openCoursePicker = () => {
showCoursePicker.value = true
......
......@@ -190,7 +190,7 @@
import { ref, computed, onMounted, nextTick, reactive } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { getTaskDetailAPI, getUploadTaskInfoAPI } from "@/api/checkin"
import { getTeacherFindSettingsAPI } from '@/api/teacher'
import { getTeacherFindSettingsAPI, getTeacherSubtaskListAPI } from '@/api/teacher'
import { useTitle } from '@vueuse/core'
import { useCheckin } from '@/composables/useCheckin'
import AudioPlayer from '@/components/ui/AudioPlayer.vue'
......@@ -233,11 +233,7 @@ const taskType = computed(() => route.query.task_type)
const showTaskPicker = ref(false)
const selectedTaskText = ref('')
const selectedTaskValue = ref('')
const taskOptions = [
{ text: '作业一:基础练习', value: 'task1' },
{ text: '作业二:进阶挑战', value: 'task2' },
{ text: '作业三:综合应用', value: 'task3' },
]
const taskOptions = [{ text: '全部作业', value: '' }]
const onConfirmTask = ({ selectedOptions }) => {
const option = selectedOptions[0]
......@@ -787,6 +783,16 @@ onMounted(async () => {
getTaskDetail(dayjs().format('YYYY-MM'));
}
// 获取小作业列表
const subtask_list = await getTeacherSubtaskListAPI({ task_id: route.query.id })
if (subtask_list.code) {
taskOptions.value = [...taskOptions.value, ...subtask_list.data.map(item => ({
text: item.title,
value: item.id
}))
]
}
// 初始化编辑数据
await initEditData()
})
......
<!--
* @Date: 2025-05-29 15:34:17
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-12-11 13:46:21
* @LastEditTime: 2025-12-11 15:19:52
* @FilePath: /mlaj/src/views/checkin/IndexCheckInPage.vue
* @Description: 文件描述
-->
......@@ -14,6 +14,7 @@
ref="calendarRef"
:title="taskDetail.title"
:formatter="formatter"
:subtask-list="taskDetail.subtask_list"
v-model="selectedDate"
@select="onSelectDay"
@click-subtitle="onClickSubtitle"
......@@ -535,15 +536,17 @@ const onPanelChange = ({ date }) => {
getTaskDetail(dayjs(date).format('YYYY-MM'));
}
const selectedCourseText = ref('')
/**
* 处理作业选择事件
* @param {string} course - 选中的作业
*/
const selectedSubtaskId = ref('')
const onSelectCourse = (course) => {
selectedCourseText.value = course.text;
selectedSubtaskId.value = course;
console.warn('选中的作业:', course);
// 切换作业后, 刷新当前日期的打卡详情
getTaskDetail(dayjs(selectedDate.value).format('YYYY-MM'));
}
/**
......@@ -719,7 +722,7 @@ const isPatchCheckin = ref(false);
const attachmentTypeOptions = ref([]);
const getTaskDetail = async (month) => {
const { code, data } = await getTaskDetailAPI({ i: route.query.id, month });
const { code, data } = await getTaskDetailAPI({ i: route.query.id, month, subtask_id: selectedSubtaskId.value });
if (code) {
taskDetail.value = data;
progress1.value = ((data.checkin_number/data.target_number)*100).toFixed(1); // 计算进度条百分比
......