xiatian 3 年之前
父节点
当前提交
93e0554f91

+ 5 - 0
src/modules/questions/constants/constants.js

@@ -20,6 +20,11 @@ export const QUESTION_TYPES = [
   { value: "PARAGRAPH_MATCHING", label: "段落匹配" },
   { value: "BANKED_CLOZE", label: "选词填空" },
 ];
+export const QUESTION_MAIN_TYPES = [
+  { value: "BASICS", label: "基础题型" },
+  { value: "COMBINATION", label: "组合题型" },
+  { value: "SPECIAL", label: "特殊题型" },
+];
 export const PUBLICITY_LIST = [
   { label: "公开", value: true },
   { label: "非公开", value: false },

+ 8 - 0
src/modules/questions/filters/filters.js

@@ -3,6 +3,7 @@ import {
   QUESTION_TYPES,
   EXAM_TYPES,
   EXPORT_TYPES,
+  QUESTION_MAIN_TYPES,
 } from "../constants/constants";
 //option字母顺序过滤器
 Vue.filter("optionOrderWordFilter", function (value) {
@@ -16,6 +17,13 @@ Vue.filter("questionType", function (value) {
     }
   }
 });
+Vue.filter("questionMainType", function (value) {
+  for (let questionType of QUESTION_MAIN_TYPES) {
+    if (questionType.value === value) {
+      return questionType.label;
+    }
+  }
+});
 Vue.filter("examTypesFilter", function (value) {
   for (let item of EXAM_TYPES) {
     if (item.value === value) {

+ 12 - 6
src/modules/questions/routes/routes.js

@@ -30,7 +30,9 @@ import OrgProperty from "../views/OrgProperty.vue";
 import PaperPendingTrial from "../views/PaperPendingTrial.vue";
 import EditPaperPendingTrial from "../views/EditPaperPendingTrial.vue";
 import ExamPaperPendingTrial from "../views/ExamPaperPendingTrial.vue";
-import ClientConfig from "../views/ClientConfig.vue";
+import CheckDuplicateList from "../views/CheckDuplicateList.vue";
+import CheckDuplicateInfo from "../views/CheckDuplicateInfo.vue";
+
 export default [
   {
     path: "/questions", //首页
@@ -51,11 +53,6 @@ export default [
         name: "org_property", //学校管理
         component: OrgProperty,
       },
-      {
-        path: "client_config",
-        name: "client_config", //客户端管理
-        component: ClientConfig,
-      },
       {
         path: "user", //用户管理
         meta: { privilegeCodes: "index_user" },
@@ -136,6 +133,15 @@ export default [
         path: "question_list/:isClear", //试题列表
         component: Question,
       },
+      {
+        path: "check_duplicate_list/:isClear", //题库查重
+        component: CheckDuplicateList,
+      },
+      {
+        path: "check_duplicate_info", //题库查重审核
+        name: "check_duplicate_info",
+        component: CheckDuplicateInfo,
+      },
       {
         path: "edit_select_question/:id", //编辑选择题(单选、多选)
         component: EditSelectQuestion,

+ 234 - 0
src/modules/questions/views/CheckDuplicateInfo.vue

@@ -0,0 +1,234 @@
+<template>
+  <div v-loading="loading" style="background-color: white">
+    <div style="display: flex; justify-content: flex-end; margin-top: 10px">
+      <el-radio-group
+        v-model="duplicateQuestionIndex"
+        size="mini"
+        @change="selChange"
+      >
+        <el-radio-button
+          v-for="(city, index) in duplicateQuestions"
+          :key="index"
+          :label="index + 1"
+        ></el-radio-button>
+      </el-radio-group>
+    </div>
+    <div style="display: flex; gap: 10px; justify-content: space-between">
+      <div style="width: 49%">
+        <QuestionInfo :question="curQuestion"></QuestionInfo>
+      </div>
+      <div style="width: 49%">
+        <QuestionInfo :question="duplicateQuestion"></QuestionInfo>
+      </div>
+    </div>
+    <div
+      style="
+        display: flex;
+        justify-content: center;
+        margin-top: 10px;
+        margin-bottom: 10px;
+      "
+    >
+      <el-button type="primary" size="mini" @click="retain">保留</el-button>
+      <el-button type="danger" size="mini" @click="deleteQues">删除</el-button>
+      <el-button type="primary" size="mini" @click="ignore">跳过</el-button>
+      <el-button type="primary" size="mini" @click="back">返回</el-button>
+    </div>
+  </div>
+</template>
+<script>
+import { QUESTION_API } from "@/constants/constants";
+import { mapState } from "vuex";
+import QuestionInfo from "./QuestionInfo.vue";
+export default {
+  components: {
+    QuestionInfo,
+  },
+  data() {
+    return {
+      basePaperId: null,
+      loading: false,
+      ignoreIds: [],
+      from: "",
+      curQuestionId: null,
+      curQuestion: {},
+      duplicateQuestion: {},
+      duplicateQuestions: [],
+      duplicateQuestionIndex: 1,
+    };
+  },
+  computed: {
+    ...mapState({ user: (state) => state.user }),
+  },
+  watch: {},
+  //钩子函数
+  created() {
+    this.from = this.$route.params.from;
+    if ("question" == this.from) {
+      this.curQuestionId = this.$route.params.quesId;
+      this.queryData();
+    } else if ("list" == this.from) {
+      this.$http
+        .post(
+          QUESTION_API + "/question/duplicate/next",
+          new URLSearchParams({ ignoreIds: this.ignoreIds })
+        )
+        .then((response) => {
+          if (response.data) {
+            this.curQuestionId = response.data;
+            this.queryData();
+          } else {
+            this.$notify({
+              message: "没有需要处理的数据",
+              type: "success",
+            });
+          }
+        });
+    } else if ("paper" == this.from) {
+      this.basePaperId = this.$route.params.basePaperId;
+      this.$http
+        .post(
+          QUESTION_API + "/question/duplicate/next",
+          new URLSearchParams({
+            ignoreIds: this.ignoreIds,
+            basePaperId: this.basePaperId,
+          })
+        )
+        .then((response) => {
+          if (response.data) {
+            this.curQuestionId = response.data;
+            this.queryData();
+          } else {
+            this.$notify({
+              message: "没有需要处理的数据",
+              type: "success",
+            });
+          }
+        });
+    }
+  },
+  methods: {
+    next() {
+      this.$http
+        .post(
+          QUESTION_API + "/question/duplicate/next",
+          new URLSearchParams({
+            ignoreIds: this.ignoreIds,
+            basePaperId: this.basePaperId,
+          })
+        )
+        .then((response) => {
+          if (response.data) {
+            this.curQuestionId = response.data;
+            this.queryData();
+          } else {
+            this.$notify({
+              message: "当前已是最后一个",
+              type: "success",
+            });
+          }
+        });
+    },
+    ignore() {
+      if (this.from == "question") {
+        this.$router.push({
+          path: "/questions/check_duplicate_list/0",
+        });
+        return;
+      }
+      this.ignoreIds.push(this.curQuestionId);
+      this.$http
+        .post(
+          QUESTION_API + "/question/duplicate/next",
+          new URLSearchParams({
+            ignoreIds: this.ignoreIds,
+            basePaperId: this.basePaperId,
+          })
+        )
+        .then((response) => {
+          if (response.data) {
+            this.curQuestionId = response.data;
+            this.queryData();
+          } else {
+            this.$notify({
+              message: "当前已是最后一个",
+              type: "success",
+            });
+          }
+        });
+    },
+    back() {
+      if (this.from == "question" || this.from == "list") {
+        this.$router.push({
+          path: "/questions/check_duplicate_list/0",
+        });
+      }
+    },
+    deleteQues() {
+      this.$confirm("确认删除吗?", "提示", {
+        type: "warning",
+      }).then(() => {
+        let quesIds = [];
+        quesIds.push(this.curQuestionId);
+        this.$http
+          .post(
+            QUESTION_API + "/question/duplicate/delete",
+            new URLSearchParams({ questionIds: quesIds })
+          )
+          .then(() => {
+            this.$notify({
+              message: "删除成功",
+              type: "success",
+            });
+            if (this.from == "question") {
+              this.$router.push({
+                path: "/questions/check_duplicate_list/0",
+              });
+            } else if (this.from == "list") {
+              this.next();
+            }
+          });
+      });
+    },
+    retain() {
+      let quesIds = [];
+      quesIds.push(this.curQuestionId);
+      this.$http
+        .post(
+          QUESTION_API + "/question/duplicate/retain",
+          new URLSearchParams({ questionIds: quesIds })
+        )
+        .then(() => {
+          this.$notify({
+            message: "操作成功",
+            type: "success",
+          });
+          if (this.from == "question") {
+            this.$router.push({
+              path: "/questions/check_duplicate_list/0",
+            });
+          } else if (this.from == "list") {
+            this.next();
+          }
+        });
+    },
+    selChange(val) {
+      this.duplicateQuestion = this.duplicateQuestions[val - 1];
+    },
+    async queryData() {
+      this.$http
+        .get(
+          QUESTION_API + "/question/duplicate?questionId=" + this.curQuestionId
+        )
+        .then((response) => {
+          this.curQuestion = response.data.curQuestion;
+          this.duplicateQuestions = response.data.duplicateQuestions;
+          if (this.duplicateQuestions && this.duplicateQuestions.length > 0) {
+            this.duplicateQuestion = this.duplicateQuestions[0];
+          }
+        });
+    },
+  },
+};
+</script>
+<style scoped></style>

+ 687 - 0
src/modules/questions/views/CheckDuplicateList.vue

@@ -0,0 +1,687 @@
+<template>
+  <section class="content">
+    <!-- 正文信息 -->
+    <div class="box-body">
+      <el-form
+        :inline="true"
+        :model="formSearch"
+        label-position="right"
+        label-width="70px"
+      >
+        <el-row>
+          <el-col :span="6">
+            <el-form-item label="课程名称">
+              <el-select
+                v-model="formSearch.courseNo"
+                class="search_width"
+                filterable
+                :remote-method="getCourses"
+                remote
+                clearable
+                placeholder="请选择"
+                size="small"
+                @focus="(e) => getCourses(e.target.value)"
+              >
+                <el-option
+                  v-for="item in courseInfoSelect"
+                  :key="item.courseNo"
+                  :label="item.courseInfo"
+                  :value="item.courseNo"
+                >
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="试卷名称">
+              <el-select
+                v-model="formSearch.basePaperId"
+                class="search_width"
+                filterable
+                :remote-method="getPapers"
+                remote
+                clearable
+                placeholder="请选择"
+                size="small"
+                @focus="(e) => getPapers(e.target.value)"
+              >
+                <el-option
+                  v-for="item in paperList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+                >
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="题干">
+              <el-input
+                v-model="formSearch.quesBodyText"
+                class="search_width"
+                placeholder="题干"
+                size="small"
+              ></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="题型">
+              <el-select
+                v-model="formSearch.questionType"
+                class="search_width"
+                filterable
+                clearable
+                placeholder="请选择"
+                size="small"
+              >
+                <el-option
+                  v-for="item in questionTypes"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                >
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <div class="search_down">
+              <el-button size="small" type="primary" @click="searchFrom"
+                ><i class="el-icon-search"></i> 查询</el-button
+              >
+            </div>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-form-item>
+            <el-button size="mini" type="primary" plain @click="dispose"
+              >快速审核</el-button
+            >
+            <el-button
+              :disabled="noBatchSelected"
+              size="mini"
+              type="danger"
+              plain
+              @click="deleteQuestions"
+              >批量删除</el-button
+            >
+            <el-button
+              :disabled="noBatchSelected"
+              size="mini"
+              type="primary"
+              plain
+              @click="retainQuestions"
+              >批量保留</el-button
+            >
+          </el-form-item>
+        </el-row>
+      </el-form>
+      <div
+        style="width: 100%; border-bottom: 1px solid #ddd; margin: 10px 0"
+      ></div>
+      <!-- 页面列表 -->
+      <el-table
+        v-loading="loading"
+        :data="tableData"
+        border
+        @selection-change="selectChange"
+      >
+        <el-table-column type="selection" width="40"></el-table-column>
+        <el-table-column label="课程名称" width="180">
+          <template slot-scope="scope">
+            <span>{{ scope.row.course.name }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="试卷名称" width="180">
+          <template slot-scope="scope">
+            <span>{{ scope.row.basePaperName }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="题干">
+          <template slot-scope="scope">
+            <span
+              class="row_quesBody"
+              @click="prevViewQues(scope.row)"
+              v-html="scope.row.quesBody"
+            >
+            </span>
+          </template>
+        </el-table-column>
+        <el-table-column label="题型大类" width="100">
+          <template slot-scope="scope">
+            <span>{{ scope.row.quesMainType | questionMainType }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="题型小类" width="100">
+          <template slot-scope="scope">
+            <span>{{ scope.row.questionType | questionType }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="最高重复比率" width="120">
+          <template slot-scope="scope">
+            <span>{{ scope.row.maxRepetition }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="创建时间" width="100">
+          <template slot-scope="scope">
+            <span>{{ scope.row.creationDate }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="创建人" width="100">
+          <template slot-scope="scope">
+            <span>{{ scope.row.creator }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" width="195" fixed="right">
+          <template slot-scope="scope">
+            <div class="operate_left">
+              <el-button
+                size="mini"
+                type="primary"
+                plain
+                @click="info(scope.row)"
+              >
+                详情
+              </el-button>
+              <el-dropdown class="button_left">
+                <el-button type="primary" size="mini" plain>
+                  快速审核<i class="el-icon-arrow-down el-icon--right"></i>
+                </el-button>
+                <el-dropdown-menu slot="dropdown">
+                  <el-dropdown-item>
+                    <el-button
+                      size="mini"
+                      type="success"
+                      @click="retainQuestion(scope.row.id)"
+                    >
+                      保留
+                    </el-button>
+                  </el-dropdown-item>
+                  <el-dropdown-item>
+                    <el-button
+                      size="mini"
+                      type="danger"
+                      @click="deleteQuestion(scope.row.id)"
+                    >
+                      删除
+                    </el-button>
+                  </el-dropdown-item>
+                </el-dropdown-menu>
+              </el-dropdown>
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+      <!-- 分页栏 -->
+      <div class="page pull-right">
+        <el-pagination
+          :current-page="currentPage"
+          :page-size="pageSize"
+          :page-sizes="[10, 20, 50, 100, 200, 300]"
+          layout="total, sizes, prev, pager, next, jumper"
+          :total="total"
+          @current-change="handleCurrentChange"
+          @size-change="handleSizeChange"
+        >
+        </el-pagination>
+      </div>
+    </div>
+
+    <div class="text-left">
+      <el-dialog
+        title="试题预览"
+        :visible.sync="quesDialog"
+        @close="closeQuesDialog"
+      >
+        <el-form :model="quesModel" label-position="right" label-width="80px">
+          <el-row :gutter="10">
+            <el-col :xs="10" :sm="10" :md="10" :lg="10">
+              <el-form-item label="题型">
+                <el-select
+                  v-model="quesModel.questionType"
+                  :disabled="true"
+                  placeholder="题型"
+                >
+                  <el-option
+                    v-for="item in questionTypes"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="10">
+            <el-col :xs="30" :sm="30" :md="30" :lg="30">
+              <el-form-item label="题干">
+                <span class="ques-body" v-html="quesModel.quesBody"></span>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <!-- 非套题 -->
+          <div v-if="quesModel.questionType !== 'NESTED_ANSWER_QUESTION'">
+            <el-row
+              v-for="(quesOption, index) in quesModel.quesOptions"
+              :key="index"
+              :gutter="10"
+            >
+              <el-col :xs="30" :sm="30" :md="30" :lg="30">
+                <el-form-item :label="index | optionOrderWordFilter">
+                  <span class="ques-body" v-html="quesOption.optionBody"></span>
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </div>
+          <!-- 套题 -->
+          <div v-if="quesModel.questionType === 'NESTED_ANSWER_QUESTION'">
+            <el-row
+              v-for="subQuestionModel in quesModel.subQuestions"
+              :key="subQuestionModel"
+              :gutter="10"
+            >
+              <el-col :xs="30" :sm="30" :md="30" :lg="30">
+                <el-row>
+                  <el-form-item label="题目">
+                    <span v-html="subQuestionModel.quesBody"></span>
+                  </el-form-item>
+                </el-row>
+                <el-row
+                  v-for="(
+                    subQuesOption, subIndex
+                  ) in subQuestionModel.quesOptions"
+                  :key="subIndex"
+                  :gutter="10"
+                >
+                  <el-col :xs="30" :sm="30" :md="30" :lg="30">
+                    <el-form-item :label="subIndex | optionOrderWordFilter">
+                      <span v-html="subQuesOption.optionBody"></span>
+                    </el-form-item>
+                  </el-col>
+                </el-row>
+                <el-row>
+                  <el-form-item label="答案">
+                    <span v-html="subQuestionModel.quesAnswer"></span>
+                  </el-form-item>
+                </el-row>
+              </el-col>
+            </el-row>
+          </div>
+          <!-- 非套题答案 -->
+          <div v-if="quesModel.questionType !== 'NESTED_ANSWER_QUESTION'">
+            <el-form-item label="答案">
+              <span v-html="answer"></span>
+            </el-form-item>
+          </div>
+        </el-form>
+      </el-dialog>
+    </div>
+    <el-dialog title="提示" :visible.sync="deleteDialogVisible">
+      <span>{{ deleteInfo }}</span>
+      <span slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="deleteDialogVisible = false"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
+  </section>
+</template>
+<script>
+import { QUESTION_API } from "@/constants/constants";
+import { QUESTION_TYPES } from "../constants/constants";
+import { mapState } from "vuex";
+export default {
+  data() {
+    return {
+      selectedQuesIds: [],
+      formSearch: {
+        basePaperId: "",
+        quesBodyText: "",
+        questionType: "",
+        courseNo: "",
+        courseName: "",
+      },
+      paperList: [],
+      courseList: [], //课程list
+      tableData: [],
+      currentPage: 1,
+      pageSize: 10,
+      total: 10,
+      quesModel: {},
+      questionTypes: [],
+      quesDialog: false,
+      loading: false,
+      deleteDialogVisible: false,
+      deleteInfo: "",
+      singleRightAnswer: "", //接收单选答案
+      multipleRightAnswer: [], //接收多选答案
+      isClear: 0,
+    };
+  },
+  computed: {
+    ...mapState({ user: (state) => state.user }),
+    courseInfoSelect() {
+      var courseList = [];
+      for (let course of this.courseList) {
+        var courseInfo = course.name + "(" + course.code + ")";
+        var courseNo = course.code;
+        courseList.push({ courseNo: courseNo, courseInfo: courseInfo });
+      }
+      return courseList;
+    },
+    answer() {
+      if (this.quesModel.questionType == "SINGLE_ANSWER_QUESTION") {
+        return this.singleRightAnswer;
+      } else if (this.quesModel.questionType == "MULTIPLE_ANSWER_QUESTION") {
+        var obj = this.multipleRightAnswer;
+        return obj.sort().toString();
+      } else {
+        return this.quesModel.quesAnswer;
+      }
+    },
+    noBatchSelected() {
+      return this.selectedQuesIds.length === 0;
+    },
+  },
+  watch: {
+    $route: "initVue",
+  },
+  //钩子函数
+  created() {
+    var url =
+      QUESTION_API +
+      "/org/property/" +
+      this.user.rootOrgId +
+      "/ROOT_ORG_QUESTION_TYPES";
+    this.$http.get(url).then((response) => {
+      if (response.data && response.data.length > 0) {
+        this.questionTypes = QUESTION_TYPES.filter((m) =>
+          response.data.includes(m.value)
+        );
+      }
+    });
+    this.initVue();
+  },
+  methods: {
+    dispose() {
+      this.$router.push({
+        name: "check_duplicate_info",
+        params: {
+          from: "list",
+        },
+      });
+      sessionStorage.setItem("question", JSON.stringify(this.formSearch));
+      sessionStorage.setItem("question_currentPage", this.currentPage);
+    },
+    deleteQuestions() {
+      this.$confirm("确认删除吗?", "提示", {
+        type: "warning",
+      }).then(() => {
+        this.$http
+          .post(
+            QUESTION_API + "/question/duplicate/delete",
+            new URLSearchParams({ questionIds: this.selectedQuesIds })
+          )
+          .then(() => {
+            this.$notify({
+              message: "删除成功",
+              type: "success",
+            });
+            this.searchQues();
+          });
+      });
+    },
+    retainQuestions() {
+      this.$http
+        .post(
+          QUESTION_API + "/question/duplicate/retain",
+          new URLSearchParams({ questionIds: this.selectedQuesIds })
+        )
+        .then(() => {
+          this.$notify({
+            message: "操作成功",
+            type: "success",
+          });
+          this.searchQues();
+        });
+    },
+    deleteQuestion(id) {
+      this.$confirm("确认删除吗?", "提示", {
+        type: "warning",
+      }).then(() => {
+        let quesIds = [];
+        quesIds.push(id);
+        this.$http
+          .post(
+            QUESTION_API + "/question/duplicate/delete",
+            new URLSearchParams({ questionIds: quesIds })
+          )
+          .then(() => {
+            this.$notify({
+              message: "删除成功",
+              type: "success",
+            });
+            this.searchQues();
+          });
+      });
+    },
+    retainQuestion(id) {
+      let quesIds = [];
+      quesIds.push(id);
+      this.$http
+        .post(
+          QUESTION_API + "/question/duplicate/retain",
+          new URLSearchParams({ questionIds: quesIds })
+        )
+        .then(() => {
+          this.$notify({
+            message: "操作成功",
+            type: "success",
+          });
+          this.searchQues();
+        });
+    },
+    selectChange(row) {
+      this.selectedQuesIds = [];
+      row.forEach((element) => {
+        this.selectedQuesIds.push(element.id);
+      });
+    },
+    //查询列表
+    searchFrom() {
+      this.currentPage = 1;
+      this.searchQues();
+    },
+    searchQues() {
+      var pageNo = this.currentPage || 1;
+      this.currentPage = 1;
+      this.tableData = [];
+      var url =
+        QUESTION_API +
+        "/question/to_be_dispose/" +
+        pageNo +
+        "/" +
+        this.pageSize;
+      this.loading = true;
+      this.$http.get(url, { params: this.formSearch }).then((response) => {
+        this.tableData = response.data.content;
+        this.total = response.data.totalElements;
+        this.currentPage = pageNo;
+        this.loading = false;
+      });
+    },
+    //分页
+    handleCurrentChange(val) {
+      this.currentPage = val;
+      this.searchQues();
+    },
+    handleSizeChange(val) {
+      this.pageSize = val;
+      this.currentPage = 1;
+      this.searchQues();
+    },
+    getCourseName(courseNo) {
+      for (let course of this.courseList) {
+        if (course.code == courseNo) {
+          this.formSearch.courseName = course.name;
+        }
+      }
+    },
+    //修改
+    info(row) {
+      this.$router.push({
+        name: "check_duplicate_info",
+        params: {
+          quesId: row.id,
+          from: "question",
+        },
+      });
+      sessionStorage.setItem("question", JSON.stringify(this.formSearch));
+      sessionStorage.setItem("question_currentPage", this.currentPage);
+    },
+    //打开弹窗
+    openQuesDialog() {
+      this.quesDialog = true;
+    },
+    //关闭弹窗
+    closeQuesDialog() {
+      this.quesDialog = false;
+      this.quesModel = {};
+    },
+    //预览
+    prevViewQues(row) {
+      this.quesModel = row;
+      this.disposeSelectAnswer();
+      this.openQuesDialog();
+    },
+    //查询所有课程
+    getCourses(query) {
+      this.$http
+        .get(QUESTION_API + "/course/query?name=" + query + "&enable=true")
+        .then((response) => {
+          this.courseList = response.data;
+        });
+    },
+    getPapers(query) {
+      this.$http
+        .get(QUESTION_API + "/import_paper/to_be_dispose?name=" + query)
+        .then((response) => {
+          this.paperList = response.data;
+        });
+    },
+    //重置查询表单
+    resetSearchForm() {
+      this.formSearch = {
+        questionType: "",
+        courseNo: "",
+      };
+    },
+    /*处理选择题答案显示,处理套题下选择题答案显示*/
+    disposeSelectAnswer() {
+      this.singleRightAnswer = "";
+      this.multipleRightAnswer = [];
+      //处理选择题答案显示
+      if (
+        this.quesModel.questionType == "SINGLE_ANSWER_QUESTION" ||
+        this.quesModel.questionType == "MULTIPLE_ANSWER_QUESTION"
+      ) {
+        for (var i = 0; i < this.quesModel.quesOptions.length; i++) {
+          var option = this.quesModel.quesOptions[i];
+          var orderNum = String.fromCharCode(65 + i);
+          if (
+            this.quesModel.questionType == "SINGLE_ANSWER_QUESTION" &&
+            option.isCorrect == 1
+          ) {
+            this.singleRightAnswer = orderNum;
+          }
+          if (
+            this.quesModel.questionType == "MULTIPLE_ANSWER_QUESTION" &&
+            option.isCorrect == 1
+          ) {
+            this.multipleRightAnswer.push(orderNum);
+          }
+        }
+      }
+      //处理套题下选择题答案显示
+      if (this.quesModel.questionType == "NESTED_ANSWER_QUESTION") {
+        var subQuestions = this.quesModel.subQuestions;
+        for (var ii = 0; ii < subQuestions.length; ii++) {
+          var subQuestion = subQuestions[ii];
+          if (subQuestion.questionType == "SINGLE_ANSWER_QUESTION") {
+            for (var j = 0; j < subQuestion.quesOptions.length; j++) {
+              var option_j = subQuestion.quesOptions[j];
+              var orderNum_j = String.fromCharCode(65 + j);
+              if (option_j.isCorrect == 1) {
+                subQuestion["quesAnswer"] = orderNum_j;
+              }
+            }
+          }
+          if (subQuestion.questionType == "MULTIPLE_ANSWER_QUESTION") {
+            var subQuestionMultipleRightAnswer = [];
+            for (var k = 0; k < subQuestion.quesOptions.length; k++) {
+              var option2 = subQuestion.quesOptions[k];
+              var orderNum2 = String.fromCharCode(65 + k);
+              if (option2.isCorrect == 1) {
+                subQuestionMultipleRightAnswer.push(orderNum2);
+              }
+            }
+            subQuestion["quesAnswer"] = subQuestionMultipleRightAnswer
+              .sort()
+              .toString();
+          }
+        }
+      }
+    },
+    initVue() {
+      this.isClear = this.$route.params.isClear;
+      if (this.isClear == 0 || !this.isClear) {
+        sessionStorage.removeItem("question");
+        sessionStorage.removeItem("question_currentPage");
+        this.formSearch = {
+          questionType: "",
+          courseNo: "",
+          courseLevel: "",
+          courseName: "",
+          publicity: "",
+          coursePropertyName: "",
+          firstPropertyId: "",
+          secondPropertyId: "",
+        };
+        this.currentPage = 1;
+      } else {
+        this.formSearch = JSON.parse(sessionStorage.getItem("question"));
+        this.currentPage = parseInt(
+          sessionStorage.getItem("question_currentPage")
+        );
+      }
+      if (this.formSearch && this.formSearch.courseName) {
+        this.getCourses(this.formSearch.courseName);
+      } else {
+        this.formSearch = {
+          questionType: "",
+          courseNo: "",
+          courseLevel: "",
+          courseName: "",
+          publicity: "",
+          coursePropertyName: "",
+          firstPropertyId: "",
+          secondPropertyId: "",
+        };
+      }
+      this.searchQues();
+    },
+  },
+};
+</script>
+<style scoped>
+.select_width {
+  width: 150px;
+}
+.row_quesBody >>> p {
+  text-overflow: ellipsis;
+  overflow: hidden;
+}
+</style>
+<style scoped src="../styles/Common.css"></style>

+ 0 - 25
src/modules/questions/views/EditPaper.vue

@@ -46,15 +46,6 @@
               更多 <i class="el-icon-arrow-down el-icon--right"></i>
             </el-button>
             <el-dropdown-menu slot="dropdown">
-              <el-dropdown-item>
-                <el-button
-                  type="primary"
-                  :loading="duplicateLoading"
-                  size="small"
-                  @click="getreduplicateQuestions"
-                  ><i class="el-icon-zoom-in"></i>查重
-                </el-button>
-              </el-dropdown-item>
               <el-dropdown-item>
                 <el-button type="primary" size="small" @click="openDialog"
                   ><i class="el-icon-upload2"></i>上传音频
@@ -1245,7 +1236,6 @@ export default {
     this.paperId = this.$route.params.id;
     this.parentView = this.$route.params.parentView;
     this.initPaper();
-    this.getreduplicateQuestions();
     this.uploadAction = QUESTION_API + "/uploadRadio/" + this.paperId;
     this.uploadHeaders = {
       key: this.user.key,
@@ -2254,7 +2244,6 @@ export default {
               .delete(QUESTION_API + "/paperDetailUnit/" + paperDetailUnitId)
               .then(() => {
                 this.initPaper();
-                this.getreduplicateQuestions();
                 this.reduplicateGroup = [];
                 this.loading = true;
                 this.$notify({
@@ -2293,7 +2282,6 @@ export default {
                   });
                 } else {
                   this.initPaper();
-                  this.getreduplicateQuestions();
                   this.reduplicateGroup = [];
                   this.loading = true;
                   this.$notify({
@@ -2307,19 +2295,6 @@ export default {
         },
       });
     },
-    //获取重复试题
-    getreduplicateQuestions() {
-      this.duplicateLoading = true;
-      this.$http
-        .get(QUESTION_API + "/paper/" + this.paperId + "/reduplicate-questions")
-        .then((response) => {
-          this.reduplicateQuestions = response.data;
-          this.duplicateLoading = false;
-          this.initReduplicateQuesColor();
-          // var ques = document.getElementsByClassName("ques")[0];
-          // ques.style.display = "inline";
-        });
-    },
     exportPaperAnswer() {
       var key = this.user.key;
       var token = this.user.token;

+ 1 - 5
src/modules/questions/views/ImportPaper.vue

@@ -665,12 +665,8 @@ export default {
           },
           (error) => {
             var message = error.response.data.desc;
-            var err = message
-              .replace("[", "")
-              .replace("]", "")
-              .substring(message.indexOf("desc") + 4);
             this.$notify({
-              message: err,
+              message: message,
               type: "error",
             });
             this.loading = false;

+ 0 - 11
src/modules/questions/views/PaperPendingTrial.vue

@@ -402,17 +402,6 @@ export default {
     ...mapState({
       user: (state) => state.user,
     }),
-    paperIds() {
-      var paperIds = "";
-      for (let paperId of this.selectedPaperIds) {
-        if (!paperIds) {
-          paperIds += paperId;
-        } else {
-          paperIds += "," + paperId;
-        }
-      }
-      return paperIds;
-    },
     courseInfoSelect() {
       var courseList = [];
       for (let course of this.courseList) {

+ 154 - 0
src/modules/questions/views/QuestionInfo.vue

@@ -0,0 +1,154 @@
+<template>
+  <section class="content">
+    <div class="box-body">
+      <el-form :model="quesModel" label-position="right" label-width="80px">
+        <div style="border: 1px solid black">
+          <el-form-item label="题目">
+            <span v-html="quesModel.quesBody"></span>
+          </el-form-item>
+
+          <el-form-item
+            v-for="(quesOption, optIndex) in quesModel.quesOptions"
+            :key="optIndex"
+          >
+            <div style="display: flex; gap: 4px">
+              <span>{{ optIndex | optionOrderWordFilter }}:</span>
+              <span v-html="quesOption.optionBody"></span>
+            </div>
+          </el-form-item>
+
+          <el-form-item label="答案">
+            <span v-html="quesModel.quesAnswer"></span>
+          </el-form-item>
+        </div>
+        <div style="display: flex; border: 1px solid black">
+          <div
+            style="
+              flex: 2 1 auto;
+              border-right: 1px solid black;
+              padding-right: 20px;
+            "
+          >
+            <el-form-item label="题型">
+              <span>{{ quesModel.questionType | questionType }}</span>
+            </el-form-item>
+            <!-- <div style="display: flex"></div> -->
+            <div style="display: flex; justify-content: space-between">
+              <el-form-item label="预估难度">
+                <span>{{ quesModel.difficultyDegree || "-" }}</span>
+              </el-form-item>
+              <el-form-item label="计算难度">
+                <span>{{ quesModel.calculateDifficultyDegree || "-" }}</span>
+              </el-form-item>
+            </div>
+            <div style="display: flex; justify-content: space-between">
+              <el-form-item label="区分度">
+                <span>{{ quesModel.discrimination || "-" }}</span>
+              </el-form-item>
+              <el-form-item label="标准差">
+                <span>{{ quesModel.std || "-" }}</span>
+              </el-form-item>
+            </div>
+            <div style="display: flex; justify-content: space-between">
+              <el-form-item label="信度">
+                <span>{{ quesModel.reliability || "-" }}</span>
+              </el-form-item>
+              <el-form-item label="差异系数">
+                <span>{{ quesModel.cv || "-" }}</span>
+              </el-form-item>
+            </div>
+            <el-form-item label="平均分值">
+              <span>{{ quesModel.calculateAvgScore || "-" }}</span>
+            </el-form-item>
+          </div>
+
+          <div style="width: 35%">
+            <el-form-item label="属性列表">
+              <el-tooltip
+                v-for="(content, propIndex) in quesModel.quesProperties"
+                :key="propIndex"
+                placement="top"
+              >
+                <div slot="content">
+                  <span v-if="content.firstProperty != null"
+                    >一级属性:{{ content.firstProperty.name }}({{
+                      content.firstProperty.code
+                    }})</span
+                  ><br />
+                  <span v-if="content.secondProperty != null"
+                    >二级属性:{{ content.secondProperty.name }}({{
+                      content.secondProperty.code
+                    }})</span
+                  >
+                </div>
+                <span>
+                  <el-tag
+                    :key="content.id"
+                    style="margin-right: 5px"
+                    type="primary"
+                    size="mini"
+                  >
+                    {{ content.courseProperty.name }}
+                  </el-tag>
+                </span>
+              </el-tooltip>
+            </el-form-item>
+          </div>
+        </div>
+      </el-form>
+    </div>
+  </section>
+</template>
+<script>
+import { mapState } from "vuex";
+
+export default {
+  props: {
+    question: {
+      type: Object,
+      default: () => {},
+    },
+  },
+  data() {
+    return { quesModel: this.question };
+  },
+  computed: {
+    ...mapState({ user: (state) => state.user }),
+  },
+  watch: {
+    question: {
+      immediate: false,
+      handler(val) {
+        this.quesModel = val;
+      },
+    },
+  },
+  //初始化查询
+  created() {},
+  methods: {
+    isMatchingQuestion(questionType) {
+      if (
+        questionType == "PARAGRAPH_MATCHING" ||
+        questionType == "BANKED_CLOZE"
+      ) {
+        return true;
+      } else {
+        return false;
+      }
+    },
+    isNested(questionType) {
+      if (
+        questionType == "PARAGRAPH_MATCHING" ||
+        questionType == "BANKED_CLOZE" ||
+        questionType == "CLOZE" ||
+        questionType == "READING_COMPREHENSION" ||
+        questionType == "LISTENING_QUESTION"
+      ) {
+        return true;
+      } else {
+        return false;
+      }
+    },
+  },
+};
+</script>