hookehuyr

feat(打卡): 重构计数打卡功能,支持表单数据复用

- 修改计数对象为列表项,增加确认模式
- 重构动态表单字段处理逻辑
- 更新API接口参数为gratitude_form_list
- 优化计数打卡的提交逻辑
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-16 11:52:53 4 + * @LastEditTime: 2025-12-16 17:54:43
5 * @FilePath: /mlaj/src/api/checkin.js 5 * @FilePath: /mlaj/src/api/checkin.js
6 * @Description: 签到模块相关接口 6 * @Description: 签到模块相关接口
7 */ 7 */
...@@ -22,6 +22,7 @@ const Api = { ...@@ -22,6 +22,7 @@ const Api = {
22 CHECKIN_TEACHER_LIST: '/srv/?a=checkin&t=teacher_list', 22 CHECKIN_TEACHER_LIST: '/srv/?a=checkin&t=teacher_list',
23 CHECKIN_TEACHER_REVIEW: '/srv/?a=checkin&t=teacher_review', 23 CHECKIN_TEACHER_REVIEW: '/srv/?a=checkin&t=teacher_review',
24 CHECKIN_TEACHER_CHECKED_DATES: '/srv/?a=checkin&t=teacher_checked_dates', 24 CHECKIN_TEACHER_CHECKED_DATES: '/srv/?a=checkin&t=teacher_checked_dates',
25 + CHECKIN_TEACHER_REUSE_GRATITUDE_FORM: '/srv/?a=checkin&t=reuse_gratitude_form',
25 } 26 }
26 27
27 /** 28 /**
...@@ -75,7 +76,7 @@ export const checkinTaskAPI = (params) => fn(fetch.post(Api.TASK_CHECKIN, param ...@@ -75,7 +76,7 @@ export const checkinTaskAPI = (params) => fn(fetch.post(Api.TASK_CHECKIN, param
75 * @param file_type 上传附件的类型 image=上传图片,video=视频,audio=音频 76 * @param file_type 上传附件的类型 image=上传图片,video=视频,audio=音频
76 * @param makeup_time 补卡时间 77 * @param makeup_time 补卡时间
77 * @param gratitude_count 感恩次数 78 * @param gratitude_count 感恩次数
78 - * @param gratitude_people_ids 感恩对象ID数组 [id1,id2,id3] 79 + * @param gratitude_form_list 感恩表单数据 [{id,name,city,unit,其他信息字段}]
79 * @returns 80 * @returns
80 */ 81 */
81 export const addUploadTaskAPI = (params) => fn(fetch.post(Api.TASK_UPLOAD_ADD, params)) 82 export const addUploadTaskAPI = (params) => fn(fetch.post(Api.TASK_UPLOAD_ADD, params))
...@@ -106,7 +107,7 @@ export const getUploadTaskListAPI = (params) => fn(fetch.post(Api.TASK_UPLOAD_L ...@@ -106,7 +107,7 @@ export const getUploadTaskListAPI = (params) => fn(fetch.post(Api.TASK_UPLOAD_L
106 * avatar 打卡人头像, created_time 打卡时间, created_time_desc 打卡时间描述, note 打卡内容, files[{meta_id,name,value,extension}] 附件列表, 107 * avatar 打卡人头像, created_time 打卡时间, created_time_desc 打卡时间描述, note 打卡内容, files[{meta_id,name,value,extension}] 附件列表,
107 * file_type 上传附件的类型 image=上传图片,video=视频,audio=音频, like_count 点赞数, is_my 是不是我的打卡, is_like 我是否已经点赞, is_makeup 是否补卡 108 * file_type 上传附件的类型 image=上传图片,video=视频,audio=音频, like_count 点赞数, is_my 是不是我的打卡, is_like 我是否已经点赞, is_makeup 是否补卡
108 * gratitude_count 感恩次数 109 * gratitude_count 感恩次数
109 - * gratitude_people 感恩对象列表 [{id,name,city,unit}] 110 + * gratitude_form_list 感恩表单数据 [{id,name,city,unit,其他信息字段}]
110 * } 111 * }
111 */ 112 */
112 export const getUploadTaskInfoAPI = (params) => fn(fetch.get(Api.TASK_UPLOAD_INFO, params)) 113 export const getUploadTaskInfoAPI = (params) => fn(fetch.get(Api.TASK_UPLOAD_INFO, params))
...@@ -118,7 +119,7 @@ export const getUploadTaskInfoAPI = (params) => fn(fetch.get(Api.TASK_UPLOAD_IN ...@@ -118,7 +119,7 @@ export const getUploadTaskInfoAPI = (params) => fn(fetch.get(Api.TASK_UPLOAD_IN
118 * @param meta_id[] 附件ID列表 119 * @param meta_id[] 附件ID列表
119 * @param file_type 上传附件的类型 image=上传图片,video=视频,audio=音频 120 * @param file_type 上传附件的类型 image=上传图片,video=视频,audio=音频
120 * @param gratitude_count 感恩次数 121 * @param gratitude_count 感恩次数
121 - * @param gratitude_people_ids 感恩对象ID数组 [id1,id2,id3] 122 + * @param gratitude_form_list 感恩表单数据 [{id,name,city,unit,其他信息字段}]
122 * @returns 123 * @returns
123 */ 124 */
124 export const editUploadTaskInfoAPI = (params) => fn(fetch.get(Api.TASK_UPLOAD_EDIT, params)) 125 export const editUploadTaskInfoAPI = (params) => fn(fetch.get(Api.TASK_UPLOAD_EDIT, params))
...@@ -183,3 +184,10 @@ export const checkinTaskReviewAPI = (params) => fn(fetch.post(Api.CHECKIN_TEACH ...@@ -183,3 +184,10 @@ export const checkinTaskReviewAPI = (params) => fn(fetch.post(Api.CHECKIN_TEACH
183 * @returns data: { my_checkin_dates 已打卡日期列表 } 184 * @returns data: { my_checkin_dates 已打卡日期列表 }
184 */ 185 */
185 export const getCheckinTeacherCheckedDatesAPI = (params) => fn(fetch.get(Api.CHECKIN_TEACHER_CHECKED_DATES, params)) 186 export const getCheckinTeacherCheckedDatesAPI = (params) => fn(fetch.get(Api.CHECKIN_TEACHER_CHECKED_DATES, params))
187 +
188 +/**
189 + * @description: 复用感恩表单数据
190 + * @param subtask_id 小作业ID
191 + * @returns
192 + */
193 +export const reuseGratitudeFormAPI = (params) => fn(fetch.post(Api.CHECKIN_TEACHER_REUSE_GRATITUDE_FORM, params))
......
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-16 13:59:55 4 + * @LastEditTime: 2025-12-16 17:52:19
5 * @FilePath: /mlaj/src/api/gratitude.js 5 * @FilePath: /mlaj/src/api/gratitude.js
6 * @Description: 计数模块相关接口 6 * @Description: 计数模块相关接口
7 */ 7 */
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
12 <div v-for="field in localFields" :key="field.id"> 12 <div v-for="field in localFields" :key="field.id">
13 <van-field 13 <van-field
14 v-model="field.value" 14 v-model="field.value"
15 - label-width="4rem" 15 + label-width="5rem"
16 :label="field.label" 16 :label="field.label"
17 :placeholder="'请输入' + field.label" 17 :placeholder="'请输入' + field.label"
18 :type="field.type === 'textarea' ? 'textarea' : 'text'" 18 :type="field.type === 'textarea' ? 'textarea' : 'text'"
...@@ -43,7 +43,7 @@ const props = defineProps({ ...@@ -43,7 +43,7 @@ const props = defineProps({
43 */ 43 */
44 title: { 44 title: {
45 type: String, 45 type: String,
46 - default: '添加对象' 46 + default: '添加列表项'
47 }, 47 },
48 /** 48 /**
49 * 表单字段配置 49 * 表单字段配置
...@@ -101,14 +101,8 @@ const onBeforeClose = (action) => { ...@@ -101,14 +101,8 @@ const onBeforeClose = (action) => {
101 } 101 }
102 } 102 }
103 103
104 - // 收集表单数据 104 + // 触发确认事件,传递表单数据 (保持与 fields 结构一致)
105 - const formData = localFields.value.reduce((acc, field) => { 105 + emit('confirm', localFields.value)
106 - acc[field.id] = field.value
107 - return acc
108 - }, {})
109 -
110 - // 触发确认事件,传递表单数据
111 - emit('confirm', formData)
112 return true // 允许关闭 106 return true // 允许关闭
113 } 107 }
114 return true // 取消时允许关闭 108 return true // 取消时允许关闭
......
1 <!-- 1 <!--
2 * @Date: 2025-12-16 11:44:27 2 * @Date: 2025-12-16 11:44:27
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-12-16 14:17:38 4 + * @LastEditTime: 2025-12-16 17:59:29
5 * @FilePath: /mlaj/src/components/count/CheckinTargetList.vue 5 * @FilePath: /mlaj/src/components/count/CheckinTargetList.vue
6 * @Description: 打卡动态对象列表组件 6 * @Description: 打卡动态对象列表组件
7 --> 7 -->
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
9 <div class="mb-4"> 9 <div class="mb-4">
10 <div class="flex justify-between items-center mb-2 mx-2"> 10 <div class="flex justify-between items-center mb-2 mx-2">
11 <div class="flex items-center gap-2"> 11 <div class="flex items-center gap-2">
12 - <div class="text-sm font-bold text-gray-700">{{ dynamicFieldText }}对象</div> 12 + <div class="text-sm font-bold text-gray-700">{{ dynamicFieldText }}列表</div>
13 <div class="text-xs text-gray-400 font-normal scale-90 origin-left">(长按可编辑/删除)</div> 13 <div class="text-xs text-gray-400 font-normal scale-90 origin-left">(长按可编辑/删除)</div>
14 </div> 14 </div>
15 <van-button size="small" type="primary" plain icon="plus" @click="onAdd" class="!h-7">添加</van-button> 15 <van-button size="small" type="primary" plain icon="plus" @click="onAdd" class="!h-7">添加</van-button>
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
49 </div> 49 </div>
50 </template> 50 </template>
51 <div v-else class="w-full text-center py-4 text-gray-400 text-sm"> 51 <div v-else class="w-full text-center py-4 text-gray-400 text-sm">
52 - 暂无{{ dynamicFieldText }}对象,请点击上方添加按钮 52 + 暂无{{ dynamicFieldText }}列表,请点击上方添加按钮
53 </div> 53 </div>
54 </div> 54 </div>
55 </div> 55 </div>
......
...@@ -307,13 +307,20 @@ export function useCheckin() { ...@@ -307,13 +307,20 @@ export function useCheckin() {
307 let result 307 let result
308 if (route.query.status === 'edit') { 308 if (route.query.status === 'edit') {
309 // 编辑打卡 309 // 编辑打卡
310 - result = await editUploadTaskInfoAPI({ 310 + const editData = {
311 i: route.query.post_id, 311 i: route.query.post_id,
312 subtask_id: submitData.subtask_id || route.query.subtask_id, 312 subtask_id: submitData.subtask_id || route.query.subtask_id,
313 note: submitData.note, 313 note: submitData.note,
314 meta_id: submitData.meta_id, 314 meta_id: submitData.meta_id,
315 file_type: submitData.file_type, 315 file_type: submitData.file_type,
316 - }) 316 + }
317 +
318 + // 如果有计数对象列表,也需要传递
319 + if (submitData.gratitude_form_list) {
320 + editData.gratitude_form_list = submitData.gratitude_form_list
321 + }
322 +
323 + result = await editUploadTaskInfoAPI(editData)
317 } else { 324 } else {
318 // 新增打卡 325 // 新增打卡
319 result = await addUploadTaskAPI(submitData) 326 result = await addUploadTaskAPI(submitData)
......
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
58 <!-- 新增计数对象弹框 --> 58 <!-- 新增计数对象弹框 -->
59 <AddTargetDialog 59 <AddTargetDialog
60 v-model:show="showAddTargetDialog" 60 v-model:show="showAddTargetDialog"
61 - :title="editingTarget ? `编辑${dynamicFieldText}对象` : `添加${dynamicFieldText}对象`" 61 + :title="editingTarget ? (isConfirmMode ? `确认${dynamicFieldText}项` : `编辑${dynamicFieldText}项`) : `添加${dynamicFieldText}项`"
62 :fields="dynamicFormFields" 62 :fields="dynamicFormFields"
63 :initial-values="editingTarget" 63 :initial-values="editingTarget"
64 @confirm="confirmAddTarget" 64 @confirm="confirmAddTarget"
...@@ -174,9 +174,8 @@ ...@@ -174,9 +174,8 @@
174 <script setup> 174 <script setup>
175 import { ref, computed, onMounted, nextTick, reactive, watch } from 'vue' 175 import { ref, computed, onMounted, nextTick, reactive, watch } from 'vue'
176 import { useRoute, useRouter } from 'vue-router' 176 import { useRoute, useRouter } from 'vue-router'
177 -import { getTaskDetailAPI, getUploadTaskInfoAPI, getSubtaskListAPI } from "@/api/checkin" 177 +import { getTaskDetailAPI, getUploadTaskInfoAPI, getSubtaskListAPI, reuseGratitudeFormAPI } from "@/api/checkin"
178 import { getTeacherFindSettingsAPI } from '@/api/teacher' 178 import { getTeacherFindSettingsAPI } from '@/api/teacher'
179 -import { getGratitudeListAPI, gratitudeAddAPI, gratitudeEditAPI, gratitudeDelAPI } from '@/api/gratitude'
180 import { useTitle } from '@vueuse/core' 179 import { useTitle } from '@vueuse/core'
181 import { useCheckin } from '@/composables/useCheckin' 180 import { useCheckin } from '@/composables/useCheckin'
182 import AudioPlayer from '@/components/ui/AudioPlayer.vue' 181 import AudioPlayer from '@/components/ui/AudioPlayer.vue'
...@@ -225,34 +224,48 @@ const taskType = computed(() => route.query.task_type) ...@@ -225,34 +224,48 @@ const taskType = computed(() => route.query.task_type)
225 const showTaskPicker = ref(false) 224 const showTaskPicker = ref(false)
226 const taskOptions = ref([]) 225 const taskOptions = ref([])
227 226
228 -const fetchTargetList = async (person_type) => { 227 +const fetchTargetList = async (subtask_id) => {
229 - const { code, data } = await getGratitudeListAPI({ person_type }) 228 + const { code, data } = await reuseGratitudeFormAPI({ subtask_id })
230 if (code) { 229 if (code) {
231 targetList.value = data.gratitude_people || [] 230 targetList.value = data.gratitude_people || []
232 } 231 }
232 +
233 + targetList.value = [{
234 + id: 1,
235 + name: '张三',
236 + city: '北京',
237 + unit: '公司',
238 + }, {
239 + id: 2,
240 + name: '李四',
241 + city: '上海',
242 + unit: '公司',
243 + }]
233 } 244 }
234 245
235 // 动态表单字段 (默认值,实际会根据选择的作业动态更新) 246 // 动态表单字段 (默认值,实际会根据选择的作业动态更新)
236 const dynamicFormFields = ref([]) 247 const dynamicFormFields = ref([])
237 const personType = ref('') // 动态表单字段中的person_type 248 const personType = ref('') // 动态表单字段中的person_type
238 249
239 -// 确认作业选择 250 +/**
240 -const onConfirmTask = ({ selectedOptions }) => { 251 + * 更新动态表单字段
241 - const option = selectedOptions[0] 252 + * @param {Object} option - 选中的作业选项
242 - selectedTaskText.value = option.text 253 + */
243 - selectedTaskValue.value = [option.value] 254 +const updateDynamicFormFields = (option) => {
244 - isMakeup.value = !!option.is_makeup
245 - showTaskPicker.value = false
246 - personType.value = option.person_type
247 -
248 - // 动态表单字段映射
249 if (option.field_list && Array.isArray(option.field_list)) { 255 if (option.field_list && Array.isArray(option.field_list)) {
250 - dynamicFormFields.value = option.field_list.map(field => ({ 256 + dynamicFormFields.value = option.field_list.map(field => {
251 - id: field.field_name, 257 + // 尝试多种方式获取ID
252 - label: field.label, 258 + const id = field.field_name || field.id || field.name || field.key || field.field
253 - type: 'text', // 默认类型,如果后端有类型字段可替换 259 + if (!id) {
254 - required: true // 默认必填,如果后端有必填字段可替换 260 + console.warn('动态表单字段缺少ID:', field)
255 - })) 261 + }
262 + return {
263 + id: id,
264 + label: field.label || '未命名',
265 + type: 'text', // 默认类型,如果后端有类型字段可替换
266 + required: true // 默认必填,如果后端有必填字段可替换
267 + }
268 + })
256 // 确保如果有city字段,类型为textarea 269 // 确保如果有city字段,类型为textarea
257 const cityField = dynamicFormFields.value.find(f => f.id === 'city') 270 const cityField = dynamicFormFields.value.find(f => f.id === 'city')
258 if (cityField) { 271 if (cityField) {
...@@ -271,10 +284,23 @@ const onConfirmTask = ({ selectedOptions }) => { ...@@ -271,10 +284,23 @@ const onConfirmTask = ({ selectedOptions }) => {
271 { id: 'unit', label: '单位', type: 'textarea', required: true }, 284 { id: 'unit', label: '单位', type: 'textarea', required: true },
272 ] 285 ]
273 } 286 }
287 +}
288 +
289 +// 确认作业选择
290 +const onConfirmTask = ({ selectedOptions }) => {
291 + const option = selectedOptions[0]
292 + selectedTaskText.value = option.text
293 + selectedTaskValue.value = [option.value]
294 + isMakeup.value = !!option.is_makeup
295 + showTaskPicker.value = false
296 + personType.value = option.person_type
297 +
298 + // 更新动态表单字段
299 + updateDynamicFormFields(option)
274 300
275 // 如果是计数打卡,根据选中的作业ID查询计数对象 301 // 如果是计数打卡,根据选中的作业ID查询计数对象
276 if (taskType.value === 'count') { 302 if (taskType.value === 'count') {
277 - fetchTargetList(personType.value) 303 + fetchTargetList(selectedTaskValue.value[0])
278 } 304 }
279 } 305 }
280 306
...@@ -293,62 +319,76 @@ const selectedTargets = ref([]) ...@@ -293,62 +319,76 @@ const selectedTargets = ref([])
293 const targetList = ref([]) 319 const targetList = ref([])
294 const showAddTargetDialog = ref(false) 320 const showAddTargetDialog = ref(false)
295 const editingTarget = ref(null) 321 const editingTarget = ref(null)
322 +const isConfirmMode = ref(false) // 是否为确认模式(首次点击选中)
296 323
297 const toggleTarget = (item) => { 324 const toggleTarget = (item) => {
298 const index = selectedTargets.value.findIndex(t => t.name === item.name) 325 const index = selectedTargets.value.findIndex(t => t.name === item.name)
299 if (index > -1) { 326 if (index > -1) {
327 + // 取消选中
300 selectedTargets.value.splice(index, 1) 328 selectedTargets.value.splice(index, 1)
301 } else { 329 } else {
302 - selectedTargets.value.push(item) 330 + // 选中逻辑:如果是第一次选中(未确认过),则弹出确认框
331 + if (!item.has_confirmed) {
332 + editingTarget.value = item
333 + isConfirmMode.value = true
334 + showAddTargetDialog.value = true
335 + } else {
336 + // 已确认过,直接选中
337 + selectedTargets.value.push(item)
338 + }
303 } 339 }
304 } 340 }
305 341
306 const openAddTargetDialog = () => { 342 const openAddTargetDialog = () => {
307 editingTarget.value = null; // 重置编辑对象 343 editingTarget.value = null; // 重置编辑对象
344 + isConfirmMode.value = false;
308 showAddTargetDialog.value = true; 345 showAddTargetDialog.value = true;
309 } 346 }
310 347
311 /** 348 /**
312 * 确认添加/编辑对象 349 * 确认添加/编辑对象
313 - * @param {Object} formData - 表单数据 350 + * @param {Array} formFields - 表单字段数组
314 */ 351 */
315 -const confirmAddTarget = async (formData) => { 352 +const confirmAddTarget = async (formFields) => {
316 - console.log(`${editingTarget.value ? '编辑' : '新增'}${dynamicFieldText.value}对象信息:`, formData) 353 + // 将表单字段数组转换为对象
354 + const formData = formFields.reduce((acc, field) => {
355 + if (field.id) {
356 + acc[field.id] = field.value
357 + }
358 + return acc
359 + }, {})
317 360
318 if (editingTarget.value) { 361 if (editingTarget.value) {
319 - // 编辑模式 362 + // 编辑模式或确认模式
320 const index = targetList.value.findIndex(t => t === editingTarget.value) 363 const index = targetList.value.findIndex(t => t === editingTarget.value)
321 if (index > -1) { 364 if (index > -1) {
322 - const { code } = await gratitudeEditAPI({ ...editingTarget.value }) 365 + // 更新对象
323 - if (code) { 366 + targetList.value[index] = { ...targetList.value[index], ...formData }
324 - // 更新对象 367 + if (isConfirmMode.value) {
325 - targetList.value[index] = { ...targetList.value[index], ...formData } 368 + targetList.value[index].has_confirmed = true // 标记为已确认
326 -
327 - // 如果在选中列表中,也需要更新
328 - const selectedIndex = selectedTargets.value.findIndex(t => t.id === editingTarget.value.id)
329 - if (selectedIndex > -1) {
330 - selectedTargets.value[selectedIndex] = { ...selectedTargets.value[selectedIndex], ...formData }
331 - }
332 } 369 }
333 - } 370 +
334 - showToast('修改成功') 371 + // 如果在选中列表中,也需要更新
335 - } else { 372 + const selectedIndex = selectedTargets.value.findIndex(t => t.id === editingTarget.value.id)
336 - // 新增模式 373 + if (selectedIndex > -1) {
337 - try { 374 + selectedTargets.value[selectedIndex] = { ...selectedTargets.value[selectedIndex], ...formData }
338 - const res = await gratitudeAddAPI({ 375 + }
339 - ...formData, 376 +
340 - person_type: personType.value 377 + // 如果是确认模式,确认后自动加入选中列表
341 - }) 378 + if (isConfirmMode.value && selectedIndex === -1) {
342 - if (res.code) { 379 + selectedTargets.value.push(targetList.value[index])
343 - // 新增成功,更新本地列表
344 - targetList.value.push({
345 - ...formData,
346 - })
347 - showToast('新增成功')
348 } 380 }
349 - } catch (error) { 381 +
350 - showToast(`新增失败:${error.message || '未知错误'}`) 382 + showToast(isConfirmMode.value ? '确认成功' : '修改成功')
351 } 383 }
384 + } else {
385 + // 新增成功,更新本地列表
386 + targetList.value.push({
387 + ...formData,
388 + })
389 + console.warn(formData);
390 + console.warn(targetList.value);
391 + showToast('新增成功')
352 } 392 }
353 393
354 showAddTargetDialog.value = false; 394 showAddTargetDialog.value = false;
...@@ -359,6 +399,7 @@ const confirmAddTarget = async (formData) => { ...@@ -359,6 +399,7 @@ const confirmAddTarget = async (formData) => {
359 */ 399 */
360 const handleTargetEdit = (item) => { 400 const handleTargetEdit = (item) => {
361 editingTarget.value = item 401 editingTarget.value = item
402 + isConfirmMode.value = false // 明确设置为非确认模式
362 showAddTargetDialog.value = true 403 showAddTargetDialog.value = true
363 } 404 }
364 405
...@@ -410,31 +451,31 @@ const isSubmitDisabled = computed(() => { ...@@ -410,31 +451,31 @@ const isSubmitDisabled = computed(() => {
410 } 451 }
411 }) 452 })
412 453
454 +/**
455 + * 提交打卡
456 + */
413 const handleSubmit = async () => { 457 const handleSubmit = async () => {
414 - // 1. 校验作业选择 458 + // 计数打卡校验
415 - if (!selectedTaskValue.value || selectedTaskValue.value.length === 0) {
416 - showToast('请选择作业')
417 - return
418 - }
419 -
420 - const extraData = {
421 - subtask_id: selectedTaskValue.value[0] // 小作业ID
422 - }
423 -
424 - // 2. 计数打卡特定校验
425 if (taskType.value === 'count') { 459 if (taskType.value === 'count') {
426 - if (selectedTargets.value.length === 0) { 460 + if (selectedTaskValue.value.length === 0) {
427 - showToast(`请选择${dynamicFieldText.value}对象`) 461 + const taskText = taskOptions.value.find(t => t.value === selectedTaskValue.value[0])?.text || '作业'
462 + showToast(`请选择${taskText}`)
428 return 463 return
429 } 464 }
430 - if (!countValue.value || countValue.value <= 0) { 465 + if (selectedTargets.value.length === 0) {
431 - showToast(`${dynamicFieldText.value}次数必须大于0`) 466 + const targetText = dynamicFieldText.value || '对象'
467 + showToast(`请选择${targetText}`)
432 return 468 return
433 } 469 }
470 + }
471 +
472 + const extraData = {
473 + subtask_id: selectedTaskValue.value.length > 0 ? selectedTaskValue.value[0] : ''
474 + }
434 475
435 - // 传递额外数据 476 + // 如果是计数打卡,添加选中的计数对象列表
436 - extraData.targets = selectedTargets.value.map(t => t.id) 477 + if (taskType.value === 'count') {
437 - extraData.count = countValue.value 478 + extraData.gratitude_form_list = selectedTargets.value
438 } 479 }
439 480
440 await onSubmit(extraData) 481 await onSubmit(extraData)
...@@ -883,11 +924,13 @@ onMounted(async () => { ...@@ -883,11 +924,13 @@ onMounted(async () => {
883 selectedTaskText.value = option.text 924 selectedTaskText.value = option.text
884 isMakeup.value = !!option.is_makeup 925 isMakeup.value = !!option.is_makeup
885 personType.value = option.person_type 926 personType.value = option.person_type
927 + // 初始化动态表单字段
928 + updateDynamicFormFields(option)
886 } 929 }
887 930
888 // 如果是计数打卡,根据选中的作业ID查询计数对象 931 // 如果是计数打卡,根据选中的作业ID查询计数对象
889 if (taskType.value === 'count') { 932 if (taskType.value === 'count') {
890 - fetchTargetList(personType.value) 933 + fetchTargetList(selectedTaskValue.value[0])
891 } 934 }
892 } 935 }
893 936
......