MarkHistory.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. <template>
  2. <div :class="['mark-history', { hide: !markStore.historyOpen }]">
  3. <div class="mark-history-title">
  4. {{ title }}
  5. </div>
  6. <div
  7. v-if="showSearch && markStore.getStatusValueName !== '试评'"
  8. class="mark-history-search"
  9. >
  10. <a-select
  11. ref="select"
  12. v-model:value="searchType"
  13. style="width: 75px; margin-right: 12px; font-size: 12px"
  14. >
  15. <a-select-option value="1">编号</a-select-option>
  16. <a-select-option value="2">分数</a-select-option>
  17. </a-select>
  18. <a-input
  19. v-model:value="secretNumberInput"
  20. style="font-size: 13px"
  21. class="search-value"
  22. placeholder="查找试卷"
  23. allowClear
  24. @keyup.enter="searchHistoryTask"
  25. @keypress.stop=""
  26. @keydown.stop=""
  27. >
  28. </a-input>
  29. <a-button
  30. type="primary"
  31. style="margin-left: 8px"
  32. @click="searchHistoryTask"
  33. >搜索</a-button
  34. >
  35. </div>
  36. <div class="mark-history-table-head">
  37. <div class="head-item">编号</div>
  38. <div class="head-item head-item-time">时间</div>
  39. <div class="head-item">分数</div>
  40. </div>
  41. <div class="mark-history-table-body">
  42. <a-spin :spinning="loading" size="large" tip="Loading..." :delay="500">
  43. <div
  44. v-for="(task, index) of markStore.historyTasks"
  45. :key="index"
  46. :class="[
  47. 'body-row',
  48. {
  49. 'is-active': markStore.currentTask?.studentId === task.studentId,
  50. },
  51. ]"
  52. @click="replaceCurrentTask(task)"
  53. >
  54. <div class="body-col">
  55. {{ task.secretNumber }}
  56. </div>
  57. <div class="body-col">
  58. {{ $filters.datetimeFilter(task.markerTime ?? task.inspectTime) }}
  59. </div>
  60. <div class="body-col">
  61. {{ task.markerScore === -1 ? "未选做" : task.markerScore }}
  62. </div>
  63. </div>
  64. </a-spin>
  65. </div>
  66. <div class="mark-history-table-page">
  67. <div>共{{ total }}项数据</div>
  68. <a-pagination
  69. :current="currentPage"
  70. simple
  71. :total="total"
  72. :pageSize="limitPageSize"
  73. @change="pageChange"
  74. />
  75. </div>
  76. </div>
  77. </template>
  78. <script setup lang="ts">
  79. import type {
  80. GetHistory,
  81. HistoryQueryParams,
  82. MarkHistoryOrderBy,
  83. MarkHistorySortField,
  84. Task,
  85. } from "@/types";
  86. import { watch } from "vue";
  87. import { message } from "ant-design-vue";
  88. import { cloneDeep } from "lodash-es";
  89. import { useMarkStore } from "@/store";
  90. import EventBus from "@/plugins/eventBus";
  91. import useDraw from "./composables/useDraw";
  92. const limitPageSize = 20;
  93. const markStore = useMarkStore();
  94. const { preDrawImageHistory } = useDraw();
  95. const {
  96. title = "回评",
  97. showSearch = false,
  98. orderTimeField = "marker_time",
  99. subjectCode = undefined,
  100. groupNumber = undefined,
  101. markerId = undefined,
  102. markerScore = undefined,
  103. examId = undefined,
  104. getHistory,
  105. } = defineProps<{
  106. title?: string;
  107. showSearch?: boolean;
  108. orderTimeField?: "marker_time" | "inspect_time";
  109. subjectCode?: string;
  110. groupNumber?: string;
  111. markerId?: string;
  112. markerScore?: string;
  113. examId?: string;
  114. getHistory: GetHistory;
  115. }>();
  116. let searchType = $ref("1");
  117. // 密号输入
  118. let secretNumberInput = $ref("");
  119. const format = (val: string, preVal: string) => {
  120. const reg = /^-?\d*(\.\d*)?$/;
  121. if ((!isNaN(+val) && reg.test(val)) || val === "" || val === "-") {
  122. secretNumberInput = val;
  123. } else {
  124. secretNumberInput = preVal;
  125. }
  126. };
  127. watch(
  128. () => secretNumberInput,
  129. (val, preVal) => {
  130. format(val, preVal);
  131. }
  132. );
  133. let loading = $ref(false);
  134. let currentPage = $ref(1);
  135. let total = $ref(0);
  136. let order: MarkHistoryOrderBy = $ref("marker_time");
  137. if (orderTimeField) {
  138. order = orderTimeField;
  139. }
  140. let sort: MarkHistorySortField = $ref("DESC");
  141. const currentTaskChange = async () => {
  142. if (markStore.historyOpen) {
  143. markStore.globalMask = true;
  144. try {
  145. await updateHistoryTask({
  146. secretNumber: secretNumberInput,
  147. order: order,
  148. sort: sort,
  149. pageNumber: currentPage,
  150. });
  151. } catch (e) {
  152. // 恢复以前的行为,取回评失败则评卷任务为空
  153. await replaceCurrentTask(undefined);
  154. } finally {
  155. markStore.globalMask = false;
  156. }
  157. await replaceCurrentTask(markStore.historyTasks[0]);
  158. } else {
  159. await replaceCurrentTask(markStore.tasks[0]);
  160. markStore.historyTasks.splice(0);
  161. secretNumberInput = "";
  162. currentPage = 1;
  163. order = "marker_time";
  164. sort = "DESC";
  165. }
  166. };
  167. watch(() => markStore.historyOpen, currentTaskChange);
  168. watch([$$(order), $$(sort), $$(currentPage)], currentTaskChange);
  169. EventBus.on("should-reload-history", () => {
  170. (async () => {
  171. markStore.globalMask = true;
  172. try {
  173. const res = await getHistory({
  174. secretNumber: markStore.currentTask?.secretNumber,
  175. order,
  176. sort,
  177. pageNumber: 1,
  178. subjectCode,
  179. groupNumber,
  180. markerId,
  181. markerScore,
  182. examId,
  183. pageSize: 10,
  184. });
  185. if (res?.data) {
  186. const data = res.data.records;
  187. if (markStore.currentTask) {
  188. // 这种方式(对象被重新构造了)能查找到index,我也很惊讶
  189. const indexOfTasks = markStore.historyTasks.indexOf(
  190. markStore.currentTask
  191. );
  192. if (data[0]) {
  193. // 如果原任务依然存在
  194. markStore.historyTasks.splice(indexOfTasks, 1, data[0]);
  195. await replaceCurrentTask(markStore.historyTasks[indexOfTasks]);
  196. } else {
  197. // 问题卷会查找不到,这里直接删除此任务
  198. markStore.historyTasks.splice(indexOfTasks, 1);
  199. await replaceCurrentTask(markStore.historyTasks[indexOfTasks]);
  200. }
  201. } else {
  202. // 问题卷会将清除它作为 currentTask ,然后刷新当前页
  203. markStore.historyTasks = data;
  204. await replaceCurrentTask(markStore.historyTasks[0]);
  205. }
  206. }
  207. } finally {
  208. markStore.globalMask = false;
  209. }
  210. })().catch((e) => console.log("reload-history error", e));
  211. });
  212. async function updateHistoryTask({
  213. pageNumber = 1,
  214. order = "marker_time",
  215. sort = "DESC",
  216. secretNumber = null,
  217. }: HistoryQueryParams) {
  218. loading = true;
  219. let params = {
  220. pageNumber,
  221. pageSize: limitPageSize,
  222. order,
  223. sort,
  224. subjectCode,
  225. groupNumber,
  226. markerId,
  227. markerScore,
  228. examId,
  229. };
  230. let key = searchType == "1" ? "secretNumber" : "markerScore";
  231. params[key] = secretNumber || undefined;
  232. const res = await getHistory(params);
  233. loading = false;
  234. if (res?.data) {
  235. markStore.historyTasks = res.data.records;
  236. total = res.data.total;
  237. replaceCurrentTask(markStore.historyTasks[0]).catch((err) => {
  238. console.log(err);
  239. void message.error("切换至回评任务失败");
  240. });
  241. }
  242. }
  243. async function replaceCurrentTask(task: Task | undefined) {
  244. if (markStore.isScanImage && !!task) {
  245. await preDrawImageHistory(task);
  246. }
  247. markStore.currentTask = cloneDeep(task);
  248. }
  249. function pageChange(page) {
  250. currentPage = page;
  251. }
  252. async function searchHistoryTask() {
  253. if (currentPage !== 1) {
  254. currentPage = 1;
  255. } else {
  256. await currentTaskChange();
  257. }
  258. }
  259. </script>