123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746 |
- <template>
- <div class="grade-action">
- <!-- 头部信息 ------ -->
- <!-- 试卷状态 -->
- <!-- 状态:已评,待评,打回,仲裁,改大裆,改大裆打小档 -->
- <div class="action-paper-state" v-if="stepType === 'reject'">
- <p class="paper-state-cont">
- {{ curPaperOrTask.isRejectedByLeader ? "科组长打回" : "自动打回" }}
- </p>
- <p class="paper-state-intro">
- <span v-if="curPaperOrTask.rejectedCount"
- >共打回{{ curPaperOrTask.rejectedCount }}次</span
- >
- </p>
- </div>
- <div class="action-paper-state" v-else>
- <p class="paper-state-cont">{{ stepLabel }}</p>
- </div>
- <!-- 试卷信息 -->
- <div class="action-paper-info">
- <p>
- <span v-if="IS_MARKER">任务密号:</span>
- <span v-else>试卷密号:</span>
- <span v-if="curPaperOrTask.sn && !isBatchAction">
- NO.{{ curPaperOrTask.sn }}
- </span>
- <span v-else>--</span>
- </p>
- </div>
- <!-- 改档信息 -->
- <div class="action-grade-change" v-if="rights.gradeChange">
- <p>
- <span>原始粗档位:</span
- ><span>{{ curPaperOrTask.originLevel | levelNameFilter }}</span>
- </p>
- <p>
- <span v-if="IS_MARKER">建议粗档位:</span>
- <span v-else>申请粗档位:</span>
- <span>{{ curPaperOrTask.redoLevel | levelNameFilter }}</span>
- </p>
- </div>
- <div
- :class="[
- 'action-grade-change-status',
- { 'action-grade-change-status-error': curPaperOrTask.auditStatus === 0 }
- ]"
- v-if="rights.gradeChange && IS_ADMIN"
- >
- <p>{{ curPaperOrTask.auditStatus === 1 ? "同意改档" : "不同意改档" }}</p>
- </div>
- <!-- 大档位信息 -->
- <!-- 已评/待评(已评档位),改大裆打小档(已评档位) -->
- <div
- class="action-grade-info"
- v-if="rights.roughGradeInfo && curRoughLevel.name"
- >
- <h3 class="grade-info-name">
- {{ curRoughLevel.name | levelNameFilter }}
- </h3>
- <div class="grade-info-range">
- <p>档位范围</p>
- <p>
- <span>{{ curRoughLevel.minScore }}</span>
- <span>~</span>
- <span>{{ curRoughLevel.maxScore }}</span>
- </p>
- </div>
- </div>
- <!-- 小档位信息 -->
- <!-- 已评(已评档位),打回(建议档位) -->
- <h3
- class="action-grade-info-title"
- v-if="IS_MARKER && stepType === 'reject'"
- >
- <span>原细分档档位:{{ curPaperOrTask.originLevel || "" }}</span>
- <span
- v-if="
- paramsSet.levelConfig &&
- paramsSet.levelConfig.autoCallbackShowDeviation &&
- curPaperOrTask.deviationDirection &&
- curPaperOrTask.deviationDirection !== '0'
- "
- :class="[
- 'grade-info-deviation',
- {
- 'grade-info-deviation-error':
- curPaperOrTask.deviationDirection * 1 > 0
- }
- ]"
- >{{ curPaperOrTask.deviationDirection * 1 > 0 ? "偏高" : "偏低" }}</span
- >
- </h3>
- <h3
- class="action-grade-info-title"
- v-if="curPaperOrTask.rejected && curPaperOrTask.isRejectedByLeader"
- >
- 建议细分档位:
- </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-info action-mark-info"
- v-if="rights.gradeInfo && !curLevel.name"
- >
- <p class="grade-info-name grade-info-none">未分档</p>
- </div>
- <!-- 选择小档位 -->
- <div class="action-grade-list" v-if="rights.levelList">
- <div
- class="action-grade-item"
- v-for="(level, index) in levelList"
- :key="index"
- >
- <div
- :class="[
- 'action-grade-item-content',
- {
- 'action-item-content-disabled': btnClicked,
- 'is-active': keyInput == level.name
- }
- ]"
- @click="selectLevel(level)"
- >
- <p>{{ level.name }}</p>
- <p>{{ level.minScore }}~{{ level.maxScore }}</p>
- </div>
- </div>
- </div>
- <!-- 选择大档位 -->
- <h3
- class="action-grade-info-title"
- v-if="IS_MARK_LEADER && markLeaderOnlyRight && rights.roughLevelList"
- >
- 当前操作:{{ markLeaderOnlyRight.name }}
- </h3>
- <div class="action-grade-list" v-if="rights.roughLevelList">
- <div
- class="action-grade-item"
- v-for="(level, index) in roughLevelList"
- :key="index"
- >
- <div
- :class="[
- 'action-grade-item-content',
- {
- 'action-item-content-disabled': btnClicked,
- 'is-active': keyInput == level.name
- }
- ]"
- @click="selectRoughLevel(level)"
- >
- <p>{{ level.name | levelNameFilter }}</p>
- <p>{{ level.minScore }}~{{ level.maxScore }}</p>
- <p v-if="level.minSubScore || level.maxSubScore">
- {{ level.minSubScore }}~{{ level.maxSubScore }}
- </p>
- </div>
- </div>
- </div>
- <div
- v-if="
- ribbonSet.keyboardMark && (rights.roughLevelList || rights.levelList)
- "
- class="action-grade-keyboard"
- >
- <div class="keyboard-input">{{ keyInput }}</div>
- <div class="keyboard-clear" @click="clearKeyInput">
- <Icon type="md-trash" />
- </div>
- </div>
- <!-- 跳过 -->
- <div
- class="action-grade-pass"
- v-if="rights.gradePass && IS_MARKER"
- @click="toPass"
- >
- 跳过
- </div>
- <!-- marker confirm grade change -->
- <div
- class="action-grade-change-confirm"
- v-if="IS_MARKER && rights.gradeChange"
- >
- <Button type="primary" @click="gradeChangeConfirm">确认改档</Button>
- </div>
- <!-- 评卷记录 -->
- <div class="action-grade-history" v-if="rights.gradeHis">
- <h3>评卷记录</h3>
- <div class="grade-history-list">
- <div
- class="grade-history-item"
- v-for="his in gradingHistory"
- :key="his.id"
- >
- <p>{{ his.loginName }}</p>
- <p>{{ his.value }}</p>
- </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>
- <script>
- import { markHistoryList } from "@/api";
- import { CODE_TYPE } from "@/constants/enumerate";
- import { mapState, mapMutations } from "vuex";
- import { levelNameTransform } from "@/plugins/utils";
- // 三种情况:
- // 管理员(ADMIN),科组长(MARK_LEADER),评卷员(MARKER)
- // MARK_LEADER / ADMIN: curPaperOrTask => paper
- // MARKER: curPaperOrTask => task
- //
- /*
- [paper template]
- {
- "id": 165,
- "sn": "029947536",
- "examNumber": "1901040084",
- "level": "A",
- "score": null,
- "redoLevel": null,
- "updatedOn": 1591767742000,
- "imgSrc": "",
- "thumbSrc": "",
- "markByLeader": false,
- "markedLogic": true,
- "areaCode": "2",
- "inspectScore": null,
- "inspectLevel": null,
- "inspector": null,
- "sheetSrc": null,
- "stage": "LEVEL",
- "test": 0,
- "paperTest": 0,
- "markResults": [],
- "rejected": false,
- "arbitrated": false,
- "sample": false,
- "tagged": false,
- "missing": false,
- "manual": false
- }
- [marktask template]
- {
- id: 58,
- sn: "18111595446",
- redoLevel: null,
- level: null,
- roughLevel: "5",
- score: null,
- result: null,
- originLevel: "",
- markerId: 16,
- loginName: "sm1",
- marker: "sm1",
- updatedOn: null,
- imgSrc: "",
- thumbSrc: "",
- markByLeader: false,
- oldRejected: false,
- paperId: 107,
- randomSeqNew: 11595446,
- randomSeq: null,
- serialNumber: null,
- displayNumber: false,
- shift: false,
- shiftScore: false,
- isRejectedByLeader: false,
- rejectedCount: 0,
- dateMineResult: null,
- deviationDirection: null,
- sample: false,
- rejected: false,
- mark: false,
- key: "i9k7nqr8s2kb60uo",
- title: "NO.18111595446",
- selected: false
- };
- */
- const initRights = {
- roughGradeInfo: false,
- gradeInfo: false,
- levelList: false,
- roughLevelList: false,
- gradePass: false,
- gradeHis: false,
- search: false
- };
- export default {
- name: "grade-action-rough",
- props: {
- curPaperOrTask: {
- type: Object,
- default() {
- return {};
- }
- },
- levels: {
- type: Array,
- default() {
- return [];
- }
- },
- paramsSet: {
- type: Object,
- default() {
- return {};
- }
- },
- isBatchAction: {
- type: Boolean,
- default: false
- },
- // 是否处于粗分档
- isRoughLevel: {
- type: Boolean,
- default: false
- }
- },
- data() {
- return {
- curUserRoleType: this.$ls.get("user", { role: "" }).role,
- curPaperOrTaskLevel: "",
- rights: {
- ...initRights
- },
- cacheRights: null,
- roleRight: {
- ADMIN: {
- done: ["roughGradeInfo", "gradeInfo", "gradeHis", "search"],
- reject: ["roughGradeInfo", "gradeInfo", "gradeHis", "search"],
- arbitrate: ["gradeHis", "search"],
- shift: [
- "roughGradeInfo",
- "gradeInfo",
- "search",
- "gradeChangeSearch",
- "gradeChange"
- ]
- },
- MARK_LEADER: {
- undo: ["roughGradeInfo", "gradeInfo", "levelList", "roughLevelList"],
- done: [
- "roughGradeInfo",
- "gradeInfo",
- "levelList",
- "roughLevelList",
- "gradeHis"
- ],
- reject: [
- "roughGradeInfo",
- "gradeInfo",
- "levelList",
- "roughLevelList",
- "gradeHis"
- ],
- arbitrate: ["roughGradeInfo", "gradeInfo", "levelList", "gradeHis"],
- shift: ["gradeChange", "roughLevelList"],
- batch: ["levelList"]
- },
- MARKER: {
- done: ["roughGradeInfo", "gradeInfo", "levelList"],
- undo: ["roughGradeInfo", "gradeInfo", "levelList", "gradePass"],
- reject: ["gradeInfo", "levelList", "gradePass"],
- shift: ["gradeChange"],
- shiftScore: ["roughGradeInfo", "gradeInfo", "levelList", "levelPass"],
- batch: ["levelList"]
- },
- STANDARD: ["gradeInfo"]
- },
- filter: {
- codeType: "examNumber",
- code: ""
- },
- codeTypes: [],
- stepDict: {
- undo: "待评",
- done: "已评",
- reject: "打回",
- arbitrate: "待仲裁",
- shift: "改大档",
- shiftScore: "改大档打小档",
- sample: "标准卷",
- batch: "批量操作"
- },
- stepType: "",
- stepLabel: "",
- gradingHistory: [],
- levelList: [],
- curLevel: {},
- roughLevelList: [],
- curRoughLevel: {},
- setT: null,
- btnClicked: false,
- keyInput: null,
- // 科组长权限
- markLeaderOnlyRight: null
- };
- },
- computed: {
- ...mapState("marker", ["ribbonSet", "shortcutKeyStatus", "curSubject"]),
- IS_ADMIN() {
- return this.curUserRoleType === "ADMIN";
- },
- IS_MARKER() {
- return this.curUserRoleType === "MARKER";
- },
- IS_MARK_LEADER() {
- return this.curUserRoleType === "MARK_LEADER";
- }
- },
- watch: {
- curPaperOrTask() {
- this.rebuildRight();
- },
- isBatchAction(val) {
- if (val) {
- this.stepType = "batch";
- this.stepLabel = this.stepDict[this.stepType];
- const roleRights =
- this.roleRight[this.curUserRoleType][this.stepType] || [];
- this.rights = { ...initRights };
- roleRights.map(key => {
- this.rights[key] = true;
- });
- } else {
- this.rebuildRight();
- }
- this.keyInput = null;
- },
- "ribbonSet.keyboardMark": {
- immediate: true,
- handler(val) {
- this.setShortcutStatus({ action: val });
- }
- },
- "shortcutKeyStatus.action": {
- immediate: true,
- handler(val, oldval) {
- // console.log(val, oldval);
- if (val === oldval) return;
- if (val) {
- document.addEventListener("keydown", this.keyEvent);
- } else {
- document.removeEventListener("keydown", this.keyEvent);
- }
- }
- }
- },
- mounted() {
- this.markLeaderOnlyRight = this.$ls.get("user", {
- markLeaderOnlyRight: null
- }).markLeaderOnlyRight;
- this.codeTypes = Object.entries(CODE_TYPE)
- .map(([key, val]) => {
- return {
- key,
- val
- };
- })
- .filter(item => item.key !== "examNumber");
- // .filter(item => this.IS_ADMIN || item.key !== "examNumber");
- this.rebuildRight();
- },
- methods: {
- ...mapMutations("marker", ["setShortcutStatus"]),
- getStepType() {
- const info = this.curPaperOrTask;
- if (info.sample) return "sample";
- if (info.shift && info.shiftScore && !info.level && !info.result)
- return "shift";
- if (!info.shift && info.shiftScore && !info.result) return "shiftScore";
- if (this.curPaperOrTaskLevel) return "done";
- if (info.arbitrated) return "arbitrate";
- if (info.rejected) return "reject";
- if (!info.rejected && !info.arbitrated && !info.level) return "undo";
- return;
- },
- rebuildRight() {
- if (this.setT) clearTimeout(this.setT);
- this.curPaperOrTaskLevel =
- this.curSubject.stage === "LEVEL"
- ? this.curPaperOrTask.level
- : this.curPaperOrTask.roughLevel || this.curPaperOrTask.level;
- let roleRights = [];
- this.stepType = this.getStepType();
- this.stepLabel = this.stepDict[this.stepType];
- if (this.stepType === "sample") {
- roleRights = this.roleRight.STANDARD;
- } else {
- roleRights = this.roleRight[this.curUserRoleType][this.stepType] || [];
- }
- this.rights = { ...initRights };
- roleRights.map(key => {
- this.rights[key] = true;
- });
- this.initLevels();
- if (this.rights.gradeHis) {
- this.getMarkHistory();
- }
- this.btnClicked = false;
- this.keyInput = null;
- },
- initLevels() {
- this.levelList = this.levels.filter(
- item => item.roughCode === this.curPaperOrTask.roughLevel
- );
- this.roughLevelList = this.parseRoughLevels(this.levels);
- const curRoughLevel = this.roughLevelList.find(
- item => item.name === this.curPaperOrTask.roughLevel
- );
- this.curRoughLevel = curRoughLevel || {};
- const levelName = this.curPaperOrTask.rejected
- ? this.curPaperOrTask.redoLevel
- : this.curPaperOrTaskLevel;
- if (levelName) {
- this.curLevel =
- this.levelList.find(item => item.name === levelName) || {};
- } else {
- this.curLevel = {};
- }
- },
- parseRoughLevels(levelList) {
- const levelMap = {};
- levelList.forEach(item => {
- const ind = item.roughCode;
- if (!levelMap[ind]) levelMap[ind] = [];
- levelMap[ind].push(item);
- });
- let roughLevelList = Object.keys(levelMap).map((roughCode, ind) => {
- const group = levelMap[roughCode];
- const levels = group.map(item => item.code);
- const minSs = group.map(item => item.minScore);
- const maxSs = group.map(item => item.maxScore);
- return {
- id: ind + 1,
- name: roughCode,
- minScore: levels[0],
- maxScore: levels.slice(-1)[0],
- minSubScore: Math.min.apply(null, minSs),
- maxSubScore: Math.max.apply(null, maxSs)
- };
- });
- roughLevelList.sort((a, b) => (a.name < b.name ? -1 : 1));
- return roughLevelList;
- },
- async getMarkHistory() {
- // 只有科组长和超管才会展示评卷记录
- const data = await markHistoryList(
- this.curPaperOrTask.id,
- this.curSubject.stage
- );
- this.gradingHistory = data.map(item => {
- let level = item.result || "未评";
- if (this.stepType === "reject" && !item.result) {
- level = `${levelNameTransform(level)}(${levelNameTransform(
- item.originLevel
- )})`;
- }
- return {
- id: item.id,
- markerId: item.markerId,
- name: item.marker,
- loginName: item.loginName,
- value: level
- };
- });
- },
- selectLevel(level) {
- if (this.isBatchAction) {
- if (this.btnClicked) return;
- this.btnClicked = true;
- this.setT = setTimeout(() => {
- this.btnClicked = false;
- }, 500);
- this.$emit("on-batch-level", level);
- return;
- }
- if (this.IS_MARKER && this.curPaperOrTaskLevel === level.name) return;
- if (this.btnClicked) return;
- this.btnClicked = true;
- if (this.IS_MARK_LEADER) {
- this.setT = setTimeout(() => {
- this.btnClicked = false;
- }, 500);
- this.$emit(
- "on-leader-level",
- {
- paperIds: this.curPaperOrTask.id + "",
- curLevel: this.curPaperOrTaskLevel,
- selectedLevel: level.name,
- markLeaderOnlyRight: this.markLeaderOnlyRight
- },
- this.gradingHistory.map(item => {
- return {
- id: item.markerId,
- name: item.loginName
- };
- })
- );
- return;
- }
- this.$emit("on-select-level", level);
- },
- selectRoughLevel(level) {
- if (this.curPaperOrTask.roughLevel === level.name) return;
- if (this.btnClicked) return;
- this.btnClicked = true;
- this.setT = setTimeout(() => {
- this.btnClicked = false;
- }, 500);
- // 科组长改档 / 评卷同意改档:只使用selectedLevel
- const curLevel =
- this.stepType === "shift"
- ? this.curPaperOrTask.redoLevel
- : this.curPaperOrTask.roughLevel;
- this.$emit("on-leader-change-level", {
- paperId: this.curPaperOrTask.paperId,
- curLevel,
- selectedLevel: level.name
- });
- },
- gradeChangeConfirm() {
- this.selectRoughLevel({ name: this.curPaperOrTask.redoLevel });
- },
- toPass() {
- this.$emit("on-pass");
- },
- searchCode() {
- if (!this.filter.code || !this.filter.codeType) {
- this.$Message.error("请设置密号类型和密号!");
- return;
- }
- this.$emit("on-code-search", this.filter);
- },
- // keyboard submit
- keyEvent(e) {
- this.$Message.destroy();
- if (this.btnClicked) return;
- // if (!this.ribbonSet.keyboardMark) return;
- if (!e.altKey && !e.shiftKey && !e.ctrlKey) {
- if (e.key === "Enter" && this.ribbonSet.needEnterSubmit) {
- e.preventDefault();
- this.toKeySubmit();
- return;
- }
- if (!/^[a-z0-9]$/.test(e.key)) return;
- const keyInput = e.key.toUpperCase();
- if (this.getKeyInputLevel(keyInput)) {
- e.preventDefault();
- this.keyInput = keyInput;
- if (!this.ribbonSet.needEnterSubmit) {
- this.toKeySubmit();
- }
- } else {
- this.$Message.error("按键无效");
- }
- }
- },
- getKeyInputLevel(key) {
- return (
- this.levelList.find(item => item.name === key) ||
- this.roughLevelList.find(item => item.name === key)
- );
- },
- toKeySubmit() {
- if (!this.keyInput) {
- this.$Message.error("请选择档位");
- return;
- }
- const level = this.getKeyInputLevel(this.keyInput);
- if (/^[a-z]$/.test(level.name)) {
- this.selectLevel(level);
- } else {
- this.selectRoughLevel(level);
- }
- },
- clearKeyInput() {
- this.keyInput = null;
- }
- },
- beforeDestroy() {
- if (this.setT) clearTimeout(this.setT);
- if (this.ribbonSet.keyboardMark)
- document.removeEventListener("click", this.keyEvent);
- }
- };
- </script>
|