Преглед изворни кода

题库新页面代码提交

weiwenhai пре 6 година
родитељ
комит
1f6d6c3bdf

+ 57 - 0
src/modules/questions/component/reduplicate_mark.vue

@@ -0,0 +1,57 @@
+<style lang="css">
+.icon.reduplicate {
+  position: absolute;
+  left: -30px;
+  top: 20px;
+  transform: rotate(-45deg);
+}
+</style>
+<template>
+  <svg
+    @click="markCheck"
+    v-if="show"
+    class="icon reduplicate"
+    v-bind:style="{ fill: fillColor }"
+    width="50px"
+    height="26px"
+    viewBox="0 0 1984 1024"
+    version="1.1"
+    xmlns="http://www.w3.org/2000/svg"
+  >
+    <path
+      d="M0 1024 0 0l1984 0 0 1024L0 1024zM57.6 966.4l1868.8 0L1926.4 57.6 57.6 57.6 57.6 966.4z"
+    />
+    <path
+      d="M329.6 796.8l0-32 275.2 0 0-54.4-233.6 0 0-35.2 233.6 0 0-57.6-211.2 0 0-208 211.2 0 0-54.4-272 0 0-32 272 0L604.8 268.8l-230.4 0L374.4 233.6l320 0c6.4 0 12.8 0 19.2 0 60.8 0 124.8-6.4 188.8-22.4l0 38.4c-51.2 12.8-108.8 19.2-169.6 19.2-6.4 0-16 0-22.4 0l-41.6 0 0 51.2 278.4 0 0 32L672 352l0 54.4 214.4 0L886.4 544c0 25.6-3.2 44.8-16 57.6-9.6 12.8-28.8 16-48 16-3.2 0-6.4 0-9.6 0l-137.6 0 0 57.6 236.8 0 0 35.2L672 710.4l0 54.4 278.4 0 0 32L329.6 796.8zM672 585.6l115.2 0c0 0 3.2 0 6.4 0 12.8 0 19.2-3.2 25.6-9.6 6.4-6.4 9.6-16 6.4-28.8l0-19.2L672 528 672 585.6zM454.4 585.6l153.6 0 0-57.6-153.6 0L454.4 585.6zM672 499.2l153.6 0 0-57.6L672 441.6 672 499.2zM454.4 499.2l153.6 0 0-57.6-153.6 0L454.4 499.2z"
+    />
+    <path
+      d="M1049.6 790.4c92.8-16 166.4-28.8 227.2-41.6l9.6-3.2L1280 739.2c-41.6-19.2-83.2-44.8-124.8-76.8l0 0-3.2 0c-28.8 12.8-57.6 22.4-92.8 28.8l0-32c76.8-28.8 134.4-67.2 166.4-115.2l3.2-3.2-105.6 0 0-201.6L1120 339.2c-28.8 12.8-54.4 22.4-76.8 28.8l0-35.2c67.2-32 112-76.8 131.2-134.4l67.2 0c-6.4 16-9.6 28.8-16 38.4l-3.2 3.2 425.6 0 0 38.4L1193.6 278.4l0 0c-12.8 19.2-32 32-54.4 44.8l-9.6 6.4 464 0 0 134.4c0 25.6-6.4 44.8-16 57.6-12.8 12.8-32 19.2-57.6 19.2-3.2 0-3.2 0-6.4 0l-217.6 0 0 3.2c-3.2 9.6-9.6 19.2-22.4 32l-12.8 12.8 323.2 0 0 35.2c-54.4 51.2-108.8 92.8-166.4 118.4l-6.4 3.2 6.4 3.2c32 9.6 89.6 19.2 169.6 28.8 25.6 6.4 44.8 9.6 60.8 9.6l0 32c-131.2-16-230.4-32-300.8-57.6l0 0 0 0c-67.2 22.4-166.4 41.6-300.8 60.8L1046.4 790.4zM1225.6 652.8c48 28.8 89.6 51.2 124.8 67.2l0 0 0 0c54.4-22.4 102.4-54.4 144-92.8l6.4-6.4-278.4 0 0 0c-9.6 9.6-22.4 19.2-35.2 22.4l0 6.4L1225.6 649.6zM1184 505.6l310.4 0c0 0 3.2 0 3.2 0 0 0 0 0 0 0 9.6 0 19.2-3.2 22.4-9.6 6.4-6.4 9.6-16 6.4-28.8l0-16L1184 451.2 1184 505.6zM1184 422.4l345.6 0 0-54.4L1184 368 1184 422.4z"
+    />
+  </svg>
+</template>
+<script>
+export default {
+  props: {
+    id: {
+      type: String
+    },
+    show: {
+      type: Boolean,
+      default: false
+    },
+    fillColor: {
+      type: String,
+      default: "blue"
+    },
+    checked: {
+      type: Boolean,
+      default: false
+    }
+  },
+  methods: {
+    markCheck() {
+      this.$emit("reduplicate_mark_check", this.id, this.checked);
+    }
+  }
+};
+</script>

+ 4 - 4
src/modules/questions/constants/constants.js

@@ -34,26 +34,26 @@ Vue.filter("questionType", function(value) {
   }
 });
 
-export const examTypes = [
+export const EXAM_TYPES = [
   { value: "TRADITION", label: "传统考试" },
   { value: "ONLINE", label: "网络考试" },
   { value: "PRACTICE", label: "在线练习" }
 ];
 
-export const exportTypes = [
+export const EXPORT_TYPES = [
   { value: "ONLINE", label: "机考" },
   { value: "NORMAL", label: "普通" }
 ];
 
 Vue.filter("examTypesFilter", function(value) {
-  for (let item of examTypes) {
+  for (let item of EXAM_TYPES) {
     if (item.value === value) {
       return item.label;
     }
   }
 });
 Vue.filter("exportTypesFilter", function(value) {
-  for (let item of exportTypes) {
+  for (let item of EXPORT_TYPES) {
     if (item.value === value) {
       return item.label;
     }

+ 66 - 0
src/modules/questions/routes/routes.js

@@ -9,6 +9,16 @@ import CourseProperty from "../views/CourseProperty.vue";
 import PropertyInfo from "../views/PropertyInfo.vue";
 import ImportPaper from "../views/ImportPaper.vue";
 import GenPaper from "../views/GenPaper.vue";
+import ImportPaperInfo from "../views/ImportPaperInfo.vue";
+import GenPaperDetail from "../views/GenPaperDetail.vue";
+import ExtractPaperRule from "../views/ExtractPaperRule.vue";
+import ExtractPaperInfo from "../views/ExtractPaperInfo.vue";
+import ExportStructure from "../views/ExportStructure.vue";
+import Question from "../views/Question.vue";
+import EditSelectQuestion from "../views/EditSelectQuestion.vue";
+import EditOtherQuestion from "../views/EditOtherQuestion.vue";
+import InsertPaperTitle from "../views/InsertPaperTitle.vue";
+import EditPaper from "../views/EditPaper.vue";
 
 export default [
   {
@@ -55,6 +65,62 @@ export default [
       {
         path: "gen_paper/:isClear", //卷库试卷列表
         component: GenPaper
+      },
+      {
+        path: "edit_paper/:id/:parentView", //试卷编辑
+        component: EditPaper
+      },
+      {
+        path: "import_paper_info", //导入试卷页面
+        component: ImportPaperInfo
+      },
+      {
+        path: "gen_paper_detail/:courseNo/:level", //组卷页面
+        component: GenPaperDetail
+      },
+      {
+        path: "extract_paper_rule/:isClear", //调卷规则列表
+        component: ExtractPaperRule
+      },
+      {
+        path: "extract_paper_info_add", //调卷规则——新增
+        name: "extract_paper_info_add",
+        component: ExtractPaperInfo
+      },
+      {
+        path: "extract_paper_info_edit/:extractConfigId", //调卷规则——修改
+        name: "extract_paper_info_edit",
+        component: ExtractPaperInfo
+      },
+      {
+        path: "export_structure", //导出结构列表
+        component: ExportStructure
+      },
+      {
+        path: "question_list/:isClear", //试题列表
+        component: Question
+      },
+      {
+        path: "edit_select_question/:id", //编辑选择题(单选、多选)
+        component: EditSelectQuestion
+      },
+      {
+        path: "edit_other_question/:id", //编辑其他题(填空、问答)
+        component: EditOtherQuestion
+      },
+      {
+        path: "insert_paper_title", //添加试卷
+        component: InsertPaperTitle
+      },
+      {
+        path:
+          "edit_other_question/:paperId/:paperDetailId/:questionType/:courseNo/:courseName",
+        component: EditOtherQuestion
+      },
+      {
+        path:
+          "edit_select_question/:paperId/:paperDetailId/:questionType/:courseNo/:courseName",
+        component: EditSelectQuestion
       }
     ]
   }

+ 152 - 0
src/modules/questions/styles/EditPaper.css

@@ -0,0 +1,152 @@
+.red {
+  color: red;
+}
+.center {
+  margin: 0 auto 0 auto;
+  text-align: center;
+}
+h1 {
+  font-size: 16px;
+  font-family: "微软雅黑", serif;
+  font-weight: bold;
+}
+
+h3 {
+  font-size: 33px;
+  font-family: "微软雅黑", serif;
+  font-weight: bold;
+}
+h4 {
+  font-size: 21px;
+  font-family: "微软雅黑", serif;
+}
+span > p {
+  font-size: 16px;
+  font-family: "微软雅黑", serif;
+  text-align: left;
+  display: block;
+}
+.ques-title {
+  margin-right: 10px;
+}
+.mainQues {
+  margin-left: 3.5%;
+  text-align: left;
+}
+.mainQuesTitle {
+  font-size: 16px;
+  font-family: "微软雅黑", serif;
+  font-weight: bold;
+  margin-bottom: 20px;
+}
+.ques {
+  font-size: 16px;
+  font-family: "微软雅黑", serif;
+  text-align: left;
+  padding-left: 10px;
+  position: relative;
+}
+.subQues {
+  position: relative;
+  padding-left: 10px;
+}
+.quesBody {
+  display: flex;
+}
+.quesOption {
+  margin-top: 10px;
+  display: flex;
+}
+.quesSelect {
+  border: solid 1px #fff;
+}
+.quesSelect:hover {
+  border: solid 1px #99a9bf;
+}
+.text-left {
+  margin-left: 3.5%;
+  text-align: left;
+}
+
+.paper-title {
+  margin-right: 10px;
+  margin-bottom: 10px;
+}
+
+small {
+  font-size: 15px;
+  font-weight: bold;
+  margin-left: 10px;
+  margin-top: 20px;
+}
+.titlefont {
+  font-size: 14px;
+}
+.paper {
+  width: 80%;
+  margin: 0 auto;
+}
+.btnDiv {
+  height: 30px;
+  text-align: right;
+  position: relative;
+  right: 2px;
+  top: 1px;
+  visibility: hidden;
+}
+textarea {
+  width: 200px;
+}
+.paperName {
+  margin-top: 30px;
+  text-align: center;
+}
+.showContentBtn {
+  display: none;
+}
+.score-span {
+  width: 200px;
+}
+.edit-paper-top {
+  background: #eff2f7;
+  color: #000;
+  position: fixed;
+  left: 0;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  height: 60px;
+  line-height: 60px;
+  z-index: 100;
+  text-align: center;
+}
+.edit-paper-top-inline {
+  margin-left: 6%;
+}
+.paper-top-div {
+  float: left;
+  margin-left: 20px;
+  padding-left: 10px;
+}
+.paper-top-title {
+  font-size: 16px;
+  font-weight: bold;
+}
+.paper-top-value {
+  font-size: 16px;
+  padding: 3px 10px;
+}
+.paperName-input {
+  background-color: #eff2f7;
+  border: 1px solid #000;
+  border-top: 0;
+  border-left: 0;
+  border-right: 0;
+  box-sizing: border-box;
+  color: #1f2d3d;
+  font-size: inherit;
+  height: 20px;
+  padding: 2px 10px;
+  transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
+  outline: none;
+}

+ 512 - 0
src/modules/questions/views/EditOtherQuestion.vue

@@ -0,0 +1,512 @@
+<!-- 编辑填空,问答,判断题 -->
+<style></style>
+<template>
+  <section class="content" v-loading="fullscreenLoading">
+    <div class="box box-info">
+      <div class="box-header with-border">
+        <h3 class="box-title">
+          <span v-if="!quesModel.id">试题新增</span>
+          <span v-if="quesModel.id">试题修改</span>
+        </h3>
+      </div>
+      <div class="box-body">
+        <el-form
+          :model="quesModel"
+          ref="quesModel"
+          :rules="rules"
+          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
+                  :disabled="true"
+                  v-model="quesModel.questionType"
+                  placeholder="请输入题型"
+                >
+                  <el-option
+                    v-for="item in questionTypes"
+                    :label="item.label"
+                    :value="item.value"
+                    :key="item.value"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <!-- created by weiwenhai -->
+          <el-form-item label="难度">
+            <el-select
+              v-model="quesModel.difficultyDegree"
+              placeholder="请输入难度"
+            >
+              <el-option
+                v-for="item in difficultyDegreeList"
+                :label="item.label"
+                :value="item.value"
+                :key="item.value"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="公开度">
+            <el-select v-model="quesModel.publicity" placeholder="请输入公开度">
+              <el-option
+                v-for="item in publicityList"
+                :label="item.label"
+                :value="item.value"
+                :key="item.value"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="属性列表">
+            <el-tooltip
+              placement="top"
+              v-for="(content, index) in quesModel.quesProperties"
+              :key="index"
+            >
+              <div slot="content">
+                <span v-if="content.firstProperty != null"
+                  >一级属性:{{ content.firstProperty.name }}</span
+                ><br />
+                <span v-if="content.secondProperty != null"
+                  >二级属性:{{ content.secondProperty.name }}</span
+                >
+              </div>
+              <el-tag
+                style="margin-right:5px;"
+                :key="content.id"
+                closable
+                type="success"
+                @close="handleClose(content);"
+              >
+                {{ content.coursePropertyName }}
+              </el-tag>
+            </el-tooltip>
+          </el-form-item>
+          <el-row :gutter="20">
+            <el-col :xs="6" :sm="6" :md="6" :lg="6">
+              <el-form-item label="属性名">
+                <el-select
+                  v-model="coursePropertyName"
+                  placeholder="属性名"
+                  @change="searchFirst"
+                  class="property_with"
+                >
+                  <el-option
+                    v-for="item in coursePropertyList"
+                    :label="item.name"
+                    :value="item.name"
+                    :key="item.name"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :xs="6" :sm="6" :md="6" :lg="6">
+              <el-form-item label="一级">
+                <el-select
+                  v-model="firstPropertyId"
+                  placeholder="一级"
+                  @change="searchSecond"
+                  class="property_with"
+                >
+                  <el-option
+                    v-for="item in firstPropertyList"
+                    :label="item.name"
+                    :value="item.id"
+                    :key="item.id"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :xs="6" :sm="6" :md="6" :lg="6">
+              <el-form-item label="二级">
+                <el-select
+                  v-model="secondPropertyId"
+                  placeholder="二级"
+                  class="property_with"
+                >
+                  <el-option
+                    v-for="item in secondPropertyList"
+                    :label="item.name"
+                    :value="item.id"
+                    :key="item.id"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :xs="3" :sm="3" :md="3" :lg="3">
+              <el-form-item>
+                <el-button
+                  type="info"
+                  @click="insertProperty"
+                  style="margin-left:-30px;"
+                  >新增属性</el-button
+                >
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <!-- end -->
+          <el-row :gutter="10">
+            <el-col :xs="30" :sm="30" :md="30" :lg="30">
+              <el-form-item label="题干" prop="quesBody">
+                <ckeditor
+                  v-model="quesModel.quesBody"
+                  :height="'100px'"
+                ></ckeditor>
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <el-row
+            :gutter="10"
+            v-for="quesOption in quesModel.quesOptions"
+            :key="quesOption"
+          >
+            <el-col :xs="30" :sm="30" :md="30" :lg="30">
+              <el-form-item :label="quesOption.number">
+                <ckeditor
+                  v-model="quesOption.optionBody"
+                  :height="'50px'"
+                ></ckeditor>
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <!-- 非套题 -->
+          <div
+            v-if="
+              quesModel.questionType !== 'NESTED_ANSWER_QUESTION' &&
+                quesModel.questionType !== 'BOOL_ANSWER_QUESTION'
+            "
+          >
+            <el-form-item label="答案" prop="quesAnswer">
+              <ckeditor
+                v-model="quesModel.quesAnswer"
+                :height="'100px'"
+              ></ckeditor>
+            </el-form-item>
+          </div>
+          <div v-if="quesModel.questionType == 'BOOL_ANSWER_QUESTION'">
+            <el-row>
+              <el-col>
+                <el-form-item label="答案" prop="quesAnswer">
+                  <el-select
+                    v-model="quesModel.quesAnswer"
+                    placeholder="请选择"
+                  >
+                    <el-option
+                      v-for="op in options"
+                      :label="op"
+                      :value="op"
+                      :key="op"
+                    >
+                    </el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </div>
+          <div class="paper-top">
+            <el-form-item>
+              <el-button type="primary" @click="saveQues('quesModel');"
+                >保存</el-button
+              >
+              <el-button
+                type="primary"
+                icon="caret-left"
+                @click="backToQuesList();"
+                >返回列表</el-button
+              >
+            </el-form-item>
+          </div>
+        </el-form>
+      </div>
+    </div>
+  </section>
+</template>
+<script>
+import { CORE_API, QUESTION_TYPES } from "../constants/constants";
+import ckeditor from "../components/ckeditor.vue";
+export default {
+  components: { ckeditor },
+  data() {
+    return {
+      fullscreenLoading: false,
+      questionTypes: QUESTION_TYPES,
+      courseName: "",
+      courseNo: "",
+      paperDetailId: "",
+      paperId: "",
+      quesModel: {
+        courseName: "",
+        courseNo: "",
+        quesAnswer: "",
+        quesBody: "",
+        questionType: "",
+        difficultyDegree: "",
+        publicity: true,
+        quesProperties: [],
+        score: 0
+      },
+      options: ["正确", "错误"],
+      difficultyDegreeList: [
+        { label: 0.1, value: 0.1 },
+        { label: 0.2, value: 0.2 },
+        { label: 0.3, value: 0.3 },
+        { label: 0.4, value: 0.4 },
+        { label: 0.5, value: 0.5 },
+        { label: 0.6, value: 0.6 },
+        { label: 0.7, value: 0.7 },
+        { label: 0.8, value: 0.8 },
+        { label: 0.9, value: 0.9 },
+        { label: 1.0, value: 1.0 }
+      ],
+      publicityList: [
+        { label: "公开", value: true },
+        { label: "非公开", value: false }
+      ],
+      coursePropertyList: [],
+      coursePropertyName: "", //课程属性名
+      firstPropertyList: [], //一级属性集合
+      firstPropertyId: "", //一级属性id
+      secondPropertyList: [], //二级属性集合
+      secondPropertyId: "", //二级属性id
+      //验证
+      rules: {
+        // quesBody: [
+        //     {required: true, message: '请输入题干', trigger: 'blur'}
+        // ],
+        quesAnswer: [{ required: true, message: "请输入答案", trigger: "blur" }]
+      }
+    };
+  },
+  methods: {
+    saveQues(formName) {
+      if (!this.quesModel.difficultyDegree) {
+        this.$notify({
+          message: "请选择试题难度",
+          type: "error"
+        });
+        return false;
+      }
+      this.$refs[formName].validate(valid => {
+        if (valid) {
+          if (this.questionId) {
+            this.fullscreenLoading = true;
+            //修改逻辑
+            this.$http.put(CORE_API + "/question", this.quesModel).then(() => {
+              this.$notify({
+                message: "保存成功",
+                type: "success"
+              });
+              this.fullscreenLoading = false;
+            });
+          } else {
+            //新增逻辑
+            this.quesModel.courseNo = this.courseNo;
+            this.quesModel.courseName = this.courseName;
+            this.fullscreenLoading = true;
+            this.$http
+              .post(
+                CORE_API +
+                  "/paper/addQuestion/" +
+                  this.paperId +
+                  "/" +
+                  this.paperDetailId,
+                this.quesModel
+              )
+              .then(() => {
+                this.fullscreenLoading = false;
+                this.$notify({
+                  type: "info",
+                  message: `保存成功`
+                });
+                this.$router.push({ path: "/questions/question_list/0" });
+              })
+              .catch(() => {
+                this.fullscreenLoading = false;
+                console.log("添加失败");
+              });
+          }
+        } else {
+          return false;
+        }
+      });
+    },
+    getQues(id) {
+      this.$http.get(CORE_API + "/question/" + id).then(response => {
+        this.quesModel = response.body;
+        this.initCourseProperty();
+      });
+    },
+    backToQuesList() {
+      this.$router.push({
+        path: "/questions/question_list/0"
+      });
+    },
+    //查询所有课程属性名
+    initCourseProperty() {
+      console.log(this.quesModel);
+      var code = this.quesModel.course.code;
+      this.$http
+        .get(CORE_API + "/courseProperty/code/" + code)
+        .then(response => {
+          this.coursePropertyList = response.body;
+        });
+    },
+    //查询一级属性
+    searchFirst() {
+      this.firstPropertyId = "";
+      this.secondPropertyId = "";
+      this.secondPropertyList = [];
+      for (let courseProperty of this.coursePropertyList) {
+        if (courseProperty.name == this.coursePropertyName) {
+          this.$http
+            .get(CORE_API + "/property/first/" + courseProperty.id)
+            .then(response => {
+              this.firstPropertyList = response.body;
+            });
+        }
+      }
+    },
+    //查询二级属性
+    searchSecond() {
+      this.secondPropertyId = "";
+      this.$http
+        .get(CORE_API + "/property/second/" + this.firstPropertyId)
+        .then(response => {
+          this.secondPropertyList = response.body;
+        });
+    },
+    //新增属性
+    insertProperty() {
+      if (!this.checkInsertPro()) {
+        return false;
+      }
+      var quesProperty = {
+        id: "",
+        coursePropertyName: "",
+        firstProperty: {},
+        secondProperty: {}
+      };
+      if (
+        this.quesModel.quesProperties === undefined ||
+        this.quesModel.quesProperties.length == 0
+      ) {
+        this.quesModel.quesProperties = [];
+      }
+      quesProperty.id =
+        this.coursePropertyName +
+        "-" +
+        this.firstPropertyId +
+        "-" +
+        this.secondPropertyId;
+      for (let quesPro of this.quesModel.quesProperties) {
+        if (quesPro.id == quesProperty.id) {
+          this.$notify({
+            message: "该属性已存在,请重新选择",
+            type: "error"
+          });
+          return false;
+        }
+      }
+      quesProperty.coursePropertyName = this.coursePropertyName;
+      //取到一级属性对象
+      for (let property of this.firstPropertyList) {
+        if (property.id == this.firstPropertyId) {
+          quesProperty.firstProperty = property;
+        }
+      }
+      //判断是否有二级属性
+      if (
+        this.secondPropertyList != undefined &&
+        this.secondPropertyList.length > 0
+      ) {
+        if (!this.secondPropertyId) {
+          this.$notify({
+            message: "请选择二级属性",
+            type: "error"
+          });
+          return false;
+        }
+      }
+      //取到二级属性对象
+      for (let property of this.secondPropertyList) {
+        if (property.id == this.secondPropertyId) {
+          quesProperty.secondProperty = property;
+        }
+      }
+      this.quesModel.quesProperties.push(quesProperty);
+      this.quesModel = Object.assign({}, this.quesModel);
+      console.log(
+        "this.quesModel.quesProperties:",
+        this.quesModel.quesProperties
+      );
+      //清空下拉框
+      this.coursePropertyName = "";
+      this.firstPropertyId = "";
+      this.secondPropertyId = "";
+      this.firstPropertyList = [];
+      this.secondPropertyList = [];
+    },
+    //删除属性
+    handleClose(tag) {
+      console.log("tag:", tag);
+      this.quesModel.quesProperties.splice(
+        this.quesModel.quesProperties.indexOf(tag),
+        1
+      );
+      this.quesModel = Object.assign({}, this.quesModel);
+    },
+    //新增属性验证
+    checkInsertPro() {
+      if (!this.coursePropertyName) {
+        this.$notify({
+          message: "请选择属性",
+          type: "error"
+        });
+        return false;
+      }
+      if (!this.firstPropertyId) {
+        this.$notify({
+          message: "请选择一级属性",
+          type: "error"
+        });
+        return false;
+      }
+      return true;
+    }
+  },
+  computed: {},
+  created() {
+    this.paperId = this.$route.params.paperId;
+    this.paperDetailId = this.$route.params.paperDetailId;
+    this.courseName = this.$route.params.courseName;
+    this.courseNo = this.$route.params.courseNo;
+    let questionType = this.$route.params.questionType;
+    if (questionType) {
+      this.quesModel.questionType = questionType;
+    }
+    this.questionId = this.$route.params.id;
+    if (this.questionId) {
+      this.quesModel["id"] = this.questionId;
+      this.getQues(this.questionId);
+    }
+    if (this.courseNo) {
+      this.$http
+        .get(CORE_API + "/courseProperty/enable/" + this.courseNo)
+        .then(response => {
+          this.coursePropertyList = response.body;
+        });
+    }
+  },
+  mounted() {}
+};
+</script>

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


+ 626 - 0
src/modules/questions/views/EditSelectQuestion.vue

@@ -0,0 +1,626 @@
+<template>
+  <div v-loading="fullscreenLoading">
+    <section class="content">
+      <div class="box box-info">
+        <!-- 头信息 -->
+        <div class="box-header with-border">
+          <h3 class="box-title">
+            <span v-if="!quesModel.id">试题新增</span>
+            <span v-if="quesModel.id">试题修改</span>
+          </h3>
+        </div>
+        <!-- 正文信息 -->
+        <div class="box-body">
+          <el-form
+            :model="quesModel"
+            ref="quesModel"
+            :rules="rules"
+            label-width="100px"
+            class="demo-ruleForm"
+            label-position="right"
+          >
+            <el-form-item label="题型">
+              <el-select
+                :disabled="true"
+                v-model="quesModel.questionType"
+                placeholder="请输入题型"
+              >
+                <el-option
+                  v-for="item in questionTypes"
+                  :label="item.label"
+                  :value="item.value"
+                  :key="item.value"
+                >
+                </el-option>
+              </el-select>
+            </el-form-item>
+            <!--
+              <el-form-item label="分数">
+                  <el-input placeholder="分数" v-model="quesModel.score" style="width:50px;"></el-input>
+              </el-form-item>
+            -->
+            <!-- created by weiwenhai -->
+            <el-form-item label="难度">
+              <el-select
+                v-model="quesModel.difficultyDegree"
+                placeholder="请输入难度"
+              >
+                <el-option
+                  v-for="item in difficultyDegreeList"
+                  :label="item.label"
+                  :value="item.value"
+                  :key="item.value"
+                >
+                </el-option>
+              </el-select>
+            </el-form-item>
+            <el-form-item label="公开度">
+              <el-select
+                v-model="quesModel.publicity"
+                placeholder="请输入公开度"
+              >
+                <el-option
+                  v-for="item in publicityList"
+                  :label="item.label"
+                  :value="item.value"
+                  :key="item.value"
+                >
+                </el-option>
+              </el-select>
+            </el-form-item>
+            <el-form-item label="属性列表">
+              <el-tooltip
+                placement="top"
+                v-for="(content, index) in quesModel.quesProperties"
+                :key="index"
+              >
+                <div slot="content">
+                  <span v-if="content.firstProperty != null"
+                    >一级属性:{{ content.firstProperty.name }}</span
+                  ><br />
+                  <span v-if="content.secondProperty != null"
+                    >二级属性:{{ content.secondProperty.name }}</span
+                  >
+                </div>
+                <el-tag
+                  style="margin-right:5px;"
+                  :key="content.id"
+                  closable
+                  type="success"
+                  @close="handleClose(content);"
+                >
+                  {{ content.coursePropertyName }}
+                </el-tag>
+              </el-tooltip>
+            </el-form-item>
+            <el-row :gutter="20">
+              <el-col :xs="6" :sm="6" :md="6" :lg="6">
+                <el-form-item label="属性名">
+                  <el-select
+                    v-model="coursePropertyName"
+                    placeholder="属性名"
+                    @change="searchFirst"
+                    class="property_with"
+                  >
+                    <el-option
+                      v-for="item in coursePropertyList"
+                      :label="item.name"
+                      :value="item.name"
+                      :key="item.name"
+                    >
+                    </el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :xs="6" :sm="6" :md="6" :lg="6">
+                <el-form-item label="一级">
+                  <el-select
+                    v-model="firstPropertyId"
+                    placeholder="一级"
+                    @change="searchSecond"
+                    class="property_with"
+                  >
+                    <el-option
+                      v-for="item in firstPropertyList"
+                      :label="item.name"
+                      :value="item.id"
+                      :key="item.id"
+                    >
+                    </el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :xs="6" :sm="6" :md="6" :lg="6">
+                <el-form-item label="二级">
+                  <el-select
+                    v-model="secondPropertyId"
+                    placeholder="二级"
+                    class="property_with"
+                  >
+                    <el-option
+                      v-for="item in secondPropertyList"
+                      :label="item.name"
+                      :value="item.id"
+                      :key="item.id"
+                    >
+                    </el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :xs="3" :sm="3" :md="3" :lg="3">
+                <el-form-item>
+                  <el-button
+                    type="info"
+                    @click="insertProperty"
+                    style="margin-left:-30px;"
+                    >新增属性</el-button
+                  >
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <!-- end -->
+            <el-form-item label="题干" prop="quesBody">
+              <ckeditor
+                v-model="quesModel.quesBody"
+                :height="'100px'"
+              ></ckeditor>
+            </el-form-item>
+            <el-form-item
+              v-for="(option, index) in quesModel.quesOptions"
+              :key="option.number"
+            >
+              <el-col :span="1">
+                <el-radio
+                  v-model="singleRightAnswer"
+                  :label="index | optionOrderWordFilter"
+                  v-if="quesModel.questionType === 'SINGLE_ANSWER_QUESTION'"
+                ></el-radio>
+                <el-checkbox
+                  v-model="multipleRightAnswer"
+                  :label="index | optionOrderWordFilter"
+                  v-if="quesModel.questionType === 'MULTIPLE_ANSWER_QUESTION'"
+                ></el-checkbox>
+              </el-col>
+              <el-col :span="20">
+                <ckeditor v-model="option.optionBody"></ckeditor>
+              </el-col>
+              <el-col :span="2">
+                <i
+                  class="el-icon-delete"
+                  @click.prevent="removeQuesOption(option);"
+                  title="删除"
+                ></i>
+              </el-col>
+            </el-form-item>
+            <el-form-item label="答案">
+              <el-col> <span v-html="answer"></span> </el-col>
+            </el-form-item>
+            <el-form-item>
+              <el-button type="primary" icon="plus" @click="addQuesOption"
+                >新增选项</el-button
+              >
+              <el-button
+                type="primary"
+                icon="check"
+                @click="submitForm('quesModel');"
+                :disabled="saveDisabled"
+                >保存</el-button
+              >
+              <el-button
+                type="primary"
+                icon="caret-left"
+                @click="backToQuesList();"
+                >返回列表</el-button
+              >
+            </el-form-item>
+          </el-form>
+        </div>
+      </div>
+    </section>
+  </div>
+</template>
+<script>
+import { Q_API, QUESTION_TYPES } from "../constants/constants";
+import ckeditor from "../components/ckeditor.vue";
+export default {
+  components: { ckeditor },
+  data() {
+    return {
+      questionTypes: QUESTION_TYPES,
+      fullscreenLoading: false,
+      paperId: "",
+      paperDetailId: "",
+      questionId: "",
+      quesModel: {
+        quesBody: "",
+        quesOptions: [],
+        quesAnswer: "",
+        questionType: "",
+        courseName: "",
+        courseNo: "",
+        difficultyDegree: "",
+        publicity: true,
+        quesProperties: [],
+        score: 1
+      },
+      difficultyDegreeList: [
+        { label: 0.1, value: 0.1 },
+        { label: 0.2, value: 0.2 },
+        { label: 0.3, value: 0.3 },
+        { label: 0.4, value: 0.4 },
+        { label: 0.5, value: 0.5 },
+        { label: 0.6, value: 0.6 },
+        { label: 0.7, value: 0.7 },
+        { label: 0.8, value: 0.8 },
+        { label: 0.9, value: 0.9 },
+        { label: 1.0, value: 1.0 }
+      ],
+      publicityList: [
+        { label: "公开", value: true },
+        { label: "非公开", value: false }
+      ],
+      coursePropertyList: [],
+      coursePropertyName: "", //课程属性名
+      firstPropertyList: [], //一级属性集合
+      firstPropertyId: "", //一级属性id
+      secondPropertyList: [], //二级属性集合
+      secondPropertyId: "", //二级属性id
+      //验证
+      rules: {
+        // quesBody: [
+        //     { required: true, message: '请输入题干', trigger: 'blur'}
+        // ]
+      },
+      singleRightAnswer: "", //接收单选答案
+      multipleRightAnswer: [] //接收多选答案
+    };
+  },
+  methods: {
+    findQuestionById(questionId) {
+      this.$http.get(Q_API + "/question/" + questionId).then(response => {
+        this.quesModel = response.body;
+        if (this.quesModel.quesOptions) {
+          for (var i = 0; i < this.quesModel.quesOptions.length; i++) {
+            var option = this.quesModel.quesOptions[i];
+            if (
+              this.quesModel.questionType == "SINGLE_ANSWER_QUESTION" &&
+              option.isCorrect == 1
+            ) {
+              this.singleRightAnswer = String.fromCharCode(65 + i);
+            }
+            if (
+              this.quesModel.questionType == "MULTIPLE_ANSWER_QUESTION" &&
+              option.isCorrect == 1
+            ) {
+              this.multipleRightAnswer.push(String.fromCharCode(65 + i));
+            }
+          }
+        }
+        this.initCourseProperty();
+      });
+    },
+    submitForm(formName) {
+      this.$refs[formName].validate(valid => {
+        if (valid) {
+          this.setRightAnswer();
+          if (this.questionId) {
+            this.editQuestion();
+          } else {
+            this.saveNewQuestion();
+          }
+        } else {
+          return false;
+        }
+      });
+    },
+    //修改试题
+    editQuestion() {
+      if (this.quesModel.quesOptions.length == 0) {
+        this.$confirm("无选项将删除该试题, 是否继续?", "提示", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        })
+          .then(() => {
+            this.fullscreenLoading = true;
+            this.$http
+              .delete(Q_API + "/paper/deleteQuestion/" + this.quesModel.id)
+              .then(response => {
+                if (response.body.length > 0) {
+                  this.deleteInfo =
+                    "该试题被试卷:" +
+                    response.body.join(" , ") +
+                    "使用,不能删除";
+                  this.deleteDialogVisible = true;
+                } else {
+                  this.$notify({
+                    message: "删除成功",
+                    type: "success"
+                  });
+                  this.$router.push({ path: "/questions/question_list/0" });
+                }
+              });
+          })
+          .catch(() => {});
+      } else {
+        this.fullscreenLoading = true;
+        this.$http.put(Q_API + "/question", this.quesModel).then(() => {
+          this.$notify({
+            message: "保存成功",
+            type: "success"
+          });
+          this.fullscreenLoading = false;
+        });
+      }
+    },
+    //新增试题
+    saveNewQuestion() {
+      if (!this.quesModel.difficultyDegree) {
+        this.$notify({
+          message: "请选择试题难度",
+          type: "error"
+        });
+        return false;
+      }
+      this.fullscreenLoading = true;
+      this.$http
+        .post(
+          Q_API +
+            "/paper/addQuestion/" +
+            this.paperId +
+            "/" +
+            this.paperDetailId,
+          this.quesModel
+        )
+        .then(() => {
+          this.fullscreenLoading = false;
+          this.$message({
+            type: "info",
+            message: `保存成功`
+          });
+          this.$router.push({ path: "/questions/question_list/0" });
+        })
+        .catch(() => {
+          this.fullscreenLoading = false;
+          console.log("添加失败");
+        });
+    },
+    //新增选项
+    addQuesOption() {
+      this.quesModel.quesOptions.push({
+        number: "",
+        optionBody: "",
+        isCorrect: ""
+      });
+      for (var i = 0; i < this.quesModel.quesOptions.length; i++) {
+        this.quesModel.quesOptions[i]["number"] = i + 1;
+      }
+    },
+    //删除选项
+    removeQuesOption(option) {
+      this.singleRightAnswer = "";
+      this.multipleRightAnswer = [];
+      let index = this.quesModel.quesOptions.indexOf(option);
+      if (index !== -1) {
+        this.quesModel.quesOptions.splice(index, 1);
+      }
+      if (this.quesModel.quesOptions.length > 0) {
+        for (var i = 0; i < this.quesModel.quesOptions.length; i++) {
+          var quesOption = this.quesModel.quesOptions[i];
+          quesOption["number"] = i + 1;
+          if (quesOption.isCorrect == 1) {
+            var answerOrderNum = String.fromCharCode(65 + i);
+            if (this.quesModel.questionType == "SINGLE_ANSWER_QUESTION") {
+              this.singleRightAnswer = answerOrderNum;
+            }
+            if (this.quesModel.questionType == "MULTIPLE_ANSWER_QUESTION") {
+              this.multipleRightAnswer.push(answerOrderNum);
+            }
+          }
+        }
+      }
+    },
+    //在正确的option上设置isCorrect=1
+    setRightAnswer() {
+      if (this.quesModel.quesOptions.length == 0) {
+        return false;
+      }
+      for (var i = 0; i < this.quesModel.quesOptions.length; i++) {
+        var option = this.quesModel.quesOptions[i];
+        var answerOrderNum = String.fromCharCode(65 + i);
+        if (this.quesModel.questionType == "SINGLE_ANSWER_QUESTION") {
+          option["isCorrect"] =
+            answerOrderNum == this.singleRightAnswer ? 1 : 0;
+        }
+        if (this.quesModel.questionType == "MULTIPLE_ANSWER_QUESTION") {
+          option["isCorrect"] =
+            this.multipleRightAnswer.indexOf(answerOrderNum) > -1 ? 1 : 0;
+        }
+      }
+    },
+    backToQuesList() {
+      this.$router.push({
+        path: "/questions/question_list/0"
+      });
+    },
+    //查询所有课程属性名
+    initCourseProperty() {
+      console.log(this.quesModel);
+      var code = this.quesModel.course.code;
+      this.$http
+        .get(Q_API + "/courseProperty/enable/" + code)
+        .then(response => {
+          this.coursePropertyList = response.body;
+        });
+    },
+    //查询一级属性
+    searchFirst() {
+      this.firstPropertyId = "";
+      this.secondPropertyId = "";
+      this.secondPropertyList = [];
+      for (let courseProperty of this.coursePropertyList) {
+        if (courseProperty.name == this.coursePropertyName) {
+          this.$http
+            .get(Q_API + "/property/first/" + courseProperty.id)
+            .then(response => {
+              this.firstPropertyList = response.body;
+            });
+        }
+      }
+    },
+    //查询二级属性
+    searchSecond() {
+      this.secondPropertyId = "";
+      if (this.firstPropertyId) {
+        this.$http
+          .get(Q_API + "/property/second/" + this.firstPropertyId)
+          .then(response => {
+            this.secondPropertyList = response.body;
+          });
+      }
+    },
+    //新增属性
+    insertProperty() {
+      if (!this.checkInsertPro()) {
+        return false;
+      }
+      var quesProperty = {
+        id: "",
+        coursePropertyName: "",
+        firstProperty: {},
+        secondProperty: {}
+      };
+      if (
+        this.quesModel.quesProperties === undefined ||
+        this.quesModel.quesProperties.length == 0
+      ) {
+        this.quesModel.quesProperties = [];
+      }
+      quesProperty.id =
+        this.coursePropertyName +
+        "-" +
+        this.firstPropertyId +
+        "-" +
+        this.secondPropertyId;
+      for (let quesPro of this.quesModel.quesProperties) {
+        if (quesPro.id == quesProperty.id) {
+          this.$notify({
+            message: "该属性已存在,请重新选择",
+            type: "error"
+          });
+          return false;
+        }
+      }
+      quesProperty.coursePropertyName = this.coursePropertyName;
+      //取到一级属性对象
+      for (let property of this.firstPropertyList) {
+        if (property.id == this.firstPropertyId) {
+          quesProperty.firstProperty = property;
+        }
+      }
+      //判断是否有二级属性
+      if (
+        this.secondPropertyList != undefined &&
+        this.secondPropertyList.length > 0
+      ) {
+        if (!this.secondPropertyId) {
+          this.$notify({
+            message: "请选择二级属性",
+            type: "error"
+          });
+          return false;
+        }
+      }
+      //取到二级属性对象
+      for (let property of this.secondPropertyList) {
+        if (property.id == this.secondPropertyId) {
+          quesProperty.secondProperty = property;
+        }
+      }
+      this.quesModel.quesProperties.push(quesProperty);
+      this.quesModel = Object.assign({}, this.quesModel);
+      console.log(
+        "this.quesModel.quesProperties:",
+        this.quesModel.quesProperties
+      );
+      //清空下拉框
+      this.coursePropertyName = "";
+      this.firstPropertyId = "";
+      this.secondPropertyId = "";
+      this.firstPropertyList = [];
+      this.secondPropertyList = [];
+    },
+    //删除属性
+    handleClose(tag) {
+      console.log("tag:", tag);
+      this.quesModel.quesProperties.splice(
+        this.quesModel.quesProperties.indexOf(tag),
+        1
+      );
+      this.quesModel = Object.assign({}, this.quesModel);
+    },
+    //新增属性验证
+    checkInsertPro() {
+      if (!this.coursePropertyName) {
+        this.$notify({
+          message: "请选择属性",
+          type: "error"
+        });
+        return false;
+      }
+      if (!this.firstPropertyId) {
+        this.$notify({
+          message: "请选择一级属性",
+          type: "error"
+        });
+        return false;
+      }
+      return true;
+    },
+    answer() {
+      if (this.quesModel.questionType == "SINGLE_ANSWER_QUESTION") {
+        return this.singleRightAnswer;
+      } else if (this.quesModel.questionType == "MULTIPLE_ANSWER_QUESTION") {
+        return this.multipleRightAnswer.sort().toString();
+      }
+    }
+  },
+  computed: {
+    // answer: function() {
+    //   if (this.quesModel.questionType == "SINGLE_ANSWER_QUESTION") {
+    //     return this.singleRightAnswer;
+    //   } else if (this.quesModel.questionType == "MULTIPLE_ANSWER_QUESTION") {
+    //     return this.multipleRightAnswer.sort().toString();
+    //   }
+    // },
+    saveDisabled: function() {
+      if (!this.questionId && this.quesModel.quesOptions.length == 0) {
+        return true;
+      }
+      return false;
+    }
+  },
+  created() {
+    let questionId = this.$route.params.id;
+    if (questionId) {
+      this.questionId = questionId;
+      this.quesModel["id"] = questionId;
+      this.findQuestionById(questionId);
+    }
+    this.paperId = this.$route.params.paperId;
+    this.paperDetailId = this.$route.params.paperDetailId;
+    this.courseNo = this.$route.params.courseNo;
+    let questionType = this.$route.params.questionType;
+    if (questionType) {
+      this.quesModel.questionType = questionType;
+    }
+    if (this.courseNo) {
+      this.$http
+        .get(Q_API + "/courseProperty/enable/" + this.courseNo)
+        .then(response => {
+          this.coursePropertyList = response.body;
+        });
+    }
+  }
+};
+</script>

+ 673 - 0
src/modules/questions/views/ExportStructure.vue

@@ -0,0 +1,673 @@
+<template>
+  <div v-loading="loading">
+    <section class="content">
+      <div class="box box-info">
+        <!-- 头信息 -->
+        <div class="box-header with-border">
+          <h3 class="box-title">导出结构</h3>
+        </div>
+        <!-- 正文信息 -->
+        <div class="box-body">
+          <el-form :inline="true" :model="formSearch">
+            <el-row>
+              <el-form-item label="考试类型">
+                <el-select
+                  class="input_width_lg"
+                  filterable
+                  clearable
+                  v-model="formSearch.examType"
+                  placeholder="请选择"
+                >
+                  <el-option
+                    v-for="item in EXAM_TYPES"
+                    :label="item.label"
+                    :value="item.value"
+                    :key="item.value"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+              <el-form-item label="考试名称">
+                <el-select
+                  filterable
+                  clearable
+                  v-model="formSearch.examId"
+                  placeholder="请选择"
+                  :remote-method="getExams"
+                  remote
+                >
+                  <el-option
+                    v-for="item in examList"
+                    :key="item.id"
+                    :label="item.name"
+                    :value="item.id"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+              <el-form-item label="导出类型">
+                <el-select
+                  class="input_width_lg"
+                  filterable
+                  clearable
+                  v-model="formSearch.exportType"
+                  placeholder="请选择"
+                >
+                  <el-option
+                    v-for="item in EXPORT_TYPES"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+              <el-form-item>
+                <el-button size="small" type="primary" @click="search"
+                  >查询</el-button
+                >
+              </el-form-item>
+              <el-form-item>
+                <el-button size="small" type="primary" @click="add"
+                  >新增</el-button
+                >
+              </el-form-item>
+            </el-row>
+          </el-form>
+          <!-- 页面列表 -->
+          <el-table
+            :data="tableData"
+            border
+            style="width: 100%;text-align:center;"
+          >
+            <el-table-column label="考试类型">
+              <template slot-scope="scope">
+                <div class="el_table_inner_left">
+                  <span>{{ scope.row.examType | examTypesFilter }}</span>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="考试名称">
+              <template slot-scope="scope">
+                <div class="el_table_inner_left">
+                  <span>{{ scope.row.examName }}</span>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="导出类型">
+              <template slot-scope="scope">
+                <div class="el_table_inner_left">
+                  <span>{{ scope.row.exportType | exportTypesFilter }}</span>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="题数">
+              <template slot-scope="scope">
+                <div
+                  class="el_table_inner_left"
+                  v-show="scope.row.exportType == 'NORMAL'"
+                  v-for="(item, index) in scope.row.questionTypeNums"
+                  :key="index"
+                >
+                  <span>{{ item.questionType | questionType }}</span>
+                  <span>{{ item.quantity }}</span>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column :context="_self" fixed="right" label="操作">
+              <template slot-scope="scope">
+                <div>
+                  <el-button size="small" type="info" @click="copy(scope.row);"
+                    >复用</el-button
+                  >
+                  <el-button size="small" type="danger" @click="del(scope.row);"
+                    >删除</el-button
+                  >
+                </div>
+              </template>
+            </el-table-column>
+          </el-table>
+          <div class="page pull-right">
+            <el-pagination
+              @current-change="handleCurrentChange"
+              :current-page="currentPage"
+              :page-size="pageSize"
+              layout="total, prev, pager, next, jumper"
+              :total="total"
+            >
+            </el-pagination>
+          </div>
+        </div>
+      </div>
+    </section>
+    <!-- 复用窗口 -->
+    <el-dialog title="试卷结构复用" :visible.sync="dialogCopyModel">
+      <el-form :model="exportStructureCopy" ref="exportStructureCopy">
+        <el-tabs> <el-tab-pane label="原结构信息"></el-tab-pane> </el-tabs>
+        <el-form-item label="考试类型" label-width="120px">
+          <el-select
+            v-model="exportStructureCopy.examTypeOld"
+            placeholder="请选择"
+            disabled
+          >
+            <el-option
+              v-for="item in EXAM_TYPES"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="考试名称" label-width="120px">
+          <el-select
+            v-model="exportStructureCopy.examIdOld"
+            placeholder="请选择"
+            disabled
+          >
+            <el-option
+              v-for="item in examList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="导出类型" label-width="120px">
+          <el-select
+            v-model="exportStructureCopy.exportTypeOld"
+            placeholder="请选择"
+            disabled
+          >
+            <el-option
+              v-for="item in EXPORT_TYPES"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-tabs> <el-tab-pane label="新结构信息"></el-tab-pane> </el-tabs>
+        <el-form-item label="考试类型" label-width="120px">
+          <el-select
+            v-model="exportStructureCopy.examType"
+            placeholder="请选择"
+            @change="searchExamId"
+          >
+            <el-option
+              v-for="item in EXAM_TYPES"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            ></el-option>
+          </el-select>
+          <span
+            style="color: red"
+            v-if="check_value(exportStructureCopy.examType)"
+            >请选择考试类型</span
+          >
+        </el-form-item>
+        <el-form-item label="考试名称" label-width="120px">
+          <el-select v-model="exportStructureCopy.examId" placeholder="请选择">
+            <el-option
+              v-for="item in examListNew"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            ></el-option>
+          </el-select>
+          <span
+            style="color: red"
+            v-if="check_value(exportStructureCopy.examId)"
+            >请选择考试名称</span
+          >
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="cancleCopy">取 消</el-button>
+        <el-button type="primary" @click="saveCopy">确 定</el-button>
+      </div>
+    </el-dialog>
+    <!-- 新增窗口 -->
+    <el-dialog title="新增导出结构" :visible.sync="dialogModel">
+      <el-form :model="exportStructure" ref="exportStructure">
+        <el-form-item label="考试类型" label-width="120px">
+          <el-select
+            v-model="exportStructure.examType"
+            placeholder="请选择"
+            @change="searchExportStructure('examType');"
+          >
+            <el-option
+              v-for="item in EXAM_TYPES"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            ></el-option>
+          </el-select>
+          <span style="color: red" v-if="check_value(exportStructure.examType)"
+            >请选择考试类型</span
+          >
+        </el-form-item>
+        <el-form-item label="考试名称" label-width="120px">
+          <el-select
+            v-model="exportStructure.examId"
+            filterable
+            placeholder="请选择"
+            @change="searchExportStructure('examId');"
+          >
+            <el-option
+              v-for="item in examListByExamType"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            ></el-option>
+          </el-select>
+          <span style="color: red" v-if="check_value(exportStructure.examId)"
+            >请选择考试名称</span
+          >
+        </el-form-item>
+
+        <el-form-item label="导出类型" label-width="120px">
+          <el-select
+            v-model="exportStructure.exportType"
+            placeholder="请选择"
+            :disabled="button"
+          >
+            <el-option
+              v-for="item in EXPORT_TYPES"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            ></el-option>
+          </el-select>
+          <span
+            style="color: red"
+            v-if="check_value(exportStructure.exportType)"
+            >请选择导出类型</span
+          >
+        </el-form-item>
+        <!-- 判断机考还是传统 -->
+        <div v-if="exportStructure.exportType == 'NORMAL'">
+          <div
+            v-for="(item, index) in exportStructure.questionTypeNums"
+            :key="index"
+          >
+            <el-form-item
+              :label="item.questionType | questionType"
+              label-width="120px"
+            >
+              <el-input
+                v-model="item.quantity"
+                style="width: 220px"
+                :disabled="button"
+              ></el-input>
+              <span style="color: red" v-if="check(item.quantity)"
+                >请输入正整数或0</span
+              >
+            </el-form-item>
+          </div>
+        </div>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="cancel">取 消</el-button>
+        <el-button type="primary" @click="save" :disabled="button"
+          >确 定</el-button
+        >
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  Q_API,
+  EXAM_WORK_API,
+  EXAM_TYPES,
+  EXPORT_TYPES
+} from "../constants/constants";
+import { mapState } from "vuex";
+import _ from "lodash";
+export default {
+  data() {
+    return {
+      isShow: false,
+      loading: false,
+      dialogModel: false,
+      dialogCopyModel: false,
+      formSearch: {
+        examType: null,
+        examId: null,
+        exportType: null
+      },
+      exportStructure: {
+        examType: "",
+        examId: "",
+        examName: "",
+        exportType: "",
+        useable: "1", //默认启用
+        questionTypeNums: [
+          {
+            questionType: "SINGLE_ANSWER_QUESTION",
+            quantity: ""
+          },
+          {
+            questionType: "MULTIPLE_ANSWER_QUESTION",
+            quantity: ""
+          },
+          {
+            questionType: "BOOL_ANSWER_QUESTION",
+            quantity: ""
+          }
+        ]
+      },
+      exportStructureCopy: {
+        examTypeOld: "",
+        examIdOld: "",
+        exportTypeOld: "",
+        examType: "",
+        examId: "",
+        useable: "1",
+        questionTypeNums: [
+          {
+            questionType: "SINGLE_ANSWER_QUESTION",
+            quantity: ""
+          },
+          {
+            questionType: "MULTIPLE_ANSWER_QUESTION",
+            quantity: ""
+          },
+          {
+            questionType: "BOOL_ANSWER_QUESTION",
+            quantity: ""
+          }
+        ]
+      },
+      EXAM_TYPES: EXAM_TYPES,
+      EXPORT_TYPES: EXPORT_TYPES,
+      examList: [],
+      examListByExamType: [],
+      tableData: [],
+      pageSize: 10,
+      currentPage: 1,
+      total: 10,
+      button: false,
+      examListNew: []
+    };
+  },
+  methods: {
+    search() {
+      this.tableData = [];
+      this.loading = true;
+      var url =
+        Q_API +
+        "/findPageByExportStructure/" +
+        this.currentPage +
+        "/" +
+        this.pageSize;
+      this.$http.post(url, this.formSearch).then(response => {
+        this.tableData = response.data.content;
+        this.total = response.data.totalElements;
+        this.loading = false;
+      });
+    },
+    //新增考试结构
+    add() {
+      this.dialogModel = true;
+      this.button = false;
+      this.exportStructure = {
+        examType: "",
+        examId: "",
+        examName: "",
+        exportType: "",
+        useable: "1", //默认启用
+        questionTypeNums: [
+          {
+            questionType: "SINGLE_ANSWER_QUESTION",
+            quantity: ""
+          },
+          {
+            questionType: "MULTIPLE_ANSWER_QUESTION",
+            quantity: ""
+          },
+          {
+            questionType: "BOOL_ANSWER_QUESTION",
+            quantity: ""
+          }
+        ]
+      };
+    },
+    handleCurrentChange(val) {
+      this.currentPage = val;
+      this.search();
+    },
+
+    closeQuesDialog() {
+      this.dialogModel = false;
+    },
+    //表单验证
+    check(value) {
+      var r = /^\+?[1-9][0-9]*$/;
+      if ((r.test(value) || value === "0") && this.isShow) {
+        return false;
+      }
+      return true;
+    },
+    check_value(value) {
+      if (!value && this.isShow) {
+        return true;
+      }
+      return false;
+    },
+    save() {
+      this.isShow = true;
+      if (this.check_value(this.exportStructure.examType)) {
+        return false;
+      }
+      if (this.check_value(this.exportStructure.examId)) {
+        return false;
+      }
+      if (this.check_value(this.exportStructure.exportType)) {
+        return false;
+      }
+      if (this.exportStructure.exportType == "NORMAL") {
+        for (var i = 0; i < this.exportStructure.questionTypeNums.length; i++) {
+          if (this.check(this.exportStructure.questionTypeNums[i].quantity)) {
+            return false;
+          }
+        }
+      }
+      let examId = this.exportStructure.examId;
+      this.exportStructure.examName = _.filter(this.examList, function(item) {
+        return item.id == examId;
+      })[0].name;
+      this.$http
+        .post(Q_API + "/saveExportStructure", this.exportStructure)
+        .then(() => {
+          this.$notify({
+            title: "提示",
+            message: "保存成功",
+            type: "success"
+          });
+          this.closeQuesDialog();
+          this.search();
+        });
+    },
+    //重置
+    resetForm() {
+      this.$refs.exportStructure.resetFields();
+    },
+    //取消
+    cancel() {
+      this.isShow = false;
+      this.button = false;
+      this.dialogModel = false;
+    },
+    //取消复用
+    cancleCopy() {
+      this.isShow = false;
+      this.dialogCopyModel = false;
+    },
+    //复用
+    copy(row) {
+      this.dialogCopyModel = true;
+      this.exportStructureCopy.examTypeOld = row.examType;
+      this.exportStructureCopy.examIdOld = parseInt(row.examId);
+      this.exportStructureCopy.exportTypeOld = row.exportType;
+      this.exportStructureCopy.questionTypeNums = row.questionTypeNums;
+      this.exportStructureCopy.examType = "";
+      this.exportStructureCopy.examId = "";
+    },
+    //新增的时候,先查询
+    searchExportStructure(type) {
+      if (type == "examType") {
+        this.$http
+          .get(
+            EXAM_WORK_API +
+              "/exam/queryByNameLike?name=&examType=" +
+              this.exportStructure.examType
+          )
+          .then(response => {
+            this.examListByExamType = response.data;
+            console.log("this.examListByExamType:", this.examListByExamType);
+            this.exportStructure.examId = "";
+            this.resetExportStructure();
+          });
+      }
+      if (this.exportStructure.examType && this.exportStructure.examId) {
+        var url = Q_API + "/findExportStructure/" + this.exportStructure.examId;
+        this.$http
+          .get(url)
+          .then(response => {
+            console.log(response);
+            if (!response.data.id) {
+              this.resetExportStructure();
+            } else {
+              this.button = true;
+              this.exportStructure.exportType = response.data.exportType;
+              this.exportStructure.useable = response.data.useable
+                ? response.data.useable.toString()
+                : "1";
+              for (
+                var i = 0;
+                i < this.exportStructure.questionTypeNums.length;
+                i++
+              ) {
+                this.exportStructure.questionTypeNums[i].quantity =
+                  response.data.questionTypeNums[i].quantity;
+              }
+              console.log("非空对象");
+            }
+          })
+          .catch(() => {});
+      }
+    },
+    resetExportStructure() {
+      this.button = false;
+      this.exportStructure.exportType = "";
+      this.exportStructure.useable = "1";
+      for (var i = 0; i < this.exportStructure.questionTypeNums.length; i++) {
+        this.exportStructure.questionTypeNums[i].quantity = "";
+      }
+    },
+    //点击复用,选择
+    searchExamId() {
+      if (this.exportStructureCopy.examType) {
+        this.$http
+          .get(
+            EXAM_WORK_API +
+              "/exam/queryByNameLike?name=&examType=" +
+              this.exportStructureCopy.examType
+          )
+          .then(response => {
+            let examListFilter = response.data;
+            var url =
+              Q_API +
+              "/findExportStructureByExamType/" +
+              this.exportStructureCopy.examType;
+            this.$http.get(url).then(response => {
+              let examListOld = response.data;
+              //两个数组相减
+              this.examListNew = _.filter(examListFilter, function(exam) {
+                return examListOld.indexOf(exam.id.toString()) == -1;
+              });
+            });
+          });
+      }
+    },
+    //保存复用
+    saveCopy() {
+      this.isShow = true;
+      if (this.check_value(this.exportStructureCopy.examType) === true) {
+        return false;
+      }
+      if (this.check_value(this.exportStructureCopy.examId) === true) {
+        return false;
+      }
+      this.exportStructure.examType = this.exportStructureCopy.examType;
+      this.exportStructure.examId = this.exportStructureCopy.examId;
+      this.exportStructure.exportType = this.exportStructureCopy.exportTypeOld;
+      this.exportStructure.useable = this.exportStructureCopy.useable;
+      this.exportStructure.questionTypeNums = this.exportStructureCopy.questionTypeNums;
+      let examId = this.exportStructure.examId;
+      this.exportStructure.examName = _.filter(this.examList, function(item) {
+        return item.id == examId;
+      })[0].name;
+      this.$http
+        .post(Q_API + "/saveExportStructure", this.exportStructure)
+        .then(() => {
+          this.$notify({
+            title: "提示",
+            message: "保存成功",
+            type: "success"
+          });
+          this.dialogCopyModel = false;
+          this.search();
+        });
+    },
+    //删除
+    del(row) {
+      this.$confirm("是否删除该条导出结构", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        this.loading = true;
+        var url = Q_API + "/deleteExportStructure/" + row.id;
+        this.$http.delete(url).then(
+          () => {
+            this.$notify({
+              type: "success",
+              message: "删除成功!"
+            });
+            this.loading = false;
+            this.search();
+          },
+          () => {
+            this.$notify({
+              type: "error",
+              message: "删除失败!"
+            });
+            this.loading = false;
+          }
+        );
+      });
+      this.loading = false;
+    },
+    //查询考试
+    getExams(query) {
+      query = query.trim();
+      this.$http
+        .get(EXAM_WORK_API + "/exam/queryByNameLike?name=" + query)
+        .then(response => {
+          this.examList = response.data;
+        });
+    }
+  },
+  computed: {
+    ...mapState({ user: state => state.user })
+  },
+  created() {
+    this.getExams("");
+    this.search();
+  }
+};
+</script>

+ 870 - 0
src/modules/questions/views/ExtractPaperInfo.vue

@@ -0,0 +1,870 @@
+<template>
+  <div>
+    <section
+      class="content"
+      v-loading="loading"
+      element-loading-text="保存调卷规则及生成试卷文件中..."
+    >
+      <div class="box box-info">
+        <!-- 头信息 -->
+        <div class="box-header with-border">
+          <h3 class="box-title">调卷详情</h3>
+        </div>
+        <!-- 正文信息 -->
+        <div class="box-body">
+          <el-form
+            :inline="true"
+            :model="extractConfig"
+            ref="extractPaperForm"
+            label-position="right"
+            label-width="120px"
+          >
+            <el-row>
+              <el-form-item label="考试名称">
+                <el-select
+                  filterable
+                  clearable
+                  v-model="extractConfig.examId"
+                  @change="getExamCourses"
+                  placeholder="请选择"
+                  :remote-method="getExams"
+                  remote
+                  :disabled="isInsert"
+                >
+                  <el-option
+                    v-for="item in examList"
+                    :key="item.id"
+                    :label="item.name"
+                    :value="item.id"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+              <el-form-item label="课程名称">
+                <el-select
+                  v-model="extractConfig.courseCode"
+                  filterable
+                  clearable
+                  @change="getPaperTypeList"
+                  placeholder="请选择"
+                  :disabled="isInsert"
+                >
+                  <el-option
+                    v-for="item in courseInfoSelect"
+                    :key="item.courseNo"
+                    :label="item.courseInfo"
+                    :value="item.courseNo"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-row>
+
+            <el-tabs v-model="tabs">
+              <el-tab-pane label="步骤一:调卷模式选择" name="first">
+                <el-form-item prop="status">
+                  <el-radio-group
+                    class="pull_right_ss"
+                    v-model="extractConfig.callType"
+                  >
+                    <el-radio label="WHOLE_SET">成套调用</el-radio>
+                    <!-- <el-radio label="RESTRUCT">重组调用</el-radio> -->
+                  </el-radio-group>
+                </el-form-item>
+              </el-tab-pane>
+            </el-tabs>
+            <el-tabs v-model="tabs">
+              <el-tab-pane label="步骤二:试卷抽取比例" name="first">
+                <el-row>
+                  <el-col :span="24">
+                    <el-tag v-if="extractConfig.examType === 'TRADITION'"
+                      >传统考试</el-tag
+                    >
+                    <el-tag v-if="extractConfig.examType === 'ONLINE'"
+                      >在线考试</el-tag
+                    >
+                    <el-tag v-if="extractConfig.examType === 'PRACTICE'"
+                      >练习考试</el-tag
+                    >
+                  </el-col>
+                </el-row>
+                <el-row :key="num" v-for="(examPaper, num) in examPaperList">
+                  <el-col :span="24">
+                    <el-form-item label="试卷类型" class="pull-left">
+                      <el-input
+                        class="input_width_lg"
+                        placeholder="请输入试卷类型"
+                        v-model="examPaper.groupCode"
+                        disabled
+                      ></el-input>
+                    </el-form-item>
+                    <el-button
+                      type="primary"
+                      v-if="extractConfig.examType != 'TRADITION'"
+                      @click="addOnLinePaper(examPaper.groupCode);"
+                      >添加试卷
+                    </el-button>
+                  </el-col>
+                  <el-col
+                    :span="20"
+                    :offset="2"
+                    v-for="(paperInfo, index) in examPaper.paperInfoList"
+                    :key="paperInfo.selectedPaperId"
+                  >
+                    <el-form-item>
+                      <span>试卷选定</span>
+                      <el-select
+                        filterable
+                        v-model="paperInfo.paper.id"
+                        placeholder="请选择"
+                        @change="searchAudioTimeConfig"
+                        class="select_width_lg"
+                      >
+                        <el-option
+                          v-for="item in paperList"
+                          :label="item.name"
+                          :value="item.id"
+                          :key="item.id"
+                        >
+                        </el-option>
+                      </el-select>
+                      <span>选取几率</span>
+                      <span>
+                        <el-input
+                          class="input_width_sms"
+                          v-model="paperInfo.weight"
+                          :disabled="extractConfig.examType === 'TRADITION'"
+                        ></el-input
+                        >%
+                        <i
+                          class="el-icon-delete"
+                          v-if="index > 0"
+                          @click.prevent="
+                            removePaperInfo(examPaper.groupCode, paperInfo);
+                          "
+                        ></i>
+                      </span>
+                      <span :class="'errorMsg_' + num + '_' + index"></span>
+                    </el-form-item>
+                  </el-col>
+                </el-row>
+              </el-tab-pane>
+            </el-tabs>
+            <div>
+              <el-tabs v-model="tabs">
+                <el-tab-pane label="步骤三:随机设定" name="first">
+                  <el-form-item
+                    label="客观题小题乱序"
+                    prop="scrambling_the_question_order"
+                  >
+                    <el-radio-group
+                      class="pull_right_sm"
+                      v-model="extractConfig.scrambling_the_question_order"
+                    >
+                      <el-radio :label="1">开启</el-radio>
+                      <el-radio :label="0">关闭</el-radio>
+                    </el-radio-group>
+                  </el-form-item>
+                  <br />
+                  <el-form-item
+                    label="客观题选项乱序"
+                    prop="scrambling_the_option_order"
+                  >
+                    <el-radio-group
+                      class="pull_right_sm"
+                      v-model="extractConfig.scrambling_the_option_order"
+                    >
+                      <el-radio :label="1">开启</el-radio>
+                      <el-radio :label="0">关闭</el-radio>
+                    </el-radio-group>
+                  </el-form-item>
+                </el-tab-pane>
+              </el-tabs>
+            </div>
+            <div
+              style="padding: 5px;"
+              v-show="extractConfig.examType != 'PRACTICE'"
+            >
+              <el-tabs v-model="tabs">
+                <el-tab-pane label="步骤四:音频播放次数设置" name="first">
+                  <el-row
+                    class="row_header_word"
+                    v-show="audioTimeConfigList.length > 0"
+                  >
+                    <el-col :span="4" :offset="1">试卷类型</el-col>
+                    <el-col :span="4">试卷名称</el-col>
+                    <el-col :span="3">大题号</el-col>
+                    <el-col :span="3">小题号</el-col>
+                    <el-col :span="4">播放次数</el-col>
+                  </el-row>
+                  <el-row
+                    v-for="(audioTimeConfig, index) in audioTimeConfigList"
+                    class="margin-top-10"
+                    :key="index"
+                  >
+                    <el-col :span="4" :offset="1">
+                      {{ audioTimeConfig.groupCode }}
+                    </el-col>
+                    <el-col :span="4">
+                      {{ audioTimeConfig.paper.name }}
+                    </el-col>
+                    <el-col :span="3">
+                      {{ audioTimeConfig.paperDetailUnit.paperDetail.number }}
+                    </el-col>
+                    <el-col :span="3">
+                      {{ audioTimeConfig.paperDetailUnit.number }}
+                    </el-col>
+                    <el-col :span="4">
+                      <el-input
+                        class="input_width_ss"
+                        size="small"
+                        v-model="audioTimeConfig.playTime"
+                        >次
+                      </el-input>
+                    </el-col>
+                  </el-row>
+                  <el-row v-show="audioTimeConfigList.length == 0">
+                    <el-col :span="18" :offset="1"> 无音频试题 </el-col>
+                  </el-row>
+                </el-tab-pane>
+              </el-tabs>
+            </div>
+            <div>
+              <el-tabs v-model="tabs">
+                <el-row>
+                  <el-col>
+                    <el-form-item label="是否生成文件">
+                      <el-radio-group v-model="isbuildFile">
+                        <el-radio label="1">是</el-radio>
+                        <el-radio label="0">否</el-radio>
+                      </el-radio-group>
+                    </el-form-item>
+                  </el-col>
+                </el-row>
+                <el-row :gutter="20">
+                  <el-col :span="12" :offset="1">
+                    <el-button type="primary" @click="submitForm">
+                      保存
+                    </el-button>
+                    <el-button @click="back">返 回</el-button>
+                  </el-col>
+                </el-row>
+              </el-tabs>
+            </div>
+          </el-form>
+        </div>
+      </div>
+    </section>
+  </div>
+</template>
+<script>
+import { EXAM_WORK_API, Q_API } from "../constants/constants";
+import { mapState } from "vuex";
+import _ from "lodash";
+export default {
+  data() {
+    return {
+      loading: false,
+      extractConfig: {
+        examId: "", //考试ID
+        examName: "", //考试名称
+        examType: "", //考试类型:网络考试、传统考试
+        courseCode: "", //课程代码
+        courseName: "", //课程名称
+        callType: "WHOLE_SET", //调卷类型:默认成套调用
+        examPaperList: [],
+        scrambling_the_question_order: 0, //小题乱序  默认关闭
+        scrambling_the_option_order: 0 //选项乱序  默认关闭
+      },
+      examPaperList: [],
+      audioTimeConfig: {
+        examId: "",
+        examName: "",
+        paper: {
+          id: ""
+        },
+        groupCode: "",
+        courseCode: "",
+        playTime: ""
+      },
+      audioTimeConfigModelList: [],
+      tabs: "first",
+      paperList: [],
+      isbuildFile: "0",
+      audioTimeConfigList: [],
+      paperName: "",
+      examList: [],
+      courseList: [],
+      courseAll: [],
+      isInsert: false
+    };
+  },
+
+  methods: {
+    //根据考务查询考试集合
+    getExams(query) {
+      query = query.trim();
+      this.$http
+        .get(
+          EXAM_WORK_API + "/exam/queryByNameLike?name=" + query + "&enable=true"
+        )
+        .then(response => {
+          this.examList = response.data;
+        });
+    },
+    //根据考试查询课程
+    getExamCourses() {
+      if (!this.isInsert) {
+        this.extractConfig.courseCode = "";
+        this.courseList = [];
+        if (this.extractConfig.examId) {
+          //查询该考试下的课程
+          this.$http
+            .get(
+              Q_API + "/findCourseByExtractConfig/" + this.extractConfig.examId
+            )
+            .then(response => {
+              this.courseList = response.data;
+            });
+        }
+        //查询考试对象,获取考试类型:离线,在线,传统
+        if (this.extractConfig.examId) {
+          this.$http
+            .get(EXAM_WORK_API + "/exam/" + this.extractConfig.examId)
+            .then(response => {
+              var exam = response.data;
+              this.extractConfig.examType = exam.examType;
+              this.extractConfig.examName = exam.name;
+            });
+        }
+      }
+    },
+    //根据考试ID和课程code取出试卷类型集合
+    getPaperTypeList() {
+      if (!this.isInsert) {
+        var id = "";
+        for (let course of this.courseList) {
+          if (this.extractConfig.courseCode == course.courseCode) {
+            id = course.courseId;
+            break;
+          }
+        }
+        this.$http
+          .get(
+            EXAM_WORK_API +
+              "/exam/queryExamCoursePaperTypeList?examId=" +
+              this.extractConfig.examId +
+              "&courseId=" +
+              id
+          )
+          .then(response => {
+            let examPaperArr = response.data;
+            console.log("examPaperArr:", examPaperArr);
+            if (examPaperArr && examPaperArr.length > 0) {
+              let _examPaperList = [];
+              for (let examPaper of examPaperArr) {
+                let groupCode = examPaper.paperType;
+                let weight =
+                  this.extractConfig.examType == "TRADITION" ? 100 : "";
+                let examPaperListByGroupCode = this.getWeightFromExamPaperList(
+                  groupCode
+                );
+                if (examPaperListByGroupCode) {
+                  _examPaperList.push({
+                    groupCode: groupCode,
+                    paperInfoList: examPaperListByGroupCode
+                  });
+                } else {
+                  _examPaperList.push({
+                    groupCode: groupCode,
+                    paperInfoList: [
+                      {
+                        weight: weight,
+                        paper: { id: "" }
+                      }
+                    ]
+                  });
+                }
+              }
+              this.examPaperList = _examPaperList;
+            }
+          });
+        this.getPaperList();
+      }
+    },
+    //根据groupCode得到examPaper集合
+    getWeightFromExamPaperList(groupCode) {
+      let examPaperListByGroupCode = [];
+      let examPaperList = this.extractConfig.examPaperList;
+      if (!examPaperList || examPaperList.length == 0) {
+        return null;
+      }
+      for (let examPaper of examPaperList) {
+        if (examPaper.groupCode == groupCode) {
+          examPaperListByGroupCode.push(examPaper);
+        }
+      }
+      return examPaperListByGroupCode;
+    },
+    //根据课程,查询试卷集合
+    getPaperList() {
+      if (this.extractConfig.courseCode) {
+        this.$http
+          .get(Q_API + "/getGenPaper?courseNo=" + this.extractConfig.courseCode)
+          .then(response => {
+            this.paperList = response.data;
+          });
+      }
+    },
+    //根据选择试卷集合查询音频题
+    searchAudioTimeConfig() {
+      this.audioTimeConfigModelList = [];
+      //取到数组里面每个对象
+      for (var i = 0; i < this.examPaperList.length; i++) {
+        //定一个试卷的集合,用来去重
+        var paperIds = [];
+        for (var j = 0; j < this.examPaperList[i].paperInfoList.length; j++) {
+          paperIds.push(this.examPaperList[i].paperInfoList[j].paper.id);
+        }
+        //对试卷集合进行去重
+        console.log("paperIds:", paperIds);
+        var ids = [];
+        ids = _.uniq(paperIds);
+        for (var k = 0; k < ids.length; k++) {
+          //把对象添加到集合
+          this.audioTimeConfigModelList.push({
+            courseCode: this.extractConfig.courseCode,
+            groupCode: this.examPaperList[i].groupCode,
+            paper: {
+              id: ids[k]
+            },
+            examId: this.extractConfig.examId,
+            examName: this.extractConfig.examName
+          });
+        }
+      }
+      this.$http
+        .post(Q_API + "/audioTimeConfig/all", this.audioTimeConfigModelList)
+        .then(response => {
+          this.audioTimeConfigList = response.data;
+        });
+    },
+    //增加在线考试试卷
+    addOnLinePaper(groupCode) {
+      let num = 0;
+      for (let i = 0; i < this.examPaperList.length; i++) {
+        if (this.examPaperList[i].groupCode == groupCode) {
+          num = i;
+          break;
+        }
+      }
+      this.examPaperList[num].paperInfoList.push({
+        weight: 0,
+        paper: {
+          id: ""
+        }
+      });
+    },
+    //删除试卷
+    removePaperInfo(groupCode, item) {
+      let num = 0;
+      for (let i = 0; i < this.examPaperList.length; i++) {
+        if (this.examPaperList[i].groupCode == groupCode) {
+          num = i;
+          break;
+        }
+      }
+      let index = this.examPaperList[num].paperInfoList.indexOf(item);
+      if (index !== -1) {
+        this.examPaperList[num].paperInfoList.splice(index, 1);
+      }
+      if (this.extractConfig.examType != "PRACTICE") {
+        //重新查询一次所有试卷的音频题数
+        this.searchAudioTimeConfig();
+      }
+    },
+    //保存提交
+    submitForm() {
+      this.saveExtractConfig();
+    },
+    //保存调卷规则
+    saveExtractConfig() {
+      if (!this.extractConfig.examId) {
+        this.$notify({
+          message: "请选择考试",
+          type: "error"
+        });
+        return false;
+      }
+      if (!this.extractConfig.courseCode) {
+        if (this.isInsert) {
+          this.$notify({
+            message:
+              "考务数据中,该场考试下已经没有这门课程,无法保存调卷规则。",
+            type: "error"
+          });
+        } else {
+          this.$notify({
+            message: "请选择课程",
+            type: "error"
+          });
+        }
+        return false;
+      }
+      if (this.extractConfig.examType != "PRACTICE") {
+        for (let audioTimeConfig of this.audioTimeConfigList) {
+          if (!this.checkValue(audioTimeConfig.playTime)) {
+            this.$notify({
+              message: "播放次数只能为整数",
+              type: "error"
+            });
+            return false;
+          }
+        }
+      }
+      let myExamPaperList = this.verificationData();
+      if (myExamPaperList.length > 0) {
+        this.loading = true;
+        this.extractConfig.examPaperList = myExamPaperList;
+        this.$http
+          .put(
+            Q_API + "/extractConfig" + "/" + this.isbuildFile,
+            this.extractConfig
+          )
+          .then(
+            () => {
+              if (this.extractConfig.examType != "PRACTICE") {
+                this.addAudioTimeConfig();
+              }
+              this.loading = false;
+              this.$notify({ type: "success", message: "保存成功" });
+              this.$router.push({
+                path: "/index/extract_paper_rule/" + this.extractConfig.examId
+              });
+            },
+            response => {
+              this.loading = false;
+              this.$notify({ type: "error", message: response.data.desc });
+            }
+          );
+      }
+    },
+    //音频播放次数校验
+    checkValue(val) {
+      if (/(^[0-9]\d*$)/.test(val)) {
+        return true;
+      } else {
+        return false;
+      }
+    },
+    //新增音频播放次数
+    addAudioTimeConfig() {
+      if (!this.audioTimeConfigList || this.audioTimeConfigList.length == 0) {
+        /* 未设置时则清理已存在的数据 */
+        this.$http
+          .post(
+            Q_API +
+              "/deleteAudioTimeConfig/" +
+              this.extractConfig.examId +
+              "/" +
+              this.extractConfig.courseCode
+          )
+          .then(() => {});
+      } else {
+        this.$http
+          .post(Q_API + "/addAudioTimeConfig", this.audioTimeConfigList)
+          .then(() => {});
+      }
+    },
+    //校验调卷规则数据
+    verificationData() {
+      let myExamPaperList = [];
+      let examPaperList = this.examPaperList;
+      for (let i = 0; i < examPaperList.length; i++) {
+        let selectedPaperIds = []; //校验试卷重复性
+        let weightCount = 0; //校验概率之和
+        let _paperInfoList = examPaperList[i].paperInfoList;
+        let groupCode = examPaperList[i].groupCode;
+        if (!groupCode) {
+          this.$notify({
+            message: "试卷类型不能为空",
+            type: "error",
+            duration: 2000
+          });
+          break;
+        }
+        for (let j = 0; j < _paperInfoList.length; j++) {
+          if (!_paperInfoList[j].paper.id) {
+            myExamPaperList = [];
+            // $(".errorMsg_" + i + "_" + j)
+            //   .text("试卷不能为空")
+            //   .show();
+            document.getElementById("errorMsg_" + i + "_" + j).innerHTML =
+              "试卷不能为空";
+            document.getElementById("errorMsg_" + i + "_" + j).style.display =
+              "block";
+            break;
+          } else {
+            //$(".errorMsg_" + i + "_" + j).hide();
+            document.getElementById("errorMsg_" + i + "_" + j).style.display =
+              "none";
+          }
+          var reg = /^([1]?\d{1,2})$/;
+          if (
+            !reg.test(_paperInfoList[j].weight) ||
+            _paperInfoList[j].weight == 0
+          ) {
+            myExamPaperList = [];
+            // $(".errorMsg_" + i + "_" + j)
+            //   .text("请输入1-100的整数")
+            //   .show();
+            document.getElementById("errorMsg_" + i + "_" + j).innerHTML =
+              "请输入1-100的整数";
+            document.getElementById("errorMsg_" + i + "_" + j).style.display =
+              "block";
+            break;
+          } else {
+            //$(".errorMsg_" + i + "_" + j).hide();
+            document.getElementById("errorMsg_" + i + "_" + j).style.display =
+              "none";
+            weightCount += parseInt(_paperInfoList[j].weight);
+            selectedPaperIds.push(_paperInfoList[j].paper.id);
+            myExamPaperList.push({
+              groupCode: groupCode,
+              paper: {
+                id: _paperInfoList[j].paper.id
+              },
+              weight: _paperInfoList[j].weight
+            });
+          }
+        }
+        if (myExamPaperList.length == 0) {
+          break;
+        } else {
+          if (_.uniq(selectedPaperIds).length != selectedPaperIds.length) {
+            myExamPaperList = [];
+            this.$notify({
+              message: "试卷选择不能重复",
+              type: "error",
+              duration: 2000
+            });
+            break;
+          }
+          if (weightCount != 100) {
+            myExamPaperList = [];
+            this.$notify({
+              message: "试卷选取几率总和必须等于100",
+              type: "error",
+              duration: 2000
+            });
+            break;
+          }
+        }
+      }
+      return myExamPaperList;
+    },
+    //返回
+    back() {
+      console.log("aaa");
+      console.log("this.isInsert:", this.isInsert);
+      if (this.isInsert) {
+        this.$router.push({
+          path: "/questions/extract_paper_rule/1"
+        });
+      } else {
+        this.$router.push({
+          path: "/questions/extract_paper_rule/0"
+        });
+      }
+    },
+    //修改调卷规则
+    getExtractConfig(extractConfigId) {
+      this.$http
+        .get(Q_API + "/extractConfig/" + extractConfigId)
+        .then(response => {
+          this.extractConfig = response.data;
+          //查询该考试下的课程
+          this.$http
+            .get(
+              EXAM_WORK_API +
+                "/exam/queryExamCourseList?examId=" +
+                this.extractConfig.examId +
+                "&enable=true&name=" +
+                this.extractConfig.courseCode
+            )
+            .then(response => {
+              this.courseList = response.data;
+              if (!this.courseList || this.courseList.length < 1) {
+                this.$notify({
+                  message: "考务中,该场考试下面,没有设置课程!",
+                  type: "error"
+                });
+              } else {
+                //根据考试ID和课程code取出试卷类型集合
+                this.getPaperTypes();
+              }
+            });
+        });
+    },
+    //根据考试ID和课程code取出试卷类型集合
+    getPaperTypes() {
+      var id = "";
+      if (this.courseList && this.courseList.length > 0) {
+        for (let course of this.courseList) {
+          if (this.extractConfig.courseCode == course.courseCode) {
+            id = course.courseId;
+            break;
+          }
+        }
+        if (id != "") {
+          //查询该课程下的所有试卷
+          this.getPaperList();
+          this.$http
+            .get(
+              EXAM_WORK_API +
+                "/exam/queryExamCoursePaperTypeList?examId=" +
+                this.extractConfig.examId +
+                "&courseId=" +
+                id
+            )
+            .then(response => {
+              let examPaperArr = response.data;
+              if (examPaperArr && examPaperArr.length > 0) {
+                let _examPaperList = [];
+                for (let examPaper of examPaperArr) {
+                  let groupCode = examPaper.paperType;
+                  let weight =
+                    this.extractConfig.examType == "TRADITION" ? 100 : "";
+                  let examPaperListByGroupCode = this.getWeightFromExamPaperList(
+                    groupCode
+                  );
+                  if (examPaperListByGroupCode) {
+                    _examPaperList.push({
+                      groupCode: groupCode,
+                      paperInfoList: examPaperListByGroupCode
+                    });
+                  } else {
+                    _examPaperList.push({
+                      groupCode: groupCode,
+                      paperInfoList: [
+                        {
+                          weight: weight,
+                          paper: { id: "" }
+                        }
+                      ]
+                    });
+                  }
+                }
+                this.examPaperList = _examPaperList;
+                if (this.extractConfig.examType != "PRACTICE") {
+                  this.searchAddAudioTimeConfig();
+                }
+              }
+            });
+          this.getPaperList();
+        } else {
+          this.$notify({
+            message: "考务中,该场考试下面,没有设置该门课程!",
+            type: "error"
+          });
+        }
+      }
+    },
+    //存在调卷规则id,先查询
+    searchAddAudioTimeConfig() {
+      this.audioTimeConfigModelList = [];
+      //取到数组里面每个对象
+      for (var i = 0; i < this.examPaperList.length; i++) {
+        //定一个试卷的集合,用来去重
+        var paperIds = [];
+        for (var j = 0; j < this.examPaperList[i].paperInfoList.length; j++) {
+          paperIds.push(this.examPaperList[i].paperInfoList[j].paper.id);
+        }
+        //对试卷集合进行去重
+        var ids = [];
+        ids = _.uniq(paperIds);
+        for (var k = 0; k < ids.length; k++) {
+          //把对象添加到集合
+          this.audioTimeConfigModelList.push({
+            courseCode: this.extractConfig.courseCode,
+            groupCode: this.examPaperList[i].groupCode,
+            paper: {
+              id: ids[k]
+            },
+            examId: this.extractConfig.examId,
+            examName: this.extractConfig.examName
+          });
+        }
+      }
+      this.$http
+        .post(Q_API + "/audioTimeConfig/update", this.audioTimeConfigModelList)
+        .then(response => {
+          this.audioTimeConfigList = response.data;
+        });
+    }
+  },
+  computed: {
+    ...mapState({ user: state => state.user }),
+    courseInfoSelect() {
+      var courseList = [];
+      for (let course of this.courseList) {
+        var courseInfo = course.courseName + "(" + course.courseCode + ")";
+        courseList.push({
+          courseNo: course.courseCode,
+          courseName: course.courseName,
+          courseInfo: courseInfo
+        });
+      }
+      return courseList;
+    }
+  },
+  //初始化
+  created: function() {
+    let extractConfigId = this.$route.params.extractConfigId;
+    //1.查询考试集合
+    this.getExams("");
+    if (extractConfigId) {
+      this.isInsert = true;
+      //规则ID存在,表示是修改操作
+      this.getExtractConfig(extractConfigId);
+    }
+  }
+};
+</script>
+<style scoped>
+.paper_title {
+  background-color: bisque;
+  width: 400px;
+  border-top-right-radius: 15px;
+  border-bottom-right-radius: 15px;
+}
+.pull_right_ss {
+  margin-left: 30px;
+}
+.paper_title_top {
+  margin-top: -10px;
+}
+.input_width_sms {
+  width: 80px;
+}
+.input_width_ss {
+  width: 50px;
+}
+.el-icon-delete {
+  cursor: pointer;
+}
+[class^="errorMsg_"] {
+  color: #ff4949;
+  display: none;
+}
+.margin-top-10 {
+  margin-top: 10px;
+}
+.row_header_word {
+  font-size: 14px;
+  font-weight: bold;
+}
+.select_width_lg {
+  width: 420px;
+}
+</style>

+ 652 - 0
src/modules/questions/views/ExtractPaperRule.vue

@@ -0,0 +1,652 @@
+<template>
+  <div>
+    <section class="content">
+      <div class="box box-info">
+        <!-- 头信息 -->
+        <div class="box-header with-border">
+          <h3 class="box-title">调卷规则</h3>
+        </div>
+        <!-- 正文信息 -->
+        <div class="box-body" v-loading.body="loading">
+          <el-form :inline="true" :model="formSearch">
+            <el-row>
+              <el-form-item label="考试名称">
+                <el-select
+                  filterable
+                  clearable
+                  v-model="formSearch.examId"
+                  @change="getExamCourses"
+                  placeholder="请选择"
+                  :remote-method="getExams"
+                  remote
+                >
+                  <el-option
+                    v-for="item in examList"
+                    :key="item.id"
+                    :label="item.name"
+                    :value="item.id"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+              <el-form-item label="课程名称">
+                <el-select
+                  filterable
+                  clearable
+                  v-model="formSearch.courseNo"
+                  placeholder="请选择"
+                  :remote-method="getCourses"
+                  remote
+                >
+                  <el-option
+                    v-for="item in courseInfoSelect"
+                    :label="item.courseInfo"
+                    :value="item.courseNo"
+                    :key="item.courseNo"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+              <el-form-item class="pull-right buttonframe">
+                <el-button
+                  size="small"
+                  type="primary"
+                  icon="search"
+                  @click="searchRulePaper"
+                  >查询</el-button
+                >
+                <el-button
+                  size="small"
+                  type="primary"
+                  icon="plus"
+                  @click="markRules"
+                  >新增</el-button
+                >
+                <el-button
+                  size="small"
+                  type="primary"
+                  icon="upload2"
+                  @click="openBatchExportPaperDialog"
+                  >批量导出
+                </el-button>
+              </el-form-item>
+            </el-row>
+          </el-form>
+
+          <!-- 页面列表 -->
+          <el-table
+            :data="tableData"
+            border
+            style="width: 100%;text-align:center;"
+          >
+            <el-table-column prop="examName" label="考试名称">
+            </el-table-column>
+            <el-table-column label="考试类型">
+              <template slot-scope="scope">
+                <div class="el_table_inner_left">
+                  <span v-show="scope.row.examType == 'ONLINE'">在线考试</span>
+                  <span v-show="scope.row.examType == 'TRADITION'"
+                    >传统考试</span
+                  >
+                  <span v-show="scope.row.examType == 'PRACTICE'"
+                    >练习考试</span
+                  >
+                  <span v-show="scope.row.examType == 'OFFLINE'">离线考试</span>
+                  <span v-show="scope.row.examType == 'PRINT_EXAM'"
+                    >分布式印刷考试</span
+                  >
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column prop="courseName" label="课程名称">
+            </el-table-column>
+            <el-table-column prop="courseCode" label="课程代码">
+            </el-table-column>
+            <el-table-column label="调卷类型">
+              <template slot-scope="scope">
+                <div class="el_table_inner_left">
+                  <span v-show="scope.row.callType == 'WHOLE_SET'"
+                    >成套调用</span
+                  >
+                  <span v-show="scope.row.callType == 'RESTRUCT'"
+                    >重组调用</span
+                  >
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="调卷规则">
+              <template slot-scope="scope">
+                <div class="el_table_inner_left">
+                  <span v-show="scope.row.id">
+                    <el-tag type="success">已制定</el-tag>
+                  </span>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="操作">
+              <template slot-scope="scope">
+                <div>
+                  <el-button
+                    v-if="scope.row.ifFinish == 1"
+                    size="small"
+                    type="primary"
+                    @click="openSingleExportPaperDialog(scope.row);"
+                  >
+                    导出
+                  </el-button>
+                  <el-button
+                    v-if="scope.row.id"
+                    size="small"
+                    type="warning"
+                    @click="updateRules(scope.row);"
+                  >
+                    修改
+                  </el-button>
+                </div>
+              </template>
+            </el-table-column>
+          </el-table>
+          <div class="page pull-right">
+            <el-pagination
+              @current-change="handleCurrentChange"
+              :current-page="currentPage"
+              :page-size="pageSize"
+              layout="total, prev, pager, next, jumper"
+              :total="total"
+            >
+            </el-pagination>
+          </div>
+        </div>
+      </div>
+      <el-dialog title="导出" :visible.sync="exportDialog">
+        <el-form :model="exportModel" label-position="right" label-width="80px">
+          <el-row>
+            <el-col :md="24">
+              <el-form-item label="考试名称">
+                <el-select
+                  v-model="exportModel.examId"
+                  filterable
+                  clearable
+                  :disabled="
+                    exportDialog.exportWay == 'SINGLE' &&
+                      exportModel.courseCode != ''
+                  "
+                  @change="checkPaperStructure"
+                >
+                  <el-option
+                    v-for="item in examList"
+                    :key="item.id"
+                    :label="item.name"
+                    :value="item.id"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row v-show="exportModel.courseId">
+            <el-col :md="24">
+              <el-form-item label="课程名称">
+                <el-input v-model="exportModel.courseName" disabled></el-input>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :md="24">
+              <el-form-item
+                label="导出内容"
+                v-if="exportModel.examType != 'PRINT_EXAM'"
+              >
+                <el-checkbox-group
+                  v-model="exportModel.exportContentList"
+                  v-if="exportModel.exportType == 'NORMAL'"
+                >
+                  <el-checkbox label="PAPER" :disabled="paperDisabled"
+                    >试卷</el-checkbox
+                  >
+                  <el-checkbox label="ANSWER" :disabled="answerDisabled"
+                    >答案</el-checkbox
+                  >
+                  <el-checkbox
+                    label="PAPER_STRUCTURE_OBJECTIVE,PAPER_STRUCTURE_SUBJECTIVE"
+                    :disabled="structureDisabled"
+                    >试卷结构
+                  </el-checkbox>
+                </el-checkbox-group>
+                <el-checkbox-group
+                  v-model="exportModel.exportContentList"
+                  v-if="exportModel.exportType == 'ONLINE'"
+                >
+                  <el-checkbox
+                    label="COMPUTERTEST_PACKAGE"
+                    :disabled="onlineDisabled"
+                    >机考数据包
+                  </el-checkbox>
+                </el-checkbox-group>
+              </el-form-item>
+              <el-form-item
+                label="导出内容"
+                v-if="exportModel.examType == 'PRINT_EXAM'"
+              >
+                <el-checkbox-group v-model="exportModel.exportContentList">
+                  <el-checkbox label="PAPER" :disabled="paperDisabled"
+                    >试卷</el-checkbox
+                  >
+                  <el-checkbox label="ANSWER" :disabled="answerDisabled"
+                    >答案</el-checkbox
+                  >
+                  <el-checkbox
+                    v-if="isShowPrintExamPackage"
+                    label="PRINT_EXAM_PACKAGE"
+                    >分布式印刷数据包
+                  </el-checkbox>
+                  <el-input
+                    v-if="isShowPrintExamPackagePassword"
+                    v-model="printExamPackagePassword"
+                    placeholder="加密密码 (可选)"
+                    type="password"
+                    style="width: 150px"
+                  ></el-input>
+                </el-checkbox-group>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :md="24" class="text-center">
+              <el-button type="primary" @click="exportPaperInfo"
+                >开始导出</el-button
+              >
+            </el-col>
+          </el-row>
+        </el-form>
+      </el-dialog>
+    </section>
+  </div>
+</template>
+
+<script>
+import {
+  CORE_API,
+  EXAM_WORK_API,
+  LEVEL_TYPE,
+  Q_API
+} from "../constants/constants";
+import { mapState } from "vuex";
+import _ from "lodash";
+export default {
+  data() {
+    return {
+      isClear: 0,
+      formSearch: {
+        examId: "",
+        courseNo: ""
+      },
+      tableData: [],
+      currentPage: 1,
+      levelList: LEVEL_TYPE,
+      pageSize: 10,
+      total: 0,
+      examList: [], //考试list
+      courseList: [], //课程list
+      loading: false,
+      paperModels: "",
+      exportDialog: false,
+      exportModel: {
+        examType: "",
+        examId: "",
+        courseId: "",
+        courseName: "",
+        exportWay: "",
+        exportType: "NORMAL",
+        exportContentList: []
+      },
+      paperDisabled: true,
+      answerDisabled: true,
+      structureDisabled: true,
+      onlineDisabled: true,
+      courseAllList: [],
+      isShowPrintExamPackage: false,
+      isShowPrintExamPackagePassword: false,
+      printExamPackagePassword: ""
+    };
+  },
+  methods: {
+    //初始化
+    initialize(examId) {
+      this.examList = [];
+      //查询所有考试
+      this.$http.get(EXAM_WORK_API + "/exam/" + examId).then(response => {
+        this.examList.push(response.data);
+        this.formSearch.examId = parseInt(examId);
+        this.searchRulePaper();
+      });
+    },
+    //查询列表
+    searchRulePaper() {
+      if (!this.formSearch.examId) {
+        this.$notify({
+          message: "请选择考试",
+          type: "info"
+        });
+        return false;
+      }
+      this.loading = true;
+      let currentPage = this.currentPage;
+      this.$http
+        .get(
+          Q_API +
+            "/findPageExtractConfig/" +
+            currentPage +
+            "/" +
+            this.pageSize +
+            "?examId=" +
+            this.formSearch.examId +
+            "&courseNo=" +
+            this.formSearch.courseNo
+        )
+        .then(response => {
+          this.tableData = response.data.content;
+          this.total = response.data.totalElements;
+          this.loading = false;
+        })
+        .catch(error => {
+          this.loading = false;
+          this.$notify({
+            message: error.body.desc,
+            type: "error"
+          });
+          this.tableData = [];
+          this.total = 0;
+        });
+    },
+    //分页
+    handleCurrentChange(val) {
+      this.currentPage = val;
+      this.searchRulePaper();
+    },
+    //制定调卷规则
+    markRules() {
+      this.$router.push({
+        name: "extract_paper_info_add"
+      });
+    },
+    //修改调卷规则
+    updateRules(row) {
+      sessionStorage.setItem("extract_paper_examId", row.examId);
+      sessionStorage.setItem("extract_paper_courseNo", row.courseCode);
+      sessionStorage.setItem("extract_paper_currentPage", this.currentPage);
+      this.$router.push({
+        name: "extract_paper_info_edit",
+        params: { extractConfigId: row.id }
+      });
+    },
+    openSingleExportPaperDialog(row) {
+      this.exportModel = {
+        examType: row.examType,
+        examId: row.examId,
+        examName: row.examName,
+        courseId: row.courseCode,
+        courseName: row.courseName,
+        exportType: "NORMAL",
+        exportWay: "SINGLE",
+        exportContentList: []
+      };
+      this.checkPaperStructure();
+      this.exportDialog = true;
+      /* 分布式印刷数据包设置 */
+      //this.exportModel.examType = 'PRINT_EXAM';//todo
+      this.isShowPrintExamPackage = true;
+      this.isShowPrintExamPackagePassword = false;
+      this.printExamPackagePassword = "";
+    },
+    openBatchExportPaperDialog() {
+      this.exportModel = {
+        examType: "",
+        examId: "",
+        examName: "",
+        courseId: "",
+        courseName: "",
+        exportType: "NORMAL",
+        exportWay: "BATCH",
+        exportContentList: []
+      };
+      this.resetDisabled();
+      this.exportDialog = true;
+      /* 分布式印刷数据包设置 */
+      this.isShowPrintExamPackage = false;
+      this.isShowPrintExamPackagePassword = false;
+      this.printExamPackagePassword = "";
+    },
+    checkPaperStructure() {
+      if (!this.exportModel.examId) {
+        return false;
+      }
+      this.exportModel.exportContentList = [];
+      let examFile = {
+        examId: this.exportModel.examId,
+        courseId: this.exportModel.courseId ? this.exportModel.courseId : null
+      };
+      this.resetDisabled();
+      this.$http.post(Q_API + "/findExamFile", examFile).then(response => {
+        let examFiles = response.data;
+        if (examFiles != null && examFiles.length > 0) {
+          this.paperDisabled = this.isDisabled(examFiles, "PAPER");
+          this.answerDisabled = this.isDisabled(examFiles, "ANSWER");
+          this.onlineDisabled = this.isDisabled(
+            examFiles,
+            "COMPUTERTEST_PACKAGE"
+          );
+
+          this.$http
+            .get(Q_API + "/findExportStructure/" + this.exportModel.examId)
+            .then(response => {
+              this.exportModel.exportType = response.data
+                ? response.data.exportType
+                : "NORMAL";
+              this.structureDisabled = !response.data;
+              if (this.exportModel.exportWay == "SINGLE") {
+                this.structureDisabled = this.isDisabled(
+                  examFiles,
+                  "PAPER_STRUCTURE_OBJECTIVE"
+                );
+              }
+            });
+        } else {
+          this.resetDisabled();
+        }
+      });
+    },
+    isDisabled(examFiles, fileType) {
+      return (
+        _.filter(examFiles, function(examFile) {
+          return examFile.examFileType == fileType;
+        }).length == 0
+      );
+    },
+    resetDisabled() {
+      this.paperDisabled = true;
+      this.answerDisabled = true;
+      this.structureDisabled = true;
+      this.onlineDisabled = true;
+    },
+    exportPaperInfo() {
+      let examId = this.exportModel.examId;
+      let courseId = this.exportModel.courseId;
+      let exportWay = this.exportModel.exportWay;
+      if (!examId) {
+        this.$notify({
+          message: "请选择考试",
+          type: "error"
+        });
+        return false;
+      }
+      if (this.exportModel.exportContentList.length == 0) {
+        this.$notify({
+          message: "请选择导出内容",
+          type: "error"
+        });
+        return false;
+      }
+      if (this.printExamPackagePassword.length > 0) {
+        var reg = /^[0-9A-Za-z]{6,12}$/;
+        if (!reg.test(this.printExamPackagePassword)) {
+          this.$notify({
+            message: "加密密码请输入6至12位的数字或字母!",
+            type: "error"
+          });
+          return false;
+        }
+      }
+      let exportContentList = this.exportModel.exportContentList.toString();
+      var key = this.user.key;
+      var token = this.user.token;
+      this.$http
+        .get(
+          Q_API +
+            "/exportBatchExamPaperInfoCheck/" +
+            exportWay +
+            "/" +
+            examId +
+            "?$key=" +
+            key +
+            "&$token=" +
+            token
+        )
+        .then(
+          response => {
+            console.log(response);
+            if (response.data) {
+              this.$notify({
+                message: response.data.desc,
+                type: "error"
+              });
+            } else {
+              var key = this.user.key;
+              var token = this.user.token;
+              if (exportWay == "SINGLE") {
+                window.location.href =
+                  Q_API +
+                  "/exportSingleExamPaperInfo/" +
+                  this.user.rootOrgName +
+                  "/" +
+                  exportWay +
+                  "/" +
+                  examId +
+                  "/" +
+                  courseId +
+                  "/" +
+                  exportContentList +
+                  "/" +
+                  this.user.displayName +
+                  "?psw=" +
+                  this.printExamPackagePassword +
+                  "&$key=" +
+                  key +
+                  "&$token=" +
+                  token;
+              } else if (exportWay == "BATCH") {
+                window.location.href =
+                  Q_API +
+                  "/exportBatchExamPaperInfo/" +
+                  this.user.rootOrgName +
+                  "/" +
+                  exportWay +
+                  "/" +
+                  examId +
+                  "/" +
+                  exportContentList +
+                  "/" +
+                  this.user.displayName +
+                  "?$key=" +
+                  key +
+                  "&$token=" +
+                  token;
+              }
+            }
+          },
+          error => {
+            console.log("aaa");
+            this.$notify({
+              message: error.body.desc,
+              type: "error"
+            });
+          }
+        );
+    },
+    removeItem() {
+      sessionStorage.removeItem("extract_paper_currentPage");
+      sessionStorage.removeItem("extract_paper_examId");
+      sessionStorage.removeItem("extract_paper_courseNo");
+    },
+    //查询所有课程
+    getCourses(query) {
+      query = query.trim();
+      if (query) {
+        if (!(query.indexOf("(") > -1 && query.indexOf(")") > -1)) {
+          this.courseLoading = true;
+          this.$http
+            .get(CORE_API + "/course/query?name=" + query + "&enable=true")
+            .then(response => {
+              this.courseList = response.data;
+              this.courseLoading = false;
+            });
+        }
+      } else {
+        this.courseList = [];
+      }
+    },
+    //查询考试
+    getExams(query) {
+      query = query.trim();
+      this.$http
+        .get(
+          EXAM_WORK_API + "/exam/queryByNameLike?name=" + query + "&enable=true"
+        )
+        .then(response => {
+          this.examList = response.data;
+        });
+    },
+    //清空课程列表
+    getExamCourses() {
+      console.log("clean");
+      this.formSearch.courseNo = "";
+    }
+  },
+  computed: {
+    ...mapState({ user: state => state.user }),
+    courseInfoSelect() {
+      var courseList = [];
+      for (let course of this.courseList) {
+        var courseInfo = course.name + "(" + course.code + ")";
+        courseList.push({
+          courseNo: course.code,
+          courseName: course.name,
+          courseInfo: courseInfo
+        });
+      }
+      return courseList;
+    }
+  },
+  created() {
+    this.isClear = this.$route.params.isClear;
+    if (this.isClear == 0 || !this.isClear) {
+      this.removeItem();
+      //查询所有考试
+      this.getExams("");
+    } else {
+      this.formSearch.courseNo =
+        sessionStorage.getItem("extract_paper_courseNo") == "null"
+          ? ""
+          : sessionStorage.getItem("extract_paper_courseNo");
+      this.formSearch.examId = parseInt(
+        sessionStorage.getItem("extract_paper_examId")
+      );
+      this.currentPage =
+        sessionStorage.getItem("extract_paper_currentPage") == null
+          ? 1
+          : parseInt(sessionStorage.getItem("extract_paper_currentPage"));
+      this.initialize(this.formSearch.examId);
+    }
+  }
+};
+</script>

+ 3 - 8
src/modules/questions/views/GenPaper.vue

@@ -202,7 +202,7 @@
           </div>
         </div>
       </div>
-      <el-dialog title="导出" v-model="exportDialog">
+      <el-dialog title="导出" :visible.sync="exportDialog">
         <el-form :model="exportModel" label-position="right" label-width="80px">
           <el-row v-if="isShow">
             <el-col :md="12">
@@ -300,6 +300,7 @@ import { mapState } from "vuex";
 export default {
   data() {
     return {
+      isClear: 0,
       courseLoading: false,
       formSearch: {
         courseNo: "",
@@ -371,7 +372,7 @@ export default {
         sessionStorage.setItem("gen_paper_currentPage", this.currentPage);
         sessionStorage.setItem("gen_paper_courseName", courseName);
         this.$router.push({
-          path: "/index/gen_paper_detail/" + courseNo + "/" + level
+          path: "/questions/gen_paper_detail/" + courseNo + "/" + level
         });
       }
     },
@@ -379,12 +380,6 @@ export default {
       this.currentPage = val;
       this.searchGenPaper();
     },
-    getCoursesByKey(query) {
-      this.$http.get(Q_API + "/course?keyword=" + query).then(response => {
-        this.courseList = response.data;
-        this.loading = false;
-      });
-    },
     getCourseName(courseNo) {
       for (let course of this.courseList) {
         if (course.code == courseNo) {

+ 1154 - 0
src/modules/questions/views/GenPaperDetail.vue

@@ -0,0 +1,1154 @@
+<template>
+  <div v-loading="fullscreenLoading" element-loading-text="正在组卷中...">
+    <div class="tabs">
+      <el-form
+        :inline="true"
+        :model="genPaper"
+        label-position="right"
+        label-width="100px"
+      >
+        <el-form-item label="课程代码" class="form-item">
+          <el-input
+            :disabled="true"
+            placeholder="课程代码"
+            v-model="genPaper.courseNo"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="课程名称" class="form-item">
+          <el-input
+            :disabled="true"
+            placeholder="课程名称"
+            v-model="genPaper.courseName"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="试卷名称" class="form-item">
+          <el-input
+            placeholder="试卷名称"
+            v-model="genPaper.paperName"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="组卷套数" class="form-item">
+          <el-input
+            placeholder="组卷套数"
+            v-model="genPaper.genNumber"
+          ></el-input>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div class="tabs">
+      <el-tabs v-model="tabs">
+        <el-tab-pane label="步骤一:组卷模式选择" name="first">
+          <el-radio-group
+            class="pull-left"
+            v-model="genType"
+            @change="genTypeChange"
+          >
+            <el-radio label="SIMPLE">简易成卷</el-radio>
+            <el-radio label="NORMAL">精确成卷</el-radio>
+            <el-radio label="BLUE">蓝图成卷</el-radio>
+          </el-radio-group>
+        </el-tab-pane>
+      </el-tabs>
+    </div>
+    <div class="tabs">
+      <el-tabs v-model="tabs">
+        <el-tab-pane label="步骤二:题源选择" name="first">
+          <div style="width: 50%" v-show="genType == 'SIMPLE'">
+            <el-form :inline="true" label-position="right" label-width="100px">
+              <el-form-item label="题源选择" class="form-item">
+                <el-select
+                  @change="changePaperType"
+                  v-model="paperType"
+                  clearable
+                  placeholder="题源选择"
+                  style="width: 120px;"
+                >
+                  <el-option label="题库来源" value="IMPORT"></el-option>
+                  <el-option label="卷库来源" value="GENERATE"></el-option>
+                </el-select>
+              </el-form-item>
+            </el-form>
+            <el-table
+              v-loading="loading"
+              :data="selectPapers"
+              border
+              @selection-change="selectChange"
+            >
+              <el-table-column type="selection" width="55"></el-table-column>
+              <el-table-column label="名称" width="200">
+                <template slot-scope="scope">
+                  <div>
+                    <span>{{ scope.row.name }}</span>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="总分" width="100">
+                <template slot-scope="scope">
+                  <div>
+                    <span>{{ scope.row.totalScore }}</span>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="小题数量">
+                <template slot-scope="scope">
+                  <div>
+                    <span>{{ scope.row.unitCount }}</span>
+                  </div>
+                </template>
+              </el-table-column>
+            </el-table>
+            <div class="page pull-right">
+              <el-pagination
+                @current-change="selectCurrentChange"
+                :current-page="curSelect"
+                :page-size="pageSize"
+                layout="total, prev, pager, next, jumper"
+                :total="totalSelect"
+              >
+              </el-pagination>
+            </div>
+          </div>
+          <!-- 精确组卷题源 -->
+          <div style="width: 50%;overflow:auto" v-show="genType == 'NORMAL'">
+            <el-form :inline="true" label-position="right" label-width="100px">
+              <el-form-item label="题源选择" class="form-item">
+                <el-select
+                  @change="changePaperType"
+                  v-model="paperType"
+                  clearable
+                  placeholder="题源选择"
+                  style="width: 120px;"
+                >
+                  <el-option label="题库来源" value="IMPORT"></el-option>
+                  <el-option label="卷库来源" value="GENERATE"></el-option>
+                </el-select>
+              </el-form-item>
+            </el-form>
+            <el-table
+              v-loading="loading"
+              :data="selectPapers"
+              border
+              @selection-change="selectChange"
+            >
+              <el-table-column type="selection" width="55"></el-table-column>
+              <el-table-column label="名称" width="200">
+                <template slot-scope="scope">
+                  <div>
+                    <span>{{ scope.row.name }}</span>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="总分" width="100">
+                <template slot-scope="scope">
+                  <div>
+                    <span>{{ scope.row.totalScore }}</span>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="小题数量">
+                <template slot-scope="scope">
+                  <div>
+                    <span>{{ scope.row.unitCount }}</span>
+                  </div>
+                </template>
+              </el-table-column>
+            </el-table>
+            <div class="page pull-right">
+              <el-pagination
+                @current-change="selectCurrentChange"
+                :current-page="curSelect"
+                :page-size="pageSize"
+                layout="total, prev, pager, next, jumper"
+                :total="totalSelect"
+              >
+              </el-pagination>
+            </div>
+            <el-form :inline="true" label-position="right" label-width="100px">
+              <el-form-item
+                label="选中试卷列表"
+                class="form-item"
+              ></el-form-item>
+            </el-form>
+            <el-table :data="selectedPapers" border>
+              <el-table-column label="名称" width="200">
+                <template slot-scope="scope">
+                  <div>
+                    <span>{{ scope.row.name }}</span>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="操作">
+                <template slot-scope="scope">
+                  <div>
+                    <el-button
+                      type="danger"
+                      size="mini"
+                      @click="removeSelected(scope.row.id);"
+                      >移除</el-button
+                    >
+                  </div>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+          <!-- 蓝图组卷题源 -->
+          <div style="width: 50%;overflow:auto" v-show="genType == 'BLUE'">
+            <el-form :inline="true" label-position="right" label-width="100px">
+              <el-form-item label="题源选择" class="form-item">
+                <el-select
+                  @change="changePaperType"
+                  v-model="paperType"
+                  clearable
+                  placeholder="题源选择"
+                  style="width: 120px;"
+                >
+                  <el-option label="题库来源" value="IMPORT"></el-option>
+                  <el-option label="卷库来源" value="GENERATE"></el-option>
+                </el-select>
+              </el-form-item>
+            </el-form>
+            <el-table
+              v-loading="loading"
+              :data="selectPapers"
+              border
+              @selection-change="selectChange"
+            >
+              <el-table-column type="selection" width="55"></el-table-column>
+              <el-table-column label="名称" width="200">
+                <template slot-scope="scope">
+                  <div>
+                    <span>{{ scope.row.name }}</span>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="总分" width="100">
+                <template slot-scope="scope">
+                  <div>
+                    <span>{{ scope.row.totalScore }}</span>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="小题数量">
+                <template slot-scope="scope">
+                  <div>
+                    <span>{{ scope.row.unitCount }}</span>
+                  </div>
+                </template>
+              </el-table-column>
+            </el-table>
+            <div class="page pull-right">
+              <el-pagination
+                @current-change="selectCurrentChange"
+                :current-page="curSelect"
+                :page-size="pageSize"
+                layout="total, prev, pager, next, jumper"
+                :total="totalSelect"
+              >
+              </el-pagination>
+            </div>
+            <el-form :inline="true" label-position="right" label-width="100px">
+              <el-form-item
+                label="选中试卷列表"
+                class="form-item"
+              ></el-form-item>
+            </el-form>
+            <el-table :data="selectedPapers" border>
+              <el-table-column label="名称" width="200">
+                <template slot-scope="scope">
+                  <div>
+                    <span>{{ scope.row.name }}</span>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="操作">
+                <template slot-scope="scope">
+                  <div>
+                    <el-button
+                      type="danger"
+                      size="mini"
+                      @click="removeSelected(scope.row.id);"
+                      >移除</el-button
+                    >
+                  </div>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+        </el-tab-pane>
+      </el-tabs>
+    </div>
+
+    <div class="tabs">
+      <el-tabs v-model="tabs">
+        <el-tab-pane label="步骤三:确定构成" name="first">
+          <!-- 简易 -->
+          <div style="width:98%;overflow:auto" v-show="genType == 'SIMPLE'">
+            <el-form :inline="true" label-position="right" label-width="100px">
+              <el-form-item label="抽取策略" class="form-item">
+                <el-select
+                  v-model="genPaper.simpleGenPaperPolicy"
+                  clearable
+                  placeholder="抽取策略"
+                >
+                  <el-option
+                    v-for="item in simpleGenPaperPolicys"
+                    :label="item.label"
+                    :value="item.value"
+                    :key="item.value"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-form>
+            <el-table :data="tempPapers" border>
+              <el-table-column label="名称" width="140">
+                <template slot-scope="scope">
+                  <div>
+                    <span>{{ scope.row.name }}</span>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="总分" width="80">
+                <template slot-scope="scope">
+                  <div>
+                    <span>{{ scope.row.totalScore }}</span>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="小题数量" width="100">
+                <template slot-scope="scope">
+                  <div>
+                    <span>{{ scope.row.unitCount }}</span>
+                  </div>
+                </template>
+              </el-table-column>
+              <!-- 新增公开度和难度 -->
+              <el-table-column label="公开(简单)" width="100">
+                <template slot-scope="scope">
+                  <div
+                    @mouseenter="showActiveIn(1, 1, scope.row);"
+                    @mouseleave="showActiveOff"
+                  >
+                    <el-tooltip placement="top">
+                      <div slot="content">{{ message }}</div>
+                      <span
+                        ><el-input
+                          v-model="scope.row.publicSimple"
+                          @change="
+                            sum(
+                              scope.row,
+                              scope.row.publicSimple,
+                              'publicSimple'
+                            );
+                          "
+                        ></el-input
+                      ></span>
+                    </el-tooltip>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="公开(中等)" width="100">
+                <template slot-scope="scope">
+                  <div
+                    @mouseenter="showActiveIn(1, 2, scope.row);"
+                    @mouseleave="showActiveOff"
+                  >
+                    <el-tooltip placement="top">
+                      <div slot="content">{{ message }}</div>
+                      <span
+                        ><el-input
+                          v-model="scope.row.publicMedium"
+                          @change="
+                            sum(
+                              scope.row,
+                              scope.row.publicMedium,
+                              'publicMedium'
+                            );
+                          "
+                        ></el-input
+                      ></span>
+                    </el-tooltip>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="公开(困难)" width="100">
+                <template slot-scope="scope">
+                  <div
+                    @mouseenter="showActiveIn(1, 3, scope.row);"
+                    @mouseleave="showActiveOff"
+                  >
+                    <el-tooltip placement="top">
+                      <div slot="content">{{ message }}</div>
+                      <span
+                        ><el-input
+                          v-model="scope.row.publicDifficulty"
+                          @change="
+                            sum(
+                              scope.row,
+                              scope.row.publicDifficulty,
+                              'publicDifficulty'
+                            );
+                          "
+                        ></el-input
+                      ></span>
+                    </el-tooltip>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="非公开(简单)" width="100">
+                <template slot-scope="scope">
+                  <div
+                    @mouseenter="showActiveIn(0, 1, scope.row);"
+                    @mouseleave="showActiveOff"
+                  >
+                    <el-tooltip placement="top">
+                      <div slot="content">{{ message }}</div>
+                      <span
+                        ><el-input
+                          v-model="scope.row.noPublicSimple"
+                          @change="
+                            sum(
+                              scope.row,
+                              scope.row.noPublicSimple,
+                              'noPublicSimple'
+                            );
+                          "
+                        ></el-input
+                      ></span>
+                    </el-tooltip>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="非公开(中等)" width="100">
+                <template slot-scope="scope">
+                  <div
+                    @mouseenter="showActiveIn(0, 2, scope.row);"
+                    @mouseleave="showActiveOff"
+                  >
+                    <el-tooltip placement="top">
+                      <div slot="content">{{ message }}</div>
+                      <span
+                        ><el-input
+                          v-model="scope.row.noPublicMedium"
+                          @change="
+                            sum(
+                              scope.row,
+                              scope.row.noPublicMedium,
+                              'noPublicMedium'
+                            );
+                          "
+                        ></el-input
+                      ></span>
+                    </el-tooltip>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="非公开(困难)" width="100">
+                <template slot-scope="scope">
+                  <div
+                    @mouseenter="showActiveIn(0, 3, scope.row);"
+                    @mouseleave="showActiveOff"
+                  >
+                    <el-tooltip placement="top">
+                      <div slot="content">{{ message }}</div>
+                      <span
+                        ><el-input
+                          v-model="scope.row.noPublicDifficulty"
+                          @change="
+                            sum(
+                              scope.row,
+                              scope.row.noPublicDifficulty,
+                              'noPublicDifficulty'
+                            );
+                          "
+                        ></el-input
+                      ></span>
+                    </el-tooltip>
+                  </div>
+                </template>
+              </el-table-column>
+              <!-- 总数求和 -->
+              <el-table-column :label="setName()" width="100">
+                <template slot-scope="scope">
+                  <div>
+                    <span
+                      ><el-input
+                        placeholder="抽取数值"
+                        v-model="scope.row.count"
+                        :disabled="true"
+                      ></el-input
+                    ></span>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="操作">
+                <template slot-scope="scope">
+                  <div>
+                    <el-button
+                      type="danger"
+                      size="mini"
+                      @click="removeSelected(scope.row.id);"
+                      >移除</el-button
+                    >
+                  </div>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+          <!-- 精确 -->
+          <div style="width: 50%;overflow:auto" v-show="genType == 'NORMAL'">
+            <el-form :inline="true" label-position="right" label-width="100px">
+              <el-form-item label="试卷结构" class="form-item">
+                <el-select
+                  @change="changePaperStruct"
+                  v-model="genPaper.paperStructId"
+                  clearable
+                  placeholder="试卷结构"
+                >
+                  <el-option
+                    v-for="item in exactStructs"
+                    :label="item.name"
+                    :value="item.id"
+                    :key="item.id"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-form>
+            <el-table :data="paperDetailStructs" border>
+              <el-table-column label="名称" width="250">
+                <template slot-scope="scope">
+                  <div>
+                    <span>{{ scope.row.name }}</span>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="总分" width="100">
+                <template slot-scope="scope">
+                  <div>
+                    <span>{{ scope.row.totalScore }}</span>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="题量">
+                <template slot-scope="scope">
+                  <div>
+                    <span>{{ scope.row.detailCount }}</span>
+                  </div>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+          <!-- 蓝图 -->
+          <div style="width: 50%;overflow:auto" v-show="genType == 'BLUE'">
+            <el-form :inline="true" label-position="right" label-width="100px">
+              <el-form-item label="试卷结构" class="form-item">
+                <el-select
+                  @change="changePaperStruct"
+                  v-model="genPaper.paperStructId"
+                  clearable
+                  placeholder="试卷结构"
+                  style="width: 120px;"
+                >
+                  <el-option
+                    v-for="item in blueStructs"
+                    :label="item.name"
+                    :value="item.id"
+                    :key="item.id"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+              <el-form-item label="难度">
+                <el-input
+                  v-model="difficulty"
+                  style="width: 50px;"
+                  disabled
+                ></el-input>
+              </el-form-item>
+            </el-form>
+            <el-table :data="paperDetailStructs" border>
+              <el-table-column label="名称" width="250">
+                <template slot-scope="scope">
+                  <div>
+                    <span>{{ scope.row.name }}</span>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="总分" width="100">
+                <template slot-scope="scope">
+                  <div>
+                    <span>{{ scope.row.totalScore }}</span>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column label="题量">
+                <template slot-scope="scope">
+                  <div>
+                    <span>{{ scope.row.detailCount }}</span>
+                  </div>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+        </el-tab-pane>
+      </el-tabs>
+      <div class="pull-right">
+        <el-button type="primary" icon="check" @click="confirmGenPaper"
+          >确定</el-button
+        >
+        <el-button type="primary" icon="caret-left" @click="back"
+          >返回</el-button
+        >
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { Q_API } from "../constants/constants";
+
+export default {
+  data() {
+    return {
+      tabs: "first",
+      genType: "SIMPLE",
+      genPaper: {
+        courseNo: "",
+        courseName: "",
+        level: "",
+        paperName: "",
+        paperIds: [],
+        genNumber: "",
+        paperStructId: "",
+        simpleParams: {},
+        simpleGenPaperPolicy: "BY_QUESTIONNUM"
+      },
+      simpleGenPaperPolicys: [
+        { label: "按试题数量抽取", value: "BY_QUESTIONNUM" },
+        { label: "按试题分数抽取", value: "BY_SCORE" }
+      ],
+      tempPapers: [],
+      tempPaperIds: [],
+      selectPapers: [],
+      selectAllPapers: [],
+      paperStructs: [],
+      paperDetailStructs: [],
+      blueStructs: [], //蓝图组卷
+      exactStructs: [], //精确组卷
+      curSelect: 1,
+      totalSelect: 10,
+      pageSize: 10,
+      loading: false,
+      fullscreenLoading: false,
+      difficulty: "",
+      coursePropertyList: [],
+      paperType: "IMPORT",
+      selectedNPapers: [],
+      message: ""
+    };
+  },
+  methods: {
+    setName() {
+      if (this.genPaper.simpleGenPaperPolicy == "BY_QUESTIONNUM") {
+        return "抽取数量";
+      } else {
+        return "抽取分数";
+      }
+    },
+    genTypeChange() {
+      this.curSelect = 1;
+      this.tempPapers = [];
+      this.paperIds = [];
+      this.genPaper.paperStructId = "";
+      //this.genPaper.simpleGenPaperPolicy = '';
+      this.tempPaperIds = [];
+      this.paperDetailStructs = [];
+      this.searchPaper();
+    },
+    selectChange(val) {
+      console.log("val123:");
+      val.forEach(element => {
+        element.publicSimple = 0;
+        element.publicMedium = 0;
+        element.publicDifficulty = 0;
+        element.noPublicSimple = 0;
+        element.noPublicMedium = 0;
+        element.noPublicDifficulty = 0;
+        element.count = 0;
+        this.tempPapers.push(element);
+        this.tempPaperIds.push(element.id);
+      });
+      this.searchPaper();
+    },
+    searchPaper() {
+      this.loading = true;
+      if (this.paperType == "IMPORT") {
+        this.$http
+          .get(
+            Q_API +
+              "/importPaper/" +
+              this.tempPaperIds +
+              "/" +
+              this.curSelect +
+              "/" +
+              this.pageSize +
+              "?courseNo=" +
+              this.genPaper.courseNo
+          )
+          .then(response => {
+            console.log("response:", response);
+            this.selectPapers = response.data.content;
+            this.totalSelect = response.data.totalElements;
+            this.loading = false;
+          });
+      } else if (this.paperType == "GENERATE") {
+        this.$http
+          .get(
+            Q_API +
+              "/genPaper/" +
+              this.tempPaperIds +
+              "/" +
+              this.curSelect +
+              "/" +
+              this.pageSize +
+              "?courseNo=" +
+              this.genPaper.courseNo
+          )
+          .then(response => {
+            this.selectPapers = response.data.content;
+            this.totalSelect = response.data.totalElements;
+            this.loading = false;
+          });
+      } else {
+        console.log("空值");
+        this.selectPapers = [];
+        this.totalSelect = 0;
+        this.loading = false;
+      }
+    },
+    changePaperStruct() {
+      this.paperDetailStructs = [];
+      this.searchPaperDetailStructs();
+    },
+    searchPaperStructs() {
+      console.log("bbb");
+      var courseNo = this.genPaper.courseNo;
+      var url = Q_API + "/paperStruct?courseNo=" + courseNo;
+      this.loading = true;
+      this.$http.get(url).then(response => {
+        this.paperStructs = response.data;
+        for (let paperStructObj of this.paperStructs) {
+          if (paperStructObj.paperStrucType == "BLUEPRINT") {
+            for (let couProperty of this.coursePropertyList) {
+              if (couProperty.id == paperStructObj.coursePropertyId) {
+                this.blueStructs.push(paperStructObj);
+              }
+            }
+          } else {
+            this.exactStructs.push(paperStructObj);
+          }
+        }
+        this.loading = false;
+      });
+    },
+    searchPaperDetailStructs() {
+      console.log("this.genPaper.paperStructId:", this.genPaper.paperStructId);
+      for (let paperStruct of this.paperStructs) {
+        if (paperStruct.id == this.genPaper.paperStructId) {
+          this.paperDetailStructs = paperStruct.paperDetailStructs;
+          this.difficulty = paperStruct.difficulty;
+          break;
+        }
+      }
+    },
+    checkGenPaper() {
+      if (!this.genPaper.paperName) {
+        this.$notify({
+          message: "试卷名称不能为空!",
+          type: "error"
+        });
+        return false;
+      }
+      var numReg = /^[1-9]\d*$/;
+      if (!this.genPaper.genNumber) {
+        this.$notify({
+          message: "请输入需要组卷套数!",
+          type: "error"
+        });
+        return false;
+      }
+      if (
+        !numReg.test(this.genPaper.genNumber) ||
+        parseInt(this.genPaper.genNumber) >= 100
+      ) {
+        this.$notify({
+          message: "组卷套数必须为1-99之间的整数!",
+          type: "error"
+        });
+        return false;
+      }
+      if (this.genType == "SIMPLE" && this.selectedIds.length == 0) {
+        this.$notify({
+          message: "请选择题源范围!",
+          type: "error"
+        });
+        return false;
+      }
+      if (this.genType == "NORMAL") {
+        if (!this.selectedIds || this.selectedIds.length == 0) {
+          this.$notify({
+            message: "请选择题源范围!",
+            type: "error"
+          });
+          return false;
+        } else if (this.paperDetailStructs.length == 0) {
+          this.$notify({
+            message: "请选择试卷结构!",
+            type: "error"
+          });
+          return false;
+        }
+      }
+      if (this.genType == "BLUE") {
+        if (!this.selectedIds || this.selectedIds.length == 0) {
+          this.$notify({
+            message: "请选择题源范围!",
+            type: "error"
+          });
+          return false;
+        } else if (this.paperDetailStructs.length == 0) {
+          this.$notify({
+            message: "请选择试卷结构!",
+            type: "error"
+          });
+          return false;
+        }
+      }
+      return true;
+    },
+    confirmGenPaper() {
+      if (!this.checkGenPaper()) {
+        console.log("false");
+        return false;
+      } else {
+        var url = "";
+        if (this.genType == "SIMPLE") {
+          url = Q_API + "/genPaper/simple";
+        } else if (this.genType == "NORMAL") {
+          url = Q_API + "/genPaper/normal";
+        } else {
+          url = Q_API + "/genPaper/blue";
+        }
+        console.log("this.setSimpleParams():", this.setSimpleParams());
+        if (!this.setSimpleParams()) {
+          return;
+        }
+        this.fullscreenLoading = true;
+        this.$http.post(url, this.genPaper).then(
+          response => {
+            this.$notify({
+              message: "组卷成功",
+              type: "success"
+            });
+            this.fullscreenLoading = false;
+            if (this.genPaper.genNumber == 1) {
+              let paperId = response.data.paper.id;
+              this.$router.push({
+                path: "/edit_paper/" + paperId + "/gen_paper"
+              });
+            } else {
+              this.back();
+            }
+          },
+          response => {
+            this.$notify({
+              message: response.data.msg,
+              type: "error"
+            });
+            this.fullscreenLoading = false;
+          }
+        );
+      }
+    },
+    selectCurrentChange(val) {
+      this.curSelect = val;
+      this.searchPaper();
+    },
+    back() {
+      this.$router.push({ path: "/index/gen_paper/1" });
+    },
+    removePaper(id) {
+      for (let [index, paper] of this.selectPapers.entries()) {
+        if (id == paper.id) {
+          this.selectPapers.splice(index, 1);
+          break;
+        }
+      }
+    },
+    removeSelected(id) {
+      for (let [index, paper] of this.tempPapers.entries()) {
+        if (id == paper.id) {
+          this.tempPapers.splice(index, 1);
+          this.selectPapers.push(paper);
+          break;
+        }
+      }
+      for (var i = 0; i < this.tempPaperIds.length; i++) {
+        if (this.tempPaperIds[i] == id) {
+          this.tempPaperIds.splice(i, 1);
+          break;
+        }
+      }
+      this.searchPaper();
+    },
+    setSimpleParams() {
+      var simpleParams = new Object();
+      for (let paper of this.tempPapers) {
+        console.log("paper", paper);
+        if (this.genPaper.simpleGenPaperPolicy == "BY_SCORE") {
+          if (!this.isNumber(paper.publicSimple)) {
+            this.$notify({
+              message: "“抽取策略”中的“抽取分数”列要为正数!",
+              type: "error"
+            });
+            return false;
+          }
+          if (!this.isNumber(paper.publicMedium)) {
+            this.$notify({
+              message: "“抽取策略”中的“抽取分数”列要为正数!",
+              type: "error"
+            });
+            return false;
+          }
+          if (!this.isNumber(paper.publicDifficulty)) {
+            this.$notify({
+              message: "“抽取策略”中的“抽取分数”列要为正数!",
+              type: "error"
+            });
+            return false;
+          }
+          if (!this.isNumber(paper.noPublicSimple)) {
+            this.$notify({
+              message: "“抽取策略”中的“抽取分数”列要为正数!",
+              type: "error"
+            });
+            return false;
+          }
+          if (!this.isNumber(paper.noPublicMedium)) {
+            this.$notify({
+              message: "“抽取策略”中的“抽取分数”列要为正数!",
+              type: "error"
+            });
+            return false;
+          }
+          if (!this.isNumber(paper.noPublicDifficulty)) {
+            this.$notify({
+              message: "“抽取策略”中的“抽取分数”列要为正数!",
+              type: "error"
+            });
+            return false;
+          }
+        } else {
+          if (!this.isFloat(paper.publicSimple)) {
+            this.$notify({
+              message: "“抽取策略”中的“抽取数量”列要为正整数!",
+              type: "error"
+            });
+            return false;
+          }
+          if (!this.isFloat(paper.publicMedium)) {
+            this.$notify({
+              message: "“抽取策略”中的“抽取数量”列要为正整数!",
+              type: "error"
+            });
+            return false;
+          }
+          if (!this.isFloat(paper.publicDifficulty)) {
+            this.$notify({
+              message: "“抽取策略”中的“抽取数量”列要为正整数!",
+              type: "error"
+            });
+            return false;
+          }
+          if (!this.isFloat(paper.noPublicSimple)) {
+            this.$notify({
+              message: "“抽取策略”中的“抽取数量”列要为正整数!",
+              type: "error"
+            });
+            return false;
+          }
+          if (!this.isFloat(paper.noPublicMedium)) {
+            this.$notify({
+              message: "“抽取策略”中的“抽取数量”列要为正整数!",
+              type: "error"
+            });
+            return false;
+          }
+          if (!this.isFloat(paper.noPublicDifficulty)) {
+            this.$notify({
+              message: "“抽取策略”中的“抽取数量”列要为正整数!",
+              type: "error"
+            });
+            return false;
+          }
+        }
+        var numberParams = {};
+        (numberParams.publicSimple = paper.publicSimple),
+          (numberParams.publicMedium = paper.publicMedium),
+          (numberParams.publicDifficulty = paper.publicDifficulty),
+          (numberParams.noPublicSimple = paper.noPublicSimple),
+          (numberParams.noPublicMedium = paper.noPublicMedium),
+          (numberParams.noPublicDifficulty = paper.noPublicDifficulty),
+          (numberParams.count = paper.count);
+        simpleParams[paper.id] = numberParams;
+      }
+      this.genPaper.simpleParams = simpleParams;
+      console.log("this.genPaper.simpleParams:", this.genPaper.simpleParams);
+      return true;
+    },
+    //查询课程下开启的课程属性
+    getCoursePropertyList() {
+      var courseNo = this.genPaper.courseNo;
+      this.$http
+        .get(Q_API + "/courseProperty/enable/" + courseNo)
+        .then(response => {
+          this.coursePropertyList = response.data;
+          this.searchPaperStructs();
+        });
+    },
+    changePaperType() {
+      this.curSelect = 1;
+      this.tempPapers = [];
+      this.tempPaperIds = [];
+      this.searchPaper();
+    },
+    sum(row) {
+      setTimeout(function() {
+        row.count =
+          parseFloat(row.publicSimple) +
+          parseFloat(row.publicMedium) +
+          parseFloat(row.publicDifficulty) +
+          parseFloat(row.noPublicSimple) +
+          parseFloat(row.noPublicMedium) +
+          parseFloat(row.noPublicDifficulty);
+      }, 2);
+    },
+    //判断是否为正数
+    isNumber(num) {
+      var reg = /^\d+(?=\.{0,1}\d+$|$)/;
+      if (reg.test(num)) {
+        return true;
+      }
+      return false;
+    },
+    //判断正小数
+    isFloat(num) {
+      var reg = /^[0-9]+$/;
+      if (reg.test(num)) {
+        return true;
+      }
+      return false;
+    },
+    //判断输入字符串是否为空或者全部都是空格
+    isNull(str) {
+      if (str == "") {
+        return true;
+      }
+      var regu = "^[ ]+$";
+      var re = new RegExp(regu);
+      return re.test(str);
+    },
+    //鼠标悬浮事件
+    showActiveIn(publicity, difficulty, row) {
+      //console.log('this.genPaper.simpleGenPaperPolicy',row);
+      if (this.genPaper.simpleGenPaperPolicy == "BY_QUESTIONNUM") {
+        this.$http
+          .get(
+            Q_API +
+              "/paper/questionNumbers/" +
+              row.id +
+              "/" +
+              publicity +
+              "/" +
+              difficulty
+          )
+          .then(response => {
+            this.message = response.data;
+          });
+      }
+      if (this.genPaper.simpleGenPaperPolicy == "BY_SCORE") {
+        this.$http
+          .get(
+            Q_API +
+              "/paper/questionScores/" +
+              row.id +
+              "/" +
+              publicity +
+              "/" +
+              difficulty
+          )
+          .then(response => {
+            this.message = response.data;
+          });
+      }
+    },
+    //鼠标离开事件
+    showActiveOff() {
+      this.message = "";
+    }
+  },
+  computed: {
+    selectedPapers() {
+      var selectedPapers = [];
+      for (let paper of this.tempPapers) {
+        console.log("paper123:", paper);
+        selectedPapers.push({
+          id: paper.id,
+          name: paper.name,
+          totalScore: paper.totalScore,
+          unitCount: paper.unitCount,
+          simpleParam: ""
+        });
+      }
+      return selectedPapers;
+    }
+  },
+  watch: {
+    selectedIds() {
+      var templateIds = [];
+      for (let paper of this.selectedPapers) {
+        templateIds.push(paper.id);
+      }
+      this.genPaper.paperIds = templateIds;
+      return templateIds;
+    }
+  },
+  created() {
+    this.genPaper.courseNo = this.$route.params.courseNo;
+    this.genPaper.courseName = sessionStorage.getItem("gen_paper_courseName");
+    this.genPaper.level = this.$route.params.level;
+    console.log(this.$route.params.level);
+    this.searchPaper();
+    this.getCoursePropertyList();
+  }
+};
+</script>
+<style lang="css" scoped>
+.tabs {
+    margin-left: 20px;
+    margin-bottom: 10px;
+}
+
+.form-item {
+    width: 300px;
+}
+
+.margin-bottom {
+    margin-bottom: 10px;
+}
+
+.label-margin {
+    margin-right: 10px;
+}
+</style>

+ 4 - 2
src/modules/questions/views/ImportPaper.vue

@@ -386,7 +386,9 @@ export default {
         this.formSearch.specialtyNo
       );
       sessionStorage.setItem("import_paper_currentPage", this.currentPage);
-      this.$router.push({ path: "/edit_paper/" + row.id + "/import_paper" });
+      this.$router.push({
+        path: "/questions/edit_paper/" + row.id + "/import_paper"
+      });
     },
     deleteImportPaper(row) {
       this.$confirm("确认删除试卷吗?", "提示", {
@@ -453,7 +455,7 @@ export default {
     impPaper() {
       console.log("导入试卷新页面!");
       this.$router.push({
-        path: "/index/imp_paper"
+        path: "/questions/import_paper_info"
       });
     },
     //查询所有课程

+ 337 - 0
src/modules/questions/views/ImportPaperInfo.vue

@@ -0,0 +1,337 @@
+<template>
+  <div>
+    <section class="content">
+      <div class="box box-info">
+        <!-- 头信息 -->
+        <div class="box-header with-border">
+          <h3 class="box-title">word文件上传</h3>
+        </div>
+        <!-- 正文信息 -->
+        <div
+          class="box-body"
+          v-loading.body="fileLoading"
+          element-loading-text="试题上传中,请稍后..."
+        >
+          <el-form
+            :inline="true"
+            :model="formSearch"
+            label-position="right"
+            label-width="100px"
+          >
+            <el-row>
+              <el-form-item
+                label="课程名称"
+                label-width="120px"
+                class="pull-left"
+              >
+                <el-select
+                  v-model="formSearch.courseNo"
+                  class="form_width"
+                  filterable
+                  :remote-method="getCourses"
+                  remote
+                  clearable
+                  placeholder="请选择"
+                  @change="searchCourseName"
+                >
+                  <el-option
+                    v-for="item in courseInfoSelect"
+                    :label="item.courseInfo"
+                    :value="item.courseNo"
+                    :key="item.courseNo"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+              <el-form-item class="pull-right">
+                <el-button type="primary" :plain="true" @click="back"
+                  >返回</el-button
+                >
+              </el-form-item>
+            </el-row>
+            <el-row>
+              <el-form-item
+                label="试卷名称"
+                label-width="120px"
+                class="pull-left"
+              >
+                <el-input
+                  placeholder="试卷名称"
+                  class="form_width"
+                  v-model="formSearch.name"
+                ></el-input>
+              </el-form-item>
+            </el-row>
+            <el-row>
+              <el-form-item
+                label="总分校验"
+                label-width="120px"
+                class="pull-left"
+              >
+                <el-radio v-model="scoreCheck" label="1">开启</el-radio>
+                <el-radio v-model="scoreCheck" label="0">关闭</el-radio>
+              </el-form-item>
+            </el-row>
+            <el-row v-if="scoreCheck == 1">
+              <el-form-item
+                label="试卷总分"
+                label-width="120px"
+                class="pull-left"
+              >
+                <el-input
+                  placeholder="试卷总分"
+                  class="form_width"
+                  v-model="formSearch.totalScore"
+                ></el-input>
+              </el-form-item>
+            </el-row>
+            <!--
+              <el-row>
+                  <el-form-item label="相同大题名称" label-width="120px" class="pull-left">
+                      <el-radio  v-model="formSearch.sameName"  label="1">合并</el-radio>
+                      <el-radio  v-model="formSearch.sameName"  label="0">不合并</el-radio>
+                  </el-form-item>
+              </el-row>
+            -->
+            <el-row>
+              <el-form-item>
+                <el-upload
+                  class="form_left"
+                  ref="upload"
+                  accept="application/vnd.openxmlformats-officedocument.wordprocessingml.document"
+                  :action="uploadAction"
+                  :headers="uploadHeaders"
+                  :data="uploadData"
+                  :before-upload="beforeUpload"
+                  :on-progress="uploadProgress"
+                  :on-success="uploadSuccess"
+                  :on-error="uploadError"
+                  :file-list="fileList"
+                  :auto-upload="false"
+                  :multiple="false"
+                >
+                  <el-button slot="trigger" type="primary">选择文件</el-button>
+                  <el-button
+                    style="margin-left:10px;"
+                    type="success"
+                    @click="submitUpload"
+                    >确认上传
+                  </el-button>
+                  <el-button
+                    style="margin-left: 10px;"
+                    type="danger"
+                    @click="removeFile"
+                    >清空文件
+                  </el-button>
+                  <div slot="tip" class="el-upload__tip">只能上传docx文件</div>
+                </el-upload>
+              </el-form-item>
+            </el-row>
+          </el-form>
+          <el-dialog title="错误提示" v-model="errDialog">
+            <span style="font-size: large">{{ errMessage }} !</span>
+            <span slot="footer" class="dialog-footer">
+              <el-button @click="errDialog = false;">确定</el-button>
+            </span>
+          </el-dialog>
+        </div>
+      </div>
+    </section>
+  </div>
+</template>
+<script>
+import { CORE_API, Q_API } from "../constants/constants";
+import { mapState } from "vuex";
+export default {
+  data() {
+    return {
+      scoreCheck: "0",
+      formSearch: {
+        courseNo: "",
+        couresName: "",
+        name: "",
+        totalScore: "",
+        courseLevel: "",
+        sameName: "0"
+      },
+      courseList: [],
+      uploadAction: "",
+      errMessage: "",
+      uploadData: {},
+      fileLoading: false,
+      button_tpye: false,
+      errDialog: false,
+      fileList: [],
+      uploadHeaders: {}
+    };
+  },
+  methods: {
+    searchCourseName() {
+      for (let course of this.courseList) {
+        if (course.code == this.formSearch.courseNo) {
+          this.formSearch.courseName = course.name;
+          this.formSearch.courseLevel = course.level;
+          console.log(this.formSearch.courseLevel);
+        }
+      }
+    },
+    beforeUpload(file) {
+      console.log(file);
+    },
+    uploadProgress() {
+      console.log("uploadProgress");
+    },
+    uploadSuccess(response) {
+      this.$notify({
+        message: "上传成功",
+        type: "success"
+      });
+      this.fileLoading = false;
+      this.$router.push({
+        path: "/edit_paper/" + response.id + "/import_paper"
+      });
+    },
+    uploadError(err) {
+      console.log(err);
+      var result = err.message.match(/\{.+}/);
+      var errMessage = JSON.parse(result[0]).desc;
+      this.errDialog = true;
+      this.errMessage = errMessage;
+      this.fileLoading = false;
+    },
+    initUpload() {
+      this.fileList = [];
+      this.formSearch.name = "";
+      this.formSearch.courseNo = "";
+    },
+    checkUpload() {
+      if (!this.formSearch.courseNo) {
+        this.$notify({
+          message: "课程名称不能为空",
+          type: "error"
+        });
+        return false;
+      } else {
+        this.uploadData.courseNo = this.formSearch.courseNo;
+        this.uploadData.courseName = this.formSearch.courseName;
+        this.uploadData.level = this.formSearch.courseLevel;
+        this.uploadData.sameName = this.formSearch.sameName;
+      }
+      if (!this.formSearch.name) {
+        this.$notify({
+          message: "试卷名称不能为空",
+          type: "error"
+        });
+        return false;
+      } else {
+        this.uploadData.name = this.formSearch.name;
+      }
+      if (this.scoreCheck == 1 && !this.formSearch.totalScore) {
+        this.$notify({
+          message: "试卷总分不能为空",
+          type: "error"
+        });
+        return false;
+      } else {
+        this.uploadData.totalScore = this.formSearch.totalScore;
+      }
+      var fileList = this.$refs.upload.uploadFiles;
+      if (fileList.length == 0) {
+        this.$notify({
+          message: "上传文件不能为空",
+          type: "error"
+        });
+        return false;
+      }
+      if (fileList.length > 1) {
+        this.$notify({
+          message: "每次只能上传一个word文件",
+          type: "error"
+        });
+        return false;
+      }
+      for (let file of fileList) {
+        if (!file.name.endsWith(".docx")) {
+          this.$notify({
+            message: "上传文件必须为docx格式",
+            type: "error"
+          });
+          this.initUpload();
+          return false;
+        }
+      }
+      return true;
+    },
+    //确定上传
+    submitUpload() {
+      console.log("this form:", this.formSearch);
+      if (!this.checkUpload()) {
+        return false;
+      }
+      this.$refs.upload.submit();
+      this.fileLoading = true;
+    },
+    //清空文件
+    removeFile() {
+      // this.fileList = [];
+      this.$refs.upload.clearFiles();
+    },
+    //返回
+    back() {
+      this.$router.push({ path: "/questions/import_paper/0" });
+    },
+    //查询所有课程
+    getCourses(query) {
+      query = query.trim();
+      if (query) {
+        if (!(query.indexOf("(") > -1 && query.indexOf(")") > -1)) {
+          this.courseLoading = true;
+          this.$http
+            .get(CORE_API + "/course/query?name=" + query + "&enable=true")
+            .then(response => {
+              this.courseList = response.body;
+              this.courseLoading = false;
+            });
+        }
+      } else {
+        this.courseList = [];
+      }
+    }
+  },
+  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;
+    }
+  },
+  watch: {
+    scoreCheck: function() {
+      if (this.scoreCheck == 0) {
+        this.formSearch.totalScore = "";
+      }
+    }
+  },
+  created() {
+    this.uploadAction = Q_API + "/importPaper";
+    this.uploadData = { name: this.formSearch.name };
+    this.uploadHeaders = {
+      key: this.user.key,
+      token: this.user.token
+    };
+  }
+};
+</script>
+<style scoped>
+.form_width {
+  width: 200px;
+}
+.form_left {
+  margin-left: 50px;
+}
+</style>

+ 379 - 0
src/modules/questions/views/InsertPaperTitle.vue

@@ -0,0 +1,379 @@
+<template>
+  <div>
+    <section class="content">
+      <div class="box box-info box_width_lg">
+        <!-- 头信息 -->
+        <div class="box-header with-border">
+          <h3 class="box-title">试题类型选择</h3>
+        </div>
+        <!-- 正文信息 -->
+        <div class="box-body">
+          <el-form
+            :inline="true"
+            :model="paperTitleForm"
+            label-width="150px"
+            class="demo-ruleForm"
+          >
+            <el-row>
+              <el-form-item label="课程名称(代码)" class="pull-left">
+                <el-select
+                  @change="searchGenPaper"
+                  style="width: 193px;"
+                  v-model="paperTitleForm.courseNo"
+                  filterable
+                  remote
+                  placeholder="请输入课程名称(代码)"
+                  :remote-method="queryCoursesByKeyword"
+                >
+                  <el-option
+                    v-for="item in courseInfoSelect"
+                    :key="item.courseNo"
+                    :label="item.courseInfo"
+                    :value="item.courseNo"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-row>
+            <el-row v-if="paperTitelDisable">
+              <el-form-item label="试卷名称" class="pull-left">
+                <el-select
+                  v-model="paperTitleForm.paperId"
+                  filterable
+                  placeholder="请选择"
+                  @change="searchPaperDetail"
+                  sytle="width:220px;"
+                >
+                  <el-option
+                    v-for="item in paperInfoSelect"
+                    :label="item.name"
+                    :value="item.id"
+                    :key="item.id"
+                  >
+                  </el-option>
+                </el-select>
+                <el-button type="info" @click="insertPaper">新增试卷</el-button>
+              </el-form-item>
+            </el-row>
+            <el-row v-if="paperDetailDisable">
+              <el-form-item label="试卷大题" class="pull-left">
+                <el-select
+                  v-model="paperTitleForm.paperDetailId"
+                  filterable
+                  placeholder="请选择"
+                >
+                  <el-option
+                    v-for="item in paperDetailInfoSelect"
+                    :label="item.name"
+                    :value="item.id"
+                    :key="item.id"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-row>
+            <el-row>
+              <el-form-item label="题型" class="pull-left">
+                <el-select
+                  v-model="paperTitleForm.value"
+                  filterable
+                  placeholder="请选择"
+                >
+                  <el-option
+                    v-for="item in quesTypes"
+                    :label="item.label"
+                    :value="item.value"
+                    :key="item.id"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-row>
+            <el-row>
+              <el-form-item label=" " class="pull-left">
+                <el-button
+                  type="primary"
+                  :disabled="nextDisabled"
+                  @click="submitForm"
+                  >下一步
+                </el-button>
+              </el-form-item>
+            </el-row>
+          </el-form>
+
+          <!-- 添加试卷弹出框 -->
+          <el-dialog title="新增试卷" v-model="paperDialog" size="tiny">
+            <el-form
+              :inline="true"
+              :model="paperForm"
+              ref="paperForm"
+              :rules="rules"
+              label-position="right"
+              label-width="90px"
+            >
+              <el-row>
+                <el-form-item label="试卷名称" label-width="120px" prop="name">
+                  <el-input
+                    class="pull_length"
+                    v-model="paperForm.name"
+                    auto-complete="off"
+                    placeholder="请输入试卷名称"
+                  ></el-input>
+                </el-form-item>
+              </el-row>
+              <el-row class="pull_center">
+                <el-button type="primary" @click="submitPaperForm('paperForm');"
+                  >保 存</el-button
+                >
+                <el-button type="danger" @click="resetPaperForm('paperForm');"
+                  >重 置</el-button
+                >
+              </el-row>
+            </el-form>
+          </el-dialog>
+        </div>
+      </div>
+    </section>
+  </div>
+</template>
+<script>
+import { CORE_API, Q_API } from "../constants/constants";
+import { mapState } from "vuex";
+export default {
+  data() {
+    return {
+      paperTitleForm: {
+        courseNo: "",
+        courseName: "",
+        paperId: "",
+        paperDetailId: "",
+        value: ""
+      },
+      paperForm: {
+        name: ""
+      },
+      paperDialog: false,
+      courseList: [],
+      tableData: [],
+      detailsData: [],
+      quesTypes: [
+        { value: "SINGLE_ANSWER_QUESTION", label: "单选" },
+        { value: "MULTIPLE_ANSWER_QUESTION", label: "多选" },
+        { value: "BOOL_ANSWER_QUESTION", label: "判断" },
+        { value: "FILL_BLANK_QUESTION", label: "填空" },
+        { value: "TEXT_ANSWER_QUESTION", label: "问答" }
+      ],
+      rules: {
+        name: [{ required: true, message: "请输入试卷名称", trigger: "blur" }]
+      }
+    };
+  },
+  methods: {
+    //远端查询课程
+    queryCoursesByKeyword(query) {
+      query = query.trim();
+      if (query) {
+        if (!(query.indexOf("(") > -1 && query.indexOf(")") > -1)) {
+          this.courseLoading = true;
+          this.$http
+            .get(CORE_API + "/course/query?name=" + query + "&enable=true")
+            .then(response => {
+              this.courseList = response.data;
+              this.courseLoading = false;
+            });
+        }
+      } else {
+        this.courseList = [];
+      }
+    },
+    //根据课程查询试卷集合
+    searchGenPaper() {
+      this.$http
+        .get(
+          Q_API + "/importPaper/1/500/?courseNo=" + this.paperTitleForm.courseNo
+        )
+        .then(response => {
+          this.tableData = response.data.content;
+        });
+      this.paperTitleForm.paperId = "";
+      this.paperTitleForm.paperDetailId = "";
+    },
+    //根据试卷查询大题
+    searchPaperDetail() {
+      this.$http
+        .get(Q_API + "/paperDetail/paper/" + this.paperTitleForm.paperId)
+        .then(response => {
+          this.detailsData = response.data;
+          for (var i = 0; i < this.detailsData.length; i++) {
+            if (!this.detailsData[i].name) {
+              this.detailsData[i].name = "默认大题";
+            }
+          }
+        });
+      this.paperTitleForm.paperDetailId = "";
+    },
+    //新增试卷
+    insertPaper() {
+      this.paperDialog = true;
+    },
+    //重置
+    resetPaperForm(formData) {
+      this.$refs[formData].resetFields();
+    },
+    //提交新增试卷
+    submitPaperForm(formData) {
+      this.$refs[formData].validate(valid => {
+        if (valid) {
+          for (let course of this.courseList) {
+            if (course.code == this.paperTitleForm.courseNo) {
+              this.paperTitleForm.courseName = course.name;
+            }
+          }
+          console.log("课程名称:" + this.paperTitleForm.courseName);
+          this.$http
+            .post(
+              Q_API +
+                "/importPaper/saveBlankPaper/" +
+                this.paperTitleForm.courseNo +
+                "/" +
+                this.paperForm.name
+            )
+            .then(response => {
+              console.log("需要查到的课程id:", response);
+              var paperId = response.data.paper.id;
+              this.$http
+                .get(
+                  Q_API +
+                    "/importPaper/1/500/?courseNo=" +
+                    this.paperTitleForm.courseNo
+                )
+                .then(response => {
+                  this.tableData = response.data.content;
+                  this.paperTitleForm.paperDetailId = "";
+                  this.paperTitleForm.paperId = paperId;
+                });
+              this.paperDialog = false;
+            })
+            .catch(error => {
+              this.$notify({ type: "error", message: error.body.msg });
+              this.paperDialog = false;
+            });
+        } else {
+          return false;
+        }
+      });
+    },
+    //提交
+    submitForm() {
+      var path = "";
+      switch (this.paperTitleForm.value) {
+        case "SINGLE_ANSWER_QUESTION":
+        case "MULTIPLE_ANSWER_QUESTION":
+          path = "edit_select_question";
+          break;
+        case "TEXT_ANSWER_QUESTION":
+        case "FILL_BLANK_QUESTION":
+        case "BOOL_ANSWER_QUESTION":
+          path = "edit_other_question";
+          break;
+      }
+      for (let course of this.courseList) {
+        if (course.code == this.paperTitleForm.courseNo) {
+          this.paperTitleForm.courseName = course.name;
+        }
+      }
+      console.log(path);
+      this.$router.push({
+        path:
+          path +
+          "/" +
+          this.paperTitleForm.paperId +
+          "/" +
+          this.paperTitleForm.paperDetailId +
+          "/" +
+          this.paperTitleForm.value +
+          "/" +
+          this.paperTitleForm.courseNo +
+          "/" +
+          this.paperTitleForm.courseName
+      });
+    }
+  },
+  computed: {
+    paperTitelDisable() {
+      if (this.paperTitleForm.courseNo) {
+        return true;
+      } else {
+        return false;
+      }
+    },
+    paperDetailDisable() {
+      if (
+        this.paperTitleForm.courseNo &&
+        this.paperTitleForm.paperId &&
+        this.detailsData.length > 0
+      ) {
+        return true;
+      } else {
+        return false;
+      }
+    },
+    nextDisabled() {
+      if (
+        this.paperTitleForm.courseNo &&
+        this.paperTitleForm.paperId &&
+        this.paperTitleForm.paperDetailId &&
+        this.paperTitleForm.value
+      ) {
+        return false;
+      } else {
+        return true;
+      }
+    },
+    //获取课程的集合
+    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;
+    },
+    //获取试卷的集合
+    paperInfoSelect() {
+      var paperList = [];
+      for (let paper of this.tableData) {
+        var paperId = paper.id;
+        var paperName = paper.name;
+        paperList.push({ id: paperId, name: paperName });
+      }
+      return paperList;
+    },
+    //获取大题的集合
+    paperDetailInfoSelect() {
+      var paperDetaliList = [];
+      for (let paperDetail of this.detailsData) {
+        var paperDetailId = paperDetail.id;
+        var paperDetailName = paperDetail.name;
+        paperDetaliList.push({ id: paperDetailId, name: paperDetailName });
+      }
+
+      return paperDetaliList;
+    },
+    routeType() {
+      return this.$route.params.type;
+    },
+    ...mapState({ user: state => state.user })
+  },
+  //初始化
+  created() {
+    this.queryCoursesByKeyword();
+  }
+};
+</script>
+<style scoped>
+.box_width_lg {
+  width: 600px;
+}
+</style>

+ 739 - 0
src/modules/questions/views/Question.vue

@@ -0,0 +1,739 @@
+<template>
+  <div>
+    <section class="content">
+      <!-- 头信息 -->
+      <div class="box box-info">
+        <div class="box-header with-border">
+          <h3 class="box-title">试题列表</h3>
+          <div class="box-tools pull-right">
+            <button
+              type="button"
+              class="btn btn-box-tool"
+              data-widget="collapse"
+            >
+              <i class="fa fa-minus"></i>
+            </button>
+          </div>
+        </div>
+        <!-- 正文信息 -->
+        <div class="box-body">
+          <el-form
+            :inline="true"
+            :model="formSearch"
+            label-position="right"
+            label-width="90px"
+          >
+            <el-row>
+              <el-form-item label="课程名称" class="pull-left">
+                <el-select
+                  v-model="formSearch.courseNo"
+                  :remote-method="getCourses"
+                  remote
+                  :loading="courseLoading"
+                  filterable
+                  clearable
+                  placeholder="请选择"
+                  class="select_width"
+                  @change="initCourseProperty"
+                >
+                  <el-option
+                    v-for="item in courseInfoSelect"
+                    :label="item.courseInfo"
+                    :value="item.courseNo"
+                    :key="item.courseNo"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+              <el-form-item label="层次">
+                <el-select
+                  v-model="formSearch.courseLevel"
+                  clearable
+                  placeholder="请选择"
+                  class="select_width"
+                >
+                  <el-option label="请选择" value=""></el-option>
+                  <el-option
+                    v-for="item in levelList"
+                    :label="item.label"
+                    :value="item.value"
+                    :key="item.value"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+              <el-form-item label="专业">
+                <el-select
+                  v-model="formSearch.courseMajor"
+                  clearable
+                  class="select_width"
+                  placeholder="请选择"
+                >
+                  <el-option label="请选择" value=""></el-option>
+                  <el-option
+                    v-for="item in majorList"
+                    :label="item.label"
+                    :value="item.value"
+                    :key="item.value"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+              <el-form-item label="题型">
+                <el-select
+                  v-model="formSearch.questionType"
+                  clearable
+                  placeholder="请选择"
+                  class="select_width"
+                >
+                  <el-option label="请选择" value=""></el-option>
+                  <el-option
+                    v-for="item in questionTypes"
+                    :label="item.label"
+                    :value="item.value"
+                    :key="item.value"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-row>
+            <!-- created by wwh -->
+            <el-row>
+              <el-form-item label="属性名">
+                <el-select
+                  v-model="formSearch.coursePropertyName"
+                  placeholder="属性名"
+                  @change="searchFirst"
+                  class="property_with"
+                  :disabled="updatePorperty"
+                >
+                  <el-option label="请选择" value=""></el-option>
+                  <el-option
+                    v-for="item in coursePropertyList"
+                    :label="item.name"
+                    :value="item.name"
+                    :key="item.name"
+                  ></el-option>
+                </el-select>
+              </el-form-item>
+              <el-form-item label="一级属性">
+                <el-select
+                  v-model="formSearch.firstPropertyId"
+                  placeholder="一级"
+                  @change="searchSecond"
+                  class="property_with"
+                  :disabled="updateFirst"
+                >
+                  <el-option label="请选择" value=""></el-option>
+                  <el-option
+                    v-for="item in firstPropertyList"
+                    :label="item.name"
+                    :value="item.id"
+                    :key="item.id"
+                  ></el-option>
+                </el-select>
+              </el-form-item>
+              <el-form-item label="二级属性">
+                <el-select
+                  v-model="formSearch.secondPropertyId"
+                  placeholder="二级"
+                  class="property_with"
+                  :disabled="updateSecond"
+                >
+                  <el-option label="请选择" value=""></el-option>
+                  <el-option
+                    v-for="item in secondPropertyList"
+                    :label="item.name"
+                    :value="item.id"
+                    :key="item.id"
+                  ></el-option>
+                </el-select>
+              </el-form-item>
+              <el-form-item label="公开度">
+                <el-select
+                  v-model="formSearch.publicity"
+                  clearable
+                  placeholder="请选择"
+                  class="select_width"
+                >
+                  <el-option label="请选择" value=""></el-option>
+                  <el-option
+                    v-for="item in publicityList"
+                    :label="item.label"
+                    :value="item.value"
+                    :key="item.value"
+                  >
+                  </el-option>
+                </el-select>
+              </el-form-item>
+            </el-row>
+            <!-- end by wwh -->
+            <el-form-item class="pull-right">
+              <el-button
+                size="small"
+                type="primary"
+                icon="search"
+                @click="searchQuestionPaper"
+                >查询</el-button
+              >
+            </el-form-item>
+          </el-form>
+
+          <!-- 页面列表 -->
+          <el-table
+            :data="tableData"
+            v-loading="loading"
+            element-loading-text="拼命加载中"
+            border
+            style="width: 100%;text-align:center;"
+          >
+            <el-table-column label="课程" header-align="center" width="180">
+              <template slot-scope="scope">
+                <div class="el_table_inner_left">
+                  <span>{{ scope.row.course.name }}</span>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="层次" header-align="center" width="100">
+              <template slot-scope="scope">
+                <div class="el_table_inner_left">
+                  <span>{{ getLevel(scope.row.course.level) }}</span>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="题型" header-align="center" width="100">
+              <template slot-scope="scope">
+                <div class="el_table_inner_left">
+                  <span>{{ scope.row.questionType | questionType }}</span>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column label="题干" header-align="center">
+              <template slot-scope="scope">
+                <div class="el_table_inner_left">
+                  <span
+                    class="row_quesBody"
+                    @click="prevViewQues(scope.row);"
+                    v-html="scope.row.quesBody"
+                  >
+                  </span>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column
+              :context="_self"
+              width="150"
+              label="操作"
+              header-align="center"
+            >
+              <template slot-scope="scope">
+                <div class="el_table_inner_left">
+                  <el-button
+                    v-if="scope.row.questionType !== 'NESTED_ANSWER_QUESTION'"
+                    size="mini"
+                    type="info"
+                    @click="updateRow(scope.row);"
+                  >
+                    编辑
+                  </el-button>
+                  <el-button
+                    size="mini"
+                    type="danger"
+                    @click="deleteRow(scope.row);"
+                  >
+                    删除
+                  </el-button>
+                </div>
+              </template>
+            </el-table-column>
+          </el-table>
+          <!-- 分页栏 -->
+          <div class="page pull-right">
+            <el-pagination
+              @current-change="handleCurrentChange"
+              :current-page="currentPage"
+              :page-size="pageSize"
+              layout="total, prev, pager, next, jumper"
+              :total="total"
+            >
+            </el-pagination>
+          </div>
+        </div>
+      </div>
+    </section>
+
+    <div class="text-left">
+      <el-dialog @close="closeQuesDialog" title="试题预览" v-model="quesDialog">
+        <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
+                  :disabled="true"
+                  v-model="quesModel.questionType"
+                  placeholder="题型"
+                >
+                  <el-option
+                    v-for="item in questionTypes"
+                    :label="item.label"
+                    :value="item.value"
+                    :key="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
+              :gutter="10"
+              v-for="(quesOption, index) in quesModel.quesOptions"
+              :key="index"
+            >
+              <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
+              :gutter="10"
+              v-for="subQuestionModel in quesModel.subQuestions"
+              :key="subQuestionModel"
+            >
+              <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
+                  :gutter="10"
+                  v-for="(subQuesOption,
+                  subIndex) in subQuestionModel.quesOptions"
+                  :key="subIndex"
+                >
+                  <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>
+  </div>
+</template>
+<script>
+import {
+  CORE_API,
+  Q_API,
+  QUESTION_TYPES,
+  LEVEL_TYPE
+} from "../constants/constants";
+export default {
+  data() {
+    return {
+      courseLoading: false,
+      formSearch: {
+        questionType: "",
+        courseNo: "",
+        courseLevel: "",
+        courseMajor: "",
+        publicity: "",
+        coursePropertyName: "",
+        firstPropertyId: "",
+        secondPropertyId: ""
+      },
+      courseList: [], //课程list
+      levelList: LEVEL_TYPE, //层次list
+      majorList: [], //专业
+      questionTypeList: [], //题型
+      tableData: [],
+      currentPage: 1,
+      pageSize: 10,
+      total: 10,
+      quesModel: {},
+      questionTypes: QUESTION_TYPES,
+      quesDialog: false,
+      loading: false,
+      deleteDialogVisible: false,
+      deleteInfo: "",
+      singleRightAnswer: "", //接收单选答案
+      multipleRightAnswer: [], //接收多选答案
+      publicityList: [
+        { label: "公开", value: true },
+        { label: "非公开", value: false }
+      ],
+      coursePropertyList: [], //课程属性集合
+      firstPropertyList: [], //一级属性集合
+      secondPropertyList: [], //二级属性集合
+      isClear: 0
+    };
+  },
+  methods: {
+    getLevel(level) {
+      if (level == "ZSB") {
+        return "专升本";
+      } else if (level == "GQZ") {
+        return "高起专";
+      } else if (level == "GQB") {
+        return "高起本";
+      } else if (level == "ALL") {
+        return "不限";
+      } else {
+        return "";
+      }
+    },
+    //查询列表
+    searchQuestionPaper() {
+      this.tableData = [];
+      var url = Q_API + "/question/" + this.currentPage + "/" + 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.loading = false;
+      });
+    },
+    //分页
+    handleCurrentChange(val) {
+      this.currentPage = val;
+      this.searchQuestionPaper();
+    },
+    //修改
+    updateRow(row) {
+      //选择题:单选、多选
+      if (
+        row.questionType === "SINGLE_ANSWER_QUESTION" ||
+        row.questionType === "MULTIPLE_ANSWER_QUESTION"
+      ) {
+        this.$router.push({
+          path: "/questions/edit_select_question/" + row.id
+        });
+      }
+      //判断、填空、问答
+      if (
+        row.questionType === "BOOL_ANSWER_QUESTION" ||
+        row.questionType === "FILL_BLANK_QUESTION" ||
+        row.questionType === "TEXT_ANSWER_QUESTION"
+      ) {
+        this.$router.push({
+          path: "/questions/edit_other_question/" + row.id
+        });
+      }
+      sessionStorage.setItem("question", JSON.stringify(this.formSearch));
+      sessionStorage.setItem("question_currentPage", this.currentPage);
+    },
+    //删除
+    deleteRow(row) {
+      this.$confirm("确认删除试题吗?", "提示", {
+        type: "warning"
+      }).then(() => {
+        this.loading = true;
+        this.$http.delete(Q_API + "/paper/deleteQuestion/" + row.id).then(
+          response => {
+            if (response.body.length > 0) {
+              this.loading = false;
+              this.deleteInfo =
+                "该试题被试卷:" + response.data.join(" , ") + "使用,不能删除";
+              this.deleteDialogVisible = true;
+            } else {
+              this.$notify({
+                message: "删除成功",
+                type: "success"
+              });
+              this.searchQuestionPaper();
+            }
+          },
+          () => {
+            this.$notify({
+              message: "删除失败",
+              type: "error"
+            });
+            this.loading = false;
+          }
+        );
+      });
+    },
+    //打开弹窗
+    openQuesDialog() {
+      this.quesDialog = true;
+    },
+    //关闭弹窗
+    closeQuesDialog() {
+      this.quesDialog = false;
+      this.quesModel = {};
+    },
+    //预览
+    prevViewQues(row) {
+      this.quesModel = row;
+      this.disposeSelectAnswer();
+      this.openQuesDialog();
+    },
+    //查询所有课程
+    getCourses(query) {
+      console.log("查询课程!");
+      if (query) {
+        this.courseLoading = true;
+        this.$http
+          .get(CORE_API + "/course/query?name=" + query + "&enable=true")
+          .then(response => {
+            this.courseList = response.data;
+            this.courseLoading = false;
+            if (this.formSearch.courseNo) {
+              this.$http
+                .get(
+                  Q_API + "/courseProperty/enable/" + this.formSearch.courseNo
+                )
+                .then(response => {
+                  this.coursePropertyList = response.data;
+                  //查询一级属性
+                  this.getFirst();
+                });
+            } else {
+              this.coursePropertyList = [];
+            }
+          });
+      } else {
+        this.courseList = [];
+      }
+    },
+    //重置查询表单
+    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();
+          }
+        }
+      }
+    },
+    //查询所有课程属性名
+    initCourseProperty() {
+      console.log("改变");
+      this.formSearch.coursePropertyName = "";
+      this.formSearch.firstPropertyId = "";
+      this.formSearch.secondPropertyId = "";
+      if (this.formSearch.courseNo) {
+        this.$http
+          .get(Q_API + "/courseProperty/enable/" + this.formSearch.courseNo)
+          .then(response => {
+            this.coursePropertyList = response.data;
+          });
+      } else {
+        this.coursePropertyList = [];
+      }
+    },
+    //查询一级属性
+    searchFirst() {
+      if (this.formSearch.coursePropertyName) {
+        this.formSearch.firstPropertyId = "";
+        this.formSearch.secondPropertyId = "";
+        console.log("this.coursePropertyList:", this.coursePropertyList);
+        for (let courseProperty of this.coursePropertyList) {
+          if (courseProperty.name == this.formSearch.coursePropertyName) {
+            this.$http
+              .get(Q_API + "/property/first/" + courseProperty.id)
+              .then(response => {
+                console.log(response);
+                this.firstPropertyList = response.data;
+              });
+          }
+        }
+      }
+    },
+    //查询二级属性
+    searchSecond() {
+      if (this.formSearch.firstPropertyId) {
+        this.formSearch.secondPropertyId = "";
+        this.$http
+          .get(Q_API + "/property/second/" + this.formSearch.firstPropertyId)
+          .then(response => {
+            console.log(response);
+            this.secondPropertyList = response.data;
+          });
+      }
+    },
+    getFirst() {
+      if (this.formSearch.coursePropertyName) {
+        for (let courseProperty of this.coursePropertyList) {
+          if (courseProperty.name == this.formSearch.coursePropertyName) {
+            this.$http
+              .get(Q_API + "/property/first/" + courseProperty.id)
+              .then(response => {
+                console.log(response);
+                this.firstPropertyList = response.data;
+                //查询二级
+                this.getSecond();
+              });
+          }
+        }
+      }
+    },
+    getSecond() {
+      if (this.formSearch.firstPropertyId) {
+        this.$http
+          .get(Q_API + "/property/second/" + this.formSearch.firstPropertyId)
+          .then(response => {
+            console.log(response);
+            this.secondPropertyList = response.data;
+          });
+      }
+    },
+    answer() {
+      if (this.quesModel.questionType == "SINGLE_ANSWER_QUESTION") {
+        return this.singleRightAnswer;
+      } else if (this.quesModel.questionType == "MULTIPLE_ANSWER_QUESTION") {
+        return this.multipleRightAnswer.sort().toString();
+      } else {
+        return this.quesModel.quesAnswer;
+      }
+    }
+  },
+  computed: {
+    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;
+    },
+    updateFirst() {
+      if (this.formSearch.coursePropertyName) {
+        return false;
+      }
+      return true;
+    },
+    updateSecond() {
+      if (this.formSearch.firstPropertyId) {
+        return false;
+      }
+      return true;
+    },
+    updatePorperty() {
+      if (this.formSearch.courseNo) {
+        return false;
+      }
+      return true;
+    }
+  },
+  //钩子函数
+  created() {
+    this.isClear = this.$route.params.isClear;
+    if (this.isClear == 0 || !this.isClear) {
+      sessionStorage.removeItem("question");
+      sessionStorage.removeItem("question_currentPage");
+    } else {
+      this.formSearch = JSON.parse(sessionStorage.getItem("question"));
+      //this.formSearch.firstPropertyId = parseInt(formSearch.firstPropertyId);
+      //this.formSearch.secondPropertyId = parseInt(formSearch.secondPropertyId);
+      this.currentPage = parseInt(
+        sessionStorage.getItem("question_currentPage")
+      );
+    }
+    this.searchQuestionPaper();
+  }
+};
+</script>
+<style lang="css" scoped>
+.row_quesBody {
+  cursor: pointer;
+  white-space: nowrap;
+  overflow: hidden;
+}
+.row_quesBody p {
+  font-size: 13px;
+}
+.select_width {
+  width: 150px;
+}
+</style>