Bladeren bron

Merge remote-tracking branch 'origin/release_v4.1.0' into release_v4.1.0

qinchao 3 jaren geleden
bovenliggende
commit
2ecb695308

+ 207 - 0
src/modules/questions/views/CourseProperty.vue

@@ -76,6 +76,17 @@
               @click="closeCoursePropertys"
               ><i class="el-icon-close"></i> 禁用</el-button
             >
+            <el-button
+              size="small"
+              type="primary"
+              icon="el-icon-upload2"
+              @click="impCourseProperty"
+            >
+              导入
+            </el-button>
+            <el-button size="small" type="primary" @click="exportCourseProperty"
+              ><i class="el-icon-download"></i>导出</el-button
+            >
           </el-form-item>
         </el-row>
       </el-form>
@@ -224,12 +235,86 @@
         </el-row>
       </el-form>
     </el-dialog>
+    <!-- 导入弹窗 -->
+    <el-dialog title="导入窗口" width="520px" :visible.sync="impDialog">
+      <el-form>
+        <el-row>
+          <el-form-item style="margin-left: 20px">
+            <el-upload
+              ref="upload"
+              class="form_left"
+              accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
+              :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"
+                size="small"
+                type="primary"
+                icon="el-icon-search"
+              >
+                选择文件
+              </el-button>
+              &nbsp;
+              <el-button
+                size="small"
+                type="primary"
+                icon="el-icon-check"
+                @click="submitUpload"
+              >
+                确认上传
+              </el-button>
+              <el-button
+                size="small"
+                type="primary"
+                icon="el-icon-refresh"
+                @click="removeFile"
+              >
+                清空文件
+              </el-button>
+              <el-button
+                size="small"
+                type="primary"
+                icon="el-icon-download"
+                @click="exportFile"
+              >
+                下载模板
+              </el-button>
+              <div slot="tip" class="el-upload__tip">只能上传xlsx文件</div>
+            </el-upload>
+          </el-form-item>
+        </el-row>
+      </el-form>
+    </el-dialog>
+
+    <!-- 导入错误信息列表 -->
+    <el-dialog title="错误提示" :visible.sync="errDialog">
+      <div
+        v-for="errMessage in errMessages"
+        :key="errMessage.lineNum"
+        class="text-danger"
+      >
+        第{{ errMessage.lineNum }}行:{{ errMessage.msg }}
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="errDialog = false">确定</el-button>
+      </span>
+    </el-dialog>
   </section>
 </template>
 
 <script>
 import { CORE_API, QUESTION_API } from "@/constants/constants";
 import LinkTitlesCustom from "@/components/LinkTitlesCustom.vue";
+import { mapState } from "vuex";
 export default {
   components: { LinkTitlesCustom },
   data() {
@@ -238,6 +323,16 @@ export default {
         name: "",
         courseId: "",
       },
+
+      impDialog: false,
+      uploadAction: QUESTION_API + "/courseProperty/import",
+      uploadHeaders: {},
+      uploadData: {},
+      errMessages: [],
+      errDialog: false,
+      fileLoading: false,
+      fileList: [],
+
       courseList: [],
       loading: false,
       tableData: [],
@@ -260,6 +355,9 @@ export default {
     };
   },
   computed: {
+    ...mapState({
+      user: (state) => state.user,
+    }),
     selectedIds() {
       var selectedIdsStr = "";
       for (let id of this.selectedList) {
@@ -292,9 +390,118 @@ export default {
   },
   created() {
     this.initValue();
+    this.uploadHeaders = {
+      key: this.user.key,
+      token: this.user.token,
+    };
   },
 
   methods: {
+    exportCourseProperty() {
+      var key = this.user.key;
+      var token = this.user.token;
+      window.open(
+        QUESTION_API +
+          "/courseProperty/export?$key=" +
+          key +
+          "&$token=" +
+          token +
+          "&name=" +
+          this.formSearch.name +
+          "&courseId=" +
+          this.formSearch.courseId
+      );
+    },
+    //导入
+    impCourseProperty() {
+      this.impDialog = true;
+      this.initUpload();
+    },
+    initUpload() {
+      this.fileList = [];
+    },
+    beforeUpload(file) {
+      console.log(file);
+    },
+    uploadProgress() {
+      console.log("uploadProgress");
+    },
+    uploadSuccess(response) {
+      if (!response.hasError) {
+        this.$notify({
+          message: "上传成功",
+          type: "success",
+        });
+        this.fileLoading = false;
+        this.impDialog = false;
+        this.searchCourProperty();
+      } else {
+        this.fileLoading = false;
+        this.impDialog = false;
+        this.errMessages = response.failRecords;
+        this.errDialog = true;
+      }
+    },
+    uploadError(response) {
+      var json = JSON.parse(response.message);
+      if (response.status == 500) {
+        this.$notify({
+          message: json.desc,
+          type: "error",
+        });
+      }
+      this.fileLoading = false;
+    },
+    //确定上传
+    submitUpload() {
+      if (!this.checkUpload()) {
+        return false;
+      }
+      this.$refs.upload.submit();
+      this.fileLoading = true;
+    },
+    checkUpload() {
+      var fileList = this.$refs.upload.uploadFiles;
+      if (fileList.length == 0) {
+        this.$notify({
+          message: "上传文件不能为空",
+          type: "error",
+        });
+        return false;
+      }
+      if (fileList.length > 1) {
+        this.$notify({
+          message: "每次只能上传一个文件",
+          type: "error",
+        });
+        return false;
+      }
+      for (let file of fileList) {
+        if (!file.name.endsWith(".xlsx")) {
+          this.$notify({
+            message: "上传文件必须为xlsx格式",
+            type: "error",
+          });
+          this.initUpload();
+          return false;
+        }
+      }
+      return true;
+    },
+    //清空文件
+    removeFile() {
+      // this.fileList = [];
+      this.$refs.upload.clearFiles();
+    },
+    //下载模板
+    exportFile() {
+      window.location.href =
+        QUESTION_API +
+        "/courseProperty/importTemplate?$key=" +
+        this.user.key +
+        "&$token=" +
+        this.user.token;
+    },
     //查询所有课程属性
     searchFrom() {
       this.currentPage = 1;

+ 13 - 5
src/modules/questions/views/EditPaper.vue

@@ -516,10 +516,18 @@
                 >
                   <div slot="content">
                     <span v-if="content.firstProperty != null"
-                      >一级属性:{{ content.firstProperty.name }}</span
+                      >一级属性:{{ content.firstProperty.name }}({{
+                        content.firstProperty.code
+                      }})</span
                     ><br />
-                    <span v-if="content.secondProperty != null"
-                      >二级属性:{{ content.secondProperty.name }}</span
+                    <span
+                      v-if="
+                        content.secondProperty != null &&
+                        content.secondProperty.code
+                      "
+                      >二级属性:{{ content.secondProperty.name }}({{
+                        content.secondProperty.code
+                      }})</span
                     >
                   </div>
                   <span>
@@ -572,7 +580,7 @@
                   <el-option
                     v-for="item in firstPropertyList"
                     :key="item.id"
-                    :label="item.name"
+                    :label="item.name + '(' + item.code + ')'"
                     :value="item.id"
                   >
                   </el-option>
@@ -591,7 +599,7 @@
                   <el-option
                     v-for="item in secondPropertyList"
                     :key="item.id"
-                    :label="item.name"
+                    :label="item.name + '(' + item.code + ')'"
                     :value="item.id"
                   >
                   </el-option>

+ 17 - 2
src/modules/questions/views/InsertBluePaperStructure.vue

@@ -295,7 +295,7 @@ export default {
     totalScore() {
       var sum = 0.0;
       for (let paperDetailStruct of this.paperDetailStructs) {
-        sum += paperDetailStruct.score;
+        sum = this.accAdd(paperDetailStruct.score, sum);
       }
       return sum;
     },
@@ -324,6 +324,21 @@ export default {
     this.searchForm();
   },
   methods: {
+    accAdd(num1, num2) {
+      let sq1, sq2, m;
+      try {
+        sq1 = num1.toString().split(".")[1].length;
+      } catch (e) {
+        sq1 = 0;
+      }
+      try {
+        sq2 = num2.toString().split(".")[1].length;
+      } catch (e) {
+        sq2 = 0;
+      }
+      m = Math.pow(10, Math.max(sq1, sq2));
+      return (num1 * m + num2 * m) / m;
+    },
     //查询大题结合
     searchForm() {
       this.loading = true;
@@ -421,7 +436,7 @@ export default {
     checkTotalScore() {
       var totalScore = 0;
       for (let paperDetailStruct of this.blueStruct.paperDetailStructs) {
-        totalScore = parseFloat(paperDetailStruct.totalScore) + totalScore;
+        totalScore = this.accAdd(paperDetailStruct.totalScore, totalScore);
       }
       if (totalScore != this.blueStruct.totalScore) {
         return false;

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

@@ -279,7 +279,7 @@ export default {
     totalScore() {
       var sum = 0.0;
       for (let paperDetailStruct of this.paperDetailStructs) {
-        sum += paperDetailStruct.totalScore;
+        sum = this.accAdd(paperDetailStruct.totalScore, sum);
       }
       return sum;
     },
@@ -299,6 +299,21 @@ export default {
   },
 
   methods: {
+    accAdd(num1, num2) {
+      let sq1, sq2, m;
+      try {
+        sq1 = num1.toString().split(".")[1].length;
+      } catch (e) {
+        sq1 = 0;
+      }
+      try {
+        sq2 = num2.toString().split(".")[1].length;
+      } catch (e) {
+        sq2 = 0;
+      }
+      m = Math.pow(10, Math.max(sq1, sq2));
+      return (num1 * m + num2 * m) / m;
+    },
     //查询列表集合
     searchForm() {
       this.loading = true;

+ 26 - 8
src/modules/questions/views/InsertPaperStructureInfo.vue

@@ -229,12 +229,13 @@
               </el-col>
               <el-col :span="12">
                 <el-form-item label="每题分值" prop="score" label-width="78px">
-                  <el-input
-                    v-model.number="paperUnitForm2.score"
-                    class="form_width"
-                    placeholder="请输入"
+                  <el-input-number
+                    v-model="paperUnitForm2.score"
+                    size="small"
+                    :precision="1"
+                    :min="0"
                     @change="muli2"
-                  ></el-input>
+                  ></el-input-number>
                 </el-form-item>
               </el-col>
             </el-row>
@@ -832,7 +833,7 @@ export default {
     totalScore() {
       var sum = 0.0;
       for (let unitStruct of this.unitStructs) {
-        sum += unitStruct.totalScore;
+        sum = this.accAdd(unitStruct.totalScore, sum);
       }
       return sum;
     },
@@ -860,6 +861,21 @@ export default {
     this.searchForm();
   },
   methods: {
+    accAdd(num1, num2) {
+      let sq1, sq2, m;
+      try {
+        sq1 = num1.toString().split(".")[1].length;
+      } catch (e) {
+        sq1 = 0;
+      }
+      try {
+        sq2 = num2.toString().split(".")[1].length;
+      } catch (e) {
+        sq2 = 0;
+      }
+      m = Math.pow(10, Math.max(sq1, sq2));
+      return (num1 * m + num2 * m) / m;
+    },
     //查询来源大题名称
     getQuesNameList(quesType) {
       if (quesType && quesType.length > 0) {
@@ -978,10 +994,12 @@ export default {
               unitStruct.quesNames = this.paperUnitForm2.quesNames;
               unitStruct.publicSimple = this.paperUnitForm2.publicSimple;
               unitStruct.publicMedium = this.paperUnitForm2.publicMedium;
-              unitStruct.publicDifficulty = this.paperUnitForm2.publicDifficulty;
+              unitStruct.publicDifficulty =
+                this.paperUnitForm2.publicDifficulty;
               unitStruct.noPublicSimple = this.paperUnitForm2.noPublicSimple;
               unitStruct.noPublicMedium = this.paperUnitForm2.noPublicMedium;
-              unitStruct.noPublicDifficulty = this.paperUnitForm2.noPublicDifficulty;
+              unitStruct.noPublicDifficulty =
+                this.paperUnitForm2.noPublicDifficulty;
               unitStruct.publicSum = this.paperUnitForm2.publicSum;
               unitStruct.noPublicSum = this.paperUnitForm2.noPublicSum;
               unitStruct.simpleSum = this.paperUnitForm2.simpleSum;

+ 134 - 142
src/modules/questions/views/PropertyInfo.vue

@@ -96,50 +96,67 @@
       </el-form>
 
       <el-tree
-        :data="data"
+        :data="treeData"
         node-key="id"
         :props="defaultProps"
         :default-expanded-keys="ids"
         @node-click="handleNodeClick"
-      ></el-tree>
+        ><span slot-scope="{ data }" class="custom-tree-node">
+          <span>{{ data.name }}({{ data.code }})</span>
+        </span></el-tree
+      >
     </div>
-    <el-dialog :title="title" :visible.sync="propertyDialog">
-      <el-form :model="propertyForm">
-        <el-row v-show="parentName">
-          <el-form-item label="一级名称">
+    <el-dialog
+      :title="title"
+      :visible.sync="propertyDialog"
+      @close="closeModel"
+    >
+      <el-form
+        ref="propertyForm"
+        :model="propertyForm"
+        :inline="true"
+        :rules="rules"
+        :inline-message="true"
+      >
+        <el-row>
+          <el-form-item label="编码" label-width="100px" prop="code">
+            <el-input
+              v-model="propertyForm.code"
+              auto-complete="off"
+              style="width: 220px"
+            ></el-input>
+          </el-form-item>
+        </el-row>
+        <el-row v-if="isFirstLev()">
+          <el-form-item label="一级名称" label-width="100px" prop="name">
             <el-input
-              v-model="propertyForm.parentName"
+              v-model="propertyForm.name"
               auto-complete="off"
               style="width: 220px"
-              @change="showTitle"
             ></el-input>
-            <span v-show="showParentName" style="color: red">请输一级名称</span>
           </el-form-item>
         </el-row>
-        <el-row v-show="sonName">
-          <el-form-item label="二级名称">
+        <el-row v-if="isSecondLev()">
+          <el-form-item label="二级名称" label-width="100px" prop="name">
             <el-input
-              v-model="propertyForm.sonName"
+              v-model="propertyForm.name"
               auto-complete="off"
               style="width: 220px"
-              @change="showTitle"
             ></el-input>
-            <span v-show="showSonName" style="color: red">请输二级名称</span>
           </el-form-item>
         </el-row>
         <el-row>
-          <el-form-item label="名称备注">
+          <el-form-item label="名称备注" label-width="100px">
             <el-input
               v-model="propertyForm.remark"
               auto-complete="off"
               style="width: 220px"
-              @change="showTitle"
             ></el-input>
           </el-form-item>
         </el-row>
       </el-form>
       <div slot="footer" class="dialog-footer">
-        <el-button @click="propertyDialog = false">取 消</el-button>
+        <el-button @click="closeModel">取 消</el-button>
         <el-button type="primary" @click="submit">确 定</el-button>
       </div>
     </el-dialog>
@@ -160,16 +177,19 @@ export default {
       courseList: [],
       ids: [],
       loading: false,
-      parentName: false,
-      sonName: false,
       propertyDialog: false,
       propertyForm: {
-        parentName: "",
-        sonName: "",
+        id: "",
+        code: "",
+        name: "",
+        parentId: "",
+        number: "",
+        coursePropertyId: "",
         remark: "",
       },
-      property: {
+      curProperty: {
         id: "",
+        code: "",
         name: "",
         parentId: "",
         number: "",
@@ -178,15 +198,28 @@ export default {
       },
       showButton: true,
       showSonButtton: true,
-      showParentName: false,
-      showSonName: false,
-      data: [],
+      showMoveButtton: true,
+      treeData: [],
       defaultProps: {
         children: "propertyList",
-        label: "name",
       },
       title: "新增属性",
-      showMoveButtton: true,
+      rules: {
+        code: [
+          {
+            required: true,
+            message: "请输入编码",
+            trigger: "blur",
+          },
+        ],
+        name: [
+          {
+            required: true,
+            message: "请输入名称",
+            trigger: "blur",
+          },
+        ],
+      },
     };
   },
   computed: {
@@ -208,25 +241,40 @@ export default {
     this.searchProperty();
   },
   methods: {
+    disAllBtn() {
+      this.showButton = true;
+      this.showSonButtton = true;
+      this.showMoveButtton = true;
+    },
+    isFirstLev() {
+      if (this.propertyForm.parentId == "0") {
+        return true;
+      } else {
+        return false;
+      }
+    },
+    isSecondLev() {
+      if (this.propertyForm.parentId && this.propertyForm.parentId != "0") {
+        return true;
+      } else {
+        return false;
+      }
+    },
+    closeModel() {
+      this.propertyDialog = false;
+      this.$refs.propertyForm.resetFields();
+    },
     //树形节点选中
     handleNodeClick(object) {
-      //得到选中的节点
-      console.log(object);
       this.showButton = false;
       //判断选中节点,如果是父节点,可以新增二级
       if (object.parentId == "0") {
         this.showSonButtton = false;
-        this.showMoveButtton = false;
       } else {
         this.showSonButtton = true;
-        this.showMoveButtton = true;
       }
-      this.property.id = object.id;
-      this.property.name = object.name;
-      this.property.parentId = object.parentId;
-      this.property.number = object.number;
-      this.property.coursePropertyId = object.coursePropertyId;
-      this.property.remark = object.remark;
+      this.showMoveButtton = false;
+      this.curProperty = Object.assign({}, object);
     },
     //查询所有课程
     getCourses(query) {
@@ -252,9 +300,9 @@ export default {
       this.$http
         .get(QUESTION_API + "/property/all/" + this.coursePropertyId)
         .then((response) => {
-          this.data = response.data;
-          for (var i = 0; i < this.data.length; i++) {
-            var property = this.data[i];
+          this.treeData = response.data;
+          for (var i = 0; i < this.treeData.length; i++) {
+            var property = this.treeData[i];
             this.ids.push(property.id);
           }
           this.loading = false;
@@ -262,113 +310,70 @@ export default {
     },
     //新增一级
     insertParent() {
+      this.disAllBtn();
       this.title = "新增属性";
-      this.showParentName = false;
-      this.property = {
+      this.propertyForm = {
         id: "",
+        code: "",
         name: "",
         parentId: "0",
         number: "",
         coursePropertyId: this.coursePropertyId,
         remark: "",
       };
-      this.propertyForm.parentName = "";
-      this.propertyForm.remark = "";
-      this.sonName = false;
-      this.parentName = true;
       this.propertyDialog = true;
     },
     //新增二级
     insertSon() {
+      this.disAllBtn();
       this.title = "新增属性";
-      this.showSonName = false;
       //父对象id赋值
-      this.property.parentId = this.property.id;
-      this.property.id = "";
-      this.property.name = "";
-      this.property.remark = "";
-      this.property.coursePropertyId = this.coursePropertyId;
-      this.propertyForm.sonName = "";
-      this.propertyForm.remark = "";
-      this.parentName = false;
-      this.sonName = true;
+      this.propertyForm = {
+        id: "",
+        code: "",
+        name: "",
+        parentId: this.curProperty.id,
+        number: "",
+        coursePropertyId: this.coursePropertyId,
+        remark: "",
+      };
       this.propertyDialog = true;
     },
     //修改
     updateProperty() {
+      this.disAllBtn();
       this.title = "修改属性";
-      //判断是父节点还是子节点
-      if (this.property.parentId == "0") {
-        this.propertyForm.parentName = this.property.name;
-        this.propertyForm.remark = this.property.remark;
-        this.sonName = false;
-        this.parentName = true;
-      } else {
-        this.propertyForm.sonName = this.property.name;
-        this.propertyForm.remark = this.property.remark;
-        this.parentName = false;
-        this.sonName = true;
-      }
+      this.propertyForm = Object.assign({}, this.curProperty);
       this.propertyDialog = true;
     },
     //保存
-    submit() {
-      if (this.property.parentId == "0") {
-        //非空判断
-        if (!this.propertyForm.parentName) {
-          this.showParentName = true;
-          return 0;
-        }
-        this.property.name = this.propertyForm.parentName;
-      } else {
-        //非空判断
-        if (!this.propertyForm.sonName) {
-          this.showSonName = true;
-          return 0;
-        }
-        this.property.name = this.propertyForm.sonName;
+    async submit() {
+      const res = await this.$refs.propertyForm.validate();
+      if (res === false) {
+        return;
       }
-      this.property.remark = this.propertyForm.remark;
-      if (this.property.id) {
-        this.$http
-          .put(QUESTION_API + "/property/save", this.property)
-          .then(() => {
-            this.$notify({
-              message: "修改成功",
-              type: "success",
-            });
-            this.propertyDialog = false;
-            this.searchProperty();
-          })
-          .catch((error) => {
-            this.$notify({
-              type: "error",
-              message: error.response.data.desc,
-            });
+      this.$http
+        .post(QUESTION_API + "/property/save", this.propertyForm)
+        .then(() => {
+          this.$notify({
+            message: this.propertyForm.id ? "修改成功" : "新增成功",
+            type: "success",
           });
-      } else {
-        this.$http
-          .post(QUESTION_API + "/property/save", this.property)
-          .then(() => {
-            this.$notify({
-              message: "新增成功",
-              type: "success",
-            });
-            this.propertyDialog = false;
-            this.searchProperty();
-          })
-          .catch((error) => {
-            this.$notify({
-              type: "error",
-              message: error.response.data.desc,
-            });
+          this.propertyDialog = false;
+          this.searchProperty();
+        })
+        .catch((error) => {
+          this.$notify({
+            type: "error",
+            message: error.response.data.desc,
           });
-      }
+        });
       this.showButton = true;
       this.showSonButtton = true;
     },
     //删除
     deleteProperty() {
+      this.disAllBtn();
       this.$confirm("确认删除属性吗?", "提示", {
         type: "warning",
       }).then(() => {
@@ -377,9 +382,9 @@ export default {
           .delete(
             QUESTION_API +
               "/property/delete/" +
-              this.property.id +
+              this.curProperty.id +
               "/" +
-              this.property.coursePropertyId
+              this.curProperty.coursePropertyId
           )
           .then(() => {
             this.$notify({
@@ -388,31 +393,16 @@ export default {
             });
             this.searchProperty();
           })
-          .catch(() => {
+          .catch((error) => {
             this.$notify({
               type: "error",
-              message: "删除失败",
+              message: error.response.data.desc,
             });
           });
       });
       this.showButton = true;
       this.showSonButtton = true;
     },
-    //效验
-    showTitle() {
-      if (this.propertyForm.parentName) {
-        this.showParentName = false;
-      }
-      if (!this.propertyForm.parentName) {
-        this.showParentName = true;
-      }
-      if (this.propertyForm.sonName) {
-        this.showSonName = false;
-      }
-      if (!this.propertyForm.sonName) {
-        this.showSonName = true;
-      }
-    },
     //返回
     back() {
       this.$router.push({
@@ -421,32 +411,34 @@ export default {
     },
     //上移
     moveUp() {
+      this.disAllBtn();
       this.$http
-        .put(QUESTION_API + "/property/moveUp", this.property)
+        .put(QUESTION_API + "/property/moveUp", this.curProperty)
         .then(() => {
           this.searchProperty();
           this.showMoveButtton = true;
         })
-        .catch(() => {
+        .catch((error) => {
           this.$notify({
             type: "error",
-            message: "无法上移",
+            message: error.response.data.desc,
           });
           this.showMoveButtton = true;
         });
     },
     //下移
     moveDown() {
+      this.disAllBtn();
       this.$http
-        .put(QUESTION_API + "/property/moveDown", this.property)
+        .put(QUESTION_API + "/property/moveDown", this.curProperty)
         .then(() => {
           this.searchProperty();
           this.showMoveButtton = true;
         })
-        .catch(() => {
+        .catch((error) => {
           this.$notify({
             type: "error",
-            message: "无法下移",
+            message: error.response.data.desc,
           });
           this.showMoveButtton = true;
         });