Browse Source

统一 MarkHistory ,后续再删除废弃的 MarkHistory

Michael Wang 3 năm trước cách đây
mục cha
commit
301450506a

+ 6 - 0
src/api/inspectPage.ts

@@ -87,12 +87,18 @@ export async function getInspectedSetting(subjectCode?: string) {
 /** 批量复核历史 */
 export async function getInspectedHistory({
   subjectCode,
+  order = "markerTime",
+  sort = "DESC",
   pageNumber = 1,
   pageSize = 20,
+  secretNumber,
 }: HistoryQueryParams) {
   if (!subjectCode) return;
   const form = new FormData();
   form.append("subjectCode", subjectCode);
+  secretNumber && form.append("secretNumber", secretNumber);
+  form.append("order", order);
+  form.append("sort", sort);
   form.append("pageNumber", pageNumber + "");
   form.append("pageSize", pageSize + "");
   return httpApp.post("/admin/exam/inspected/getHistory", form);

+ 8 - 7
src/api/qualityPage.ts

@@ -1,21 +1,22 @@
 import { httpApp } from "@/plugins/axiosApp";
-import { Question } from "@/types";
+import { HistoryQueryParams } from "@/types";
 
 /** 批量仲裁历史 */
 export async function getQualityHistory({
   markerId,
   markerScore,
+  order = "markerTime",
+  sort = "DESC",
   pageNumber = 1,
   pageSize = 20,
-}: {
-  markerId: string;
-  markerScore: string;
-  pageNumber?: number; // 从1开始
-  pageSize?: number;
-}) {
+  secretNumber,
+}: HistoryQueryParams) {
   const form = new FormData();
   markerId && form.append("markerId", markerId);
   markerScore && form.append("markerScore", markerScore);
+  secretNumber && form.append("secretNumber", secretNumber);
+  form.append("order", order);
+  form.append("sort", sort);
   form.append("pageNumber", pageNumber + "");
   form.append("pageSize", pageSize + "");
   return httpApp.post("/admin/exam/quality/history", form);

+ 25 - 13
src/features/arbitrate/Arbitrate.vue

@@ -3,8 +3,10 @@
     <mark-header />
     <div class="tw-flex tw-gap-1">
       <mark-history
-        @reload="reloadAndfetchTask"
-        :should-reload="shouldReloadHistory"
+        v-if="!isSingleStudent"
+        :subjectCode="subjectCode"
+        :groupNumber="groupNumber"
+        :get-history="getArbitrateHistory"
       />
       <ArbitrateMarkList />
       <mark-body @error="renderError" />
@@ -41,7 +43,7 @@ import MarkBody from "./MarkBody.vue";
 import MarkBoardKeyBoard from "@/features/mark/MarkBoardKeyBoard.vue";
 import MarkBoardMouse from "@/features/mark/MarkBoardMouse.vue";
 import MinimapModal from "@/features/mark/MinimapModal.vue";
-import MarkHistory from "./MarkHistory.vue";
+import MarkHistory from "@/features/mark/MarkHistory.vue";
 import { message } from "ant-design-vue";
 import {
   clearArbitrateTask,
@@ -57,6 +59,8 @@ import { isNumber } from "lodash";
 import AnswerModal from "../mark/AnswerModal.vue";
 import PaperModal from "../mark/PaperModal.vue";
 import { getPaper } from "@/api/jsonMark";
+import { getArbitrateHistory } from "@/api/arbitratePage";
+import EventBus from "@/plugins/eventBus";
 
 const route = useRoute();
 let isSingleStudent = !!route.query.historyId;
@@ -82,6 +86,7 @@ async function updateSetting() {
   );
   store.setting.examType = settingRes.data.examType;
   store.setting.fileServer = settingRes.data.fileServer;
+  store.setting.subject = settingRes.data.subject;
   store.setting.userName = settingRes.data.userName;
   store.setting.selective = settingRes.data.selective;
   store.setting.uiSetting = {
@@ -90,7 +95,6 @@ async function updateSetting() {
     "normal.mode": "keyboard",
   } as Setting["uiSetting"];
   store.setting.splitConfig = settingRes.data.splitConfig;
-  store.setting.subject = settingRes.data.subject;
 
   if (store.setting.subject?.answerUrl) {
     store.setting.subject.answerUrl =
@@ -137,14 +141,22 @@ async function updateTask() {
   }
 }
 
-const shouldReloadHistory = ref(0);
-
-async function reloadAndfetchTask() {
-  // 需要清除缓存,才能取到之前锁定的任务
-  await updateClearTask();
-  // await updateSetting();
-  await fetchTask();
-}
+// async function reloadAndfetchTask() {
+//   // 需要清除缓存,才能取到之前锁定的任务
+//   await updateClearTask();
+//   // await updateSetting();
+//   await fetchTask();
+// }
+watch(
+  () => store.historyOpen,
+  async () => {
+    if (!store.historyOpen) {
+      await updateClearTask();
+      // await updateSetting();
+      await fetchTask();
+    }
+  }
+);
 
 async function fetchTask() {
   !isSingleStudent && (await updateStatus());
@@ -233,7 +245,7 @@ const saveTaskToServer = async (unselective: boolean) => {
       store.currentTask = undefined;
       if (!isSingleStudent) fetchTask();
     } else {
-      shouldReloadHistory.value = Date.now();
+      EventBus.emit("should-reload-history");
     }
   } else if (res.data.message) {
     console.log(res.data.message);

+ 32 - 19
src/features/library/inspect/LibraryInspect.vue

@@ -3,8 +3,10 @@
     <mark-header />
     <div class="tw-flex tw-gap-1">
       <mark-history
-        @reload="reloadAndfetchTask"
-        :should-reload="shouldReloadHistory"
+        v-if="!isSingleStudent"
+        :subjectCode="subjectCode"
+        orderTimeField="inspectTime"
+        :get-history="getInspectedHistory"
       />
       <mark-body @error="renderError" />
       <MarkBoardInspect @inspect="saveTaskToServer" @reject="rejectQuestions" />
@@ -13,14 +15,14 @@
 </template>
 
 <script setup lang="ts">
-import { computed, onMounted, ref } from "vue";
+import { computed, onMounted, watch } from "vue";
 import { isScanImage, store } from "@/features/mark/store";
 import MarkHeader from "./MarkHeader.vue";
 import { useRoute } from "vue-router";
 import MarkBody from "./MarkBody.vue";
-import MarkHistory from "./MarkHistory.vue";
+import MarkHistory from "@/features/mark/MarkHistory.vue";
 import MarkBoardInspect from "./MarkBoardInspect.vue";
-import type { MarkStore, Question, Task } from "@/types";
+import type { Question, Setting, Task } from "@/types";
 import { message } from "ant-design-vue";
 import {
   clearInspectedTask,
@@ -30,7 +32,8 @@ import {
   saveInspectedTask,
 } from "@/api/libraryInspectPage";
 import { getPaper } from "@/api/jsonMark";
-import { getInspectedSetting } from "@/api/inspectPage";
+import { getInspectedSetting, getInspectedHistory } from "@/api/inspectPage";
+import EventBus from "@/plugins/eventBus";
 
 const route = useRoute();
 let isSingleStudent = !!route.query.libraryId;
@@ -48,12 +51,13 @@ async function updateSetting() {
   const settingRes = await getInspectedSetting(subjectCode);
   store.setting.examType = settingRes.data.examType;
   store.setting.fileServer = settingRes.data.fileServer;
-  store.setting.userName = settingRes.data.userName;
   store.setting.subject = settingRes.data.subject;
+  store.setting.userName = settingRes.data.userName;
   store.setting.uiSetting = {
     "answer.paper.scale": 1,
     "score.board.collapse": false,
-  } as MarkStore["setting"]["uiSetting"];
+    "normal.mode": "keyboard",
+  } as Setting["uiSetting"];
   store.setting.splitConfig = settingRes.data.splitConfig;
   if (store.setting.subject?.paperUrl) {
     store.setting.subject.paperUrl =
@@ -97,13 +101,21 @@ async function updateTask() {
   }
 }
 
-const shouldReloadHistory = ref(0);
-
-async function reloadAndfetchTask() {
-  await updateClearTask();
-  await updateSetting();
-  await fetchTask();
-}
+// async function reloadAndfetchTask() {
+//   await updateClearTask();
+//   await updateSetting();
+//   await fetchTask();
+// }
+watch(
+  () => store.historyOpen,
+  async () => {
+    if (!store.historyOpen) {
+      await updateClearTask();
+      await updateSetting();
+      await fetchTask();
+    }
+  }
+);
 
 async function fetchTask() {
   !isSingleStudent && (await updateStatus());
@@ -111,8 +123,9 @@ async function fetchTask() {
 }
 
 onMounted(async () => {
-  // await updateClearTask();
-  // fetchTask(); // mark-header 会调用 (watchEffect)
+  await updateClearTask();
+  await updateSetting();
+  await fetchTask();
 });
 
 async function getSingleStuTask() {
@@ -137,7 +150,7 @@ const saveTaskToServer = async () => {
       store.currentTask = undefined;
       if (!isSingleStudent) fetchTask();
     } else {
-      shouldReloadHistory.value = Date.now();
+      EventBus.emit("should-reload-history");
     }
   } else if (res.data.message) {
     console.log(res.data.message);
@@ -163,7 +176,7 @@ const rejectQuestions = async (questions: Array<Question>) => {
       store.currentTask = undefined;
       if (!isSingleStudent) fetchTask();
     } else {
-      shouldReloadHistory.value = Date.now();
+      EventBus.emit("should-reload-history");
     }
   } else if (res.data.message) {
     console.log(res.data.message);

+ 48 - 59
src/features/library/quality/Quality.vue

@@ -2,7 +2,13 @@
   <div class="my-container">
     <mark-header />
     <div class="tw-flex tw-gap-1">
-      <mark-history />
+      <mark-history
+        title="给分记录"
+        :subjectCode="subjectCode"
+        :markerId="markerId"
+        :markerScore="markerScore"
+        :get-history="getQualityHistory"
+      />
       <mark-body @error="renderError" />
     </div>
   </div>
@@ -11,80 +17,63 @@
   <MinimapModal />
 </template>
 
-<script lang="ts">
-import { defineComponent, onMounted, ref } from "vue";
+<script setup lang="ts">
+import { onMounted } from "vue";
 import { isScanImage, store } from "@/features/mark/store";
 import MarkHeader from "./MarkHeader.vue";
 import { useRoute } from "vue-router";
 import MarkBody from "./MarkBody.vue";
-import MarkHistory from "./MarkHistory.vue";
+import MarkHistory from "@/features/mark/MarkHistory.vue";
 import { MarkStore } from "@/types";
 import { getInspectedSetting } from "@/api/inspectPage";
 import MinimapModal from "@/features/mark/MinimapModal.vue";
 import PaperModal from "@/features/mark/PaperModal.vue";
 import AnswerModal from "@/features/mark/AnswerModal.vue";
 import { getPaper } from "@/api/jsonMark";
+import { getQualityHistory } from "@/api/qualityPage";
 
-export default defineComponent({
-  name: "Quality",
-  components: {
-    MarkHeader,
-    MarkBody,
-    MarkHistory,
-    PaperModal,
-    MinimapModal,
-    AnswerModal,
-  },
-  setup: () => {
-    const route = useRoute();
-    const { markerId, markerScore, subjectCode } = route.query as {
-      markerId: string;
-      markerScore: string;
-      subjectCode: string;
-    };
+const route = useRoute();
+const { subjectCode, markerId, markerScore } = route.query as {
+  subjectCode: string;
+  markerId: string;
+  markerScore: string;
+};
 
-    async function updateSetting() {
-      const settingRes = await getInspectedSetting(subjectCode);
-      store.setting.examType = settingRes.data.examType;
-      store.setting.fileServer = settingRes.data.fileServer;
-      store.setting.subject = settingRes.data.subject;
-      store.setting.userName = settingRes.data.userName;
-      store.setting.uiSetting = {
-        "answer.paper.scale": 1,
-        "score.board.collapse": false,
-      } as MarkStore["setting"]["uiSetting"];
-      store.setting.splitConfig = settingRes.data.splitConfig;
-      store.setting.subject = settingRes.data.subject || {};
-      if (store.setting.subject?.answerUrl) {
-        store.setting.subject.answerUrl =
-          store.setting.fileServer + store.setting.subject?.answerUrl;
-      }
-      if (store.setting.subject?.paperUrl) {
-        store.setting.subject.paperUrl =
-          store.setting.fileServer + store.setting.subject?.paperUrl;
+async function updateSetting() {
+  const settingRes = await getInspectedSetting(subjectCode);
+  store.setting.examType = settingRes.data.examType;
+  store.setting.fileServer = settingRes.data.fileServer;
+  store.setting.subject = settingRes.data.subject;
+  store.setting.userName = settingRes.data.userName;
+  store.setting.uiSetting = {
+    "answer.paper.scale": 1,
+    "score.board.collapse": false,
+  } as MarkStore["setting"]["uiSetting"];
+  store.setting.splitConfig = settingRes.data.splitConfig;
+  store.setting.subject = settingRes.data.subject || {};
+  if (store.setting.subject?.answerUrl) {
+    store.setting.subject.answerUrl =
+      store.setting.fileServer + store.setting.subject?.answerUrl;
+  }
+  if (store.setting.subject?.paperUrl) {
+    store.setting.subject.paperUrl =
+      store.setting.fileServer + store.setting.subject?.paperUrl;
 
-        if (!isScanImage()) {
-          await getPaper(store);
-        }
-      }
+    if (!isScanImage()) {
+      await getPaper(store);
     }
+  }
+}
 
-    onMounted(async () => {
-      await updateSetting();
-      store.historyOpen = true;
-    });
-
-    const renderError = () => {
-      store.currentTask = undefined;
-      store.message = "加载失败,请重新加载。";
-    };
-
-    return {
-      store,
-      renderError,
-    };
-  },
+onMounted(async () => {
+  await updateSetting();
+  store.historyOpen = true;
 });
+
+const renderError = () => {
+  store.currentTask = undefined;
+  store.message = "加载失败,请重新加载。";
+};
 </script>
 
 <style scoped>

+ 2 - 1
src/features/mark/Mark.vue

@@ -2,7 +2,7 @@
   <div class="my-container">
     <mark-header />
     <div class="tw-flex tw-gap-1">
-      <mark-history />
+      <mark-history show-search show-order :get-history="getHistoryTask" />
       <mark-body @error="removeBrokenTask" />
       <mark-board-track
         v-if="showMarkBoardTrack"
@@ -72,6 +72,7 @@ import SpecialTagModal from "./SpecialTagModal.vue";
 import { preDrawImage } from "@/utils/utils";
 import { getJSON, getPaper } from "@/api/jsonMark";
 import EventBus from "@/plugins/eventBus";
+import { getHistoryTask } from "@/api/markPage";
 
 const { addInterval } = useTimers();
 

+ 61 - 15
src/features/mark/MarkHistory.vue

@@ -4,8 +4,11 @@
     :class="[store.historyOpen ? 'show' : 'hide']"
   >
     <div class="tw-mt-1 tw-mb-1 tw-flex tw-place-items-center">
-      <div class="tw-text-lg main-text-color tw-mr-4 tw-font-bold">回评</div>
+      <div class="tw-text-lg main-text-color tw-mr-3 tw-font-bold">
+        {{ props.title }}
+      </div>
       <input
+        v-if="props.showSearch"
         v-model="secretNumberInput"
         @keydown.stop="() => {}"
         @keypress.stop="() => {}"
@@ -15,6 +18,7 @@
         @keyup.enter="searchHistoryTask"
       />
       <SearchOutlined
+        v-if="props.showSearch"
         style="margin-left: -24px; font-size: 18px; padding: 3px"
         @click="searchHistoryTask"
       />
@@ -22,20 +26,32 @@
     <div class="tw-flex tw-justify-between tw-mt-5">
       <div class="tw-cursor-pointer tw-flex">编号</div>
       <div
-        @click="toggleOrderBy('markerTime')"
+        @click="toggleOrderBy(props.orderTimeField)"
         class="tw-cursor-pointer tw-flex tw-items-center"
       >
         时间
-        <CaretUpOutlined v-if="order === 'markerTime' && sort === 'ASC'" />
-        <CaretDownOutlined v-if="order === 'markerTime' && sort === 'DESC'" />
+        <CaretUpOutlined
+          v-if="
+            props.showOrder && order === props.orderTimeField && sort === 'ASC'
+          "
+        />
+        <CaretDownOutlined
+          v-if="
+            props.showOrder && order === props.orderTimeField && sort === 'DESC'
+          "
+        />
       </div>
       <div
         @click="toggleOrderBy('markerScore')"
         class="tw-cursor-pointer tw-flex tw-items-center"
       >
         分数
-        <CaretUpOutlined v-if="order === 'markerScore' && sort === 'ASC'" />
-        <CaretDownOutlined v-if="order === 'markerScore' && sort === 'DESC'" />
+        <CaretUpOutlined
+          v-if="props.showOrder && order === 'markerScore' && sort === 'ASC'"
+        />
+        <CaretDownOutlined
+          v-if="props.showOrder && order === 'markerScore' && sort === 'DESC'"
+        />
       </div>
     </div>
     <a-spin :spinning="loading" size="large" tip="Loading..." :delay="500">
@@ -58,10 +74,10 @@
               {{ task.secretNumber }}
             </div>
             <div>
-              {{ $filters.datetimeFilter(task.markTime) }}
+              {{ $filters.datetimeFilter(task.markTime ?? task.inspectTime) }}
             </div>
             <div style="width: 30px; text-align: right">
-              {{ task.markerScore }}
+              {{ task.markerScore === -1 ? "未选做" : task.markerScore }}
             </div>
           </div>
         </div>
@@ -99,8 +115,9 @@
 </template>
 
 <script setup lang="ts">
-import { getHistoryTask } from "@/api/markPage";
+// import { getHistoryTask } from "@/api/markPage";
 import type {
+  getHistory,
   HistoryQueryParams,
   MarkHistoryOrderBy,
   MarkHistorySortField,
@@ -116,10 +133,33 @@ import {
 import { cloneDeep } from "lodash";
 import EventBus from "@/plugins/eventBus";
 
+const props = withDefaults(
+  defineProps<{
+    title?: string;
+    showOrder?: boolean;
+    showSearch?: boolean;
+    orderTimeField?: "markerTime" | "inspectTime";
+    subjectCode?: string;
+    groupNumber?: string;
+    markerId?: string;
+    markerScore?: string;
+    getHistory: getHistory;
+  }>(),
+  {
+    title: "回评",
+    showOrder: false,
+    showSearch: false,
+    orderTimeField: "markerTime",
+  }
+);
+
 const secretNumberInput = ref("");
 const loading = ref(false);
 const currentPage = ref(1);
 const order = ref("markerTime" as MarkHistoryOrderBy);
+if (props.orderTimeField) {
+  order.value = props.orderTimeField;
+}
 const sort = ref("DESC" as MarkHistorySortField);
 
 const currentTaskChange = async () => {
@@ -163,7 +203,7 @@ EventBus.on("should-reload-history", async () => {
   // replaceCurrentTask(store.historyTasks[0]);
   store.globalMask = true;
   try {
-    const res = await getHistoryTask({
+    const res = await props.getHistory({
       secretNumber: store.currentTask?.secretNumber,
     });
     if (res.data) {
@@ -204,12 +244,16 @@ async function updateHistoryTask({
   secretNumber = null,
 }: HistoryQueryParams) {
   loading.value = true;
-  const res = await getHistoryTask({
+  const res = await props.getHistory({
     pageNumber,
     pageSize,
     order,
     sort,
     secretNumber,
+    subjectCode: props.subjectCode,
+    groupNumber: props.groupNumber,
+    markerId: props.markerId,
+    markerScore: props.markerScore,
   });
   loading.value = false;
   if (res.data) {
@@ -255,10 +299,12 @@ function nextPage() {
 }
 
 function toggleOrderBy(toOrder: MarkHistoryOrderBy) {
-  if (toOrder === order.value) {
-    sort.value = sort.value === "DESC" ? "ASC" : "DESC";
-  } else {
-    order.value = toOrder;
+  if (props.showOrder) {
+    if (toOrder === order.value) {
+      sort.value = sort.value === "DESC" ? "ASC" : "DESC";
+    } else {
+      order.value = toOrder;
+    }
   }
 }
 

+ 3 - 1
src/features/mark/use/draggable.ts

@@ -46,7 +46,9 @@ export function dragImage() {
   };
 
   onMounted(() => {
-    dragContainer.value.addEventListener("mousedown", mouseDownHandler);
+    if (dragContainer.value) {
+      dragContainer.value.addEventListener("mousedown", mouseDownHandler);
+    }
   });
   onUnmounted(() => {
     if (dragContainer.value) {

+ 29 - 18
src/features/student/inspect/Inspect.vue

@@ -3,8 +3,10 @@
     <mark-header />
     <div class="tw-flex tw-gap-1">
       <mark-history
-        @reload="reloadAndfetchTask"
-        :should-reload="shouldReloadHistory"
+        v-if="!isSingleStudent"
+        :subjectCode="subjectCode"
+        orderTimeField="inspectTime"
+        :get-history="getInspectedHistory"
       />
       <mark-body @error="renderError" />
       <MarkBoardInspect @inspect="saveTaskToServer" @reject="rejectQuestions" />
@@ -13,7 +15,7 @@
 </template>
 
 <script setup lang="ts">
-import { computed, onMounted, ref } from "vue";
+import { computed, onMounted, ref, watch } from "vue";
 import {
   clearInspectedTask,
   getInspectedSetting,
@@ -27,11 +29,13 @@ import { isScanImage, store } from "@/features/mark/store";
 import MarkHeader from "./MarkHeader.vue";
 import { useRoute } from "vue-router";
 import MarkBody from "./MarkBody.vue";
-import MarkHistory from "./MarkHistory.vue";
+import MarkHistory from "@/features/mark/MarkHistory.vue";
 import MarkBoardInspect from "./MarkBoardInspect.vue";
 import type { Question, Task, Setting } from "@/types";
 import { message } from "ant-design-vue";
 import { getPaper } from "@/api/jsonMark";
+import { getInspectedHistory } from "@/api/inspectPage";
+import EventBus from "@/plugins/eventBus";
 
 const route = useRoute();
 let isSingleStudent = !!route.query.studentId;
@@ -124,23 +128,30 @@ async function updateTask() {
   }
 }
 
-const shouldReloadHistory = ref(0);
-
-async function reloadAndfetchTask() {
-  await updateClearTask();
-  await updateSetting();
-  await fetchTask();
-}
-
+// async function reloadAndfetchTask() {
+//   await updateClearTask();
+//   await updateSetting();
+//   await fetchTask();
+// }
+watch(
+  () => store.historyOpen,
+  async () => {
+    if (!store.historyOpen) {
+      await updateClearTask();
+      await updateSetting();
+      await fetchTask();
+    }
+  }
+);
 async function fetchTask() {
   !isSingleStudent && (await updateStatus());
   await updateTask();
 }
 
 onMounted(async () => {
-  // await updateClearTask();
-  // await updateSetting();
-  // await fetchTask(); // mark-header 会调用 (watchEffect)
+  await updateClearTask();
+  await updateSetting();
+  await fetchTask();
 });
 
 async function getSingleStuTask() {
@@ -174,7 +185,7 @@ const saveTaskToServer = async () => {
       store.currentTask = undefined;
       if (!isSingleStudent) fetchTask();
     } else {
-      shouldReloadHistory.value = Date.now();
+      EventBus.emit("should-reload-history");
     }
   } else if (res.data.message) {
     console.log(res.data.message);
@@ -198,10 +209,10 @@ const rejectQuestions = async (questions: Array<Question>) => {
       store.currentTask = undefined;
       if (!isSingleStudent) fetchTask();
     } else {
-      shouldReloadHistory.value = Date.now();
+      EventBus.emit("should-reload-history");
     }
   } else if (res.data.message) {
-    console.log(res.data.message);
+    // console.log(res.data.message);
     message.error({ content: res.data.message, key: mkey, duration: 10 });
   } else if (!store.currentTask) {
     message.warn({ content: "暂无新任务", key: mkey, duration: 10 });

+ 7 - 0
src/types/index.ts

@@ -230,6 +230,7 @@ export interface SliceImage {
 
 export type MarkHistoryOrderBy =
   | "markerTime"
+  | "inspectTime"
   | "markerScore"
   | "seceretNumber"
   | undefined;
@@ -243,6 +244,12 @@ export interface HistoryQueryParams {
   secretNumber?: string | null;
   subjectCode?: string;
   groupNumber?: string;
+  markerId?: string;
+  markerScore?: string;
+}
+
+export interface getHistory {
+  (historyQuery: HistoryQueryParams): any;
 }
 
 export type UnionStore = MarkStore | InspectStore;