瀏覽代碼

功能修改

zhangjie 4 年之前
父節點
當前提交
d26887a685

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "msyj-admin",
-  "version": "0.1.0",
+  "version": "2.0.0",
   "private": true,
   "scripts": {
     "start": "npm run serve",

+ 6 - 0
src/assets/styles/iview-custom.less

@@ -198,6 +198,12 @@
 .ivu-btn + .ivu-btn {
   margin-left: 10px;
 }
+.ivu-btn {
+  .ivu-icon {
+    font-size: 16px;
+    color: @primary-color;
+  }
+}
 
 // ivu-modal
 .ivu-modal {

+ 3 - 2
src/assets/styles/main.less

@@ -196,7 +196,8 @@
       &-detail {
         position: absolute;
         right: 20px;
-        top: 40px;
+        top: 50%;
+        transform: translateY(-50%);
         z-index: 9;
       }
     }
@@ -232,8 +233,8 @@
   text-align: center;
   &-act {
     img {
-      // box-shadow: 0px 10px 20px 0px rgba(34, 192, 255, 0.5);
       box-shadow: 0 0 20px rgba(34, 192, 255, 0.6);
+      // box-shadow: 0px 10px 20px 0px rgba(34, 192, 255, 0.5);
       // box-shadow: -20px 0px 40px 0px rgba(224, 225, 235, 1);
     }
   }

+ 10 - 3
src/assets/styles/mark.less

@@ -614,7 +614,9 @@
   font-size: 14px;
   text-align: center;
   .action-search {
-    margin-bottom: 20px;
+    margin-top: 20px;
+    padding-top: 20px;
+    border-top: 1px dashed #e0e0e0;
     text-align: left;
 
     .search-select {
@@ -636,9 +638,10 @@
     }
   }
   .action-paper-state {
+    position: relative;
     display: inline-block;
     color: @dark-color-light;
-    margin-bottom: 20px;
+    margin-bottom: 30px;
     .paper-state-cont {
       background: @background-color;
       border-radius: @box-border-radius-small;
@@ -647,7 +650,11 @@
       padding: 6px 12px;
     }
     .paper-state-intro {
-      margin-top: 5px;
+      position: absolute;
+      bottom: -22px;
+      width: 100%;
+      height: 20px;
+      text-align: center;
     }
   }
 

+ 20 - 1
src/constants/enumerate.js

@@ -27,6 +27,10 @@ export const LEVEL_TYPE = {
   ADMITED: "间隔给分",
   UNADMIT: "手动给分"
 };
+export const PROP_DENOMINATOR_TYPE = {
+  1: "全部考生数",
+  2: "去掉缺考考生数"
+};
 
 // student score
 export const CODE_TYPE = {
@@ -40,6 +44,20 @@ export const ROLE_TYPE = {
   MARKER: "评卷员",
   MARK_LEADER: "科组长"
 };
+export const MARK_LEADER_RIGHTS = {
+  oneClickLevel: {
+    name: "一键定档",
+    action: "sampling"
+  },
+  standardVolume: {
+    name: "设立标准卷",
+    action: "leveling"
+  },
+  levelCallback: {
+    name: "建议档位打回",
+    action: "reject"
+  }
+};
 // system role type
 export const SYSTEM_ROLE_TYPE = {
   MARKER: "评卷员",
@@ -68,7 +86,8 @@ export const SORT_RULE_TYPE = {
 // cafa-exception
 export const CAFA_EXCEPTION_TYPE = {
   0: "缺考",
-  1: "手工绑定"
+  1: "手工绑定",
+  2: "关联考号"
 };
 
 // action-type

+ 5 - 0
src/main.js

@@ -75,6 +75,11 @@ axios.interceptors.request.use(
     if (organizationId) {
       config.headers["organizationId"] = organizationId;
     }
+    let user = Vue.ls.get("user", {});
+    if (user) {
+      config.headers["userId"] = user.id;
+      config.headers["workId"] = user.workId;
+    }
 
     // 设置延迟时效
     config.timeout = GLOBAL.timeout;

+ 62 - 13
src/modules/grading-set/GradingRuleSet.vue

@@ -4,7 +4,7 @@
       ref="modalFormComp"
       :model="modalForm"
       :rules="rules"
-      :label-width="200"
+      :label-width="230"
       style="width: 400px;"
     >
       <FormItem prop="deviation" label="仲裁档位差:">
@@ -16,10 +16,24 @@
           style="width: 160px;"
         ></InputNumber>
       </FormItem>
+      <FormItem label="系统自动打回:">
+        <Select
+          v-model="modalForm.autoCallback"
+          :disabled="!modalFormCanEdit"
+          placeholder="请选择"
+        >
+          <Option
+            v-for="(val, key) in BOOLEAN_TYPE"
+            :key="key"
+            :value="key * 1"
+            :label="val"
+          ></Option>
+        </Select>
+      </FormItem>
       <FormItem
+        v-if="modalForm.autoCallback"
         prop="cumulativeError"
         label="打回累计误差:"
-        v-if="modalForm.autoCallback"
       >
         <InputNumber
           v-model="modalForm.cumulativeError"
@@ -29,11 +43,14 @@
           style="width: 160px;"
         ></InputNumber>
       </FormItem>
-      <FormItem prop="examNumber" label="系统自动打回:">
+      <FormItem
+        v-if="modalForm.autoCallback"
+        label="自动打回是否显示偏差方向:"
+      >
         <Select
-          v-model="modalForm.autoCallback"
+          v-model="modalForm.autoCallbackShowDeviation"
           :disabled="!modalFormCanEdit"
-          placeholder="系统自动打回"
+          placeholder="请选择"
         >
           <Option
             v-for="(val, key) in BOOLEAN_TYPE"
@@ -43,11 +60,11 @@
           ></Option>
         </Select>
       </FormItem>
-      <FormItem prop="examNumber" label="是否过半定档:">
+      <FormItem label="是否过半定档:">
         <Select
           v-model="modalForm.majority"
           :disabled="!modalFormCanEdit"
-          placeholder="是否过半定档"
+          placeholder="请选择"
         >
           <Option
             v-for="(val, key) in BOOLEAN_TYPE"
@@ -57,11 +74,11 @@
           ></Option>
         </Select>
       </FormItem>
-      <FormItem prop="examNumber" label="阅卷员是否显示所有试卷:">
+      <FormItem label="阅卷员是否显示所有试卷:">
         <Select
           v-model="modalForm.levelShowAllPaper"
           :disabled="!modalFormCanEdit"
-          placeholder="阅卷员是否显示所有试卷"
+          placeholder="请选择"
         >
           <Option
             v-for="(val, key) in BOOLEAN_TYPE"
@@ -71,11 +88,39 @@
           ></Option>
         </Select>
       </FormItem>
-      <FormItem prop="examNumber" label="是否显示试卷数量:">
+      <FormItem label="是否显示试卷数量:">
         <Select
           v-model="modalForm.showPaperCount"
           :disabled="!modalFormCanEdit"
-          placeholder="是否显示试卷数量"
+          placeholder="请选择"
+        >
+          <Option
+            v-for="(val, key) in BOOLEAN_TYPE"
+            :key="key"
+            :value="key * 1"
+            :label="val"
+          ></Option>
+        </Select>
+      </FormItem>
+      <FormItem label="档位百分比分母:">
+        <Select
+          v-model="modalForm.propDenominator"
+          :disabled="!modalFormCanEdit"
+          placeholder="请选择"
+        >
+          <Option
+            v-for="(val, key) in PROP_DENOMINATOR_TYPE"
+            :key="key"
+            :value="key * 1"
+            :label="val"
+          ></Option>
+        </Select>
+      </FormItem>
+      <FormItem label="是否显示标准卷:">
+        <Select
+          v-model="modalForm.showSample"
+          :disabled="!modalFormCanEdit"
+          placeholder="请选择"
         >
           <Option
             v-for="(val, key) in BOOLEAN_TYPE"
@@ -107,7 +152,7 @@
 
 <script>
 import { getParamsSet, updateLevelParams } from "@/api";
-import { BOOLEAN_TYPE } from "@/constants/enumerate";
+import { BOOLEAN_TYPE, PROP_DENOMINATOR_TYPE } from "@/constants/enumerate";
 import { numberValidator } from "@/plugins/formRules";
 
 export default {
@@ -117,14 +162,18 @@ export default {
       isSubmit: false,
       workId: this.$route.params.workId,
       BOOLEAN_TYPE,
+      PROP_DENOMINATOR_TYPE,
       initModalForm: {
         workId: "",
         deviation: 3,
         cumulativeError: null,
         autoCallback: 0,
+        autoCallbackShowDeviation: 1,
         majority: 0,
         levelShowAllPaper: 0,
-        showPaperCount: 1
+        showPaperCount: 1,
+        propDenominator: 1,
+        showSample: 1
       },
       modalFormCanEdit: false,
       modalForm: {},

+ 31 - 8
src/modules/grading/GradingDetail.vue

@@ -26,13 +26,14 @@
               }
             "
             @on-paper-change="standardPaperChange"
-            v-if="levels.length && filter.questionId"
+            v-if="
+              levels.length &&
+                filter.questionId &&
+                ((IS_MARK_LEADER && paramsSet.showSample) || IS_ADMIN)
+            "
             ref="GradeStandardPaper"
           ></grade-standard-paper>
-          <div
-            class="detail-papers-carousel-split"
-            v-if="ACTION_CAN_BATCH"
-          ></div>
+          <!-- TODO:科组长的操作记录 -->
           <grade-history-paper
             :question-id="filter.questionId"
             @on-paper-click="
@@ -108,7 +109,7 @@
         <grade-action
           :cur-paper-or-task="curPaper"
           :levels="levels"
-          :user-role="curUserRoleType"
+          :params-set="paramsSet"
           @on-leader-level="leaderSelectLevel"
           @on-code-search="serachPaperByCode"
           ref="GradeAction"
@@ -181,7 +182,8 @@ import {
   taskSnSearch,
   subjectDetail,
   markHistoryList,
-  getParamsSet
+  getParamsSet,
+  leaderGradingPaper
 } from "@/api";
 import SimpleImagePreview from "@/components/SimpleImagePreview";
 import GradeFilter from "./components/GradeFilter";
@@ -528,7 +530,28 @@ export default {
       this.total = 1;
       this.selectPaper(0);
     },
-    leaderSelectLevel(levelInfo, markers) {
+    async leaderSelectLevel(levelInfo, markers) {
+      // 唯一权限时,直接操作
+      if (levelInfo.markLeaderOnlyRight && !this.paramsSet.leaderConfirm) {
+        const datas = {
+          action: levelInfo.markLeaderOnlyRight.action,
+          level: levelInfo.selectedLevel,
+          originLevel: levelInfo.curLevel,
+          paperIds: levelInfo.paperIds
+        };
+        if (datas.action === "reject") {
+          datas.range = markers.map(item => item.id).join();
+        }
+        let result = true;
+        const paper = await leaderGradingPaper(datas).catch(() => {
+          result = false;
+        });
+        if (!result) return;
+
+        this.leaderGradingSuccess(datas, paper);
+        return;
+      }
+
       this.levelInfo = levelInfo;
       this.markers = markers;
       this.$refs.ModifyLeaderGrading.open();

+ 4 - 3
src/modules/grading/GradingOperation.vue

@@ -30,10 +30,11 @@
                     }
                   "
                   @on-paper-change="standardPaperChange"
-                  v-if="levels.length && filter.questionId"
+                  v-if="
+                    levels.length && filter.questionId && paramsSet.showSample
+                  "
                   ref="GradeStandardPaper"
                 ></grade-standard-paper>
-                <div class="detail-papers-carousel-split"></div>
                 <grade-history-paper
                   :question-id="filter.questionId"
                   @on-paper-click="
@@ -115,7 +116,7 @@
               <grade-action
                 :cur-paper-or-task="curPaper"
                 :levels="levels"
-                :user-role="curUserRoleType"
+                :params-set="paramsSet"
                 @on-select-level="gradeCurPaper"
                 @on-pass="passCurPaper"
                 ref="GradeAction"

+ 2 - 2
src/modules/grading/GradingProgress.vue

@@ -24,10 +24,10 @@
         </Button>
       </div>
       <div class="part-box-head-left" v-if="IS_LEVEL">
-        <Button shape="circle" icon="upload icon" @click="toExportStandard"
+        <Button shape="circle" icon="md-download" @click="toExportStandard"
           >导出标准卷信息</Button
         >
-        <Button shape="circle" icon="upload icon" @click="toExportGrading"
+        <Button shape="circle" icon="md-download" @click="toExportGrading"
           >导出一键定档信息</Button
         >
       </div>

+ 76 - 51
src/modules/grading/components/GradeAction.vue

@@ -1,30 +1,5 @@
 <template>
   <div class="grade-action">
-    <!-- 查询 -->
-    <div class="action-search" v-if="rights.search">
-      <Select
-        class="search-select"
-        v-model="filter.codeType"
-        placeholder="密号类型"
-      >
-        <Option
-          v-for="item in codeTypes"
-          :key="item.key"
-          :value="item.key"
-          :label="item.val"
-        ></Option>
-      </Select>
-      <Input
-        class="search-input"
-        v-model.trim="filter.code"
-        placeholder="输入密号"
-        clearable
-      >
-      </Input>
-      <Button size="small" type="primary" class="search-btn" @click="searchCode"
-        >查询</Button
-      >
-    </div>
     <!-- 头部信息 ------ -->
     <!-- 试卷状态 -->
     <!-- 状态:已评,待评,打回,仲裁 -->
@@ -35,6 +10,7 @@
       <p class="paper-state-intro" v-if="curPaperOrTask.rejectedCount">
         共打回{{ curPaperOrTask.rejectedCount }}次
       </p>
+      <!-- TODO:自动打回时显示偏差 -->
     </div>
     <div class="action-paper-state" v-else>
       <p class="paper-state-cont">{{ stepLabel }}</p>
@@ -50,26 +26,14 @@
         <span>NO.{{ curPaperOrTask.sn }}</span>
       </p>
     </div>
-    <!-- 档位信息 -->
-    <!-- 已评(已评档位),打回(建议档位) -->
+
+    <!-- 选择档位 -->
     <h3
       class="action-grade-info-title"
-      v-if="curPaperOrTask.rejected && curPaperOrTask.isRejectedByLeader"
+      v-if="IS_MARK_LEADER && markLeaderOnlyRight && rights.gradeList"
     >
-      建议档位:
+      当前操作:{{ markLeaderOnlyRight.name }}
     </h3>
-    <div class="action-grade-info" v-if="rights.gradeInfo && curLevel.name">
-      <h3 class="grade-info-name">{{ curLevel.name }}</h3>
-      <div class="grade-info-range">
-        <p>分数范围</p>
-        <p>
-          <span>{{ curLevel.minScore }}</span>
-          <span>~</span>
-          <span>{{ curLevel.maxScore }}</span>
-        </p>
-      </div>
-    </div>
-    <!-- 选择档位 -->
     <div class="action-grade-list" v-if="rights.gradeList">
       <div
         class="action-grade-item"
@@ -88,6 +52,28 @@
         </div>
       </div>
     </div>
+    <!-- 档位信息 -->
+    <!-- 已评(已评档位),打回(建议档位) -->
+    <h3 class="action-grade-info-title">
+      <span v-if="curPaperOrTask.rejected && curPaperOrTask.isRejectedByLeader"
+        >建议档位:</span
+      >
+      <span v-if="stepType === 'done' || stepType === 'sample'"
+        >已评档位:</span
+      >
+    </h3>
+    <div class="action-grade-info" v-if="rights.gradeInfo && curLevel.name">
+      <h3 class="grade-info-name">{{ curLevel.name }}</h3>
+      <div class="grade-info-range">
+        <p>分数范围</p>
+        <p>
+          <span>{{ curLevel.minScore }}</span>
+          <span>~</span>
+          <span>{{ curLevel.maxScore }}</span>
+        </p>
+      </div>
+    </div>
+    <!-- 跳过 -->
     <div
       class="action-grade-pass"
       v-if="rights.gradeList && IS_MARKER"
@@ -98,7 +84,7 @@
 
     <!-- 评卷记录 -->
     <div class="action-grade-history" v-if="rights.gradeHis">
-      <h3>评卷记录</h3>
+      <h3>评卷记录</h3>
       <div class="grade-history-list">
         <div
           class="grade-history-item"
@@ -110,6 +96,32 @@
         </div>
       </div>
     </div>
+
+    <!-- 查询 -->
+    <div class="action-search" v-if="rights.search">
+      <Select
+        class="search-select"
+        v-model="filter.codeType"
+        placeholder="密号类型"
+      >
+        <Option
+          v-for="item in codeTypes"
+          :key="item.key"
+          :value="item.key"
+          :label="item.val"
+        ></Option>
+      </Select>
+      <Input
+        class="search-input"
+        v-model.trim="filter.code"
+        placeholder="输入密号"
+        clearable
+      >
+      </Input>
+      <Button size="small" type="primary" class="search-btn" @click="searchCode"
+        >查询</Button
+      >
+    </div>
   </div>
 </template>
 
@@ -201,13 +213,16 @@ export default {
         return [];
       }
     },
-    userRole: {
-      type: String,
-      default: "MARKER"
+    paramsSet: {
+      type: Object,
+      default() {
+        return {};
+      }
     }
   },
   data() {
     return {
+      curUserRoleType: this.$ls.get("user", { role: "" }).role,
       rights: {
         ...initRights
       },
@@ -252,18 +267,23 @@ export default {
       gradingHistory: [],
       curLevel: {},
       setT: null,
-      btnClicked: false
+      btnClicked: false,
+      // 科组长权限
+      markLeaderOnlyRight: null
     };
   },
   computed: {
     IS_ADMIN() {
-      return this.userRole === "ADMIN" || this.userRole === "SUPER_ADMIN";
+      return (
+        this.curUserRoleType === "ADMIN" ||
+        this.curUserRoleType === "SUPER_ADMIN"
+      );
     },
     IS_MARKER() {
-      return this.userRole === "MARKER";
+      return this.curUserRoleType === "MARKER";
     },
     IS_MARK_LEADER() {
-      return this.userRole === "MARK_LEADER";
+      return this.curUserRoleType === "MARK_LEADER";
     }
   },
   watch: {
@@ -272,6 +292,10 @@ export default {
     }
   },
   mounted() {
+    this.markLeaderOnlyRight = this.$ls.get("user", {
+      markLeaderOnlyRight: null
+    }).markLeaderOnlyRight;
+
     this.codeTypes = Object.entries(CODE_TYPE)
       .map(([key, val]) => {
         return {
@@ -299,7 +323,7 @@ export default {
       if (this.stepType === "sample") {
         roleRights = this.roleRight.STANDARD;
       } else {
-        roleRights = this.roleRight[this.userRole][this.stepType] || [];
+        roleRights = this.roleRight[this.curUserRoleType][this.stepType] || [];
       }
       this.rights = { ...initRights };
       roleRights.map(key => {
@@ -352,7 +376,8 @@ export default {
           {
             paperIds: this.curPaperOrTask.id + "",
             curLevel: this.curPaperOrTask.level,
-            selectedLevel: level.name
+            selectedLevel: level.name,
+            markLeaderOnlyRight: this.markLeaderOnlyRight
           },
           this.gradingHistory.map(item => {
             return {

+ 90 - 11
src/modules/grading/components/ModifyGradingUser.vue

@@ -13,7 +13,7 @@
       :model="modalForm"
       :rules="rules"
       :key="modalForm.id"
-      :label-width="80"
+      :label-width="140"
     >
       <FormItem prop="loginName" label="账号">
         <Input
@@ -96,14 +96,46 @@
           style="width: 120px"
         ></InputNumber>
       </FormItem>
-      <FormItem v-if="modalForm.role === 'MARK_LEADER'">
-        <Checkbox v-model="modalForm.oneClickLevel">是否一键定档</Checkbox
-        ><br />
-        <Checkbox v-model="modalForm.standardVolume">是否设立标准卷</Checkbox
-        ><br />
-        <Checkbox v-model="modalForm.levelCallback"
-          >是否建议档位打回档</Checkbox
+      <FormItem
+        v-if="modalForm.role === 'MARK_LEADER'"
+        prop="leaderConfirm"
+        label="操作是否要确认"
+      >
+        <Select
+          v-model="modalForm.leaderConfirm"
+          placeholder="请选择"
+          @on-change="leaderConfirmChange"
         >
+          <Option
+            v-for="(val, key) in BOOLEAN_TYPE"
+            :key="key"
+            :value="key * 1"
+            :label="val"
+          ></Option>
+        </Select>
+      </FormItem>
+      <FormItem
+        v-if="modalForm.role === 'MARK_LEADER'"
+        prop="leaderRights"
+        label="科组长权限"
+      >
+        <CheckboxGroup v-if="modalForm.leaderConfirm" v-model="leaderRights">
+          <Checkbox
+            v-for="(val, key) in MARK_LEADER_RIGHTS"
+            :key="key"
+            :label="key"
+          >
+            {{ val.name }}
+          </Checkbox>
+        </CheckboxGroup>
+        <RadioGroup v-else v-model="leaderRights">
+          <Radio
+            v-for="(val, key) in MARK_LEADER_RIGHTS"
+            :key="key"
+            :label="key"
+            >{{ val.name }}</Radio
+          >
+        </RadioGroup>
       </FormItem>
     </Form>
     <div slot="footer">
@@ -118,7 +150,12 @@
 <script>
 import { updateGradingUser, orgDetail } from "@/api";
 import { commonCode, password, numberValidator } from "@/plugins/formRules";
-import { ROLE_TYPE, MARKER_RIGHT_TYPE } from "@/constants/enumerate";
+import {
+  BOOLEAN_TYPE,
+  ROLE_TYPE,
+  MARKER_RIGHT_TYPE,
+  MARK_LEADER_RIGHTS
+} from "@/constants/enumerate";
 
 const initModalForm = {
   id: "",
@@ -132,7 +169,8 @@ const initModalForm = {
   weight: null,
   oneClickLevel: false,
   standardVolume: false,
-  levelCallback: false
+  levelCallback: false,
+  leaderConfirm: 1
 };
 
 export default {
@@ -165,6 +203,9 @@ export default {
       isSubmit: false,
       roleTypes: [],
       MARKER_RIGHT_TYPE,
+      BOOLEAN_TYPE,
+      MARK_LEADER_RIGHTS,
+      leaderRights: [],
       modalForm: { ...initModalForm },
       loginNamePrepend: "",
       orgInfo: {},
@@ -194,7 +235,24 @@ export default {
             trigger: "change"
           }
         ],
-        weight: numberValidator("请输入权重")
+        weight: numberValidator("请输入权重"),
+        leaderConfirm: numberValidator("请选择操作是否需要确认"),
+        leaderRights: [
+          {
+            required: true,
+            validator: (rule, value, callback) => {
+              if (this.modalForm.leaderConfirm) {
+                return callback();
+              } else {
+                if (!this.leaderRights) {
+                  return callback(new Error("请选择科组长权限"));
+                }
+                return callback();
+              }
+            },
+            trigger: "change"
+          }
+        ]
       }
     };
   },
@@ -216,9 +274,15 @@ export default {
         );
       }
       this.modalForm = this.$objAssign(initModalForm, val);
+      this.modalForm.leaderConfirm = this.modalForm.leaderConfirm ? 1 : 0;
       this.loginNamePrepend = `${this.orgInfo.abbreviation.toLowerCase()}-${
         this.modalForm.workId
       }-`;
+      this.leaderRights = Object.keys(MARK_LEADER_RIGHTS).filter(
+        right => this.modalForm[right]
+      );
+      if (!this.modalForm.leaderConfirm)
+        this.leaderRights = this.leaderRights[0];
     },
     visibleChange(visible) {
       if (visible) {
@@ -229,6 +293,13 @@ export default {
       const organizationId = this.$ls.get("organizationId");
       this.orgInfo = await orgDetail(organizationId);
     },
+    leaderConfirmChange(val) {
+      if (val) {
+        this.leaderRights = [];
+      } else {
+        this.leaderRights = "";
+      }
+    },
     cancel() {
       this.modalIsShow = false;
     },
@@ -243,6 +314,14 @@ export default {
       this.isSubmit = true;
       let result = true;
       const datas = { ...this.modalForm };
+      datas.leaderConfirm = !!datas.leaderConfirm;
+      const rights = datas.leaderConfirm
+        ? this.leaderRights
+        : [this.leaderRights];
+      Object.keys(MARK_LEADER_RIGHTS).forEach(right => {
+        datas[right] = rights.includes(right);
+      });
+
       if (!this.isEdit)
         datas.loginName = `${this.loginNamePrepend}${datas.loginName}`;
       await updateGradingUser(datas).catch(() => {

+ 1 - 1
src/modules/inspection/InspectionActionLogs.vue

@@ -78,7 +78,7 @@
       </Form>
     </div>
     <div class="part-box-head">
-      <Button shape="circle" icon="upload icon" @click="exportLogs"
+      <Button shape="circle" icon="md-download" @click="exportLogs"
         >导出操作日志</Button
       >
     </div>

+ 1 - 1
src/modules/inspection/InspectionCollectLogs.vue

@@ -78,7 +78,7 @@
       </Form>
     </div>
     <div class="part-box-head">
-      <Button shape="circle" icon="upload icon" @click="exportLogs"
+      <Button shape="circle" icon="md-download" @click="exportLogs"
         >导出操作日志</Button
       >
     </div>

+ 14 - 0
src/modules/login/LoginHome.vue

@@ -57,6 +57,7 @@
 import { password } from "@/plugins/formRules";
 import { login, subjectDetail } from "@/api";
 import ResetPwd from "./ResetPwd";
+import { MARK_LEADER_RIGHTS } from "@/constants/enumerate";
 
 export default {
   name: "login",
@@ -121,6 +122,19 @@ export default {
       this.isSubmit = false;
       if (!data) return;
 
+      // 如果是科组长,解析是否只有唯一权限
+      const rights = Object.entries(MARK_LEADER_RIGHTS).filter(
+        ([k, v]) => data[k]
+      );
+      if (rights.length === 1 && !data.leaderConfirm) {
+        data.markLeaderOnlyRight = {
+          code: rights[0][0],
+          ...rights[0][1]
+        };
+      } else {
+        data.markLeaderOnlyRight = null;
+      }
+
       this.$ls.set("user", data);
       this.$ls.set("organizationId", data.organizationId);
 

+ 4 - 1
src/modules/main/PaperManage.vue

@@ -228,7 +228,10 @@ export default {
       this.subjects = data.filter(item => item.enable);
     },
     typeChange() {
-      if (this.paperType === "1") {
+      if (this.paperType === "2") {
+        // TODO:
+        // 关联考号,调原图
+      } else if (this.paperType === "1") {
         this.filter.isManual = true;
         this.filter.missing = null;
       } else if (this.paperType === "0") {

+ 43 - 3
src/modules/main/WorkOverview.vue

@@ -17,13 +17,13 @@
       </ul>
       <div class="overview-actions">
         <Button
-          icon="upload icon"
+          icon="md-download"
           shape="circle"
           @click="download(exportGradeScoreUrl)"
           >导出档位成绩</Button
         >
         <Button
-          icon="upload icon"
+          icon="md-download"
           shape="circle"
           @click="download(exportScoreUrl)"
           >导出分数成绩</Button
@@ -59,6 +59,13 @@
               <Button
                 icon="upload icon"
                 shape="circle"
+                @click="toUploadManual(subject)"
+                >导入缺考名单</Button
+              >
+              <br />
+              <Button
+                icon="md-download"
+                shape="circle"
                 @click="download(subject.exportAbsentDataUrl)"
                 >导出缺考名单</Button
               >
@@ -74,15 +81,30 @@
         </div>
       </div>
     </div>
+    <!-- import student  -->
+    <import-file
+      title="导入缺考名单"
+      :upload-url="uploadUrl"
+      :upload-data="uploadData"
+      :download-url="downloadManualTemplateUrl"
+      :download-filename="downloadManualTemplateFilename"
+      :headers="headers"
+      :format="['xls', 'xlsx']"
+      @upload-success="uploadSuccess"
+      ref="ImportManual"
+    >
+    </import-file>
   </div>
 </template>
 
 <script>
 import { workOverviewDetail } from "@/api";
 import { SUBJECT_STAGE } from "@/constants/enumerate";
+import ImportFile from "@/components/common/ImportFile";
 
 export default {
   name: "overview",
+  components: { ImportFile },
   data() {
     return {
       workId: this.$route.params.workId,
@@ -91,7 +113,18 @@ export default {
       exportScoreUrl: "",
       overviewInfo: {
         subjectOverviews: []
-      }
+      },
+      // upload
+      headers: {
+        Authorization: "token"
+      },
+      uploadData: {
+        workId: this.$route.params.workId,
+        subjectId: ""
+      },
+      uploadUrl: "/api/import/students",
+      downloadManualTemplateUrl: "/templates/考生缺考表-模板.xlsx",
+      downloadManualTemplateFilename: "考生缺考表-模板.xlsx"
     };
   },
   mounted() {
@@ -118,6 +151,13 @@ export default {
     download(url) {
       window.open(url);
     },
+    toUploadManual(subject) {
+      this.uploadData.subjectId = subject.subjectId;
+      this.$refs.ImportManual.open();
+    },
+    uploadSuccess() {
+      this.$Message.success("导入成功!");
+    },
     toCommit(subject) {
       const routerName = subject.markStage === "SCORE" ? "Mark" : "Grading";
       this.$router.push({

+ 24 - 5
src/modules/mark-set/MarkRuleSet.vue

@@ -7,7 +7,11 @@
       style="width: 400px"
     >
       <FormItem label="分数处理方式:">
-        <Select v-model="modalForm.roundUp" :disabled="!modalFormCanEdit">
+        <Select
+          v-model="modalForm.roundUp"
+          :disabled="!modalFormCanEdit"
+          placeholder="请选择"
+        >
           <Option
             v-for="(val, key) in SCORE_HANDLE_TYPE"
             :key="key"
@@ -20,7 +24,7 @@
         <Select
           v-model="modalForm.changeStage"
           :disabled="!modalFormCanEdit"
-          placeholder="阅卷员是否显示改档及改档打分"
+          placeholder="请选择"
         >
           <Option
             v-for="(val, key) in BOOLEAN_TYPE"
@@ -34,7 +38,7 @@
         <Select
           v-model="modalForm.scoreShowAllPaper"
           :disabled="!modalFormCanEdit"
-          placeholder="阅卷员是否显示所有试卷"
+          placeholder="请选择"
         >
           <Option
             v-for="(val, key) in BOOLEAN_TYPE"
@@ -48,7 +52,21 @@
         <Select
           v-model="modalForm.isLevelToScore"
           :disabled="!modalFormCanEdit"
-          placeholder="是否谁分档谁打分"
+          placeholder="请选择"
+        >
+          <Option
+            v-for="(val, key) in BOOLEAN_TYPE"
+            :key="key"
+            :value="key * 1"
+            :label="val"
+          ></Option>
+        </Select>
+      </FormItem>
+      <FormItem label="是否启用直接输分功能:">
+        <Select
+          v-model="modalForm.directScore"
+          :disabled="!modalFormCanEdit"
+          placeholder="请选择"
         >
           <Option
             v-for="(val, key) in BOOLEAN_TYPE"
@@ -95,7 +113,8 @@ export default {
         roundUp: 0,
         changeStage: 0,
         scoreShowAllPaper: 0,
-        isLevelToScore: 0
+        isLevelToScore: 0,
+        directScore: 0
       },
       modalFormCanEdit: false,
       modalForm: {}

+ 0 - 1
src/modules/mark/MarkDetail.vue

@@ -85,7 +85,6 @@
         <mark-action
           :cur-paper-or-task="curPaper"
           :levels="levels"
-          :user-role="curUserRoleType"
           @on-leader-level="leaderSelectLevel"
           @on-code-search="serachPaperByCode"
           @on-grade-change-search="searchGradeChangeList"

+ 1 - 1
src/modules/mark/MarkOperation.vue

@@ -91,8 +91,8 @@
               <mark-action
                 :cur-paper-or-task="curPaper"
                 :levels="levels"
-                :user-role="curUserRoleType"
                 :show-count="showPaperRelateCount"
+                :params-set="paramsSet"
                 @on-leader-level="gradingCurPaper"
                 @on-select-score="scoreCurPaper"
                 @on-pass="passCurPaper"

+ 18 - 8
src/modules/mark/components/MarkAction.vue

@@ -144,7 +144,10 @@
         </div>
       </div>
     </div>
-    <div class="action-mark-input" v-if="rights.levelList">
+    <div
+      class="action-mark-input"
+      v-if="rights.levelList && paramsSet.directScore"
+    >
       <Form
         ref="ManualScoreForm"
         label-position="left"
@@ -288,13 +291,16 @@ export default {
         return [];
       }
     },
-    userRole: {
-      type: String,
-      default: "MARKER"
+    paramsSet: {
+      type: Object,
+      default() {
+        return {};
+      }
     }
   },
   data() {
     return {
+      curUserRoleType: this.$ls.get("user", { role: "" }).role,
       rights: {
         ...initRights
       },
@@ -375,13 +381,16 @@ export default {
   },
   computed: {
     IS_ADMIN() {
-      return this.userRole === "ADMIN" || this.userRole === "SUPER_ADMIN";
+      return (
+        this.curUserRoleType === "ADMIN" ||
+        this.curUserRoleType === "SUPER_ADMIN"
+      );
     },
     IS_MARKER() {
-      return this.userRole === "MARKER";
+      return this.curUserRoleType === "MARKER";
     },
     IS_MARK_LEADER() {
-      return this.userRole === "MARK_LEADER";
+      return this.curUserRoleType === "MARK_LEADER";
     }
   },
   watch: {
@@ -437,7 +446,8 @@ export default {
       this.stepType = this.getStepType();
       this.stepLabel = this.stepDict[this.stepType];
       this.rights = { ...initRights };
-      const roleRights = this.roleRight[this.userRole][this.stepType] || [];
+      const roleRights =
+        this.roleRight[this.curUserRoleType][this.stepType] || [];
       roleRights.map(key => {
         this.rights[key] = true;
       });

+ 0 - 1
src/plugins/axios.js

@@ -53,7 +53,6 @@ const errorCallback = error => {
 //   let content = error.message || "数据错误";
 //   content = content.indexOf("###") !== -1 ? "参数错误" : content;
 
-//   // TODO:自定义处理逻辑,以下为epcc实例
 //   if (error.code === -100) {
 //     content = "身份验证失效,请重新登录";
 //     ViewUI.Modal.confirm({

+ 0 - 169
src/views/HomeOld.vue

@@ -1,169 +0,0 @@
-<template>
-  <div class="home">
-    <div class="home-header">
-      <div class="head-logo" :class="{ 'head-logo-tiny': isCollapsed }">
-        <!-- big logo 160*40 -->
-        <h1 v-if="!isCollapsed">LOGO</h1>
-        <!-- small logo 40*40 -->
-        <h1 v-else>A</h1>
-      </div>
-      <div class="head-switch" @click="collapsedSider">
-        <Icon :class="rotateIcon" type="md-menu" size="24"></Icon>
-      </div>
-      <div class="head-info">
-        <Breadcrumb>
-          <BreadcrumbItem>
-            <Icon type="md-home" :size="16" style="margin-top: -4px;"></Icon>
-          </BreadcrumbItem>
-          <BreadcrumbItem v-for="(bread, index) in breadcrumbs" :key="index">{{
-            bread
-          }}</BreadcrumbItem>
-        </Breadcrumb>
-      </div>
-      <div class="head-user">
-        <Avatar icon="md-person" />
-        <span class="user-name">{{ username }}</span>
-        <span class="user-logout" @click="logout">
-          <Icon type="md-power" size="20"></Icon>
-        </span>
-      </div>
-    </div>
-
-    <div class="home-navs" :class="{ 'home-navs-tiny': isCollapsed }">
-      <ul>
-        <li class="nav-item" v-for="(nav, index) in navs" :key="index">
-          <div
-            :class="[
-              'nav-item-main',
-              { 'nav-item-main-act': curMain === index }
-            ]"
-            @click="switchNav(nav, index)"
-          >
-            <span class="nav-item-icon nav-item-icon-left">
-              <Icon :type="nav.icon"></Icon>
-            </span>
-            <p class="nav-item-cont">{{ nav.title }}</p>
-            <span
-              class="nav-item-icon nav-item-icon-right"
-              v-if="nav.children && nav.children.length"
-            >
-              <Icon
-                :type="nav.showList ? 'ios-arrow-down' : 'ios-arrow-forward'"
-              ></Icon>
-            </span>
-          </div>
-          <ul
-            class="nav-item-sublist"
-            :class="{ 'nav-sublist-hide': !nav.showList }"
-            v-if="nav.children && nav.children.length"
-            :style="{ height: nav.children.length * 40 + 'px' }"
-          >
-            <li
-              v-for="(subnav, sindex) in nav.children"
-              :key="sindex"
-              :class="[
-                'nav-item-sub',
-                { 'nav-item-sub-act': curSub === index + '-' + sindex }
-              ]"
-              @click="toPage(index, sindex)"
-            >
-              {{ subnav.title }}
-            </li>
-          </ul>
-        </li>
-      </ul>
-    </div>
-
-    <div class="home-body" :class="{ 'home-body-big': isCollapsed }">
-      <div class="home-main">
-        <router-view />
-
-        <view-footer></view-footer>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import navs from "@/constants/navs";
-
-export default {
-  name: "home",
-  data() {
-    return {
-      isCollapsed: false,
-      navs,
-      curMain: 0,
-      curSub: "",
-      avatar: "",
-      breadcrumbs: []
-    };
-  },
-  computed: {
-    rotateIcon() {
-      return ["menu-icon", this.isCollapsed ? "rotate-icon" : ""];
-    },
-    username() {
-      return this.$store.state.user.realName;
-    }
-  },
-  watch: {
-    $route() {
-      this.actCurNav();
-    }
-  },
-  mounted() {
-    this.actCurNav();
-    // TODO:获取用户角色信息,动态注册路由,然后跳转路由
-  },
-  methods: {
-    collapsedSider() {
-      this.isCollapsed = !this.isCollapsed;
-    },
-    switchNav(item, mainIndex) {
-      if (item.children) {
-        item.showList = !item.showList;
-      } else {
-        this.breadcrumbs = [item.title];
-        this.curMain = mainIndex;
-        this.curSub = "";
-        this.$router.push({ name: item.router });
-      }
-    },
-    actCurNav() {
-      let router = this.$route.name;
-      this.navs.forEach((item, index) => {
-        if (item.children && item.children.length) {
-          item.children.forEach((elem, pindex) => {
-            if (elem.router === router) {
-              this.curSub = index + "-" + pindex;
-              this.curMain = index;
-              this.breadcrumbs = [item.title, elem.title];
-            }
-          });
-        } else {
-          if (item.router === router) {
-            this.curMain = index;
-            this.breadcrumbs = [item.title];
-          }
-        }
-      });
-      this.navs[this.curMain].showList = true;
-    },
-    toPage(mainIndex, subIndex) {
-      let item = this.navs[mainIndex];
-      this.breadcrumbs = [item.title, item.children[subIndex].title];
-      this.curMain = mainIndex;
-      this.curSub = mainIndex + "-" + subIndex;
-
-      this.$router.push({
-        name: this.navs[mainIndex].children[subIndex].router
-      });
-    },
-    logout() {
-      this.$ls.clear();
-      this.$router.push({ name: "Login" });
-    }
-  }
-};
-</script>