Parcourir la source

知识点相关需求

刘洋 il y a 1 an
Parent
commit
7ced67510d

+ 5 - 8
src/modules/card/assets/styles/card-design.scss

@@ -609,16 +609,13 @@
 
 // design-preview-frame
 .design-preview-frame {
-  // position: absolute;
-  position: fixed;
+  position: absolute;
   width: 1000px;
   height: 600px;
-  // left: -9999px;
-  // left: 0;
-  left: 240px;
-  top: 80px;
-  z-index: 100001;
-  // visibility: hidden;
+  left: -9999px;
+  top: 0;
+  z-index: 1001;
+  visibility: hidden;
 }
 // card-build-frame
 .card-build-frame {

+ 5 - 0
src/modules/paper-export/api.js

@@ -63,3 +63,8 @@ export const paperPdfDownloadApi = (datas) => {
     responseType: "blob",
   });
 };
+export const answerPdfDownloadApi = (datas) => {
+  return $httpWithMsg.post(QUESTION_API + "/paper/answer/download_pdf", datas, {
+    responseType: "blob",
+  });
+};

+ 1 - 1
src/modules/paper-export/components/AnswerTemplateView.vue

@@ -2,7 +2,7 @@
   <div class="paper-template-view answer-template-view card-view paper-page">
     <div v-for="(singlePageData, index) in flatData" :key="index">
       <div class="page-box page-box-A4 page-box-answer">
-        <div class="page-main-inner">
+        <div class="page-main-inner" style="font-size: 14px">
           <div v-for="(row, i) in singlePageData || []" :key="i">
             <div v-if="row.type == 'bigTitle'" class="is-detail-title">
               {{ row.number | numberToChaineseFilter }}、{{ row.name }}

Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
src/modules/paper-export/previewAnswer.js


+ 3 - 2
src/modules/paper-export/views/AnswerTemplateBuild.vue

@@ -32,7 +32,8 @@
 // import PaperTemplateView from "../components/PaperTemplateView.vue";
 import AnswerTemplateView from "../components/AnswerTemplateView.vue";
 // import { deepCopy } from "../../card/plugins/utils";
-import previewTemp from "../previewTemp";
+// import previewTemp from "../previewTemp";
+import previewTemp from "../previewAnswer";
 import { paperDetailInfoApi } from "../../paper/api";
 // import { paperTemplateListApi, paperPdfDownloadApi } from "../api";
 import { paperPdfDownloadApi } from "../api";
@@ -101,7 +102,7 @@ export default {
       });
     },
     emitFrameResult(success = true, errorMsg = "", htmlCont = "") {
-      console.log("htmlC", htmlCont);
+      // console.log("htmlC", htmlCont);
       window.parent &&
         window.parent.submitPaperTemp &&
         window.parent.submitPaperTemp({

+ 9 - 2
src/modules/portal/views/home/HomeSide.vue

@@ -69,7 +69,7 @@
       text-color="#383b4a"
       router
     >
-      <el-menu-item>
+      <el-menu-item @click="safeSetOpen">
         <i class="icon icon-safe"></i>
         <span> 安全设置 </span>
       </el-menu-item>
@@ -86,12 +86,16 @@
         <span> 回收站 </span>
       </el-menu-item>
     </el-menu>
+    <question-safety-set-dialog
+      ref="QuestionSafetySetDialog"
+    ></question-safety-set-dialog>
   </div>
 </template>
 
 <script>
 import { mapState } from "vuex";
 import { QUESTION_API } from "@/constants/constants";
+import QuestionSafetySetDialog from "@/modules/question/components/QuestionSafetySetDialog.vue";
 
 const routesToMenu = [
   {
@@ -151,6 +155,7 @@ const localMenusConfig = {
 };
 export default {
   name: "HomeSide",
+  components: { QuestionSafetySetDialog },
   data() {
     return {
       group: null,
@@ -176,12 +181,14 @@ export default {
   async created() {
     this.group = routesToMenu.find((v) => this.$route.path.startsWith(v.path));
     this.menuList = await this.getUserPrivileges();
-    console.log("menuList", this.menuList);
     this.UPDATE_MENU_LIST(this.menuList);
     this.updatePath();
   },
   methods: {
     ...mapMutations([UPDATE_CURRENT_PATHS, UPDATE_MENU_LIST]),
+    safeSetOpen() {
+      this.$refs.QuestionSafetySetDialog.open();
+    },
     toPage(path) {
       this.$router.push(path);
     },

+ 1 - 4
src/modules/portal/views/home/LinkTitles.vue

@@ -10,7 +10,7 @@
       > -->
       <el-breadcrumb-item
         v-for="(item, index) in currentPaths"
-        :key="item + index"
+        :key="'item' + index"
       >
         {{ item }}
       </el-breadcrumb-item>
@@ -26,8 +26,5 @@ export default {
   computed: {
     ...mapState(["currentPaths"]),
   },
-  mounted() {
-    console.log(this.$route);
-  },
 };
 </script>

+ 168 - 0
src/modules/question/components/KnowledgePoints.vue

@@ -0,0 +1,168 @@
+<template>
+  <div class="Knowledge-points">
+    <el-button type="primary" @click="showDialog = true">选择知识点</el-button>
+
+    <el-dialog
+      :visible.sync="showDialog"
+      title="绑定知识点"
+      top="10vh"
+      width="640px"
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+      append-to-body
+      destroy-on-close
+      @open="whenOpen"
+    >
+      <el-tree
+        ref="tree"
+        :data="treeData"
+        node-key="id"
+        :props="defaultProps"
+        highlight-current
+        show-checkbox
+        check-strictly
+        default-expand-all
+        @check="check"
+        ><span
+          slot-scope="{ data }"
+          :class="{ 'node-level-one': !data.parentId }"
+        >
+          <span>{{ data.name }}({{ data.code }})</span>
+        </span></el-tree
+      >
+
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="confirm">确定</el-button>
+        <el-button type="danger" plain @click="showDialog = false"
+          >取消</el-button
+        >
+      </div>
+    </el-dialog>
+  </div>
+</template>
+<script>
+import { QUESTION_API } from "@/constants/constants";
+import { cloneDeep } from "lodash";
+export default {
+  name: "KnowledgePoints",
+  props: {
+    courseId: { type: [String, Number] },
+    checkedProperties: {
+      type: Array,
+      default() {
+        return [];
+      },
+    },
+  },
+  data() {
+    return {
+      treeData: [],
+      checkedIds: [],
+      showDialog: false,
+      defaultProps: {
+        children: "propertyList",
+      },
+      quesProperties: [],
+    };
+  },
+  methods: {
+    getTreeData(cId) {
+      this.$http
+        .post(QUESTION_API + "/property/all/by/course?courseId=" + cId)
+        .then((res) => {
+          res.data.propertys.forEach((item) => {
+            item.propertyList = item.propertyList.map((v) => {
+              v.parentName = item.name;
+              return v;
+            });
+            return item;
+          });
+          this.treeData = res.data.propertys;
+        });
+    },
+    check(obj, { checkedNodes }) {
+      let copyCheckedNodes = cloneDeep(checkedNodes);
+      this.checkedIds = copyCheckedNodes.map((item) => item.id);
+      // let usedIds = [];
+      // let firstNodes = checkedNodes.filter((item) => item.parentId == 0);
+      // let secondNodes = checkedNodes.filter((item) => item.parentId != 0);
+      // this.quesProperties = [];
+      // for (let i = 0; i < firstNodes.length; i++) {
+      //   let fNode = firstNodes[i];
+      //   let firstProperty = { id: fNode.id, name: fNode.name };
+      //   let secondProperty = secondNodes.filter(
+      //     (item) => item.parentId == fNode.id
+      //   );
+      //   let obj = { firstProperty };
+      //   usedIds.push(firstProperty.id);
+      //   if (secondProperty.length) {
+      //     obj.secondProperty = secondProperty.map((item) => ({
+      //       id: item.id,
+      //       name: item.name,
+      //     }));
+      //     usedIds.push(...obj.secondProperty.map((item) => item.id));
+      //   }
+      //   this.quesProperties.push(obj);
+      // }
+      // let onlySecondNodes = copyCheckedNodes.filter(
+      //   (item) => !usedIds.find((id) => id == item.id)
+      // );
+      // let map = {};
+      // onlySecondNodes.forEach((item) => {
+      //   if (!map[item.parentId]) {
+      //     map[item.parentId] = [cloneDeep(item)];
+      //   } else {
+      //     map[item.parentId].push(cloneDeep(item));
+      //   }
+      // });
+      // let groups = Object.values(map);
+      // for (let j = 0; j < groups.length; j++) {
+      //   let group = groups[j];
+      //   this.quesProperties.push({
+      //     secondProperty: group.map((v) => ({ id: v.id, name: v.name })),
+      //   });
+      // }
+
+      this.quesProperties = copyCheckedNodes.map((item) => {
+        if (item.parentId == 0) {
+          return { firstProperty: { id: item.id, name: item.name } };
+        } else {
+          return {
+            firstProperty: { id: item.parentId, name: item.parentName },
+            secondProperty: { id: item.id, name: item.name },
+          };
+        }
+      });
+      console.log("this.quesProperties", this.quesProperties);
+    },
+    confirm() {
+      this.$emit("change", cloneDeep(this.quesProperties));
+      this.showDialog = false;
+    },
+    whenOpen() {
+      this.$nextTick(() => {
+        // if (this.checkedIds.length) {
+        //   this.$refs.tree.setCheckedKeys(this.checkedIds);
+        // }
+        if (this.checkedProperties.length) {
+          let ids = [];
+          for (let i = 0; i < this.checkedProperties.length; i++) {
+            let obj = this.checkedProperties[i];
+            obj.firstProperty && ids.push(obj.firstProperty.id);
+            if (obj.secondProperty) {
+              ids.push(obj.secondProperty.id);
+            }
+          }
+          this.$refs.tree.setCheckedKeys(Array.from(new Set(ids)));
+        }
+      });
+    },
+  },
+  watch: {
+    courseId(cId) {
+      this.getTreeData(cId);
+    },
+  },
+};
+</script>
+<style lang="scss" scoped></style>

+ 76 - 48
src/modules/question/components/QuestionInfoEdit.vue

@@ -77,7 +77,12 @@
         label="知识点"
       >
         <div class="box-flex">
-          <property-select
+          <KnowledgePoints
+            :courseId="modalForm.courseId"
+            @change="addProperty"
+            :checkedProperties="modalForm.quesProperties"
+          ></KnowledgePoints>
+          <!-- <property-select
             v-model="properties.coursePropertyId"
             :course-id="modalForm.courseId"
             :use-cache="useCoursePropertyCache"
@@ -104,7 +109,7 @@
             :disabled="!propSelected"
             @click="addProperty"
             >新增属性</el-button
-          >
+          > -->
         </div>
       </el-form-item>
       <el-form-item v-if="modalForm.quesProperties.length" label="属性列表">
@@ -117,14 +122,10 @@
           style="margin-right: 5px; margin-bottom: 5px"
           @close="removeProperty(content)"
         >
-          {{ content.courseProperty && content.courseProperty.name }}
-          <span style="margin: 0 3px">/</span>
+          <!-- {{ content.courseProperty && content.courseProperty.name }}
+          <span style="margin: 0 3px">/</span> -->
           {{ content.firstProperty && content.firstProperty.name }}
-          <span
-            v-if="content.secondProperty && content.secondProperty.name"
-            style="margin: 0 3px"
-            >/</span
-          >
+          <span style="margin: 0 3px">/</span>
           {{ content.secondProperty && content.secondProperty.name }}
         </el-tag>
       </el-form-item>
@@ -134,6 +135,8 @@
 
 <script>
 import { DIFFICULTY_LIST } from "@/constants/constants";
+import KnowledgePoints from "./KnowledgePoints.vue";
+import { cloneDeep } from "lodash";
 
 const initModalForm = {
   editMode: "question",
@@ -147,6 +150,7 @@ const initModalForm = {
 
 export default {
   name: "QuestionInfoEdit",
+  components: { KnowledgePoints },
   props: {
     question: {
       type: Object,
@@ -167,12 +171,12 @@ export default {
         ...initModalForm,
       },
       properties: {
-        coursePropertyId: "",
+        // coursePropertyId: "",
         firstPropertyId: "",
         secondPropertyId: "",
       },
       selection: {
-        courseProperty: {},
+        // courseProperty: {},
         firstProperty: {},
         secondProperty: {},
       },
@@ -183,11 +187,11 @@ export default {
     };
   },
   computed: {
-    propSelected() {
-      return (
-        this.properties.coursePropertyId && this.properties.firstPropertyId
-      );
-    },
+    // propSelected() {
+    //   return (
+    //     this.properties.coursePropertyId && this.properties.firstPropertyId
+    //   );
+    // },
     IS_PAPER_MODE() {
       return this.modalForm.editMode === "paper";
     },
@@ -204,9 +208,11 @@ export default {
           this.question.control
         );
       }
+      console.log("modalForm.quesProperties", modalForm.quesProperties);
       if (modalForm.quesProperties && modalForm.quesProperties.length) {
         modalForm.quesProperties.forEach((item) => {
-          let ids = [item.courseProperty.id, item.firstProperty.id];
+          // let ids = [item.courseProperty.id, item.firstProperty.id];
+          let ids = [item.firstProperty.id];
           if (item.secondProperty && item.secondProperty.id) {
             ids.push(item.secondProperty.id);
           }
@@ -217,46 +223,68 @@ export default {
       }
       this.modalForm = modalForm;
     },
-    coursePropertyChange(val) {
-      this.selection.courseProperty = val || {};
-    },
-    firstPropertyChange(val) {
-      this.selection.firstProperty = val || {};
-    },
-    secondPropertyChange(val) {
-      this.selection.secondProperty = val || {};
-    },
+    // coursePropertyChange(val) {
+    //   this.selection.courseProperty = val || {};
+    // },
+    // firstPropertyChange(val) {
+    //   this.selection.firstProperty = val || {};
+    // },
+    // secondPropertyChange(val) {
+    //   this.selection.secondProperty = val || {};
+    // },
     removeProperty(property) {
       this.modalForm.quesProperties = this.modalForm.quesProperties.filter(
         (item) => property.key !== item.key
       );
       this.emitChange();
     },
-    addProperty() {
-      if (!this.propSelected) return;
-      let ids = [
-        this.properties.coursePropertyId,
-        this.properties.firstPropertyId,
-      ];
-      if (this.properties.secondPropertyId) {
-        ids.push(this.properties.secondPropertyId);
-      }
-      const newProperty = {
-        key: ids.join("_"),
-        ...this.selection,
-      };
-      const propertyExist = this.modalForm.quesProperties.find(
-        (item) => item.key === newProperty.key
-      );
-      if (propertyExist) {
-        this.$message.error("属性已存在!");
-        return;
-      }
-      this.modalForm.quesProperties.push(newProperty);
+    // addProperty() {
+    //   if (!this.propSelected) return;
+    //   let ids = [
+    //     // this.properties.coursePropertyId,
+    //     this.properties.firstPropertyId,
+    //   ];
+    //   if (this.properties.secondPropertyId) {
+    //     ids.push(this.properties.secondPropertyId);
+    //   }
+    //   const newProperty = {
+    //     key: ids.join("_"),
+    //     ...this.selection,
+    //   };
+    //   const propertyExist = this.modalForm.quesProperties.find(
+    //     (item) => item.key === newProperty.key
+    //   );
+    //   if (propertyExist) {
+    //     this.$message.error("属性已存在!");
+    //     return;
+    //   }
+    //   this.modalForm.quesProperties.push(newProperty);
+    //   this.emitChange();
+    // },
+    addProperty(arr) {
+      this.modalForm.quesProperties = arr;
       this.emitChange();
     },
     emitChange() {
-      this.$emit("change", this.modalForm);
+      // this.$emit("change", this.modalForm);
+      let modalFormCopy = cloneDeep(this.modalForm);
+      if (modalFormCopy.quesProperties?.length) {
+        modalFormCopy.quesProperties = modalFormCopy.quesProperties.map(
+          (item) => {
+            if (item.firstProperty) {
+              item.firstProperty = {
+                id: item.firstProperty.id,
+              };
+            }
+            if (item.secondProperty) {
+              item.secondProperty = { id: item.secondProperty.id };
+            }
+            return item;
+          }
+        );
+      }
+      console.log("modalFormCopy", modalFormCopy);
+      this.$emit("change", modalFormCopy);
     },
   },
 };

+ 27 - 8
src/modules/question/components/QuestionSafetySetDialog.vue

@@ -1,19 +1,25 @@
 <template>
   <el-dialog
-    custom-class="side-dialog"
     :visible.sync="modalIsShow"
     title="安全设置"
     width="500px"
-    :modal="false"
     :close-on-click-modal="false"
     :close-on-press-escape="false"
     append-to-body
     @open="visibleChange"
   >
-    <el-form ref="modalFormComp" :model="modalForm" :rules="rules">
-      <el-form-item label="加密“题库”,“卷库”">
-        <el-switch v-model="modalForm.safeEnable"></el-switch>
-        <p class="tips-info">开启后,进入题库、卷库模块,需要进行密码验证!</p>
+    <el-form
+      ref="modalFormComp"
+      :model="modalForm"
+      :rules="rules"
+      class="safe-set-form"
+    >
+      <el-form-item>
+        <el-switch v-model="modalForm.safeEnable"></el-switch
+        ><span class="switch-name">加密“题库”,“卷库”</span>
+        <p class="tips-info switch-tip">
+          开启后,进入题库、卷库模块,需要进行密码验证!
+        </p>
       </el-form-item>
       <el-form-item
         v-if="modalForm.safeEnable"
@@ -23,9 +29,10 @@
         <el-input
           v-model="modalForm.safePassword"
           type="password"
-          class="dialog-input-width"
           auto-complete="off"
           placeholder="请输入6位以上数字和字母组合"
+          style="width: 300px"
+          show-password
         />
       </el-form-item>
       <el-form-item
@@ -36,9 +43,10 @@
         <el-input
           v-model="modalForm.checkSafePassword"
           type="password"
-          class="dialog-input-width"
           auto-complete="off"
           placeholder="请输入6位以上数字和字母组合"
+          style="width: 300px"
+          show-password
         />
       </el-form-item>
     </el-form>
@@ -153,3 +161,14 @@ export default {
   },
 };
 </script>
+<style lang="scss" scoped>
+.safe-set-form {
+  .switch-name {
+    color: #262626;
+    margin-left: 6px;
+  }
+  .switch-tip {
+    padding-left: 46px;
+  }
+}
+</style>

+ 16 - 1
src/modules/questions/views/GenPaper.vue

@@ -435,6 +435,7 @@ import { downloadByApi } from "@/plugins/download";
 import {
   paperTemplateListApi,
   paperPdfDownloadApi,
+  answerPdfDownloadApi,
 } from "../../paper-export/api";
 import { deepCopy } from "@/plugins/utils";
 
@@ -1147,7 +1148,21 @@ export default {
           this.$message.success("下载成功!");
           delete window.paperSet;
         } else {
-          alert("答案");
+          const res = await downloadByApi(() => {
+            return answerPdfDownloadApi({
+              content: htmlCont,
+              size: "A4",
+              paperId: this.exportModel.id,
+            });
+          }).catch((e) => {
+            this.$message.error(e || "下载失败,请重新尝试!");
+          });
+          this.exportDialog = false;
+          this.downloading = false;
+
+          if (!res) return;
+          this.$message.success("下载成功!");
+          delete window.answerSet;
         }
       };
     },

+ 10 - 16
src/modules/questions/views/PropertyInfo.vue

@@ -2,21 +2,14 @@
   <section class="property-info">
     <!-- 正文信息 -->
     <div class="part-box">
-      <h2 class="part-box-title">属性结构</h2>
-      <el-form
+      <h2 class="part-box-title">{{ courseProperty.name }}</h2>
+      <!-- <el-form
         class="part-filter-form"
         :inline="true"
         :model="courseProperty"
         label-position="right"
         label-width="100px"
       >
-        <el-form-item label="属性名称">
-          <el-input
-            v-model="courseProperty.name"
-            placeholder="请输入课程名称"
-            :disabled="true"
-          ></el-input>
-        </el-form-item>
         <el-form-item label="课程名称">
           <el-select
             v-model="courseProperty.courseId"
@@ -35,8 +28,7 @@
             </el-option>
           </el-select>
         </el-form-item>
-        <el-form-item></el-form-item>
-      </el-form>
+      </el-form> -->
 
       <div class="part-box-action">
         <div>
@@ -274,6 +266,7 @@ export default {
   },
   created() {
     // this.coursePropertyId = this.$route.params.id;
+    this.courseProperty.courseId = this.$route.params.id;
     this.searchProperty();
   },
   mounted() {
@@ -371,6 +364,7 @@ export default {
         this.$http.get(QUESTION_API + "/course/" + query).then((response) => {
           var courseBean = response.data;
           this.courseList.push(courseBean);
+          this.courseProperty.name = courseBean.name;
         });
       } else {
         this.courseList = [];
@@ -379,11 +373,11 @@ export default {
     //查询
     searchProperty() {
       this.loading = true;
-      var coursePropertyStorge = sessionStorage.getItem("courseProperty");
-      if (typeof coursePropertyStorge == "string") {
-        this.courseProperty = JSON.parse(coursePropertyStorge);
-        this.getCourses(this.courseProperty.courseId);
-      }
+      // var coursePropertyStorge = sessionStorage.getItem("courseProperty");
+      // if (typeof coursePropertyStorge == "string") {
+      // this.courseProperty = JSON.parse(coursePropertyStorge);
+      this.getCourses(this.courseProperty.courseId);
+      // }
       // this.$http
       //   .get(QUESTION_API + "/property/all/" + this.coursePropertyId)
       //   .then((response) => {

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff