Browse Source

test code

abpcoder 3 tuần trước cách đây
mục cha
commit
d7d899e8ad

+ 34 - 26
back-ui/src/api/dz/papers.js

@@ -46,6 +46,15 @@ export function getPaperExamTypes(query) {
 
 /// 院校
 export function getPaperUniversities(query) {
+    // TODO: remove test code
+    return Promise.resolve({
+        code: 200,
+        data: [
+            {id: 1, name: '湖南民政职业技术学院'},
+            {id: 2, name: '湖南铁道职业技术学院'},
+            {id: 3, name: '湖南大众传媒'},
+        ]
+    })
     // query: {batchId}
     return request({
         url: '/learn/teaching/universities',
@@ -54,18 +63,17 @@ export function getPaperUniversities(query) {
     })
 }
 
-/// 专业组
-export function getPaperMajorGroups(query) {
-    // query: {location, examType, batchId, universityId}
-    return request({
-        url: '/learn/teaching/majorGroups',
-        method: 'get',
-        params: query
-    })
-}
-
 /// 专业组
 export function getPaperMajors(query) {
+    // TODO: remove test code
+    return Promise.resolve({
+        code: 200,
+        data: [
+            {id: 1, majorGroup: '默认组', majorName: '电子信息'},
+            {id: 2, majorGroup: '专业组一', majorName: '商务英文'},
+            {id: 3, majorGroup: '专业组一', majorName: '商务管理'},
+        ]
+    })
     // query: {location, examType, batchId, universityId}
     return request({
         url: '/learn/teaching/majors',
@@ -77,13 +85,13 @@ export function getPaperMajors(query) {
 /// 试卷批次
 export function getPaperBatches() {
     // TODO: remove test code
-    // return Promise.resolve({
-    //     code: 200,
-    //     data: [
-    //         {name: '第二批', batchId: 2},
-    //         {name: '第一批', batchId: 1}
-    //     ]
-    // })
+    return Promise.resolve({
+        code: 200,
+        data: [
+            {name: '第二批', batchId: 2},
+            {name: '第一批', batchId: 1}
+        ]
+    })
 
     return request({
         url: '/learn/test/list',
@@ -183,15 +191,15 @@ export function getPaperDetail(query) {
 
 export function getPaperClassStatistic(query) {
     // TODO: remove test code
-    // return Promise.resolve({
-    //     code: 200,
-    //     data: [
-    //         {classId: 0, className: '2501班', total: 50, unexact: 10, exact: 40, unsend: 10, send: 20, unfinish: 5, finish: 15},
-    //         {classId: 0, className: '2502班', total: 50, unexact: 10, exact: 40, unsend: 10, send: 20, unfinish: 5, finish: 15},
-    //         {classId: 0, className: '2503班', total: 50, unexact: 10, exact: 40, unsend: 10, send: 20, unfinish: 5, finish: 15},
-    //         {classId: 0, className: '2504班', total: 50, unexact: 10, exact: 40, unsend: 10, send: 20, unfinish: 5, finish: 15}
-    //     ]
-    // })
+    return Promise.resolve({
+        code: 200,
+        data: [
+            {classId: 0, className: '2501班', total: 50, unexact: 10, exact: 40, unsend: 10, send: 20, unfinish: 5, finish: 15},
+            {classId: 0, className: '2502班', total: 50, unexact: 10, exact: 40, unsend: 10, send: 20, unfinish: 5, finish: 15},
+            {classId: 0, className: '2503班', total: 50, unexact: 10, exact: 40, unsend: 10, send: 20, unfinish: 5, finish: 15},
+            {classId: 0, className: '2504班', total: 50, unexact: 10, exact: 40, unsend: 10, send: 20, unfinish: 5, finish: 15}
+        ]
+    })
     // 2025.10.16 新增班级统计,用于组卷生成
     const queryDemo = {
         buildType: '', // 试卷构建类型,定义枚举?

+ 21 - 12
back-ui/src/views/dz/papers/components/conditions/usePaperExactCondition.js

@@ -1,5 +1,5 @@
 import {useProvidePaperBatchCondition} from "@/views/dz/papers/components/conditions/usePaperBatchCondition.js";
-import {getPaperMajorGroups, getPaperMajors, getPaperUniversities} from "@/api/dz/papers.js";
+import {getPaperMajors, getPaperUniversities} from "@/api/dz/papers.js";
 import {createEventHook, injectLocal, provideLocal} from "@vueuse/core";
 
 const key = Symbol('PaperExactCondition')
@@ -9,11 +9,23 @@ export const useProvidePaperExactCondition = function (type) {
     const universityId = ref('')
     const universities = ref([])
 
+    const _allMajors = ref([])
+
     const majorGroup = ref('')
-    const majorGroups = ref([])
+    const majorGroups = computed(() => {
+        const results = []
+        _allMajors.value.forEach(m => {
+            if (results.includes(m.majorGroup)) return
+            results.push(m.majorGroup)
+        })
+        return results
+    })
 
     const majorPlanId = ref('')
-    const majors = ref([])
+    const majors = computed(() => {
+        if (!majorGroup.value) return
+        return _allMajors.value.filter(m => m.majorGroup == majorGroup.value)
+    })
 
     const exactEvent = createEventHook()
     const triggerExactEvent = async function (args) {
@@ -34,23 +46,20 @@ export const useProvidePaperExactCondition = function (type) {
         majorGroups.value = []
 
         if (!batchId || !universityId) return
-        const res = await getPaperMajorGroups({buildType, batchId, universityId})
-        majorGroups.value = res.data
+        const res = await getPaperMajors({buildType, batchId, universityId})
+        _allMajors.value = res.data
 
         // 没有数据时,说明已经满足了条件
-        if (!res.data.length) await triggerExactEvent({buildType, batchId, universityId})
+        if (!majorGroups.value.length) await triggerExactEvent({buildType, batchId, universityId})
+        else if (majorGroups.value.length == 1) majorGroup.value = majorGroups.value[0]
     })
 
     watch([batchId, universityId, majorGroup], async ([batchId, universityId, majorGroup]) => {
         majorPlanId.value = ''
-        majors.value = []
 
         if (!batchId || !universityId || !majorGroup) return
-        const res = await getPaperMajors({buildType, batchId, universityId, majorGroup})
-        majors.value = res.data
-
-        // 没有数据时,说明已经满足了条件
-        if (!res.data.length) await triggerExactEvent({buildType, batchId, universityId, majorGroup})
+        if (!majors.value.length) await triggerExactEvent({buildType, batchId, universityId, majorGroup})
+        else if (majors.value.length == 1) majorPlanId.value = majors.value[0].id
     })
 
     watch(majorPlanId, async (majorPlanId) => {

+ 1 - 1
back-ui/src/views/dz/papers/components/conditions/usePaperQuestionCondition.js

@@ -6,7 +6,7 @@ import {ElMessage} from "element-plus";
 import {getPaperQuestions, getPaperQuestionTypes} from "@/api/dz/papers.js";
 import {injectLocal, provideLocal} from "@vueuse/core";
 
-const key = Symbol('PaperQuestionTypeCondition')
+const key = Symbol('PaperQuestionCondition')
 
 export const useProvidePaperQuestionCondition = function (exactMode, allowMultiple, disableQuestionQuery) {
     const keyword = ref('')

+ 81 - 1
back-ui/src/views/dz/papers/components/paper-exact-hand.vue

@@ -1,8 +1,88 @@
 <template>
-    定向手动组卷
+    <el-row :gutter="20">
+        <el-col :span="8">
+            <el-form label-width="68px">
+                <el-form-item label="批次">
+                    <el-select v-model="batchId" clearable style="width: 227px">
+                        <el-option v-for="b in batchList" :label="b.name" :value="b.batchId"/>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="院校">
+                    <el-select v-model="universityId" clearable style="width: 227px">
+                        <el-option v-for="u in universities" :label="u.name" :value="u.id"/>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="专业组">
+                    <el-select v-model="majorGroup" clearable style="width: 227px">
+                        <el-option v-for="g in majorGroups" :label="g" :value="g"/>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="专业">
+                    <el-select v-model="majorPlanId" clearable style="width: 227px">
+                        <el-option v-for="m in majors" :label="m.majorName" :value="m.id"/>
+                    </el-select>
+                </el-form-item>
+            </el-form>
+        </el-col>
+        <el-col :span="16">
+            <class-statistic-table exact-mode/>
+        </el-col>
+    </el-row>
+    <el-row :gutter="20" class="mt-5">
+        <el-col :span="6">
+            <knowledge-tree/>
+        </el-col>
+        <el-col :span="18">
+        </el-col>
+    </el-row>
 </template>
 
 <script setup name="PaperExactHand">
+
+import consts from "@/utils/consts.js";
+import {useProvidePaperExactCondition} from "@/views/dz/papers/components/conditions/usePaperExactCondition.js";
+import {
+    useProvidePaperClassStatisticCondition
+} from "@/views/dz/papers/components/conditions/usePaperClassStatisticCondition.js";
+import {useProvidePaperKnowledgeCondition} from "@/views/dz/papers/components/conditions/usePaperKnowledgeCondition.js";
+import ClassStatisticTable from "@/views/dz/papers/components/plugs/class-statistic-table.vue";
+import KnowledgeTree from "@/views/dz/papers/components/plugs/knowledge-tree.vue";
+
+const type = consts.enums.buildType.ExactHand
+const {
+    batchId,
+    batchList,
+    universityId,
+    universities,
+    majorGroup,
+    majorGroups,
+    majors,
+    majorPlanId,
+    onExactReady
+} = useProvidePaperExactCondition(type)
+const {selectedClasses, classList, loadClassStatistic} = useProvidePaperClassStatisticCondition()
+const {knowledgeNode, knowledgeCheckNodes, loadKnowledge} = useProvidePaperKnowledgeCondition()
+
+const handleSubmit = async () => {
+
+}
+
+let statArg = null
+const _loadClassStatistic = async () => {
+    selectedClasses.value = []
+    classList.value = []
+
+    await loadClassStatistic(statArg)
+}
+
+onExactReady(async (payload) => {
+    statArg = payload
+    knowledgeNode.value = null
+    knowledgeCheckNodes.value = []
+
+    await loadKnowledge(payload)
+    await _loadClassStatistic()
+})
 </script>
 
 <style scoped>

+ 2 - 3
back-ui/src/views/dz/papers/components/paper-full-intelligent.vue

@@ -85,9 +85,8 @@ const handleSubmit = async (qTypes) => {
         classIds
     }
     await buildPaperFullIntelligent(commit)
-    ElMessage.success('生成成功,即将打开组卷记录')
-    await sleep(2000)
-    await router.push('/paper/list')
+    ElMessage.success('生成成功')
+    _loadClassStatistic()
 }
 
 let statArg = null

+ 112 - 0
back-ui/src/views/dz/papers/components/plugs/question-hand.vue

@@ -0,0 +1,112 @@
+<template>
+    <div class="text-main mb-3">
+        当前查询知识点(从左侧选择):<el-text size="large" type="primary" class="font-bold">{{ knowledgeNode?.name }}</el-text>
+    </div>
+    <div class="flex flex-row items-center gap-3">
+        <el-input v-model="keywordLocal" clearable prefix-icon="search" placeholder="输入题目关键字-回车触发搜索"
+                  style="width: 250px" @keydown.enter="confirmKeyword" @clear="confirmKeyword"/>
+        <el-select v-model="qtpye" clearable style="width: 220px">
+            <el-option v-for="t in qTypes" :value="t.dictValue" :label="t.dictLabel"></el-option>
+        </el-select>
+        <el-popover width="250">
+            <span v-if="currentSubject" class="text-sm font-bold">科目:{{ currentSubject.subjectName }}</span>
+            <div v-for="g in groupedQuestions" class="flex flex-col">
+                <el-divider style="margin: 10px 0"/>
+                <span>{{ g.qtpye }}:{{ g.questions.length }}道</span>
+                <el-link type="danger" plain icon="delete" class="self-end" @click="removeQuestionGroup(g.qtpye)">清除
+                </el-link>
+            </div>
+            <el-divider style="margin: 10px 0"/>
+            <div class="flex items-center justify-between">
+                <el-link type="danger" plain icon="delete" @click="clearCart">全部清除</el-link>
+                <el-button type="primary" @click="buildPaper">生成试卷</el-button>
+            </div>
+            <template #reference>
+                <el-button type="primary" size="large" icon="shopping-cart" class="ml-auto">
+                    试题篮({{ cart.length }})
+                </el-button>
+            </template>
+        </el-popover>
+    </div>
+    <el-divider/>
+    <el-empty v-if="total==0"/>
+    <template v-else v-for="q in questionList">
+        <question-content :question="q" @parse="showParseQuestion=q,showParse=true">
+            <el-button v-if="!hasQuestion(q)" type="primary" icon="plus" class="ml-auto" @click="addQuestion(q)">
+                加入试题篮
+            </el-button>
+            <el-button v-else type="danger" plain icon="delete" class="ml-auto" @click="removeQuestion(q)">移出试题篮
+            </el-button>
+        </question-content>
+        <el-divider/>
+    </template>
+    <pagination v-show="total>0" :total="total" v-model:page="pageNum" v-model:limit="pageSize"
+                @pagination="getQuestionList"/>
+
+    <el-dialog v-model="showParse" append-to-body show-close @close="showParse=false">
+        <template #title>ID:{{ showParseQuestion.id }} 试题解析</template>
+        <div v-if="showParseQuestion.answer0" v-html="`【正确答案】` + showParseQuestion.answer0"/>
+        <div v-if="showParseQuestion.parse" v-html="`【解析】` + showParseQuestion.parse" class="mt-5"></div>
+        <div v-if="showParseQuestion.parse0" v-html="`【解析】` + showParseQuestion.parse0" class="mt-5"></div>
+        <template #footer>
+            <el-button type="primary" @click="showParse=false">确 定</el-button>
+        </template>
+    </el-dialog>
+</template>
+
+<script setup name="QuestionHand">
+import router from '@/router'
+import {ElMessage} from "element-plus";
+import {useProvidePaperQuestionCondition} from "@/views/dz/papers/components/conditions/usePaperQuestionCondition.js";
+import {useInjectPaperExactCondition} from "@/views/dz/papers/components/conditions/usePaperExactCondition.js";
+import {useInjectPaperFullCondition} from "@/views/dz/papers/hooks/usePaperFullCondition.js";
+import {usePaperStorage} from "@/views/dz/papers/hooks/usePaperStorage.js";
+import QuestionContent from "@/views/components/question-content.vue";
+
+const props = defineProps({
+    allowMultiple: Boolean,
+    exactMode: Boolean
+})
+
+const showParse = ref(false)
+const showParseQuestion = ref(null)
+
+const {knowledgeNode, paperArgs} = props.exactMode ? useInjectPaperExactCondition() : useInjectPaperFullCondition()
+const {
+    keyword,
+    qtpye,
+    qTypes,
+    pageNum,
+    pageSize,
+    total,
+    questionList,
+    getQuestionList,
+    cart,
+    groupedQuestions,
+    currentSubject,
+    hasQuestion,
+    addQuestion,
+    removeQuestion,
+    removeQuestionGroup,
+    clearCart
+} = useProvidePaperQuestionCondition(props.exactMode, props.allowMultiple)
+
+const keywordLocal = ref('')
+const confirmKeyword = (val) => keyword.value = keywordLocal.value
+
+const buildPaper = function () {
+    // validation
+    const {batchId} = paperArgs.value
+    if (!batchId) return ElMessage.error('请选择批次')
+    if (!knowledgeNode.value) return ElMessage.error('请选择知识点')
+    if (!cart.value.length) return ElMessage.error('请将试题加入试题篮')
+
+    const paper = {...paperArgs.value, questions: cart.value}
+    usePaperStorage(paper)
+    router.push({name: 'PaperDetail'})
+}
+</script>
+
+<style scoped>
+
+</style>