feat(打卡): 添加计数型打卡功能并优化子任务显示
- 在CheckInList组件中添加计数型打卡图标和跳转逻辑 - 在多个页面中将固定文本替换为动态子任务标题显示 - 完善打卡详情页的子任务选择和编辑功能 - 更新API文档说明并优化相关接口参数传递
Showing
8 changed files
with
71 additions
and
38 deletions
| 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-12 18:06:49 | 4 | + * @LastEditTime: 2025-12-12 21:15:25 |
| 5 | * @FilePath: /mlaj/src/api/checkin.js | 5 | * @FilePath: /mlaj/src/api/checkin.js |
| 6 | * @Description: 签到模块相关接口 | 6 | * @Description: 签到模块相关接口 |
| 7 | */ | 7 | */ |
| ... | @@ -84,9 +84,11 @@ export const addUploadTaskAPI = (params) => fn(fetch.post(Api.TASK_UPLOAD_ADD, | ... | @@ -84,9 +84,11 @@ export const addUploadTaskAPI = (params) => fn(fetch.post(Api.TASK_UPLOAD_ADD, |
| 84 | export const getUploadTaskListAPI = (params) => fn(fetch.post(Api.TASK_UPLOAD_LIST, params)) | 84 | export const getUploadTaskListAPI = (params) => fn(fetch.post(Api.TASK_UPLOAD_LIST, params)) |
| 85 | 85 | ||
| 86 | /** | 86 | /** |
| 87 | - * @description: 获取打卡动态详情 | 87 | + * @description: 上传打卡详情 |
| 88 | * @param i 打卡动态ID | 88 | * @param i 打卡动态ID |
| 89 | - * @returns | 89 | + * @returns data: {id 打卡动态ID, subtask_id 小作业ID, status 审批状态 3=待审批,5=审批通过,7=审批不通过, created_by 打卡人ID, username 打卡人昵称 |
| 90 | + * avatar 打卡人头像, created_time 打卡时间, created_time_desc 打卡时间描述, note 打卡内容, files[{meta_id,name,value,extension}] 附件列表, | ||
| 91 | + * file_type 上传附件的类型 image=上传图片,video=视频,audio=音频, like_count 点赞数, is_my 是不是我的打卡, is_like 我是否已经点赞, is_makeup 是否补卡} | ||
| 90 | */ | 92 | */ |
| 91 | export const getUploadTaskInfoAPI = (params) => fn(fetch.get(Api.TASK_UPLOAD_INFO, params)) | 93 | export const getUploadTaskInfoAPI = (params) => fn(fetch.get(Api.TASK_UPLOAD_INFO, params)) |
| 92 | 94 | ... | ... |
| ... | @@ -13,6 +13,7 @@ | ... | @@ -13,6 +13,7 @@ |
| 13 | > | 13 | > |
| 14 | <van-icon v-if="item.task_type === 'checkin'" name="edit" size="1.5rem" :color="item.is_gray ? 'gray' : ''" /> | 14 | <van-icon v-if="item.task_type === 'checkin'" name="edit" size="1.5rem" :color="item.is_gray ? 'gray' : ''" /> |
| 15 | <van-icon v-if="item.task_type === 'upload'" name="tosend" size="1.5rem" :color="item.is_gray ? 'gray' : ''" /> | 15 | <van-icon v-if="item.task_type === 'upload'" name="tosend" size="1.5rem" :color="item.is_gray ? 'gray' : ''" /> |
| 16 | + <van-icon v-if="item.task_type === 'count'" name="point-gift-o" size="1.5rem" :color="item.is_gray ? 'gray' : ''" /> | ||
| 16 | </div> | 17 | </div> |
| 17 | <span :class="['text-xs', item.is_gray ? 'text-gray-500' : '']">{{ item.name }}</span> | 18 | <span :class="['text-xs', item.is_gray ? 'text-gray-500' : '']">{{ item.name }}</span> |
| 18 | </button> | 19 | </button> |
| ... | @@ -185,6 +186,14 @@ const handle_click = (item) => { | ... | @@ -185,6 +186,14 @@ const handle_click = (item) => { |
| 185 | }) | 186 | }) |
| 186 | return | 187 | return |
| 187 | } | 188 | } |
| 189 | + // 打卡项:计数型跳转 | ||
| 190 | + if (item.task_type === 'count') { | ||
| 191 | + router.push({ | ||
| 192 | + path: '/checkin/index', | ||
| 193 | + query: { id: item.id }, | ||
| 194 | + }) | ||
| 195 | + return | ||
| 196 | + } | ||
| 188 | // 打卡项:选中后展示提交按钮 | 197 | // 打卡项:选中后展示提交按钮 |
| 189 | selected_item.value = item | 198 | selected_item.value = item |
| 190 | } | 199 | } | ... | ... |
| ... | @@ -21,7 +21,9 @@ export function useCheckin() { | ... | @@ -21,7 +21,9 @@ export function useCheckin() { |
| 21 | const message = ref('') | 21 | const message = ref('') |
| 22 | const fileList = ref([]) | 22 | const fileList = ref([]) |
| 23 | const activeType = ref('') // 当前选中的打卡类型 | 23 | const activeType = ref('') // 当前选中的打卡类型 |
| 24 | - const taskId = ref('') // 当前选中的任务ID | 24 | + const subTaskId = ref('') // 当前选中的任务ID |
| 25 | + const selectedTaskText = ref('') // 选中的任务文本 | ||
| 26 | + const selectedTaskValue = ref([]) // 选中的任务值(Picker使用) | ||
| 25 | const maxCount = ref(5) | 27 | const maxCount = ref(5) |
| 26 | 28 | ||
| 27 | // 打卡类型 | 29 | // 打卡类型 |
| ... | @@ -306,6 +308,7 @@ export function useCheckin() { | ... | @@ -306,6 +308,7 @@ export function useCheckin() { |
| 306 | // 编辑打卡 | 308 | // 编辑打卡 |
| 307 | result = await editUploadTaskInfoAPI({ | 309 | result = await editUploadTaskInfoAPI({ |
| 308 | i: route.query.post_id, | 310 | i: route.query.post_id, |
| 311 | + subtask_id: route.query.subtask_id, | ||
| 309 | note: submitData.note, | 312 | note: submitData.note, |
| 310 | meta_id: submitData.meta_id, | 313 | meta_id: submitData.meta_id, |
| 311 | file_type: submitData.file_type, | 314 | file_type: submitData.file_type, |
| ... | @@ -363,16 +366,26 @@ export function useCheckin() { | ... | @@ -363,16 +366,26 @@ export function useCheckin() { |
| 363 | 366 | ||
| 364 | /** | 367 | /** |
| 365 | * 初始化编辑数据 | 368 | * 初始化编辑数据 |
| 369 | + * @param {Array} taskOptions - 任务选项列表 | ||
| 366 | */ | 370 | */ |
| 367 | - const initEditData = async () => { | 371 | + const initEditData = async (taskOptions = []) => { |
| 368 | if (route.query.status === 'edit') { | 372 | if (route.query.status === 'edit') { |
| 369 | try { | 373 | try { |
| 370 | - const { code, data } = await getUploadTaskInfoAPI({ i: route.query.post_id }) | 374 | + const { code, data } = await getUploadTaskInfoAPI({ i: route.query.post_id, subtask_id: route.query.subtask_id }) |
| 371 | if (code) { | 375 | if (code) { |
| 372 | message.value = data.note || '' | 376 | message.value = data.note || '' |
| 373 | activeType.value = data.file_type || 'text' | 377 | activeType.value = data.file_type || 'text' |
| 374 | - // TODO: 假数据等待真实数据 | 378 | + // 小作业ID |
| 375 | - taskId.value = 'task1' | 379 | + subTaskId.value = route.query.subtask_id |
| 380 | + | ||
| 381 | + // 更新选中的任务显示 | ||
| 382 | + if (subTaskId.value) { | ||
| 383 | + selectedTaskValue.value = [subTaskId.value] | ||
| 384 | + if (taskOptions && taskOptions.length > 0) { | ||
| 385 | + const option = taskOptions.find(o => o.value === subTaskId.value) | ||
| 386 | + selectedTaskText.value = option ? option.text : '' | ||
| 387 | + } | ||
| 388 | + } | ||
| 376 | 389 | ||
| 377 | // 如果有文件数据,初始化文件列表 - 使用data.files而不是data.meta | 390 | // 如果有文件数据,初始化文件列表 - 使用data.files而不是data.meta |
| 378 | if (data.files && data.files.length > 0) { | 391 | if (data.files && data.files.length > 0) { |
| ... | @@ -416,7 +429,9 @@ export function useCheckin() { | ... | @@ -416,7 +429,9 @@ export function useCheckin() { |
| 416 | message, | 429 | message, |
| 417 | fileList, | 430 | fileList, |
| 418 | activeType, | 431 | activeType, |
| 419 | - taskId, | 432 | + subTaskId, |
| 433 | + selectedTaskText, | ||
| 434 | + selectedTaskValue, | ||
| 420 | maxCount, | 435 | maxCount, |
| 421 | canSubmit, | 436 | canSubmit, |
| 422 | 437 | ... | ... |
| ... | @@ -23,12 +23,12 @@ | ... | @@ -23,12 +23,12 @@ |
| 23 | <van-field v-model="selectedTaskText" is-link readonly label="选择作业" placeholder="请选择本次打卡的作业" | 23 | <van-field v-model="selectedTaskText" is-link readonly label="选择作业" placeholder="请选择本次打卡的作业" |
| 24 | @click="showTaskPicker = true" class="rounded-lg border border-gray-100" /> | 24 | @click="showTaskPicker = true" class="rounded-lg border border-gray-100" /> |
| 25 | <van-popup v-model:show="showTaskPicker" round position="bottom"> | 25 | <van-popup v-model:show="showTaskPicker" round position="bottom"> |
| 26 | - <van-picker :columns="taskOptions" @cancel="showTaskPicker = false" | 26 | + <van-picker v-model="selectedTaskValue" :columns="taskOptions" @cancel="showTaskPicker = false" |
| 27 | - @confirm="onConfirmTask" /> | 27 | + @confirm="onConfirmTask" /> |
| 28 | </van-popup> | 28 | </van-popup> |
| 29 | </div> | 29 | </div> |
| 30 | <!-- 计数对象 --> | 30 | <!-- 计数对象 --> |
| 31 | - <div v-if="taskType === 'count' && selectedTaskValue" class="mb-4"> | 31 | + <div v-if="taskType === 'count' && selectedTaskValue && selectedTaskValue.length > 0" class="mb-4"> |
| 32 | <div class="flex justify-between items-center mb-2 mx-2"> | 32 | <div class="flex justify-between items-center mb-2 mx-2"> |
| 33 | <div class="text-sm font-bold text-gray-700">{{ dynamicFieldText }}对象</div> | 33 | <div class="text-sm font-bold text-gray-700">{{ dynamicFieldText }}对象</div> |
| 34 | <van-button size="small" type="primary" plain icon="plus" | 34 | <van-button size="small" type="primary" plain icon="plus" |
| ... | @@ -205,7 +205,9 @@ const { | ... | @@ -205,7 +205,9 @@ const { |
| 205 | message, | 205 | message, |
| 206 | fileList, | 206 | fileList, |
| 207 | activeType, | 207 | activeType, |
| 208 | - taskId, | 208 | + subTaskId, |
| 209 | + selectedTaskText, | ||
| 210 | + selectedTaskValue, | ||
| 209 | maxCount, | 211 | maxCount, |
| 210 | canSubmit, | 212 | canSubmit, |
| 211 | beforeRead, | 213 | beforeRead, |
| ... | @@ -228,8 +230,6 @@ const taskType = computed(() => route.query.task_type) | ... | @@ -228,8 +230,6 @@ const taskType = computed(() => route.query.task_type) |
| 228 | 230 | ||
| 229 | // 作业选择相关 | 231 | // 作业选择相关 |
| 230 | const showTaskPicker = ref(false) | 232 | const showTaskPicker = ref(false) |
| 231 | -const selectedTaskText = ref('') | ||
| 232 | -const selectedTaskValue = ref('') | ||
| 233 | const taskOptions = ref([]) | 233 | const taskOptions = ref([]) |
| 234 | 234 | ||
| 235 | // TODO: 模拟任务选项数据 | 235 | // TODO: 模拟任务选项数据 |
| ... | @@ -247,10 +247,10 @@ const mockData = { | ... | @@ -247,10 +247,10 @@ const mockData = { |
| 247 | ] | 247 | ] |
| 248 | } | 248 | } |
| 249 | 249 | ||
| 250 | -const fetchTargetList = async (taskId) => { | 250 | +const fetchTargetList = async (subTaskId) => { |
| 251 | // 模拟接口调用延迟 | 251 | // 模拟接口调用延迟 |
| 252 | setTimeout(() => { | 252 | setTimeout(() => { |
| 253 | - targetList.value = mockData[taskId] || [] | 253 | + targetList.value = mockData[subTaskId] || [] |
| 254 | showLoadingToast({ | 254 | showLoadingToast({ |
| 255 | message: '加载成功', | 255 | message: '加载成功', |
| 256 | type: 'success', | 256 | type: 'success', |
| ... | @@ -262,7 +262,7 @@ const fetchTargetList = async (taskId) => { | ... | @@ -262,7 +262,7 @@ const fetchTargetList = async (taskId) => { |
| 262 | const onConfirmTask = ({ selectedOptions }) => { | 262 | const onConfirmTask = ({ selectedOptions }) => { |
| 263 | const option = selectedOptions[0] | 263 | const option = selectedOptions[0] |
| 264 | selectedTaskText.value = option.text | 264 | selectedTaskText.value = option.text |
| 265 | - selectedTaskValue.value = option.value | 265 | + selectedTaskValue.value = [option.value] |
| 266 | showTaskPicker.value = false | 266 | showTaskPicker.value = false |
| 267 | 267 | ||
| 268 | // 如果是计数打卡,根据选中的作业ID查询计数对象 | 268 | // 如果是计数打卡,根据选中的作业ID查询计数对象 |
| ... | @@ -273,8 +273,8 @@ const onConfirmTask = ({ selectedOptions }) => { | ... | @@ -273,8 +273,8 @@ const onConfirmTask = ({ selectedOptions }) => { |
| 273 | 273 | ||
| 274 | // 监听作业选择变化 | 274 | // 监听作业选择变化 |
| 275 | watch(selectedTaskValue, (newVal) => { | 275 | watch(selectedTaskValue, (newVal) => { |
| 276 | - if (taskType.value === 'count' && newVal) { | 276 | + if (taskType.value === 'count' && newVal && newVal.length > 0) { |
| 277 | - fetchTargetList(newVal) | 277 | + fetchTargetList(newVal[0]) |
| 278 | } | 278 | } |
| 279 | }) | 279 | }) |
| 280 | 280 | ||
| ... | @@ -325,7 +325,7 @@ const confirmAddTarget = (formData) => { | ... | @@ -325,7 +325,7 @@ const confirmAddTarget = (formData) => { |
| 325 | */ | 325 | */ |
| 326 | const isSubmitDisabled = computed(() => { | 326 | const isSubmitDisabled = computed(() => { |
| 327 | // 1. 校验作业选择 | 327 | // 1. 校验作业选择 |
| 328 | - if (!selectedTaskValue.value) return true | 328 | + if (!selectedTaskValue.value || selectedTaskValue.value.length === 0) return true |
| 329 | 329 | ||
| 330 | // 2. 计数打卡特定校验 | 330 | // 2. 计数打卡特定校验 |
| 331 | if (taskType.value === 'count') { | 331 | if (taskType.value === 'count') { |
| ... | @@ -348,13 +348,13 @@ const isSubmitDisabled = computed(() => { | ... | @@ -348,13 +348,13 @@ const isSubmitDisabled = computed(() => { |
| 348 | 348 | ||
| 349 | const handleSubmit = async () => { | 349 | const handleSubmit = async () => { |
| 350 | // 1. 校验作业选择 | 350 | // 1. 校验作业选择 |
| 351 | - if (!selectedTaskValue.value) { | 351 | + if (!selectedTaskValue.value || selectedTaskValue.value.length === 0) { |
| 352 | showToast('请选择作业') | 352 | showToast('请选择作业') |
| 353 | return | 353 | return |
| 354 | } | 354 | } |
| 355 | 355 | ||
| 356 | const extraData = { | 356 | const extraData = { |
| 357 | - subtask_id: selectedTaskValue.value // 小作业ID | 357 | + subtask_id: selectedTaskValue.value[0] // 小作业ID |
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | // 2. 计数打卡特定校验 | 360 | // 2. 计数打卡特定校验 |
| ... | @@ -475,7 +475,7 @@ const getTaskDetail = async (month) => { | ... | @@ -475,7 +475,7 @@ const getTaskDetail = async (month) => { |
| 475 | 475 | ||
| 476 | // 处理编辑模式下的类型合并 | 476 | // 处理编辑模式下的类型合并 |
| 477 | if (isEditMode.value && Array.isArray(data.attachment_type)) { | 477 | if (isEditMode.value && Array.isArray(data.attachment_type)) { |
| 478 | - const info = await getUploadTaskInfoAPI({ i: route.query.post_id }); | 478 | + const info = await getUploadTaskInfoAPI({ i: route.query.post_id, subtask_id: route.query.subtask_id }); |
| 479 | if (info.code) { | 479 | if (info.code) { |
| 480 | data.attachment_type = [...new Set([...data.attachment_type, info.data.file_type])]; | 480 | data.attachment_type = [...new Set([...data.attachment_type, info.data.file_type])]; |
| 481 | } | 481 | } |
| ... | @@ -796,6 +796,9 @@ onMounted(async () => { | ... | @@ -796,6 +796,9 @@ onMounted(async () => { |
| 796 | getTaskDetail(dayjs().format('YYYY-MM')); | 796 | getTaskDetail(dayjs().format('YYYY-MM')); |
| 797 | } | 797 | } |
| 798 | 798 | ||
| 799 | + // 初始化选中的子任务ID | ||
| 800 | + selectedTaskValue.value = [route.query.subtask_id] | ||
| 801 | + | ||
| 799 | // TODO: 获取小作业列表 | 802 | // TODO: 获取小作业列表 |
| 800 | const subtask_list = await getSubtaskListAPI({ task_id: route.query.id }) | 803 | const subtask_list = await getSubtaskListAPI({ task_id: route.query.id }) |
| 801 | if (subtask_list.code) { | 804 | if (subtask_list.code) { |
| ... | @@ -811,15 +814,18 @@ onMounted(async () => { | ... | @@ -811,15 +814,18 @@ onMounted(async () => { |
| 811 | { text: '作业二:进阶挑战', value: 'task2' }, | 814 | { text: '作业二:进阶挑战', value: 'task2' }, |
| 812 | { text: '作业三:综合应用', value: 'task3' }] | 815 | { text: '作业三:综合应用', value: 'task3' }] |
| 813 | 816 | ||
| 817 | + // 如果有默认选中值,初始化显示文本 | ||
| 818 | + if (selectedTaskValue.value.length > 0) { | ||
| 819 | + const option = taskOptions.value.find(o => o.value === selectedTaskValue.value[0]) | ||
| 820 | + if (option) { | ||
| 821 | + selectedTaskText.value = option.text | ||
| 822 | + } | ||
| 823 | + } | ||
| 824 | + | ||
| 814 | // 初始化编辑数据 | 825 | // 初始化编辑数据 |
| 815 | - await initEditData() | 826 | + await initEditData(taskOptions.value) |
| 816 | 827 | ||
| 817 | - // TODO: 临时处理,待后端返回真实数据 | 828 | + console.warn(selectedTaskValue.value); |
| 818 | - if (taskId.value) { | ||
| 819 | - selectedTaskText.value = taskOptions.value.find(option => option.value === taskId.value)?.text || '' | ||
| 820 | - selectedTaskValue.value = taskId.value | ||
| 821 | - console.warn('当前选中的任务ID:', taskId.value); | ||
| 822 | - } | ||
| 823 | }) | 829 | }) |
| 824 | </script> | 830 | </script> |
| 825 | 831 | ... | ... |
| 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-12 17:27:43 | 4 | + * @LastEditTime: 2025-12-12 20:49:55 |
| 5 | * @FilePath: /mlaj/src/views/checkin/IndexCheckInPage.vue | 5 | * @FilePath: /mlaj/src/views/checkin/IndexCheckInPage.vue |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | --> | 7 | --> |
| ... | @@ -84,7 +84,7 @@ | ... | @@ -84,7 +84,7 @@ |
| 84 | @audio-play="handleAudioPlay" | 84 | @audio-play="handleAudioPlay" |
| 85 | > | 85 | > |
| 86 | <template #content-top> | 86 | <template #content-top> |
| 87 | - <div class="text-gray-500 font-bold text-sm mb-4">阅读与写作</div> | 87 | + <div class="text-gray-500 font-bold text-sm mb-4">{{ post.subtask_title }}</div> |
| 88 | </template> | 88 | </template> |
| 89 | </CheckinCard> | 89 | </CheckinCard> |
| 90 | </van-list> | 90 | </van-list> |
| ... | @@ -392,10 +392,10 @@ const goToCheckinDetailPage = () => { | ... | @@ -392,10 +392,10 @@ const goToCheckinDetailPage = () => { |
| 392 | path: '/checkin/detail', | 392 | path: '/checkin/detail', |
| 393 | query: { | 393 | query: { |
| 394 | id: route.query.id, | 394 | id: route.query.id, |
| 395 | + subtask_id: selectedSubtaskId.value, | ||
| 395 | date: current_date, | 396 | date: current_date, |
| 396 | is_patch: isPatchCheckin.value ? '1' : '0', | 397 | is_patch: isPatchCheckin.value ? '1' : '0', |
| 397 | task_type: taskDetail.value.task_type, | 398 | task_type: taskDetail.value.task_type, |
| 398 | - // type: 'count', | ||
| 399 | } | 399 | } |
| 400 | }) | 400 | }) |
| 401 | } | 401 | } |
| ... | @@ -463,6 +463,7 @@ const editCheckin = (post) => { | ... | @@ -463,6 +463,7 @@ const editCheckin = (post) => { |
| 463 | path: '/checkin/detail', | 463 | path: '/checkin/detail', |
| 464 | query: { | 464 | query: { |
| 465 | post_id: post.id, | 465 | post_id: post.id, |
| 466 | + subtask_id: post.subtask_id, | ||
| 466 | type: post.file_type, | 467 | type: post.file_type, |
| 467 | task_type: taskDetail.value.task_type, | 468 | task_type: taskDetail.value.task_type, |
| 468 | status: 'edit', | 469 | status: 'edit', | ... | ... |
| ... | @@ -100,7 +100,7 @@ | ... | @@ -100,7 +100,7 @@ |
| 100 | @audio-play="handleAudioPlay" | 100 | @audio-play="handleAudioPlay" |
| 101 | > | 101 | > |
| 102 | <template #content-top> | 102 | <template #content-top> |
| 103 | - <div class="text-gray-500 font-bold text-sm mb-4">阅读与写作</div> | 103 | + <div class="text-gray-500 font-bold text-sm mb-4">{{ post.subtask_title }}</div> |
| 104 | </template> | 104 | </template> |
| 105 | <template #footer-right> | 105 | <template #footer-right> |
| 106 | <div class="flex items-center cursor-pointer" @click="openAuditDialog(post)"> | 106 | <div class="flex items-center cursor-pointer" @click="openAuditDialog(post)"> | ... | ... |
| ... | @@ -198,7 +198,7 @@ | ... | @@ -198,7 +198,7 @@ |
| 198 | @audio-play="handleAudioPlay" | 198 | @audio-play="handleAudioPlay" |
| 199 | > | 199 | > |
| 200 | <template #content-top> | 200 | <template #content-top> |
| 201 | - <div class="text-gray-500 font-bold text-sm mb-4">阅读与写作</div> | 201 | + <div class="text-gray-500 font-bold text-sm mb-4">{{ post.subtask_title }}</div> |
| 202 | </template> | 202 | </template> |
| 203 | <template #footer-right> | 203 | <template #footer-right> |
| 204 | <div class="flex items-center cursor-pointer" @click="openCommentPopup(post)"> | 204 | <div class="flex items-center cursor-pointer" @click="openCommentPopup(post)"> | ... | ... |
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2025-11-19 22:05:00 | 2 | * @Date: 2025-11-19 22:05:00 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-12-12 18:09:33 | 4 | + * @LastEditTime: 2025-12-12 21:26:17 |
| 5 | * @FilePath: /mlaj/src/views/teacher/studentRecordPage.vue | 5 | * @FilePath: /mlaj/src/views/teacher/studentRecordPage.vue |
| 6 | * @Description: 学生作业记录页面(仅作业记录与点评功能),固定 user_id 与 group_id | 6 | * @Description: 学生作业记录页面(仅作业记录与点评功能),固定 user_id 与 group_id |
| 7 | --> | 7 | --> |
| ... | @@ -20,7 +20,7 @@ | ... | @@ -20,7 +20,7 @@ |
| 20 | @audio-play="handleAudioPlay" | 20 | @audio-play="handleAudioPlay" |
| 21 | > | 21 | > |
| 22 | <template #content-top> | 22 | <template #content-top> |
| 23 | - <div class="text-gray-500 font-bold text-sm mb-4">阅读与写作</div> | 23 | + <div class="text-gray-500 font-bold text-sm mb-4">{{ post.subtask_title }}</div> |
| 24 | </template> | 24 | </template> |
| 25 | <template #footer-right> | 25 | <template #footer-right> |
| 26 | <div class="flex items-center cursor-pointer" @click="openCommentPopup(post)"> | 26 | <div class="flex items-center cursor-pointer" @click="openCommentPopup(post)"> | ... | ... |
-
Please register or login to post a comment