zhangjie il y a 2 ans
Parent
commit
52eca01b02

BIN
public/img/course-link-import-sample.png


+ 13 - 0
src/assets/styles/base.scss

@@ -219,6 +219,10 @@ body {
   display: flex;
   align-items: center;
   justify-content: space-between;
+
+  &.align-top {
+    align-items: flex-start;
+  }
 }
 
 // page-head
@@ -385,6 +389,15 @@ body {
     }
   }
 }
+.btn-primary-strict {
+  &.el-button--text:not(.is-disabled) {
+    color: mix(#fff, $--color-primary, 20%) !important;
+    &:hover {
+      font-weight: 600;
+      color: $--color-primary !important;
+    }
+  }
+}
 
 .btn-white {
   background-color: #fff !important;

+ 27 - 0
src/assets/styles/pages.scss

@@ -1104,6 +1104,7 @@
       display: inline-block;
       vertical-align: top;
       margin-left: 10px;
+      min-height: 84px;
 
       &:first-child {
         background-color: $--color-cyan;
@@ -1151,6 +1152,12 @@
     }
   }
 
+  .formula-tips {
+    margin-top: 10px;
+    line-height: 20px;
+    color: $--color-text-gray-1;
+  }
+
   .rate-detail {
     > div {
       display: inline-block;
@@ -1162,3 +1169,23 @@
     }
   }
 }
+.assign-result {
+  .el-form {
+    border-bottom: 1px solid $--color-border;
+  }
+}
+.score-detail-dialog {
+  .el-dialog__body {
+    padding: 20px;
+  }
+  .table {
+    margin-bottom: 20px;
+    td,
+    th {
+      padding: 6px 8px;
+    }
+  }
+  h4 {
+    margin: 0 0 10px;
+  }
+}

+ 6 - 1
src/components/base/ClazzSelect.vue

@@ -56,8 +56,13 @@ export default {
     },
     filterData: {
       deep: true,
-      handler() {
+      handler(val, oldval) {
+        if (JSON.stringify(val) === JSON.stringify(oldval)) return;
+        console.log(val);
+
         this.search();
+        this.$emit("input", "");
+        this.$emit("change", {});
       },
     },
   },

+ 5 - 1
src/components/base/KcCollegeSelect.vue

@@ -55,8 +55,12 @@ export default {
     },
     filterData: {
       deep: true,
-      handler() {
+      handler(val, oldval) {
+        if (JSON.stringify(val) === JSON.stringify(oldval)) return;
+
         this.search();
+        this.$emit("input", "");
+        this.$emit("change", {});
       },
     },
   },

+ 5 - 1
src/components/base/TeacherSelect.vue

@@ -56,8 +56,12 @@ export default {
     },
     filterData: {
       deep: true,
-      handler() {
+      handler(val, oldval) {
+        if (JSON.stringify(val) === JSON.stringify(oldval)) return;
+        console.log(val);
         this.search();
+        this.$emit("input", "");
+        this.$emit("change", {});
       },
     },
   },

+ 93 - 0
src/modules/base/components/CourseLinkUploadDialog.vue

@@ -0,0 +1,93 @@
+<template>
+  <div>
+    <el-dialog
+      class="upload-file-dialog"
+      :visible.sync="modalIsShow"
+      title="导入"
+      top="10vh"
+      width="600px"
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+      append-to-body
+      @opened="visibleChange"
+    >
+      <div class="file-upload-body mb-4">
+        <upload-file-view
+          input-width="350px"
+          :format="['xls', 'xlsx']"
+          :upload-url="uploadUrl"
+          :upload-data="uploadData"
+          @valid-error="validError"
+          @upload-success="uploadSuccess"
+          ref="UploadFileView"
+        ></upload-file-view>
+      </div>
+      <div class="tips-info">
+        <p>
+          示例:
+          <el-image
+            style="width: 200px; height: 50px"
+            :src="imgUrl"
+            :preview-src-list="[imgUrl]"
+          >
+          </el-image>
+        </p>
+        <div class="box-justify align-top">
+          <span style="width: 58px">说明:</span>
+          <div>
+            <p>
+              1.只有从本系统下载的考务数据中课程代码与导入云阅卷考务数据课程代码不一致时,才操作此功能;
+            </p>
+            <p>2.文件为导入云阅卷系统的考务数据文件;</p>
+            <p>3.将文件中“考生信息备注”填入原考务数据中的课程代码;</p>
+          </div>
+        </div>
+      </div>
+      <div slot="footer"></div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import UploadFileView from "@/components/UploadFileView";
+
+export default {
+  name: "upload-file-dialog",
+  components: { UploadFileView },
+  props: {
+    uploadData: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+  },
+  data() {
+    return {
+      modalIsShow: false,
+      imgUrl: "/img/course-link-import-sample.png",
+      // import
+      uploadUrl: "/api/exam_course_mapping/import",
+    };
+  },
+  methods: {
+    visibleChange() {
+      this.$refs.UploadFileView.setAttachmentName("");
+    },
+    // upload-handler
+    validError(errorData) {
+      this.$message.error(errorData.message);
+    },
+    uploadSuccess() {
+      this.$message.success("上传成功!");
+      this.cancel();
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+  },
+};
+</script>

+ 1 - 1
src/modules/base/components/assignment/AssignCompare.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="assign-compare">
-    <el-form ref="FilterForm" label-position="left" label-width="85px" inline>
+    <el-form ref="FilterForm" label-position="left" inline>
       <!-- <el-form-item label="卷面总分:">
         <el-input-number
           v-model.number="filter.scope"

+ 7 - 5
src/modules/base/components/assignment/AssignConfig.vue

@@ -19,7 +19,7 @@
             :value="key"
           ></el-option>
         </el-select>
-        <div v-if="modalForm.formula">
+        <div class="formula-tips" v-if="modalForm.formula">
           <div v-if="modalForm.formula === 'FORMULA1'">
             <p>赋值分=卷面成绩+ (100- 卷面成绩)/赋分系数</p>
           </div>
@@ -29,7 +29,7 @@
             </p>
             <div>
               <span style="float: left">说明:</span>
-              <div>
+              <div style="margin-left: 50px">
                 <p>1.如果初始卷面最高的大于99时,则x=100,否则x=99;</p>
                 <p>2.参数根据每次总体初始成绩的不及格率进行调整。</p>
               </div>
@@ -87,9 +87,11 @@
         ></el-input-number>
       </el-form-item>
       <el-form-item>
-        <el-button type="primary" :loading="loading" @click="toCalc">{{
-          loading ? "正在计算中" : "开始试算"
-        }}</el-button>
+        <div class="mb-1">
+          <el-button type="primary" :loading="loading" @click="toCalc">{{
+            loading ? "正在计算中" : "开始试算"
+          }}</el-button>
+        </div>
         <p v-if="calcErrorMsg" class="tips-info tips-error">
           错误信息:{{ calcErrorMsg }}
         </p>

+ 66 - 14
src/modules/base/components/assignment/AssignResult.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="assign-result">
-    <el-form ref="FilterForm" label-position="left" label-width="85px" inline>
+    <el-form ref="FilterForm" label-position="left" inline>
       <el-form-item label="考查学院:">
         <kc-college-select
           v-model="filter.kcCollege"
@@ -29,10 +29,26 @@
     </el-form>
 
     <el-table ref="TableList" :data="dataList">
-      <el-table-column prop="courseCode" label="课程代码"></el-table-column>
-      <el-table-column prop="courseName" label="课程名称"></el-table-column>
-      <el-table-column prop="studentCode" label="学号"></el-table-column>
-      <el-table-column prop="studentName" label="姓名"></el-table-column>
+      <el-table-column
+        prop="courseCode"
+        label="课程代码"
+        min-width="150"
+      ></el-table-column>
+      <el-table-column
+        prop="courseName"
+        label="课程名称"
+        min-width="150"
+      ></el-table-column>
+      <el-table-column
+        prop="studentCode"
+        label="学号"
+        width="160"
+      ></el-table-column>
+      <el-table-column
+        prop="studentName"
+        label="姓名"
+        width="120"
+      ></el-table-column>
       <el-table-column
         prop="objectiveScore"
         label="客观总分"
@@ -48,17 +64,38 @@
         label="总分"
         width="80"
       ></el-table-column>
-      <el-table-column prop="scoreDetail" label="评分明细"></el-table-column>
-      <el-table-column prop="clazzName" label="班级"></el-table-column>
-      <el-table-column prop="collegeName" label="学院"></el-table-column>
-      <el-table-column prop="teacherName" label="任课老师"></el-table-column>
+      <el-table-column class-name="action-column" label="评分明细" width="100">
+        <template slot-scope="scope">
+          <el-button
+            class="btn-primary-strict"
+            type="text"
+            @click="toViewScoreDetail(scope.row)"
+            >查看</el-button
+          >
+        </template>
+      </el-table-column>
+      <el-table-column
+        prop="clazzName"
+        label="班级"
+        min-width="150"
+      ></el-table-column>
+      <el-table-column
+        prop="collegeName"
+        label="学院"
+        min-width="150"
+      ></el-table-column>
+      <el-table-column
+        prop="teacherName"
+        label="任课老师"
+        width="120"
+      ></el-table-column>
       <el-table-column
         prop="assignScore"
         label="赋分后总分"
         width="100"
       ></el-table-column>
     </el-table>
-    <!-- <div class="part-page">
+    <div class="part-page">
       <el-pagination
         background
         layout="total,prev, pager, next"
@@ -69,15 +106,23 @@
         @current-change="toPage"
       >
       </el-pagination>
-    </div> -->
+    </div>
+
+    <!-- ScoreDetailDialog -->
+    <score-detail-dialog
+      ref="ScoreDetailDialog"
+      :data="curRow"
+    ></score-detail-dialog>
   </div>
 </template>
 
 <script>
 import { assignmentCalcResult } from "../../api";
+import ScoreDetailDialog from "./ScoreDetailDialog.vue";
 
 export default {
   name: "assign-result",
+  components: { ScoreDetailDialog },
   props: {
     assignInfo: {
       type: Object,
@@ -97,6 +142,8 @@ export default {
       size: this.GLOBAL.pageSize,
       total: 0,
       dataList: [],
+      curRow: {},
+      scoreDetailDialog: false,
     };
   },
   methods: {
@@ -104,17 +151,22 @@ export default {
       const datas = {
         ...this.assignInfo,
         ...this.filter,
+        pageNumber: this.current,
+        pageSize: this.size,
       };
 
       const data = await assignmentCalcResult(datas);
-      this.dataList = data || [];
-      // this.dataList = data.records;
-      // this.total = data.total;
+      this.dataList = data.records;
+      this.total = data.total;
     },
     toPage(page) {
       this.current = page;
       this.getList();
     },
+    toViewScoreDetail(row) {
+      this.curRow = row;
+      this.$refs.ScoreDetailDialog.open();
+    },
   },
 };
 </script>

+ 75 - 0
src/modules/base/components/assignment/ScoreDetailDialog.vue

@@ -0,0 +1,75 @@
+<template>
+  <el-dialog
+    class="score-detail-dialog"
+    :visible.sync="modalIsShow"
+    title="评分明细"
+    top="10px"
+    width="500px"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    append-to-body
+    @open="visibleChange"
+  >
+    <h4>客观题评分明细:</h4>
+    <table class="table">
+      <tr>
+        <td>大题号</td>
+        <td>小题号</td>
+        <td>答案</td>
+        <td>得分</td>
+      </tr>
+      <tr v-for="(item, ind) in objectiveScoreDetail" :key="ind">
+        <td>{{ item.mainNumber }}</td>
+        <td>{{ item.subNumber }}</td>
+        <td>{{ item.answer }}</td>
+        <td>{{ item.score }}</td>
+      </tr>
+    </table>
+    <h4>主观题评分明细:</h4>
+    <table class="table">
+      <tr>
+        <td>大题号</td>
+        <td>小题号</td>
+        <td>得分</td>
+      </tr>
+      <tr v-for="(item, ind) in subjectiveScoreDetail" :key="ind">
+        <td>{{ item.mainNumber }}</td>
+        <td>{{ item.subNumber }}</td>
+        <td>{{ item.score }}</td>
+      </tr>
+    </table>
+  </el-dialog>
+</template>
+
+<script>
+export default {
+  name: "score-detail-dialog",
+  props: {
+    data: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+  },
+  data() {
+    return {
+      modalIsShow: false,
+      objectiveScoreDetail: [],
+      subjectiveScoreDetail: [],
+    };
+  },
+  methods: {
+    visibleChange() {
+      this.objectiveScoreDetail = JSON.parse(this.data.objectiveScoreDetail);
+      this.subjectiveScoreDetail = JSON.parse(this.data.subjectiveScoreDetail);
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+  },
+};
+</script>

+ 3 - 0
src/modules/base/router.js

@@ -68,6 +68,9 @@ export default [
     path: "/base/assignment-calculate-detail",
     name: "AssignmentCalculateDetail",
     component: AssignmentCalculateDetail,
+    meta: {
+      relate: "AssignmentCalculate",
+    },
   },
   {
     path: "/base/system-setting",

+ 1 - 1
src/modules/base/views/AssignmentCalculateDetail.vue

@@ -104,7 +104,7 @@ export default {
   created() {
     this.curAssignInfo = this.$ls.get("curAssignInfo");
     this.assignData = { ...this.curAssignInfo };
-    delete this.assignData.courseCode;
+    delete this.assignData.courseName;
 
     this.getData();
   },

+ 19 - 17
src/modules/base/views/CourseLinkManage.vue

@@ -29,21 +29,12 @@
         </el-form-item>
       </el-form>
       <div class="part-box-action">
-        <upload-button
-          btn-content="导入"
-          btn-type="primary"
-          :upload-url="uploadUrl"
-          :upload-data="{
-            semesterId: filter.semesterId,
-            examTypeId: filter.examTypeId,
-          }"
-          :format="['xls', 'xlsx']"
-          accept=".xls,.xlsx"
+        <el-button
+          type="primary"
           :disabled="!filter.semesterId || !filter.examTypeId"
-          @valid-error="validError"
-          @upload-success="uploadSuccess"
+          @click="toImport"
+          >导入</el-button
         >
-        </upload-button>
       </div>
     </div>
     <div class="part-box part-box-pad">
@@ -78,16 +69,22 @@
         </el-pagination>
       </div>
     </div>
+
+    <!-- CourseLinkUploadDialog -->
+    <course-link-upload-dialog
+      ref="CourseLinkUploadDialog"
+      :upload-data="uploadData"
+    ></course-link-upload-dialog>
   </div>
 </template>
 
 <script>
 import { courseLinkList } from "../api";
-import UploadButton from "@/components/UploadButton";
+import CourseLinkUploadDialog from "../components/CourseLinkUploadDialog.vue";
 
 export default {
   name: "course-link-manage",
-  components: { UploadButton },
+  components: { CourseLinkUploadDialog },
   data() {
     return {
       filter: {
@@ -101,6 +98,7 @@ export default {
       total: 0,
       dataList: [],
       uploadUrl: "/api/exam_course_mapping/import",
+      uploadData: {},
     };
   },
   mounted() {
@@ -122,8 +120,12 @@ export default {
       this.current = page;
       this.getList();
     },
-    validError(errorData) {
-      this.$message.error(errorData.message);
+    toImport() {
+      this.uploadData = {
+        semesterId: this.filter.semesterId,
+        examTypeId: this.filter.examTypeId,
+      };
+      this.$refs.CourseLinkUploadDialog.open();
     },
     uploadSuccess() {
       this.search();

+ 14 - 4
src/modules/base/views/EcsDataManage.vue

@@ -124,10 +124,20 @@ export default {
         this.$message.error("请选选择学院");
         return;
       }
-      const result = await this.$confirm(`确定要同步吗?`, "提示", {
-        type: "warning",
-      }).catch(() => {});
-      if (result !== "confirm") return;
+
+      const result = await this.$confirm(
+        `请确认下载的考务数据文件中的课程代码与导入云阅卷课程代码是否相同。相同,则点击【是】继续同步操作无不相同,则点击【否】进入课程关联管理进行对应关系导入操作。?`,
+        "提示",
+        {
+          type: "warning",
+          cancelButtonText: "否",
+          confirmButtonText: "是",
+        }
+      ).catch(() => {});
+      if (result !== "confirm") {
+        this.$router.push({ name: "CourseLinkManage" });
+        return;
+      }
 
       await syncEcsData({
         type: "CLOUD_MARKING_STUDENT_SCORE",

+ 2 - 5
src/views/Home.vue

@@ -176,6 +176,7 @@ export default {
       }
 
       const privsList = Array.from(privsSet);
+      this.validRoutes = privsList;
       this.privileges = localMenus
         .filter((menu) => privsList.includes(menu.url))
         .map((item) => {
@@ -203,21 +204,17 @@ export default {
       };
 
       let menus = getChildren("-1");
-      let validRoutes = [];
       const toTree = (menus) => {
         menus.forEach((menu) => {
           const children = getChildren(menu.id);
           if (children.length) {
             menu.children = children;
             toTree(menu.children);
-          } else {
-            validRoutes.push(menu.url);
           }
         });
       };
       toTree(menus);
 
-      this.validRoutes = validRoutes;
       // console.log(JSON.stringify(menus));
       return menus;
     },
@@ -247,7 +244,7 @@ export default {
       });
     },
     updateBreadcrumbs() {
-      this.curRouteName = this.$route.name;
+      this.curRouteName = this.$route.meta.relate || this.$route.name;
       let breadcrumbs = [];
       let curBreadcrumb = this.privileges.find(
         (item) => item.url === this.curRouteName