|
@@ -0,0 +1,274 @@
|
|
|
+<template>
|
|
|
+ <div class="question-export-edit">
|
|
|
+ <el-dialog
|
|
|
+ custom-class="question-export-edit-dialog"
|
|
|
+ :visible.sync="modalIsShow"
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ :close-on-press-escape="false"
|
|
|
+ append-to-body
|
|
|
+ fullscreen
|
|
|
+ destroy-on-close
|
|
|
+ :show-close="false"
|
|
|
+ @open="visibleChange"
|
|
|
+ >
|
|
|
+ <div slot="title" class="box-justify">
|
|
|
+ <div>
|
|
|
+ <h2>文件上传</h2>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <el-button
|
|
|
+ size="small"
|
|
|
+ type="danger"
|
|
|
+ plain
|
|
|
+ icon="icon icon-back"
|
|
|
+ @click="cancel"
|
|
|
+ >返回</el-button
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="qe-body">
|
|
|
+ <div class="qe-part qe-part-edit">
|
|
|
+ <div class="qe-part-main">
|
|
|
+ <div class="qe-part-head">
|
|
|
+ <h3>题目编辑</h3>
|
|
|
+ <div>
|
|
|
+ <i class="icon icon-tips"></i>
|
|
|
+ 提示:若识别有误,可点击左侧题目按格式进行修改后重新识别
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="qe-part-body">
|
|
|
+ <v-editor v-model="paperRichJson"></v-editor>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="qe-part qe-part-view">
|
|
|
+ <div class="qe-part-main">
|
|
|
+ <div class="qe-part-head">
|
|
|
+ <h3>题目阅览</h3>
|
|
|
+ <div>
|
|
|
+ <el-button
|
|
|
+ size="small"
|
|
|
+ type="primary"
|
|
|
+ plain
|
|
|
+ icon="icon icon-export-answer"
|
|
|
+ @click="toImportAnswer"
|
|
|
+ >导入答案</el-button
|
|
|
+ >
|
|
|
+ <el-button
|
|
|
+ size="small"
|
|
|
+ type="primary"
|
|
|
+ plain
|
|
|
+ icon="icon icon-export-prop"
|
|
|
+ @click="toImportProp"
|
|
|
+ >导入属性</el-button
|
|
|
+ >
|
|
|
+ <el-button
|
|
|
+ size="small"
|
|
|
+ type="primary"
|
|
|
+ icon="icon icon-save-white"
|
|
|
+ @click="confirm"
|
|
|
+ >识别无误,加入题库</el-button
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="qe-part-body">
|
|
|
+ <question-import-paper-edit
|
|
|
+ ref="QuestionImportPaperEdit"
|
|
|
+ :key="questionKey"
|
|
|
+ :paper="paperData"
|
|
|
+ :course-id="data.courseId"
|
|
|
+ ></question-import-paper-edit>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="qe-middle">
|
|
|
+ <el-button
|
|
|
+ size="small"
|
|
|
+ type="primary"
|
|
|
+ :loading="loading"
|
|
|
+ @click="toParse"
|
|
|
+ >识别</el-button
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <!-- 上传答案文件 -->
|
|
|
+ <import-file-dialog
|
|
|
+ ref="ImportAnswerDialog"
|
|
|
+ dialog-title="导入答案"
|
|
|
+ :template-download-handle="answerTemplateDownload"
|
|
|
+ :upload-url="uploadAnswerUrl"
|
|
|
+ add-file-param="dataFile"
|
|
|
+ @uploaded="answerUploaded"
|
|
|
+ ></import-file-dialog>
|
|
|
+ <!-- 上传属性文件 -->
|
|
|
+ <import-file-dialog
|
|
|
+ ref="ImportPropDialog"
|
|
|
+ dialog-title="导入属性"
|
|
|
+ :template-download-handle="propTemplateDownload"
|
|
|
+ :upload-url="uploadPropUrl"
|
|
|
+ add-file-param="dataFile"
|
|
|
+ @uploaded="propUploaded"
|
|
|
+ ></import-file-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { deepCopy, randomCode } from "@/plugins/utils";
|
|
|
+import paperRichTextJson from "../datas/paperRichText.json";
|
|
|
+import QuestionImportPaperEdit from "./QuestionImportPaperEdit.vue";
|
|
|
+import { isAnEmptyRichText } from "@/utils/utils";
|
|
|
+import { questionImportPaperSave, questionImportParseRichText } from "../api";
|
|
|
+import ImportFileDialog from "@/components/ImportFileDialog.vue";
|
|
|
+import { QUESTION_API } from "@/constants/constants";
|
|
|
+
|
|
|
+const questionInfoField = [
|
|
|
+ "courseId",
|
|
|
+ "difficulty",
|
|
|
+ "quesProperties",
|
|
|
+ "score",
|
|
|
+ "publicity",
|
|
|
+ "control",
|
|
|
+ "quesAnswer",
|
|
|
+];
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: "QuestionExportEdit",
|
|
|
+ components: { QuestionImportPaperEdit, ImportFileDialog },
|
|
|
+ props: {
|
|
|
+ data: {
|
|
|
+ type: Object,
|
|
|
+ default() {
|
|
|
+ return {
|
|
|
+ paperRichText: { sections: [] },
|
|
|
+ paperData: [],
|
|
|
+ courseId: "",
|
|
|
+ };
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ modalIsShow: true,
|
|
|
+ loading: false,
|
|
|
+ paperData: [],
|
|
|
+ paperRichJson: paperRichTextJson,
|
|
|
+ // paperRichJson: { sections: [] },
|
|
|
+ // upload answer
|
|
|
+ uploadAnswerUrl: `${QUESTION_API}/paper/answer/import/`,
|
|
|
+ // upload prop
|
|
|
+ uploadPropUrl: `${QUESTION_API}/paper/answer/import/`,
|
|
|
+ };
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ visibleChange() {
|
|
|
+ this.paperRichJson = deepCopy(this.data.paperRichText);
|
|
|
+ this.paperData = deepCopy(this.data.paperData);
|
|
|
+ this.questionKey = randomCode();
|
|
|
+ },
|
|
|
+ cancel() {
|
|
|
+ this.modalIsShow = false;
|
|
|
+ },
|
|
|
+ open() {
|
|
|
+ this.modalIsShow = true;
|
|
|
+ },
|
|
|
+ async toParse() {
|
|
|
+ if (isAnEmptyRichText(this.paperRichJson)) {
|
|
|
+ this.$message.error("请输入试卷内容!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.loading) return;
|
|
|
+ this.loading = true;
|
|
|
+
|
|
|
+ const res = questionImportParseRichText(this.paperRichJson).catch(
|
|
|
+ () => {}
|
|
|
+ );
|
|
|
+ this.loading = false;
|
|
|
+ if (!res) return;
|
|
|
+
|
|
|
+ const cacheData = this.getCachePaperInfo(
|
|
|
+ this.paperData,
|
|
|
+ questionInfoField
|
|
|
+ );
|
|
|
+ this.paperData = this.assignCachePaperData(res.data, cacheData);
|
|
|
+ this.questionKey = randomCode();
|
|
|
+ },
|
|
|
+ getCachePaperInfo(paperData, cacheFields = []) {
|
|
|
+ let cachePaperInfo = {};
|
|
|
+ paperData.forEach((detail) => {
|
|
|
+ detail.questions.forEach((question) => {
|
|
|
+ let info = {};
|
|
|
+ let k = `${detail.number}_${question.number}`;
|
|
|
+ if (cacheFields.length) {
|
|
|
+ cacheFields.forEach((field) => {
|
|
|
+ info[field] = question[field];
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ info = { ...question };
|
|
|
+ }
|
|
|
+
|
|
|
+ cachePaperInfo[k] = info;
|
|
|
+ });
|
|
|
+ });
|
|
|
+ return cachePaperInfo;
|
|
|
+ },
|
|
|
+ assignCachePaperData(paperData, cacheData) {
|
|
|
+ paperData.forEach((detail) => {
|
|
|
+ detail.questions.forEach((question) => {
|
|
|
+ Object.assign(
|
|
|
+ question,
|
|
|
+ cacheData[`${detail.number}_${question.number}`] || {}
|
|
|
+ );
|
|
|
+ });
|
|
|
+ });
|
|
|
+ return paperData;
|
|
|
+ },
|
|
|
+ async confirm() {
|
|
|
+ const confirm = await this.$confirm("确认加入题库吗?", "提示", {
|
|
|
+ type: "warning",
|
|
|
+ }).catch(() => {});
|
|
|
+ if (confirm !== "confirm") return;
|
|
|
+
|
|
|
+ if (this.loading) return;
|
|
|
+ this.loading = true;
|
|
|
+
|
|
|
+ const paperData = this.$refs.QuestionImportPaperEdit.getData();
|
|
|
+ console.log(paperData);
|
|
|
+
|
|
|
+ const res = await questionImportPaperSave({
|
|
|
+ courseId: this.courseId,
|
|
|
+ paperData,
|
|
|
+ }).catch(() => {});
|
|
|
+
|
|
|
+ this.loading = false;
|
|
|
+ if (!res) return;
|
|
|
+
|
|
|
+ this.$message.success("提交成功!");
|
|
|
+ this.$emit("modified");
|
|
|
+ this.cancel();
|
|
|
+ },
|
|
|
+ // 导入答案
|
|
|
+ toImportAnswer() {
|
|
|
+ this.$refs.ImportAnswerDialog.open();
|
|
|
+ },
|
|
|
+ answerTemplateDownload() {},
|
|
|
+ answerUploaded(answerData) {
|
|
|
+ const cacheData = this.getCachePaperInfo(answerData, ["quesAnswer"]);
|
|
|
+ this.paperData = this.assignCachePaperData(this.paperData, cacheData);
|
|
|
+ this.questionKey = randomCode();
|
|
|
+ },
|
|
|
+ // 导入属性
|
|
|
+ toImportProp() {
|
|
|
+ this.$refs.ImportPropDialog.open();
|
|
|
+ },
|
|
|
+ propTemplateDownload() {},
|
|
|
+ propUploaded(propData) {
|
|
|
+ const cacheData = this.getCachePaperInfo(propData, ["quesProperties"]);
|
|
|
+ this.paperData = this.assignCachePaperData(this.paperData, cacheData);
|
|
|
+ this.questionKey = randomCode();
|
|
|
+ },
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|