Bladeren bron

feat: 评卷参数设置-主观题标答上传

zhangjie 3 maanden geleden
bovenliggende
commit
6643254c0e

+ 0 - 161
src/modules/mark/components/markParam/MarkParamClass.marker.vue

@@ -1,161 +0,0 @@
-<template>
-  <div class="mark-param-class">
-    <div class="part-box part-box-pad">
-      <el-table :data="classList" border>
-        <el-table-column type="index" width="50"> </el-table-column>
-
-        <el-table-column label="班级" width="200">
-          <template slot-scope="scope">
-            <el-tag size="medium">
-              {{ scope.row.className }}
-            </el-tag>
-          </template>
-        </el-table-column>
-        <el-table-column label="评阅题目" prop="groupQuestions">
-        </el-table-column>
-        <el-table-column label="评卷员">
-          <template slot-scope="scope">
-            <el-tag
-              v-for="item in scope.row.classMarkerList"
-              :key="item"
-              size="medium"
-              class="mb-1 mr-1"
-            >
-              {{ item.name }}({{ item.loginName }})
-            </el-tag>
-          </template>
-        </el-table-column>
-        <el-table-column class-name="action-column" label="操作" width="120">
-          <template slot-scope="scope">
-            <el-button
-              class="btn-primary"
-              type="text"
-              @click="toSelectMarker(scope.row)"
-              >选择评卷员</el-button
-            >
-          </template>
-        </el-table-column>
-      </el-table>
-    </div>
-
-    <!-- 选择评卷员 -->
-    <el-dialog
-      :visible.sync="modalIsShow"
-      title="选择评卷员"
-      top="10px"
-      width="600px"
-      :close-on-click-modal="false"
-      :close-on-press-escape="false"
-      append-to-body
-    >
-      <el-form ref="modalFormComp" :model="modalForm" :rules="rules">
-        <el-form-item prop="selectedMarkerIds">
-          <el-checkbox-group v-model="modalForm.selectedMarkerIds">
-            <el-checkbox
-              v-for="mark in curClass.markerList"
-              :key="mark.userId"
-              :label="mark.userId"
-            >
-              {{ mark.name }}({{ mark.loginName }})
-            </el-checkbox>
-          </el-checkbox-group>
-        </el-form-item>
-      </el-form>
-      <div slot="footer">
-        <el-button type="primary" :disabled="isSubmit" @click="conform"
-          >确认</el-button
-        >
-        <el-button @click="modalIsShow = false">取消</el-button>
-      </div>
-    </el-dialog>
-  </div>
-</template>
-
-<script>
-import { markClassList, markClassSave } from "../../api";
-import { mapState } from "vuex";
-
-export default {
-  name: "mark-param-class",
-  components: {},
-  data() {
-    return {
-      classList: [],
-      curClass: {},
-      // modify
-      modalIsShow: false,
-      isSubmit: false,
-      modalForm: { selectedMarkerIds: [] },
-      rules: {
-        selectedMarkerIds: [
-          {
-            required: true,
-            validator: (rule, value, callback) => {
-              if (!value.length) {
-                callback(new Error("请选择评卷员"));
-              } else {
-                callback();
-              }
-            },
-            trigger: "change",
-          },
-        ],
-      },
-    };
-  },
-  computed: {
-    ...mapState("markParam", ["basicInfo", "paperStructureInfo"]),
-  },
-  mounted() {
-    this.initData();
-  },
-  methods: {
-    async initData() {
-      const params = {
-        examId: this.basicInfo.examId,
-        paperNumber: this.basicInfo.paperNumber,
-      };
-      const res = await markClassList(params);
-      this.classList = res || [];
-    },
-    toSelectMarker(row) {
-      this.curClass = row;
-      this.modalForm.selectedMarkerIds = row.classMarkerList.map(
-        (item) => item.userId
-      );
-      this.modalIsShow = true;
-    },
-    async conform() {
-      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
-      if (!valid) return;
-
-      this.isSubmit = true;
-      const classMarkerList = this.curClass.markerList.filter((item) =>
-        this.modalForm.selectedMarkerIds.includes(item.userId)
-      );
-      const res = await markClassSave({
-        examId: this.basicInfo.examId,
-        paperNumber: this.basicInfo.paperNumber,
-        className: this.curClass.className,
-        groupNumber: this.curClass.groupNumber,
-        classMarkerList,
-      }).catch(() => {});
-      this.isSubmit = false;
-      if (!res) return;
-      this.$message.success("操作成功!");
-      this.curClass.classMarkerList = classMarkerList;
-      this.modalIsShow = false;
-    },
-    getData() {
-      return {
-        openClassReading: this.openClassReading,
-        classInfo: this.markerClassList.map((item) => {
-          let nitem = { ...item };
-          nitem.className = item.className.join();
-          return nitem;
-        }),
-      };
-    },
-  },
-};
-</script>

+ 9 - 1
src/modules/mark/components/markParam/MarkParamGroup.vue

@@ -87,6 +87,13 @@
           </template>
         </el-table-column>
       </el-table>
+
+      <!-- subjective answer -->
+      <el-form>
+        <el-form-item label="请上传标答PDF文档:">
+          <mark-param-subjective-answer></mark-param-subjective-answer>
+        </el-form-item>
+      </el-form>
     </div>
 
     <!-- ModifyMarkType -->
@@ -119,7 +126,7 @@ import { mapState, mapMutations } from "vuex";
 import ModifyMarkType from "./ModifyMarkType.vue";
 import ModifyMarkArea from "./ModifyMarkArea.vue";
 import ModifyMarkMarker from "./ModifyMarkMarker.vue";
-
+import MarkParamSubjectiveAnswer from "./MarkParamSubjectiveAnswer.vue";
 import {
   examStructureFindJpg,
   markSubjectiveBindMarker,
@@ -135,6 +142,7 @@ export default {
     ModifyMarkType,
     ModifyMarkArea,
     ModifyMarkMarker,
+    MarkParamSubjectiveAnswer,
   },
   data() {
     return {

+ 85 - 73
src/modules/mark/components/markParam/MarkParamSubjectiveAnswer.vue

@@ -1,46 +1,31 @@
 <template>
   <div class="mark-param-subjective-answer">
-    <div class="part-box part-box-pad">
-      <div>
-        <p class="tips-info">1.主观题标答请上传PDF文档;</p>
-        <p class="tips-info">
-          2.主观题标答文档上传后,在评卷界面小助手里可以打开进行查看,作为评卷参考;
-        </p>
-        <p class="tips-info">3.支持重复提交,以最后一次提交标答文件为准。</p>
-      </div>
-    </div>
-    <div class="part-box part-box-pad">
-      <el-form ref="modalFormComp" :model="infos" label-width="50px">
-        <div class="part-box">
-          <h3 class="mb-2">卷型{{ basicInfo.paperType }}</h3>
-          <el-form-item prop="file" label="标答:">
-            <select-file
-              :format="fileFormat"
-              :disabled="loading"
-              @file-change="fileChange"
-            ></select-file>
-            <p v-if="infos.errorMsg" class="tips-info tips-error">
-              {{ infos.errorMsg }}
-            </p>
-          </el-form-item>
-          <el-form-item v-if="answerFileUrl">
-            <span
-              class="cont-link"
-              title="点击查看已上传标答文件"
-              @click="toViewAnswer"
-            >
-              <i class="el-icon-document mr-1"></i>{{ answerFileName }}
-            </span>
-          </el-form-item>
-        </div>
-      </el-form>
-    </div>
-    <div class="text-center">
-      <el-button type="primary" :disabled="loading" @click="submit"
-        >确认</el-button
+    <el-form
+      v-for="item in subjectiveAnswerList"
+      :key="item.paperType"
+      label-width="50px"
+    >
+      <el-form-item
+        prop="file"
+        :label="`${item.paperType}卷:`"
+        :error="item.errorMsg"
       >
-      <el-button @click="cancel">取消</el-button>
-    </div>
+        <select-file
+          :format="fileFormat"
+          :disabled="item.loading"
+          @file-change="(data) => fileChange(data, item)"
+        ></select-file>
+      </el-form-item>
+      <el-form-item v-if="item.answerFileUrl">
+        <span
+          class="cont-link"
+          title="点击查看已上传标答文件"
+          @click="toViewAnswer(item)"
+        >
+          <i class="el-icon-document mr-1"></i>{{ item.answerFileName }}
+        </span>
+      </el-form-item>
+    </el-form>
 
     <!-- PreviewFile -->
     <preview-file ref="PreviewFile" :data="curFile"></preview-file>
@@ -48,7 +33,7 @@
 </template>
 
 <script>
-import { mapState } from "vuex";
+import { mapState, mapMutations } from "vuex";
 import {
   markSubjectiveQuestionList,
   markSubjectiveQuestionUpload,
@@ -62,10 +47,8 @@ export default {
   data() {
     return {
       modalIsShow: false,
-      loading: false,
-      infos: { file: null, md5: null, errorMsg: null },
       fileFormat: ["pdf"],
-      answerFileUrl: "",
+      subjectiveAnswerList: [],
       // preview file
       curFile: {
         url: "",
@@ -75,66 +58,95 @@ export default {
   },
   computed: {
     ...mapState("markParam", ["basicInfo"]),
-    answerFileName() {
-      return `${this.basicInfo.courseName}-标答文件`;
-    },
   },
   mounted() {
     this.initData();
   },
   methods: {
+    ...mapMutations("markParam", ["setSubjectiveAnswer"]),
     async initData() {
+      this.initSubjectiveAnswerList();
+
       const params = {
         examId: this.basicInfo.examId,
         paperNumber: this.basicInfo.paperNumber,
       };
       const res = await markSubjectiveQuestionList(params);
-      this.answerFileUrl = res || "";
+      (res || []).forEach((item, index) => {
+        this.subjectiveAnswerList[index].answerFileUrl = item;
+      });
+
+      this.updateSubjectiveAnswer();
+    },
+    initSubjectiveAnswerList() {
+      this.subjectiveAnswerList = this.basicInfo.paperType
+        .split(",")
+        .map((paperType) => {
+          return {
+            paperType,
+            answerFileUrl: "",
+            file: null,
+            md5: null,
+            errorMsg: null,
+            loading: false,
+            answerFileName: `${this.basicInfo.courseName}-${paperType}卷-标答文件`,
+          };
+        });
     },
-    toViewAnswer() {
-      // window.open(this.answerFileUrl);
+    toViewAnswer(item) {
       this.curFile = {
-        url: this.answerFileUrl,
+        url: item.answerFileUrl,
         type: "application/pdf",
       };
       this.$refs.PreviewFile.open();
     },
-    fileChange(data) {
+    fileChange(data, item) {
       if (data.errorMsg) {
-        this.infos.file = null;
-        this.infos.md5 = null;
-        this.infos.errorMsg = data.errorMsg;
+        item.file = null;
+        item.md5 = null;
+        item.errorMsg = data.errorMsg;
       } else {
-        this.infos.file = data.file;
-        this.infos.md5 = data.md5;
-        this.infos.errorMsg = null;
+        item.file = data.file;
+        item.md5 = data.md5;
+        item.errorMsg = null;
+        this.submit(item);
       }
     },
-    async submit() {
-      if (!this.infos.file) {
-        this.$message.error("请选择标答文件");
-        return;
-      }
-
-      if (this.loading) return;
-      this.loading = true;
+    async submit(item) {
+      if (item.loading) return;
+      item.loading = true;
 
-      let formData = new FormData();
+      const formData = new FormData();
       formData.append("examId", this.basicInfo.examId);
       formData.append("paperNumber", this.basicInfo.paperNumber);
-      formData.append(`file`, this.infos.file);
-      formData.append(`md5`, this.infos.md5);
-      const data = await markSubjectiveQuestionUpload(formData).catch(() => {});
-      this.loading = false;
+      formData.append(`file`, item.file);
+      formData.append(`md5`, item.md5);
+      formData.append(`paperType`, item.paperType);
+      const data = await markSubjectiveQuestionUpload(formData).catch(
+        (error) => {
+          item.errorMsg = error.message || "上传失败";
+        }
+      );
+      item.loading = false;
       if (!data) return;
 
-      this.answerFileUrl = data;
+      item.answerFileUrl = data;
       this.$message.success("上传成功!");
-      // this.$emit("confirm");
+      this.updateSubjectiveAnswer();
     },
     cancel() {
       this.$emit("cancel");
     },
+    updateSubjectiveAnswer() {
+      this.setSubjectiveAnswer(
+        this.subjectiveAnswerList.map((item) => {
+          return {
+            answerFileUrl: item.answerFileUrl,
+            paperType: item.paperType,
+          };
+        })
+      );
+    },
   },
 };
 </script>

+ 0 - 2
src/modules/mark/components/markParam/ModifyMarkParams.vue

@@ -55,7 +55,6 @@ import MarkParamStructure from "./MarkParamStructure.vue";
 import MarkParamGroup from "./MarkParamGroup.vue";
 import MarkParamClass from "./MarkParamClass.vue";
 import MarkParamObjectiveAnswer from "./MarkParamObjectiveAnswer.vue";
-import MarkParamSubjectiveAnswer from "./MarkParamSubjectiveAnswer.vue";
 import { markStructureList, markSubjectiveList } from "../../api";
 
 const steps = [
@@ -92,7 +91,6 @@ export default {
     MarkParamGroup,
     MarkParamClass,
     MarkParamObjectiveAnswer,
-    MarkParamSubjectiveAnswer,
   },
   props: {
     instance: {

+ 6 - 0
src/modules/mark/components/markParam/store.js

@@ -25,6 +25,8 @@ const state = {
   classInfo: [],
   // 客观题结构
   objectiveStructure: [],
+  // 主观题标答
+  subjectiveAnswer: [],
 };
 
 const mutations = {
@@ -67,6 +69,9 @@ const mutations = {
   setObjectiveAnswerInfo(state, objectiveAnswerInfo) {
     state.objectiveAnswerInfo = objectiveAnswerInfo;
   },
+  setSubjectiveAnswer(state, subjectiveAnswer) {
+    state.subjectiveAnswer = subjectiveAnswer;
+  },
   initStore(state) {
     state.basicInfo = {};
     state.structureCanEdit = false;
@@ -77,6 +82,7 @@ const mutations = {
     state.openDoubleMarking = false;
     state.classInfo = [];
     state.objectiveStructure = [];
+    state.subjectiveAnswer = [];
   },
 };