Ver código fonte

paper ui cc.

abpcoder 1 mês atrás
pai
commit
538ae2f151

+ 7 - 2
back-ui/src/views/dz/papers/components/paper-by-hand.vue

@@ -1,10 +1,10 @@
 <template>
-    <el-tabs type="border-card">
+    <el-tabs type="border-card" @tab-change="handleTabChange">
         <el-tab-pane label="全量组卷">
             <paper-hand-full />
         </el-tab-pane>
         <el-tab-pane label="定向组卷">
-            <paper-hand-exact />
+            <paper-hand-exact v-if="exactVisited" />
         </el-tab-pane>
     </el-tabs>
 </template>
@@ -12,6 +12,11 @@
 <script setup name="PaperByHand">
 import PaperHandFull from "@/views/dz/papers/components/paper-hand-full.vue";
 import PaperHandExact from "@/views/dz/papers/components/paper-hand-exact.vue";
+
+// 延迟加载,减少初次加载项
+const exactVisited = ref(false)
+const handleTabChange = () => exactVisited.value = true
+
 </script>
 
 <style scoped>

+ 6 - 2
back-ui/src/views/dz/papers/components/paper-by-intelligent.vue

@@ -1,10 +1,10 @@
 <template>
-    <el-tabs type="border-card">
+    <el-tabs type="border-card" @tab-change="handleTabChange">
         <el-tab-pane label="全量组卷">
             <paper-intelligent-full />
         </el-tab-pane>
         <el-tab-pane label="定向组卷">
-            <paper-intelligent-exact />
+            <paper-intelligent-exact v-if="exactVisited" />
         </el-tab-pane>
     </el-tabs>
 </template>
@@ -12,6 +12,10 @@
 <script setup name="PaperByIntelligent">
 import PaperIntelligentFull from "@/views/dz/papers/components/paper-intelligent-full.vue";
 import PaperIntelligentExact from "@/views/dz/papers/components/paper-intelligent-exact.vue";
+
+// 延迟加载,减少初次加载项
+const exactVisited = ref(false)
+const handleTabChange = () => exactVisited.value = true
 </script>
 
 <style scoped>

+ 16 - 5
back-ui/src/views/dz/papers/components/paper-intelligent-exact.vue

@@ -1,11 +1,22 @@
 <template>
-
+    <paper-exact-conditions/>
+    <el-container class="mt-5">
+        <el-aside width="350px">
+            <paper-knowledge-tree allow-multiple exact-mode/>
+        </el-aside>
+        <el-main>
+            <paper-question-intelligent exact-mode/>
+        </el-main>
+    </el-container>
 </template>
 
-<script>
-export default {
-    name: "paper-intelligent-exact"
-}
+<script setup name="PaperIntelligentExact">
+import PaperExactConditions from "@/views/dz/papers/components/paper-exact-conditions.vue";
+import PaperKnowledgeTree from "@/views/dz/papers/components/paper-knowledge-tree.vue";
+import PaperQuestionIntelligent from "@/views/dz/papers/components/paper-question-intelligent.vue";
+import {useProvidePaperExactCondition} from "@/views/dz/papers/hooks/usePaperExactCondition.js";
+
+useProvidePaperExactCondition()
 </script>
 
 <style scoped>

+ 0 - 13
back-ui/src/views/dz/papers/components/paper-intelligent-form.vue

@@ -1,13 +0,0 @@
-<template>
-
-</template>
-
-<script>
-export default {
-    name: "paper-intelligent-form"
-}
-</script>
-
-<style scoped>
-
-</style>

+ 16 - 5
back-ui/src/views/dz/papers/components/paper-intelligent-full.vue

@@ -1,11 +1,22 @@
 <template>
-
+    <paper-full-conditions/>
+    <el-container class="mt-5">
+        <el-aside width="350px">
+            <paper-knowledge-tree allow-multiple/>
+        </el-aside>
+        <el-main>
+            <paper-question-intelligent/>
+        </el-main>
+    </el-container>
 </template>
 
-<script>
-export default {
-    name: "paper-intelligent-full"
-}
+<script setup name="PaperIntelligentFull">
+import PaperFullConditions from "@/views/dz/papers/components/paper-full-conditions.vue";
+import PaperKnowledgeTree from "@/views/dz/papers/components/paper-knowledge-tree.vue";
+import PaperQuestionIntelligent from "@/views/dz/papers/components/paper-question-intelligent.vue";
+import {useProvidePaperFullCondition} from "@/views/dz/papers/hooks/usePaperFullCondition.js";
+
+useProvidePaperFullCondition()
 </script>
 
 <style scoped>

+ 7 - 2
back-ui/src/views/dz/papers/components/paper-knowledge-tree.vue

@@ -1,7 +1,7 @@
 <template>
     <el-input v-model="keyword" placeholder="请输入知识点名称" clearable prefix-icon="Search"
               style="margin-bottom: 20px"/>
-    <el-tree v-if="knowledges.length" :data="knowledges" :props="{ label: 'name', children: 'children' }"
+    <el-tree ref="treeRef" v-if="knowledges.length" :data="knowledges" :props="{ label: 'name', children: 'children' }"
              :expand-on-click-node="false" :filter-node-method="filterNode" node-key="id" highlight-current
              default-expand-all :show-checkbox="allowMultiple" @node-click="handleNodeClick" @check="handleNodeCheck"/>
 </template>
@@ -15,8 +15,9 @@ const props = defineProps({
     exactMode: Boolean
 })
 
+const treeRef = ref(null)
 const keyword = ref('')
-const {knowledges, knowledgeNode, knowledgeCheckNodes} = props.exactMode
+const {knowledges, knowledgeNode, knowledgeCheckNodes, onKnowledgeRemove} = props.exactMode
     ? useInjectPaperExactCondition()
     : useInjectPaperFullCondition()
 
@@ -33,6 +34,10 @@ const handleNodeCheck = function (data, {checkedNodes}) {
     // 多选时,只保留叶子节点
     knowledgeCheckNodes.value = checkedNodes.filter(k => !!!k.children?.length)
 }
+
+onKnowledgeRemove((k) => {
+    treeRef.value.setChecked(k, false, false)
+})
 </script>
 
 <style scoped>

+ 3 - 1
back-ui/src/views/dz/papers/components/paper-question-hand.vue

@@ -1,5 +1,7 @@
 <template>
-    <div v-if="knowledgeNode" class="text-xs mb-2">当前查询知识点:<strong>{{ knowledgeNode.name }}</strong></div>
+    <div class="text-main mb-3">
+        当前查询知识点(从左侧选择):<el-text type="primary 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"/>

+ 40 - 0
back-ui/src/views/dz/papers/components/paper-question-intelligent.vue

@@ -0,0 +1,40 @@
+<template>
+    <div class="text-main mb-3 flex items-center">
+        <div :class="seqClass">1</div>选择知识点(从左侧勾选)
+    </div>
+    <div class="flex flex-row flex-wrap gap-3">
+        <el-tag v-for="k in knowledgeCheckNodes" type="primary" round closable @close="removeKnowledge(k)">{{k.name}}</el-tag>
+    </div>
+    <div class="text-main mt-10 mb-3 flex items-center">
+        <div :class="seqClass">2</div>试题设置
+    </div>
+    <div class="flex flex-row flex-warp gap-10">
+        <div v-for="t in qTypes" class="flex items-center gap-3">
+            <el-text class="font-bold break-keep">{{t.dictLabel}}</el-text>
+            <el-input-number v-model="t.count" :min="0"/>
+        </div>
+    </div>
+    <div class="mt-10 text-right">
+        <el-button type="primary" size="large">生成试卷</el-button>
+    </div>
+</template>
+
+<script setup name="PaperQuestionIntelligent">
+
+import {useInjectPaperExactCondition} from "@/views/dz/papers/hooks/usePaperExactCondition.js";
+import {useInjectPaperFullCondition} from "@/views/dz/papers/hooks/usePaperFullCondition.js";
+import {useProvidePaperQuestionCondition} from "@/views/dz/papers/hooks/usePaperQuestionCondition.js";
+
+const props = defineProps({
+    allowMultiple: Boolean,
+    exactMode: Boolean
+})
+
+const seqClass = 'inline-block rounded-full bg-blue-100 w-5 h-5 text-center mr-2'
+const {knowledgeCheckNodes, removeKnowledge} = props.exactMode ? useInjectPaperExactCondition() : useInjectPaperFullCondition()
+const {qTypes} = useProvidePaperQuestionCondition(props.exactMode, props.allowMultiple, true)
+</script>
+
+<style scoped>
+
+</style>

+ 12 - 2
back-ui/src/views/dz/papers/hooks/usePaperExactCondition.js

@@ -1,4 +1,4 @@
-import {injectLocal, provideLocal} from "@vueuse/core";
+import {createEventHook, injectLocal, provideLocal} from "@vueuse/core";
 import {
     getPaperBatches,
     getPaperExamTypes,
@@ -31,11 +31,21 @@ export const useProvidePaperExactCondition = function () {
     const knowledgeCheckNodes = ref([]) // 多选的节点
     const knowledgeIds = computed(() => knowledgeCheckNodes.value.map(k => k.id))
     const knowledgeId = computed(() => knowledgeNode.value?.id || '') // 单选
+    const knowledgeRemoveEvent = createEventHook()
+    const removeKnowledge = async (k) => {
+        const nodes = knowledgeCheckNodes.value
+        const idx = nodes.indexOf(k)
+        if (idx > -1) {
+            nodes.splice(idx, 1)
+            await knowledgeRemoveEvent.trigger(k)
+        }
+    }
 
     const payload = {
         location, provinces, examType, examTypes, universityId, universities,
         batchId, batchList, majorPlanId, majors, subjects, subjectId,
-        knowledges, knowledgeNode, knowledgeId, knowledgeCheckNodes, knowledgeIds
+        knowledges, knowledgeNode, knowledgeId, knowledgeCheckNodes, knowledgeIds,
+        removeKnowledge, onKnowledgeRemove: knowledgeRemoveEvent.on
     }
     provideLocal(key, payload)
 

+ 12 - 2
back-ui/src/views/dz/papers/hooks/usePaperFullCondition.js

@@ -1,4 +1,4 @@
-import {injectLocal, provideLocal} from "@vueuse/core";
+import {createEventHook, injectLocal, provideLocal} from "@vueuse/core";
 import {getPaperBatches, getPaperKnowledges, getPaperSubjects} from "@/api/dz/papers.js";
 import {watch} from "vue";
 
@@ -15,10 +15,20 @@ export const useProvidePaperFullCondition = function () {
     const knowledgeCheckNodes = ref([]) // 多选的节点
     const knowledgeIds = computed(() => knowledgeCheckNodes.value.map(k => k.id))
     const knowledgeId = computed(() => knowledgeNode.value?.id || '')
+    const knowledgeRemoveEvent = createEventHook()
+    const removeKnowledge = async (k) => {
+        const nodes = knowledgeCheckNodes.value
+        const idx = nodes.indexOf(k)
+        if (idx > -1) {
+            nodes.splice(idx, 1)
+            await knowledgeRemoveEvent.trigger(k)
+        }
+    }
 
     const payload = {
         batchId, batchList, subjectId, subjects,
-        knowledges, knowledgeId, knowledgeNode, knowledgeCheckNodes, knowledgeIds
+        knowledges, knowledgeId, knowledgeNode, knowledgeCheckNodes, knowledgeIds,
+        removeKnowledge, onKnowledgeRemove: knowledgeRemoveEvent.on
     }
     provideLocal(key, payload)
 

+ 2 - 1
back-ui/src/views/dz/papers/hooks/usePaperQuestionCondition.js

@@ -7,7 +7,7 @@ import {ElMessage} from "element-plus";
 
 const key = Symbol('PaperQuestionCondition')
 
-export const useProvidePaperQuestionCondition = function (exactMode, allowMultiple) {
+export const useProvidePaperQuestionCondition = function (exactMode, allowMultiple, disableQuestionQuery = false) {
     // exactMode: exact condition & full condition
     // allowMultiple: multiple knowledge selection
 
@@ -82,6 +82,7 @@ export const useProvidePaperQuestionCondition = function (exactMode, allowMultip
         knowledges: knowledgeIds.value.toString()
     }))
     const getQuestionList = async function () {
+        if (disableQuestionQuery) return // 智能组卷时不需要查询
         loading.value = true
         try {
             const res = await getPaperQuestions(questionQuery.value)

+ 6 - 2
back-ui/src/views/dz/papers/index.vue

@@ -1,11 +1,11 @@
 <template>
     <div class="app-container" v-loading="loading">
-        <el-tabs>
+        <el-tabs @tab-change="handleTabChange">
             <el-tab-pane label="手动组卷">
                 <paper-by-hand />
             </el-tab-pane>
             <el-tab-pane label="智能组卷">
-                <paper-by-intelligent />
+                <paper-by-intelligent v-if="intelligentVisited" />
             </el-tab-pane>
         </el-tabs>
     </div>
@@ -17,6 +17,10 @@ import PaperByIntelligent from "@/views/dz/papers/components/paper-by-intelligen
 import {useProvideLoading} from "@/views/hooks/useLoading.js";
 
 const {loading} = useProvideLoading()
+
+// 延迟渲染,减少初次打开页面时的加载项
+const intelligentVisited = ref(false)
+const handleTabChange = () => intelligentVisited.value = true
 </script>
 
 <style scoped></style>