| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- <template>
- <div class="app-container">
- <div class="flex flex-row justify-between items-center">
- <el-button icon="back" @click="router.back()">返回</el-button>
- <div class="flex-1 flex justify-center items-center">
- <el-text>{{ paperLocal.batchName }}</el-text>
- <el-input v-model="paperLocal.name" placeholder="输入试卷名称" class="ml-5" style="width: 220px"/>
- </div>
- <el-button type="primary" icon="select" @click="handleSavePaper">保存</el-button>
- </div>
- <el-divider/>
- <el-card v-for="(group, idx) in groupedQuestions" shadow="never" class="mb-5">
- <div :class="'drag_' + idx">
- <div slot="header" class="clearfix" @mouseover="showScore(group, idx)"
- @mouseout="hideScore(group, idx)" draggable="true"
- @dragstart="handleDragStart($event, group)"
- @dragover.prevent="handleDragOver($event, group)"
- @drop="handleDragEnter($event, group)" @dragend="handleDragEnd($event, group)">
- <el-text class="font-bold">
- {{ numberToChinese(idx + 1) }}、{{ group.title }}(共{{ group.num }}题;共{{ group.score }}分)
- </el-text>
- <span style="float: right; display: none" :id="'parent_score_' + idx">
- <el-button type="text" @click="openGroupScore=true,groupIdx=idx">批量设置得分</el-button>
- <el-button type="text" @click="deleteType(idx)">删除分类</el-button>
- </span>
- </div>
- <div v-for="(q, i) in group.list" class="mb-5"
- @mouseover="showQuestionScore(idx, i)" @mouseout="hideQuestionScore(idx, i)"
- @dragstart="handleQuestionDragStart($event, q, i)"
- @dragover.prevent="handleQuestionDragOver($event, q)"
- @drop="handleQuestionDragEnter($event, q, idx, i)"
- @dragend="handleQuestionDragEnd($event, q)" draggable="true">
- <div style="display: none" :id="'score_' + idx + '_' + i">
- <el-button type="text" @click="openScore=true,groupIdx=idx,qIdx=i">
- 设置得分
- </el-button>
- <el-button type="text" @click="showQuestionParse(q)">解析</el-button>
- <el-button type="text" @click="deleteQuestion(idx, i)">删除题目</el-button>
- </div>
- <div>
- {{ i + 1 }}.
- <span style="color: #1890ff">题号:{{ q.id }}({{ q.score }}分)</span><span
- v-html="q.title"></span>
- </div>
- </div>
- </div>
- </el-card>
- <!-- 批量设置分数-->
- <el-dialog v-model="openGroupScore" width="500px" append-to-body>
- <el-form label-width="80px">
- <el-form-item label="分数" prop="parentScore">
- <el-input-number v-model.number="groupScore" :min="1" placeholder="请输入分数"/>
- </el-form-item>
- </el-form>
- <div slot="footer" class="dialog-footer">
- <el-button type="primary" @click="setGroupScore">确 定</el-button>
- <el-button @click="openGroupScore=false">取 消</el-button>
- </div>
- </el-dialog>
- <!-- 设置题目分数 -->
- <el-dialog v-model="openScore" width="500px" append-to-body>
- <el-form label-width="80px">
- <el-form-item label="分数" prop="parentScore">
- <el-input-number v-model.number="qScore" :min="1" placeholder="请输入分数"/>
- </el-form-item>
- </el-form>
- <div slot="footer" class="dialog-footer">
- <el-button type="primary" @click="setScore">确 定</el-button>
- <el-button @click="openScore=false">取 消</el-button>
- </div>
- </el-dialog>
- <!-- 设置题目解析 -->
- <el-dialog v-model="openParse" title="解析" width="70%" append-to-body center>
- <el-form label-width="80px" id="paperDialog">
- <el-form-item label="解析">
- <editor v-model="parseCopy.parse" :min-height="122"/>
- </el-form-item>
- <el-form-item label="答案1">
- <editor v-model="parseCopy.answer1" :min-height="122"/>
- </el-form-item>
- <el-form-item label="答案2">
- <editor v-model="parseCopy.answer2" :min-height="122"/>
- </el-form-item>
- </el-form>
- <div slot="footer" class="dialog-footer">
- <el-button type="primary" @click="setQuestionParse">确 定</el-button>
- <el-button @click="openParse=false">取 消</el-button>
- </div>
- </el-dialog>
- </div>
- </template>
- <script setup name="PaperDetail">
- import {usePaperResolver} from "@/views/dz/papers/hooks/usePaperStorage.js";
- import router from "@/router/index.js";
- import {ElMessage} from "element-plus";
- import {buildPaperManual} from "@/api/dz/papers.js";
- const {paperLocal, groupedQuestions, toCommitPaper} = usePaperResolver()
- const chnNumChar = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
- const chnUnitSection = ["", "万", "亿", "万亿", "亿亿"];
- const chnUnitChar = ["", "十", "百", "千"];
- const groupIdx = ref(0)
- const qIdx = ref(0)
- const openGroupScore = ref(false)
- const openScore = ref(false)
- const groupScore = ref(1)
- const qScore = ref(1)
- const openParse = ref(false)
- const parseQuestion = ref(null)
- const parseCopy = ref(null)
- const sectionToChinese = function (section) {
- let strIns = "", chnStr = "";
- let unitPos = 0;
- let zero = true;
- while (section > 0) {
- const v = section % 10;
- if (v === 0) {
- if (!zero) {
- zero = true;
- chnStr = chnNumChar[v] + chnStr;
- }
- } else {
- zero = false;
- strIns = chnNumChar[v];
- strIns += chnUnitChar[unitPos];
- chnStr = strIns + chnStr;
- }
- unitPos++;
- section = Math.floor(section / 10);
- }
- return chnStr;
- }
- const numberToChinese = function (num) {
- let unitPos = 0;
- let strIns = "", chnStr = "";
- let needZero = false;
- if (num === 0) {
- return chnNumChar[0];
- }
- while (num > 0) {
- const section = num % 10000;
- if (needZero) {
- chnStr = chnNumChar[0] + chnStr;
- }
- strIns = sectionToChinese(section);
- strIns +=
- section !== 0 ? chnUnitSection[unitPos] : chnUnitSection[0];
- chnStr = strIns + chnStr;
- needZero = section < 1000 && section > 0;
- num = Math.floor(num / 10000);
- unitPos++;
- }
- return chnStr;
- }
- const showQuestionParse = function (q) {
- openParse.value = true
- parseQuestion.value = q
- parseCopy.value = {...q}
- }
- const setQuestionParse = function () {
- openParse.value = false
- const {parse, answer1, answer2} = parseCopy.value
- parseQuestion.value.parse = parse
- parseQuestion.value.answer1 = answer1
- parseQuestion.value.answer2 = answer2
- }
- const showScore = function (data, index) {
- const doc = document.getElementById("parent_score_" + index);
- doc.style.display = "block";
- }
- const hideScore = function (data, index) {
- const doc = document.getElementById("parent_score_" + index);
- doc.style.display = "none";
- }
- const setGroupScore = function () {
- const group = groupedQuestions.value[groupIdx.value];
- const len = group.list.length;
- group.score = len * groupScore.value;
- for (let q of group.list) {
- q.score = groupScore.value;
- }
- openGroupScore.value = false;
- }
- const setScore = function () {
- const group = groupedQuestions.value[groupIdx.value]
- const q = group.list[qIdx.value]
- q.score = qScore.value
- group.score = group.list.reduce((a, b) => a + b.score, 0)
- openScore.value = false
- }
- const showQuestionScore = function (gIdx, qIdx) {
- const doc = document.getElementById("score_" + gIdx + "_" + qIdx);
- doc.style.display = "block";
- }
- const hideQuestionScore = function (gIdx, qIdx) {
- const doc = document.getElementById("score_" + gIdx + "_" + qIdx);
- doc.style.display = "none";
- }
- const deleteType = function (gIdx) {
- groupedQuestions.value.splice(gIdx, 1);
- }
- const deleteQuestion = function (gIdx, qIdx) {
- const group = groupedQuestions.value[gIdx]
- group.list.splice(qIdx, 1)
- if (group.list.length) {
- group.num = group.list.length
- group.score = group.list.reduce((a, b) => a + b.score, 0)
- } else {
- groupedQuestions.value.splice(gIdx, 1)
- }
- }
- // 拖动组
- const draggingGroup = ref(null)
- const handleDragStart = function (e, group) {
- draggingGroup.value = group
- }
- const handleDragEnd = function (e, group) {
- draggingGroup.value = null;
- }
- const handleDragOver = function (e) {
- e.dataTransfer.dropEffect = "move"; // e.dataTransfer.dropEffect="move";//在dragenter中针对放置目标来设置!
- }
- const handleDragEnter = function (e, group) {
- e.dataTransfer.effectAllowed = "move"; //为需要移动的元素设置dragstart事件
- if (group === draggingGroup.value) {
- return;
- }
- const newItems = groupedQuestions.value;
- const src = newItems.indexOf(draggingGroup.value);
- const dst = newItems.indexOf(group);
- newItems.splice(dst, 0, ...newItems.splice(src, 1))
- }
- // 拖动题
- const draggingQuestion = ref(null)
- const draggingQIdx = ref(0)
- const handleQuestionDragStart = function (e, q, i) {
- draggingQuestion.value = q
- draggingQIdx.value = i
- }
- const handleQuestionDragEnd = function (e, q) {
- draggingQuestion.value = null
- draggingQIdx.value = null
- }
- const handleQuestionDragOver = function (e) {
- e.dataTransfer.dropEffect = "move"; // e.dataTransfer.dropEffect="move";//在dragenter中针对放置目标来设置!
- }
- const handleQuestionDragEnter = function (e, q, gIdx, qIdx) {
- e.dataTransfer.effectAllowed = "move"; //为需要移动的元素设置dragstart事件
- if (q === draggingQuestion.value && qIdx == draggingQIdx) {
- return;
- }
- const newItems = groupedQuestions.value[gIdx].list;
- const src = draggingQIdx.value;
- const dst = qIdx;
- newItems.splice(dst, 0, ...newItems.splice(src, 1));
- }
- const handleSavePaper = async function () {
- const commit = toCommitPaper()
- // validation
- if (!commit.name) return ElMessage.error('请填写试卷名称')
- if (!commit.questions?.length) return ElMessage.error('试卷至少包含1道试题')
- // save
- // TODO: 看看这个编辑有没有包含自动组卷的情况
- await buildPaperManual(commit)
- ElMessage.success('保存成功')
- }
- </script>
- <style scoped>
- </style>
|