import type { Ref } from 'vue' import type { CreateMarkingTaskRecordRequest, StudentMarkingQuestionResponse, } from '@/service/types' import { useQuery } from '@tanstack/vue-query' import { computed, inject, provide, readonly, ref, watch } from 'vue' import { markingTasksQuestionQuestionIdTaskTaskIdAverageScoreComparisonUsingGet, } from '@/service/yuejuanrenwu' import { markingTaskRecordsBatchUsingPost, markingTaskRecordsUsingPost, } from '@/service/yuejuanrenwujilu' export interface MarkingSubmitData { score: number remark: any status: 'draft' | 'submitted' markingTime?: number isExcellent?: boolean isTypical?: boolean isProblem?: boolean problemType?: string problemRemark?: string } export interface UseMarkingDataOptions { taskId: Ref questionId: Ref isLandscape?: Ref } function createMarkingData(options: UseMarkingDataOptions) { const { taskId, questionId, isLandscape } = options // 基础数据 const questionData = ref([]) const currentMarkingSubmitData = ref([]) const isLoading = ref(false) const isSubmitted = ref(false) const markingStartTime = ref(0) const mode = ref<'single' | 'multi'>('single') // 当前分数 const firstNotScoredIndex = computed(() => { return 0 }) const currentScore = computed({ get: () => { return currentMarkingSubmitData.value[firstNotScoredIndex.value]?.score || -1 }, set: (value) => { if (currentMarkingSubmitData.value[firstNotScoredIndex.value]) { currentMarkingSubmitData.value[firstNotScoredIndex.value].score = value } }, }) // 获取题目数据 const { data: questionResponse, isLoading: isQuestionLoading, error: questionError, refetch: refetchQuestion, } = useQuery({ queryKey: computed(() => ['marking-question', taskId.value]), queryFn: async () => { return { tpl_question_id: 0, full_score: 12, question_type: 'single', question_major: '一', question_minor: '1', image_urls: [ 'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png', 'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png', ], } // return await markingTasksTaskIdQuestionUsingGet({ // params: { task_id: taskId.value }, // }) }, enabled: computed(() => !!taskId.value), }) // 获取平均分对比 const { data: avgScoreData, refetch: refetchAvgScore, } = useQuery({ queryKey: computed(() => ['marking-avg-score', questionId.value, taskId.value]), queryFn: () => markingTasksQuestionQuestionIdTaskTaskIdAverageScoreComparisonUsingGet({ params: { question_id: questionId.value, task_id: taskId.value, }, }), enabled: computed(() => !!questionId.value && !!taskId.value), }) // 处理题目数据 const processQuestionData = () => { if (!questionResponse.value) return let questions: StudentMarkingQuestionResponse[] = [] questions = [questionResponse.value] questionData.value = questions // 初始化提交数据 currentMarkingSubmitData.value = questions.map(() => ({ score: -1, remark: '', status: 'draft' as const, })) // 设置开始时间 if (questions.length > 0) { markingStartTime.value = Date.now() } } // 监听数据变化 watch(() => questionResponse.value, processQuestionData, { immediate: true }) // 计算阅卷用时 const getMarkingTime = (): number => { return markingStartTime.value > 0 ? Math.floor((Date.now() - markingStartTime.value) / 1000) : 0 } // 提交单个记录 const submitSingleRecord = async (data?: MarkingSubmitData, index: number = 0) => { try { const question = questionData.value[index] if (!question) throw new Error('题目数据不存在') const currentData = data || currentMarkingSubmitData.value[index] const submitData: CreateMarkingTaskRecordRequest = { scan_info_id: question.scan_info_id!, question_id: questionId.value, task_id: taskId.value, duration: getMarkingTime(), score: currentData.score, remark: JSON.stringify(currentData.remark), page_mode: 'single', is_excellent: currentData.isExcellent ? 1 : 0, is_model: currentData.isTypical ? 1 : 0, is_problem: currentData.isProblem ? 1 : 0, } const response = await markingTaskRecordsUsingPost({ body: submitData, }) if (response) { isSubmitted.value = true // 重新获取下一题 await refetchQuestion() processQuestionData() return response } } catch (error) { console.error('提交阅卷记录失败:', error) throw error } } // 批量提交记录 const submitBatchRecords = async () => { try { const submitDataList: CreateMarkingTaskRecordRequest[] = currentMarkingSubmitData.value.map( (item, index) => { const question = questionData.value[index] return { scan_info_id: question.scan_info_id!, question_id: questionId.value, task_id: taskId.value, duration: getMarkingTime(), score: item.score, remark: JSON.stringify(item.remark), page_mode: 'single', is_excellent: item.isExcellent ? 1 : 0, is_model: item.isTypical ? 1 : 0, is_problem: item.isProblem ? 1 : 0, } }, ) const response = await markingTaskRecordsBatchUsingPost({ body: { batch_data: submitDataList, }, }) if (response) { isSubmitted.value = true // 重新获取下一批题目 await refetchQuestion() processQuestionData() return response } } catch (error) { console.error('批量提交阅卷记录失败:', error) throw error } } // 提交记录(根据模式选择单个或批量) const submitRecord = async (data?: MarkingSubmitData, index?: number) => { return await submitSingleRecord(data, index) } // 重新加载数据 const reload = async () => { await Promise.all([ refetchQuestion(), refetchAvgScore(), ]) } return { // 数据状态 questionData, currentMarkingSubmitData, currentScore, firstNotScoredIndex, isLoading: computed(() => isQuestionLoading.value || isLoading.value), isSubmitted: readonly(isSubmitted), mode, isLandscape: isLandscape || ref(false), // 平均分数据 avgScoreData: computed(() => avgScoreData.value), // 错误状态 questionError, // 方法 submitRecord, submitSingleRecord, submitBatchRecords, getMarkingTime, reload, refetchQuestion, refetchAvgScore, } } type MarkingData = ReturnType const markingDataKey = Symbol('markingData') export function useMarkingData() { const markingData = inject(markingDataKey) if (!markingData) { throw new Error('Marking data not found') } return markingData } export function provideMarkingData(options: UseMarkingDataOptions) { const markingData = createMarkingData(options) provide(markingDataKey, markingData) return markingData }