import {useInjectPaperExactCondition} from "@/views/dz/papers/hooks/usePaperExactCondition.js"; import {useInjectPaperFullCondition} from "@/views/dz/papers/hooks/usePaperFullCondition.js"; import {useInjectPaperKnowledgeCondition} from "@/views/dz/papers/hooks/usePaperKnowledgeCondition.js"; import {useInjectGlobalLoading} from "@/views/hooks/useGlobalLoading.js"; import {getPaperQuestions, getPaperQuestionTypes} from "@/api/dz/papers.js"; import {injectLocal, provideLocal} from "@vueuse/core"; import {ElMessage} from "element-plus"; const key = Symbol('PaperQuestionCondition') export const useProvidePaperQuestionCondition = function (exactMode, handMode) { const keyword = ref('') const questionId = ref('') const qtpye = ref('') // 历史遗留拼写错误 const qTypes = ref([]) const pageNum = ref(1) const pageSize = ref(10) const total = ref(0) const questionList = ref([]) const {conditionArgs, conditionData} = exactMode ? useInjectPaperExactCondition() : useInjectPaperFullCondition() const {knowledgeId, knowledgeIds, knowledgeNode, knowledgeCheckNodes} = useInjectPaperKnowledgeCondition() const loading = useInjectGlobalLoading() // question cart const cart = ref([]) const currentSubject = computed(() => { // 如果组卷条件里没有科目,试题篮就不设当前科目,即可以随意加题 if (!conditionArgs.value.subjectId) return null if (!cart.value.length) return null // 否则,试题篮里不能跨科目加题 const demoId = cart.value[0].subjectId return conditionData.value.subjectList.find(s => s.subjectId == demoId) }) const subjectStat = computed(() => { const results = [] cart.value.forEach(q => { const match = results.find(i => i.subjectId == q.subjectId) if (!match) { const subject = conditionData.value.subjectList.find(s => s.subjectId == q.subjectId) results.push({subjectId: q.subjectId, subjectName: subject?.subjectName || ('未知'+q.subjectId), count: 1}) } else { match.count += 1 } }) return results }) const groupedQuestions = computed(() => { const results = {} cart.value.forEach(q => { if (!results[q.qtpye]) { results[q.qtpye] = [] } results[q.qtpye].push(q) }) return Object.keys(results).map(k => ({qtpye: k, questions: results[k]})) }) const hasQuestion = (q) => { return cart.value.some(c => c.id == q.id) } const removeQuestion = (q) => { const idx = cart.value.findIndex(c => c.id == q.id) if (idx > -1) cart.value.splice(idx, 1) } const addQuestion = (q) => { // 2025.10.25 取消科目限制,让用户随意添加 // if (currentSubject.value && currentSubject.value.subjectId != q.subjectId) { // return ElMessage.error(`当前科目【${currentSubject.value.subjectName}】冲突`) // } cart.value.push(q) } const removeQuestionGroup = (qtpye) => { const ls = groupedQuestions.value.find(g => g.qtpye == qtpye)?.questions ls?.forEach(q => removeQuestion(q)) } const clearCart = () => cart.value = [] // hooks - 监听知识点变化,重新获取题型数据 // 监听单个知识点节点和多选知识点节点的变化 watch([() => conditionArgs.value.subjectId, knowledgeNode, knowledgeCheckNodes], async ([subjectId, knowledgeNodeVal, knowledgeCheckNodesVal]) => { // 获取知识点ID:优先使用单个知识点,否则使用多选知识点 const currentKnowledgeId = knowledgeNodeVal?.id const currentKnowledgeIds = knowledgeCheckNodesVal?.map(k => k.id) || [] // 如果没有知识点,直接返回 if (!currentKnowledgeId && currentKnowledgeIds.length === 0) return // 定向模式下,如果subjectId为空,使用默认值11L(与后端逻辑一致) // 全量模式下,必须有subjectId才能继续 let finalSubjectId = subjectId if (!finalSubjectId) { if (exactMode) { // 定向模式下,后端会自动设置subjectId为11L finalSubjectId = 11 } else { // 全量模式下,必须有subjectId if (conditionData.value.subjectList?.length) return } } // 构建查询参数 const knowledgeIdsToUse = currentKnowledgeId ? [currentKnowledgeId] : currentKnowledgeIds const query = {subjectId: finalSubjectId, knowledgeIds: knowledgeIdsToUse} try { const res = await getPaperQuestionTypes(query) const newQTypes = res.data || [] // 保留已有的题型设置(特别是 count 和 score 值),只更新题型列表 // 如果已有题型设置,则合并新旧题型,保留已有的 count 和 score if (qTypes.value.length > 0) { const existingTypesMap = new Map() qTypes.value.forEach(qt => { existingTypesMap.set(qt.dictValue, { count: qt.count || 0, score: qt.score !== undefined ? qt.score : 0 }) }) // 合并新题型和已有设置 qTypes.value = newQTypes.map(newQt => { const existing = existingTypesMap.get(newQt.dictValue) return { ...newQt, count: existing ? existing.count : (newQt.count || 0), score: existing ? existing.score : (newQt.score !== undefined ? newQt.score : 0) } }) } else { // 如果没有已有设置,直接使用新的题型列表,初始化 score 为 0 qTypes.value = newQTypes.map(qt => ({ ...qt, score: qt.score !== undefined ? qt.score : 0 })) } // 清空选中的题型 qtpye.value = '' } catch (error) { console.error('获取题型列表失败:', error) // 出错时不清空已有设置 } }, { deep: true, immediate: false }) const questionQuery = computed(() => ({ pageNum: pageNum.value, pageSize: pageSize.value, title: keyword.value, id: questionId.value, qtpye: qtpye.value, knowledgeId: knowledgeId.value, knowledges: knowledgeIds.value.toString() })) const getQuestionList = async function () { if (!handMode) return // 智能组卷时不需要查询 loading.value = true try { const res = await getPaperQuestions(questionQuery.value) total.value = res.total questionList.value = res.rows } finally { loading.value = false } } watch([keyword, questionId, qtpye, knowledgeId, () => knowledgeIds.value.toString()], async ([title, id, qtpye, knowledgeId, knowledges]) => { pageNum.value = 1 questionList.value = [] total.value = 0 if (!knowledgeId && !knowledges) return // 有知识点即可以查询题库 await getQuestionList() }) const payload = { keyword, questionId, qtpye, qTypes, pageNum, pageSize, total, questionList, getQuestionList, cart, currentSubject, groupedQuestions, subjectStat, hasQuestion, addQuestion, removeQuestion, removeQuestionGroup, clearCart } provideLocal(key, payload) return payload } export const useInjectPaperQuestionCondition = function () { return injectLocal(key) }