Переглянути джерело

feat: 普通阅卷模式评卷调整

zhangjie 2 місяців тому
батько
коміт
2a06ab771f

+ 4 - 0
src/features/mark/Mark.vue

@@ -87,6 +87,7 @@ import useMarkTask from "./composables/useMarkTask";
 import useSetting from "./composables/useSetting";
 import useSetting from "./composables/useSetting";
 import useStatus from "./composables/useStatus";
 import useStatus from "./composables/useStatus";
 import useMarkSubmit from "./composables/useMarkSubmit";
 import useMarkSubmit from "./composables/useMarkSubmit";
+import useAutoChooseFirstQuestion from "./composables/useAutoChooseFirstQuestion";
 
 
 // 试评、正评的页面提示
 // 试评、正评的页面提示
 let statusSpinning = $ref(true);
 let statusSpinning = $ref(true);
@@ -99,6 +100,7 @@ const { clearTask, nextTask, removeBrokenTask } = useMarkTask();
 const { updateSetting } = useSetting();
 const { updateSetting } = useSetting();
 const { updateStatus, listenStatusQuestion } = useStatus();
 const { updateStatus, listenStatusQuestion } = useStatus();
 const { saveTaskToServer, allZeroSubmit, unselectiveSubmit } = useMarkSubmit();
 const { saveTaskToServer, allZeroSubmit, unselectiveSubmit } = useMarkSubmit();
+const { watchCurrentTaskChooseQuestion } = useAutoChooseFirstQuestion();
 
 
 const { addInterval } = useTimers();
 const { addInterval } = useTimers();
 
 
@@ -113,6 +115,8 @@ onMounted(async () => {
     }
     }
     await updateStatus();
     await updateStatus();
     await nextTask();
     await nextTask();
+
+    watchCurrentTaskChooseQuestion();
   } catch (error) {
   } catch (error) {
     result = false;
     result = false;
   }
   }

+ 8 - 2
src/features/mark/MarkHistory.vue

@@ -43,7 +43,12 @@
         <div
         <div
           v-for="(task, index) of markStore.historyTasks"
           v-for="(task, index) of markStore.historyTasks"
           :key="index"
           :key="index"
-          :class="['body-row', { 'is-active': markStore.currentTask === task }]"
+          :class="[
+            'body-row',
+            {
+              'is-active': markStore.currentTask?.studentId === task.studentId,
+            },
+          ]"
           @click="replaceCurrentTask(task)"
           @click="replaceCurrentTask(task)"
         >
         >
           <div class="body-col">
           <div class="body-col">
@@ -81,6 +86,7 @@ import type {
 } from "@/types";
 } from "@/types";
 import { watch } from "vue";
 import { watch } from "vue";
 import { message } from "ant-design-vue";
 import { message } from "ant-design-vue";
+import { cloneDeep } from "lodash-es";
 import { useMarkStore } from "@/store";
 import { useMarkStore } from "@/store";
 import EventBus from "@/plugins/eventBus";
 import EventBus from "@/plugins/eventBus";
 import useDraw from "./composables/useDraw";
 import useDraw from "./composables/useDraw";
@@ -249,7 +255,7 @@ async function replaceCurrentTask(task: Task | undefined) {
   if (markStore.isScanImage && !!task) {
   if (markStore.isScanImage && !!task) {
     await preDrawImageHistory(task);
     await preDrawImageHistory(task);
   }
   }
-  markStore.currentTask = task;
+  markStore.currentTask = cloneDeep(task);
 }
 }
 
 
 function pageChange(page) {
 function pageChange(page) {

+ 26 - 16
src/features/mark/composables/useAutoChooseFirstQuestion.ts

@@ -8,22 +8,25 @@ export default function useAutoChooseFirstQuestion() {
   const markStore = useMarkStore();
   const markStore = useMarkStore();
   const { showRejectedReason } = useTaskRejection();
   const { showRejectedReason } = useTaskRejection();
 
 
-  watch(
-    () => markStore.currentTask,
-    () => {
-      // 重置当前选择的quesiton和score
-      markStore.currentQuestion = undefined;
-      markStore.currentScore = undefined;
+  // 监听currentTask的变化,自动选择第一题
+  function watchCurrentTaskChooseQuestion() {
+    watch(
+      () => markStore.currentTask,
+      () => {
+        // 重置当前选择的quesiton和score
+        markStore.currentQuestion = undefined;
+        markStore.currentScore = undefined;
 
 
-      // FIXed ME: 此时取到的还是score:null,但是 chooseQuestion之后就变成了score:0
-      const firstQuestion = markStore.currentTask?.questionList.find(
-        (question) => question.selfMark
-      );
-      if (firstQuestion) {
-        chooseQuestion(firstQuestion);
+        // FIXed ME: 此时取到的还是score:null,但是 chooseQuestion之后就变成了score:0
+        const firstQuestion = markStore.currentTask?.questionList.find(
+          (question) => !isDisabledQuestion(question)
+        );
+        if (firstQuestion) {
+          chooseQuestion(firstQuestion);
+        }
       }
       }
-    }
-  );
+    );
+  }
 
 
   const scrollToQuestionOfBoard = async (question: Question) => {
   const scrollToQuestionOfBoard = async (question: Question) => {
     const node = document.querySelector(
     const node = document.querySelector(
@@ -60,8 +63,15 @@ export default function useAutoChooseFirstQuestion() {
     }
     }
   };
   };
 
 
+  function isDisabledQuestion(question: Question) {
+    return (
+      (!markStore.historyOpen && !question.selfMark) ||
+      (markStore.historyOpen && question.problem)
+    );
+  }
+
   function chooseQuestion(question: Question) {
   function chooseQuestion(question: Question) {
-    if (!question.selfMark) return;
+    if (isDisabledQuestion(question)) return;
 
 
     markStore.currentQuestion = question;
     markStore.currentQuestion = question;
     // FIXME: maybe should be an async function, temp fix for eslint
     // FIXME: maybe should be an async function, temp fix for eslint
@@ -74,5 +84,5 @@ export default function useAutoChooseFirstQuestion() {
     });
     });
   }
   }
 
 
-  return { chooseQuestion };
+  return { watchCurrentTaskChooseQuestion, chooseQuestion, isDisabledQuestion };
 }
 }

+ 1 - 1
src/features/mark/composables/useDraw.ts

@@ -39,7 +39,7 @@ export default function useDraw() {
     const key = `${urlForCache}-${i}-${x}-${y}-${w}-${h}`;
     const key = `${urlForCache}-${i}-${x}-${y}-${w}-${h}`;
 
 
     if (objectUrlMap.get(key)) {
     if (objectUrlMap.get(key)) {
-      console.log("cached slice objectUrl");
+      // console.log("cached slice objectUrl");
       return objectUrlMap.get(key);
       return objectUrlMap.get(key);
     }
     }
 
 

+ 13 - 3
src/features/mark/scoring/MarkBoardKeyBoard.vue

@@ -70,7 +70,7 @@
               'board-question',
               'board-question',
               {
               {
                 'is-current': isCurrentQuestion(question),
                 'is-current': isCurrentQuestion(question),
-                'is-disabled': !question.selfMark,
+                'is-disabled': isDisabledQuestion(question),
               },
               },
             ]"
             ]"
             @click="
             @click="
@@ -94,9 +94,19 @@
               </div>
               </div>
             </div>
             </div>
 
 
-            <div class="question-score">
+            <div
+              :class="[
+                'question-score',
+                {
+                  'is-problem': question.problem,
+                },
+              ]"
+            >
               <transition-group name="score-number-animation" tag="span">
               <transition-group name="score-number-animation" tag="span">
+                <span v-if="question.problem" key="problem"> 问题卷 </span>
+                <span v-else-if="!question.selfMark">已评</span>
                 <span
                 <span
+                  v-else
                   :key="`${question.mainNumber}_${question.subNumber}_${index}`"
                   :key="`${question.mainNumber}_${question.subNumber}_${index}`"
                 >
                 >
                   {{
                   {{
@@ -130,7 +140,7 @@ const emit = defineEmits([
 ]);
 ]);
 const props = defineProps<{ isCheckAnswer?: boolean }>();
 const props = defineProps<{ isCheckAnswer?: boolean }>();
 
 
-const { chooseQuestion } = useAutoChooseFirstQuestion();
+const { chooseQuestion, isDisabledQuestion } = useAutoChooseFirstQuestion();
 const hasModifyScore = ref(false);
 const hasModifyScore = ref(false);
 
 
 const markStore = useMarkStore();
 const markStore = useMarkStore();

+ 37 - 3
src/features/mark/scoring/MarkBoardMouse.vue

@@ -65,7 +65,14 @@
         <div class="board-question-full-box">
         <div class="board-question-full-box">
           <div
           <div
             :id="'bq-' + question.mainNumber + '-' + question.subNumber"
             :id="'bq-' + question.mainNumber + '-' + question.subNumber"
-            :class="['board-question', { 'is-disabled': !question.selfMark }]"
+            :class="[
+              'board-question',
+              {
+                'is-current': isCurrentQuestion(question),
+                'is-disabled': isDisabledQuestion(question),
+              },
+            ]"
+            @click="chooseQuestion(question)"
           >
           >
             <div class="question-info">
             <div class="question-info">
               <div class="question-title" :title="question.title">
               <div class="question-title" :title="question.title">
@@ -75,7 +82,18 @@
                 {{ question.mainNumber }}-{{ question.subNumber }}
                 {{ question.mainNumber }}-{{ question.subNumber }}
               </div>
               </div>
             </div>
             </div>
-            <div class="board-scores">
+            <div
+              v-if="question.problem"
+              :class="[
+                'question-score',
+                {
+                  'is-problem': question.problem,
+                },
+              ]"
+            >
+              问题卷
+            </div>
+            <div v-if="!isDisabledQuestion(question)" class="board-scores">
               <div
               <div
                 v-for="(s, i) in questionScoreSteps(question)"
                 v-for="(s, i) in questionScoreSteps(question)"
                 :key="i"
                 :key="i"
@@ -87,6 +105,13 @@
               >
               >
                 {{ s }}
                 {{ s }}
               </div>
               </div>
+              <qm-button
+                v-if="question.problem"
+                class="board-clear"
+                @click="cancelProblem"
+              >
+                取消问题卷
+              </qm-button>
             </div>
             </div>
           </div>
           </div>
         </div>
         </div>
@@ -96,11 +121,13 @@
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
+import { ref } from "vue";
 import type { Question } from "@/types";
 import type { Question } from "@/types";
 import { useMarkStore } from "@/store";
 import { useMarkStore } from "@/store";
-import { ref } from "vue";
+import useAutoChooseFirstQuestion from "../composables/useAutoChooseFirstQuestion";
 
 
 const markStore = useMarkStore();
 const markStore = useMarkStore();
+const { chooseQuestion, isDisabledQuestion } = useAutoChooseFirstQuestion();
 
 
 const emit = defineEmits([
 const emit = defineEmits([
   "submit",
   "submit",
@@ -119,7 +146,14 @@ const normalMode = ref(
 function normalModeChange(value: string) {
 function normalModeChange(value: string) {
   markStore.setting.uiSetting["normal.mode"] = value;
   markStore.setting.uiSetting["normal.mode"] = value;
 }
 }
+function isCurrentQuestion(question: Question) {
+  return (
+    markStore.currentQuestion?.mainNumber === question.mainNumber &&
+    markStore.currentQuestion?.subNumber === question.subNumber
+  );
+}
 function chooseScore(question: Question, score: number) {
 function chooseScore(question: Question, score: number) {
+  if (isDisabledQuestion(question)) return;
   // 只要修改了分值,就当做已修改
   // 只要修改了分值,就当做已修改
   hasModifyScore.value = true;
   hasModifyScore.value = true;
 
 

+ 1 - 5
src/features/mark/scoring/MarkBoardTrack.vue

@@ -264,7 +264,7 @@ const positioning = (question: Question) => {
   activeRightMenuItem.value = null;
   activeRightMenuItem.value = null;
 };
 };
 
 
-const { chooseQuestion } = useAutoChooseFirstQuestion();
+const { chooseQuestion, isDisabledQuestion } = useAutoChooseFirstQuestion();
 let sliceImagesWithTrackListCopy = ref([]);
 let sliceImagesWithTrackListCopy = ref([]);
 EventBus.on("draw-change", (list: any) => {
 EventBus.on("draw-change", (list: any) => {
   sliceImagesWithTrackListCopy.value = cloneDeep(list);
   sliceImagesWithTrackListCopy.value = cloneDeep(list);
@@ -350,10 +350,6 @@ function isCurrentQuestion(question: Question) {
   );
   );
 }
 }
 
 
-function isDisabledQuestion(question: Question) {
-  return !question.selfMark;
-}
-
 function isCurrentScore(score: number) {
 function isCurrentScore(score: number) {
   return markStore.currentScore === score;
   return markStore.currentScore === score;
 }
 }

+ 42 - 38
src/styles/page.less

@@ -520,42 +520,6 @@
     padding-bottom: 16px;
     padding-bottom: 16px;
   }
   }
 
 
-  &.is-mouse-board {
-    padding-bottom: 16px;
-
-    .board-question-full-box {
-      padding: 0 8px;
-      margin: 16px 0;
-    }
-    .board-question {
-      display: block;
-      border: none;
-      padding: 0;
-      overflow: unset;
-      user-select: none;
-      cursor: auto;
-
-      &:hover {
-        border-color: none;
-        color: inherit;
-      }
-
-      .question-info {
-        .flex-between;
-        height: 21px;
-        overflow: hidden;
-        margin-bottom: 10px;
-      }
-      .question-no {
-        .flex-static;
-        margin-left: 10px;
-      }
-    }
-    .board-score {
-      margin-bottom: 8px;
-    }
-  }
-
   &.in-dialog {
   &.in-dialog {
     max-width: 100%;
     max-width: 100%;
     min-width: 100%;
     min-width: 100%;
@@ -688,7 +652,7 @@
       background: #f7f7f7;
       background: #f7f7f7;
       border-radius: 3px;
       border-radius: 3px;
       border: 1px solid #f0f0f0;
       border: 1px solid #f0f0f0;
-      line-height: 36px;
+      line-height: 34px;
       color: #165dff;
       color: #165dff;
       font-size: 20px;
       font-size: 20px;
       font-weight: 600;
       font-weight: 600;
@@ -719,6 +683,10 @@
       .question-score {
       .question-score {
         color: #999;
         color: #999;
       }
       }
+      .board-score {
+        color: #999;
+        border-color: #e5e5e5 !important;
+      }
     }
     }
   }
   }
 
 
@@ -801,7 +769,7 @@
     font-size: 14px;
     font-size: 14px;
     min-width: 34px;
     min-width: 34px;
     height: 34px;
     height: 34px;
-    line-height: 30px;
+    line-height: 32px;
     border-radius: 4px;
     border-radius: 4px;
     border: 1px solid #e5e5e5;
     border: 1px solid #e5e5e5;
     text-align: center;
     text-align: center;
@@ -904,6 +872,42 @@
       }
       }
     }
     }
   }
   }
+
+  &.is-mouse-board {
+    padding-bottom: 16px;
+
+    .board-question-full-box {
+      padding: 0 8px;
+      margin: 0 0 16px;
+
+      &:last-child {
+        margin-bottom: 0;
+      }
+    }
+    .board-question {
+      display: block;
+      overflow: unset;
+      user-select: none;
+      cursor: auto;
+
+      .question-info {
+        .flex-between;
+        height: 21px;
+        overflow: hidden;
+        margin-bottom: 10px;
+      }
+      .question-no {
+        .flex-static;
+        margin-left: 10px;
+      }
+    }
+    .board-score {
+      margin-bottom: 8px;
+    }
+    .board-scores {
+      min-height: 40px;
+    }
+  }
 }
 }
 // mark-body
 // mark-body
 .mark-body {
 .mark-body {