Browse Source

feat: 导出导入调整

zhangjie 8 months ago
parent
commit
e4db1f7e28

+ 1 - 20
src/render/ap/absentCheck.ts

@@ -60,31 +60,12 @@ export const absentTemplateDownload = (): Promise<Blob> =>
     download: true,
     download: true,
   });
   });
 
 
-// 缺考校验导入进度
-export const absentImportStatus = (
-  examId: number
-): Promise<{ synching: boolean }> =>
-  request({
-    url: "/api/admin/check/exam-status/import/status",
-    method: "post",
-    data: { examId },
-  });
-
 // 缺考校验导入进度
 // 缺考校验导入进度
 export const absentReset = (
 export const absentReset = (
   data: AbsentResetParams
   data: AbsentResetParams
-): Promise<{ synching: boolean }> =>
+): Promise<{ taskId: string }> =>
   request({
   request({
     url: "/api/admin/check/exam-status/reset",
     url: "/api/admin/check/exam-status/reset",
     method: "post",
     method: "post",
     data,
     data,
   });
   });
-
-export const absentResetStatus = (
-  examId: number
-): Promise<{ synching: boolean }> =>
-  request({
-    url: "/api/admin/check/exam-status/reset/status",
-    method: "post",
-    data: { examId },
-  });

+ 6 - 6
src/render/ap/resultExport.ts

@@ -12,8 +12,8 @@ import {
   StudentStatusListItem,
   StudentStatusListItem,
   MarkSiteListPageResult,
   MarkSiteListPageResult,
   MarkSiteSaveParams,
   MarkSiteSaveParams,
-  markSiteSetParams,
-  dbfExportProgressResult,
+  MarkSiteSetParams,
+  ExportProgressResult,
 } from "./types/resultExport";
 } from "./types/resultExport";
 
 
 // 违纪导入
 // 违纪导入
@@ -78,7 +78,7 @@ export const markSiteDelete = (id: string): Promise<RequestActionResult> =>
 
 
 // 扫描点代码
 // 扫描点代码
 export const markSiteCodeSet = (
 export const markSiteCodeSet = (
-  data: markSiteSetParams
+  data: MarkSiteSetParams
 ): Promise<RequestActionResult> =>
 ): Promise<RequestActionResult> =>
   request({
   request({
     url: "/api/admin/exam/scan-site/save",
     url: "/api/admin/exam/scan-site/save",
@@ -113,11 +113,11 @@ export const dbfPackageExport = (
     data,
     data,
   });
   });
 
 
-export const dbfExportProgress = (
+export const asyncTaskProgress = (
   taskId: string
   taskId: string
-): Promise<dbfExportProgressResult> =>
+): Promise<ExportProgressResult> =>
   request({
   request({
-    url: "/api/admin/subject/data/progress",
+    url: "/api/admin/async-task/progress",
     method: "post",
     method: "post",
     data: { taskId },
     data: { taskId },
   });
   });

+ 2 - 7
src/render/ap/types/resultExport.ts

@@ -35,17 +35,12 @@ export interface MarkSiteSaveParams {
   evenNumber: number;
   evenNumber: number;
 }
 }
 
 
-export interface markSiteSetParams {
+export interface MarkSiteSetParams {
   examId: number;
   examId: number;
   scanSite: string;
   scanSite: string;
 }
 }
 
 
-export interface dbfExportParams {
-  examId: number;
-  subjectCode: string;
-}
-
-export interface dbfExportProgressResult {
+export interface ExportProgressResult {
   progress: number;
   progress: number;
   success: boolean;
   success: boolean;
   errMsg: string;
   errMsg: string;

+ 1 - 10
src/render/components/ImportDialog/index.vue

@@ -239,16 +239,6 @@ const customRequest: UploadProps["customRequest"] = (option) => {
     }) as Promise<Record<string, any>>
     }) as Promise<Record<string, any>>
   )
   )
     .then((res) => {
     .then((res) => {
-      // 所有excel导入的特殊处理
-      // if (res.hasError) {
-      //   const failRecords = res.failRecords;
-      //   const message = failRecords
-      //     .map((item) => `第${item.lineNum}行:${item.msg}`)
-      //     .join("。");
-
-      //   handleError(message);
-      //   return;
-      // }
       handleSuccess(res);
       handleSuccess(res);
     })
     })
     .catch((error: AxiosError<{ message: string }> | null) => {
     .catch((error: AxiosError<{ message: string }> | null) => {
@@ -276,6 +266,7 @@ function handleSuccess(data: Record<string, any>) {
     ...result.value,
     ...result.value,
     ...data,
     ...data,
   });
   });
+  close();
 }
 }
 
 
 function handleFormatError() {
 function handleFormatError() {

+ 19 - 25
src/render/views/AbsentCheck/ImportTypeDialog.vue

@@ -12,7 +12,7 @@
           :upload-url="uploadUrl"
           :upload-url="uploadUrl"
           :upload-data="updateData"
           :upload-data="updateData"
           :format="['txt']"
           :format="['txt']"
-          @upload-success="checkUploadStatus"
+          @upload-success="uploadSuccessHandle"
           @valid-error="onValidError"
           @valid-error="onValidError"
         >
         >
           <a-button class="type-box" @click="seleted('COMPARE')">
           <a-button class="type-box" @click="seleted('COMPARE')">
@@ -27,7 +27,7 @@
           :upload-url="uploadUrl"
           :upload-url="uploadUrl"
           :upload-data="updateData"
           :upload-data="updateData"
           :format="['txt']"
           :format="['txt']"
-          @upload-success="startLoopSync"
+          @upload-success="uploadSuccessHandle"
           @valid-error="onValidError"
           @valid-error="onValidError"
         >
         >
           <a-button class="type-box" @click="seleted('OVERRIDE')">
           <a-button class="type-box" @click="seleted('OVERRIDE')">
@@ -45,6 +45,9 @@
       </a-button>
       </a-button>
     </div>
     </div>
   </a-modal>
   </a-modal>
+
+  <!-- TaskProgressDialog -->
+  <TaskProgressDialog ref="taskProgressDialogRef" :task="curExportTask" />
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
@@ -57,14 +60,13 @@ import {
 import { computed, ref } from "vue";
 import { computed, ref } from "vue";
 import useModal from "@/hooks/useModal";
 import useModal from "@/hooks/useModal";
 import { ImportType } from "@/ap/types/absentCheck";
 import { ImportType } from "@/ap/types/absentCheck";
-import { absentImportStatus } from "@/ap/absentCheck";
 import { absentTemplateDownload } from "@/ap/absentCheck";
 import { absentTemplateDownload } from "@/ap/absentCheck";
 import useLoading from "@/hooks/useLoading";
 import useLoading from "@/hooks/useLoading";
-import useLoop from "@/hooks/useLoop";
+import { message } from "@qmth/ui";
+import { useUserStore } from "@/store";
 
 
 import ImportBtn from "@/components/ImportBtn/index.vue";
 import ImportBtn from "@/components/ImportBtn/index.vue";
-import { useUserStore } from "@/store";
-import { message } from "@qmth/ui";
+import TaskProgressDialog from "../ResultExport/TaskProgressDialog.vue";
 
 
 defineOptions({
 defineOptions({
   name: "ImportTypeDialog",
   name: "ImportTypeDialog",
@@ -90,25 +92,6 @@ function seleted(type: ImportType) {
   uploadMode.value = type;
   uploadMode.value = type;
 }
 }
 
 
-const { start: startLoopSync, stop: stopLoopSync } = useLoop(
-  checkUploadStatus,
-  1000
-);
-
-async function checkUploadStatus() {
-  const res = await absentImportStatus(userStore.curExam.id).catch(() => {});
-  if (res) {
-    if (!res.synching) {
-      stopLoopSync();
-      message.success("导入成功!");
-      close();
-    }
-  } else {
-    stopLoopSync();
-    message.error("导入错误!");
-  }
-}
-
 function onValidError(data: { message: string }) {
 function onValidError(data: { message: string }) {
   message.error(message);
   message.error(message);
 }
 }
@@ -126,6 +109,17 @@ async function onDownloadTemp() {
   if (!res) return;
   if (!res) return;
   message.success("下载成功!");
   message.success("下载成功!");
 }
 }
+
+// task progress
+const curExportTask = ref({ id: "", name: "" });
+const taskProgressDialogRef = ref();
+function uploadSuccessHandle(res: { taskId: string }) {
+  curExportTask.value = {
+    id: res.taskId,
+    name: "缺考名单导入",
+  };
+  taskProgressDialogRef.value?.open();
+}
 </script>
 </script>
 
 
 <style lang="less" scoped>
 <style lang="less" scoped>

+ 28 - 31
src/render/views/AbsentCheck/ResetDialog.vue

@@ -34,19 +34,23 @@
       </div>
       </div>
     </template>
     </template>
   </a-modal>
   </a-modal>
+
+  <!-- TaskProgressDialog -->
+  <TaskProgressDialog ref="taskProgressDialogRef" :task="curExportTask" />
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
-import { computed, ref } from "vue";
+import { computed, ref, watch } from "vue";
 import useModal from "@/hooks/useModal";
 import useModal from "@/hooks/useModal";
-import { absentResetStatus, absentReset } from "@/ap/absentCheck";
+import { absentReset } from "@/ap/absentCheck";
 import { absentTemplateDownload } from "@/ap/absentCheck";
 import { absentTemplateDownload } from "@/ap/absentCheck";
 import useLoading from "@/hooks/useLoading";
 import useLoading from "@/hooks/useLoading";
-import useLoop from "@/hooks/useLoop";
 
 
 import { useUserStore } from "@/store";
 import { useUserStore } from "@/store";
 import { message } from "@qmth/ui";
 import { message } from "@qmth/ui";
 
 
+import TaskProgressDialog from "../ResultExport/TaskProgressDialog.vue";
+
 defineOptions({
 defineOptions({
   name: "ImportTypeDialog",
   name: "ImportTypeDialog",
 });
 });
@@ -60,29 +64,8 @@ const userStore = useUserStore();
 const examNumberFillCount = ref<number>();
 const examNumberFillCount = ref<number>();
 
 
 const { loading, setLoading } = useLoading();
 const { loading, setLoading } = useLoading();
-
-const { start: startLoopSync, stop: stopLoopSync } = useLoop(
-  checkUploadStatus,
-  1000
-);
-
-async function checkUploadStatus() {
-  const res = await absentResetStatus(userStore.curExam.id).catch(() => {});
-
-  if (res) {
-    if (!res.synching) {
-      stopLoopSync();
-      setLoading(false);
-      message.success("缺考校验重新生成成功!");
-      close();
-    }
-  } else {
-    setLoading(false);
-    stopLoopSync();
-    message.error("缺考校验重新生成错误!");
-  }
-}
-
+const curExportTask = ref({ id: "", name: "" });
+const taskProgressDialogRef = ref();
 async function confirm() {
 async function confirm() {
   if (!examNumberFillCount.value) {
   if (!examNumberFillCount.value) {
     message.error("请输入位数");
     message.error("请输入位数");
@@ -96,14 +79,28 @@ async function confirm() {
     examId: userStore.curExam.id,
     examId: userStore.curExam.id,
     examNumberFillCount: examNumberFillCount.value,
     examNumberFillCount: examNumberFillCount.value,
   }).catch(() => {});
   }).catch(() => {});
+  setLoading(false);
 
 
-  if (!res) {
-    setLoading(false);
-    return;
-  }
+  if (!res) return;
 
 
-  startLoopSync();
+  curExportTask.value = {
+    id: res.taskId,
+    name: "缺考校验重新生成",
+  };
+  taskProgressDialogRef.value?.open();
 }
 }
+
+watch(
+  () => visible.value,
+  (val) => {
+    if (val) {
+      examNumberFillCount.value = undefined;
+    }
+  },
+  {
+    immediate: true,
+  }
+);
 </script>
 </script>
 
 
 <style lang="less" scoped>
 <style lang="less" scoped>

+ 14 - 0
src/render/views/ResultExport/BreachImport.vue

@@ -30,7 +30,11 @@
     :upload-data="uploadData"
     :upload-data="uploadData"
     download-btn-title="违纪导入模版"
     download-btn-title="违纪导入模版"
     :download-handle="downloadHandle"
     :download-handle="downloadHandle"
+    @upload-success="uploadSuccessHandle"
   />
   />
+
+  <!-- TaskProgressDialog -->
+  <TaskProgressDialog ref="taskProgressDialogRef" :task="curExportTask" />
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
@@ -44,6 +48,7 @@ import { breachList, breachTemplateDownload } from "@/ap/resultExport";
 import { useUserStore } from "@/store";
 import { useUserStore } from "@/store";
 
 
 import ImportDialog from "@/components/ImportDialog/index.vue";
 import ImportDialog from "@/components/ImportDialog/index.vue";
+import TaskProgressDialog from "./TaskProgressDialog.vue";
 
 
 defineOptions({
 defineOptions({
   name: "BreachImport",
   name: "BreachImport",
@@ -102,6 +107,15 @@ async function downloadHandle() {
   if (!res) return;
   if (!res) return;
   message.success("下载成功!");
   message.success("下载成功!");
 }
 }
+const curExportTask = ref({ id: "", name: "" });
+const taskProgressDialogRef = ref();
+function uploadSuccessHandle(res: { taskId: string }) {
+  curExportTask.value = {
+    id: res.taskId,
+    name: "违纪导入",
+  };
+  taskProgressDialogRef.value?.open();
+}
 
 
 onMounted(() => {
 onMounted(() => {
   getData();
   getData();

+ 23 - 8
src/render/views/ResultExport/DbfExport.vue

@@ -36,10 +36,11 @@
     :row-data="siteCodeData"
     :row-data="siteCodeData"
     @modified="siteCodeModified"
     @modified="siteCodeModified"
   />
   />
-  <!-- ExportTaskProgressDialog -->
-  <ExportTaskProgressDialog
-    ref="exportTaskProgressDialogRef"
+  <!-- TaskProgressDialog -->
+  <TaskProgressDialog
+    ref="taskProgressDialogRef"
     :task="curExportTask"
     :task="curExportTask"
+    :download-handle="downloadTaskFile"
   />
   />
 </template>
 </template>
 
 
@@ -47,18 +48,21 @@
 import { ref, onMounted } from "vue";
 import { ref, onMounted } from "vue";
 import { SettingOutlined } from "@ant-design/icons-vue";
 import { SettingOutlined } from "@ant-design/icons-vue";
 import type { TableProps } from "ant-design-vue";
 import type { TableProps } from "ant-design-vue";
+import { message } from "ant-design-vue";
+
 import { SubjectItem } from "@/ap/types/base";
 import { SubjectItem } from "@/ap/types/base";
 import { getSubjectList } from "@/ap/base";
 import { getSubjectList } from "@/ap/base";
 import {
 import {
   markSiteCodeInfo,
   markSiteCodeInfo,
   dbfAnswerExport,
   dbfAnswerExport,
   dbfPackageExport,
   dbfPackageExport,
+  dbfExportTaskDownload,
 } from "@/ap/resultExport";
 } from "@/ap/resultExport";
 import { markSiteSetParams } from "@/ap/types/resultExport";
 import { markSiteSetParams } from "@/ap/types/resultExport";
 import { useUserStore } from "@/store";
 import { useUserStore } from "@/store";
 
 
 import ModifySiteCode from "./ModifySiteCode.vue";
 import ModifySiteCode from "./ModifySiteCode.vue";
-import ExportTaskProgressDialog from "./ExportTaskProgressDialog.vue";
+import TaskProgressDialog from "./TaskProgressDialog.vue";
 
 
 defineOptions({
 defineOptions({
   name: "DbfExport",
   name: "DbfExport",
@@ -110,15 +114,18 @@ async function getData() {
   dataList.value = res || [];
   dataList.value = res || [];
 }
 }
 
 
-const exportTaskProgressDialogRef = ref();
+const taskProgressDialogRef = ref();
 async function onExportAnswer(index: number) {
 async function onExportAnswer(index: number) {
   const record = dataList.value[index];
   const record = dataList.value[index];
   const res = await dbfAnswerExport({
   const res = await dbfAnswerExport({
     examId: userStore.curExam.id,
     examId: userStore.curExam.id,
     subjectCode: record.code,
     subjectCode: record.code,
   });
   });
-  curExportTask.value = { id: res.taskId, name: "扫描答案DBF" };
-  exportTaskProgressDialogRef.value?.open();
+  curExportTask.value = {
+    id: res.taskId,
+    name: "扫描答案DBF",
+  };
+  taskProgressDialogRef.value?.open();
 }
 }
 
 
 async function onExportPackage(index: number) {
 async function onExportPackage(index: number) {
@@ -128,7 +135,15 @@ async function onExportPackage(index: number) {
     subjectCode: record.code,
     subjectCode: record.code,
   });
   });
   curExportTask.value = { id: res.taskId, name: "打包DBF" };
   curExportTask.value = { id: res.taskId, name: "打包DBF" };
-  exportTaskProgressDialogRef.value?.open();
+  taskProgressDialogRef.value?.open();
+}
+
+async function downloadTaskFile() {
+  const res = await dbfExportTaskDownload(curExportTask.value.id).catch(
+    () => false
+  );
+  if (!res) return;
+  message.success("文件下载成功!");
 }
 }
 
 
 onMounted(() => {
 onMounted(() => {

+ 16 - 0
src/render/views/ResultExport/StudentStatus.vue

@@ -25,10 +25,12 @@
   <ImportDialog
   <ImportDialog
     ref="importDialogRef"
     ref="importDialogRef"
     title="考生状态导入"
     title="考生状态导入"
+    :format="['txt']"
     upload-url="/api/admin/student/cust-status/import"
     upload-url="/api/admin/student/cust-status/import"
     :upload-data="uploadData"
     :upload-data="uploadData"
     download-btn-title="考生状态导入模版"
     download-btn-title="考生状态导入模版"
     :download-handle="downloadHandle"
     :download-handle="downloadHandle"
+    @upload-success="uploadSuccessHandle"
   >
   >
     <a-form-item
     <a-form-item
       label="科目"
       label="科目"
@@ -37,6 +39,9 @@
       >{{ curRow.subjectName }}</a-form-item
       >{{ curRow.subjectName }}</a-form-item
     >
     >
   </ImportDialog>
   </ImportDialog>
+
+  <!-- TaskProgressDialog -->
+  <TaskProgressDialog ref="taskProgressDialogRef" :task="curExportTask" />
 </template>
 </template>
 
 
 <script setup lang="ts">
 <script setup lang="ts">
@@ -50,6 +55,7 @@ import { studentStatusList, statusTemplateDownload } from "@/ap/resultExport";
 import { useUserStore } from "@/store";
 import { useUserStore } from "@/store";
 
 
 import ImportDialog from "@/components/ImportDialog/index.vue";
 import ImportDialog from "@/components/ImportDialog/index.vue";
+import TaskProgressDialog from "./TaskProgressDialog.vue";
 
 
 defineOptions({
 defineOptions({
   name: "StudentStatus",
   name: "StudentStatus",
@@ -113,6 +119,16 @@ async function downloadHandle() {
   message.success("下载成功!");
   message.success("下载成功!");
 }
 }
 
 
+const curExportTask = ref({ id: "", name: "" });
+const taskProgressDialogRef = ref();
+function uploadSuccessHandle(res: { taskId: string }) {
+  curExportTask.value = {
+    id: res.taskId,
+    name: "考生状态导入",
+  };
+  taskProgressDialogRef.value?.open();
+}
+
 onMounted(() => {
 onMounted(() => {
   getData();
   getData();
 });
 });

+ 31 - 18
src/render/views/ResultExport/ExportTaskProgressDialog.vue → src/render/views/ResultExport/TaskProgressDialog.vue

@@ -7,7 +7,7 @@
     :keyboard="false"
     :keyboard="false"
     :mask-closable="false"
     :mask-closable="false"
   >
   >
-    <template #title> 导出进度 </template>
+    <template #title> {{ task.name }}进度 </template>
 
 
     <p>{{ tips }}</p>
     <p>{{ tips }}</p>
     <a-progress :percent="curProgress" />
     <a-progress :percent="curProgress" />
@@ -17,7 +17,7 @@
 <script setup lang="ts">
 <script setup lang="ts">
 import { ref, watch, computed } from "vue";
 import { ref, watch, computed } from "vue";
 import { message } from "ant-design-vue";
 import { message } from "ant-design-vue";
-import { dbfExportProgress, dbfExportTaskDownload } from "@/ap/resultExport";
+import { asyncTaskProgress } from "@/ap/resultExport";
 
 
 import useLoading from "@/hooks/useLoading";
 import useLoading from "@/hooks/useLoading";
 import useModal from "@/hooks/useModal";
 import useModal from "@/hooks/useModal";
@@ -25,38 +25,57 @@ import useLoop from "@/hooks/useLoop";
 import { downloadByUrl } from "@/utils/download";
 import { downloadByUrl } from "@/utils/download";
 
 
 defineOptions({
 defineOptions({
-  name: "ExportTaskProgressDialog",
+  name: "TaskProgressDialog",
 });
 });
 
 
 /* modal */
 /* modal */
 const { visible, open, close } = useModal();
 const { visible, open, close } = useModal();
 defineExpose({ open, close });
 defineExpose({ open, close });
 
 
+interface PromiseFunc {
+  (): Promise<void>;
+}
+
 const props = defineProps<{
 const props = defineProps<{
   task: {
   task: {
     id: string;
     id: string;
     name: string;
     name: string;
   };
   };
+  downloadHandle?: PromiseFunc;
 }>();
 }>();
 
 
 const curProgress = ref(0);
 const curProgress = ref(0);
 
 
 const tips = computed(() => {
 const tips = computed(() => {
-  return curProgress.value < 100
-    ? `${props.task.name}导出中……`
-    : `文件生成完毕,正在下载……`;
+  if (curProgress.value < 100) {
+    return `${props.task.name}中……`;
+  }
+
+  if (props.downloadHandle) {
+    return `文件生成完毕,正在下载……`;
+  }
+
+  return `任务执行成功!`;
 });
 });
 
 
+const delayClose = () => {
+  setTimeout(() => {
+    close();
+  }, 500);
+};
+
 const { start, stop } = useLoop(getProgress, 1000);
 const { start, stop } = useLoop(getProgress, 1000);
 async function getProgress() {
 async function getProgress() {
-  const result = await dbfExportProgress(props.task.id).catch(() => {});
+  const result = await asyncTaskProgress(props.task.id).catch(() => {});
   if (!result) {
   if (!result) {
     stop();
     stop();
+    delayClose();
     return;
     return;
   }
   }
   if (!result.success) {
   if (!result.success) {
     message.error(result.errMsg);
     message.error(result.errMsg);
     stop();
     stop();
+    delayClose();
     return;
     return;
   }
   }
   curProgress.value = result.progress;
   curProgress.value = result.progress;
@@ -64,18 +83,12 @@ async function getProgress() {
   // 文件生成成功,开始下载
   // 文件生成成功,开始下载
   if (result.progress >= 100) {
   if (result.progress >= 100) {
     stop();
     stop();
-    downloadTaskFile();
-  }
-}
-
-async function downloadTaskFile() {
-  const res = await dbfExportTaskDownload(props.task.id).catch(() => false);
-  if (!res) return;
-  message.success("文件下载成功!");
+    if (props.downloadHandle) {
+      await props.downloadHandle();
+    }
 
 
-  setTimeout(() => {
-    close();
-  }, 500);
+    delayClose();
+  }
 }
 }
 
 
 watch(
 watch(