|
@@ -0,0 +1,243 @@
|
|
|
+<template>
|
|
|
+ <a-button @click="exportReport">导出报告</a-button>
|
|
|
+
|
|
|
+ <!-- card-view-frame -->
|
|
|
+ <div v-if="reportPreviewUrl" class="report-preview-frame">
|
|
|
+ <iframe :src="reportPreviewUrl" frameborder="0"></iframe>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <SelectProject ref="selectProjectRef" @confirm="projectSelected" />
|
|
|
+
|
|
|
+ <a-modal
|
|
|
+ v-model:visible="loadModalVisible"
|
|
|
+ dialogClass="report-load-modal"
|
|
|
+ centered
|
|
|
+ :closable="false"
|
|
|
+ :keyboard="false"
|
|
|
+ :maskClosable="false"
|
|
|
+ >
|
|
|
+ <div class="report-load-body">
|
|
|
+ <LoadingOutlined />
|
|
|
+ <div class="report-load-progress">
|
|
|
+ <p v-for="(item, index) in progressList" :key="index">
|
|
|
+ {{ item.title }}...
|
|
|
+ <span v-if="item.loading">
|
|
|
+ <LoadingOutlined /><i v-if="item.progress"
|
|
|
+ >{{ item.progress }}%</i
|
|
|
+ ></span
|
|
|
+ >
|
|
|
+ <span v-else>完成</span>
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </a-modal>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+import { Project } from "@/types";
|
|
|
+import { message } from "ant-design-vue";
|
|
|
+import SelectProject from "../paperAnalysis/SelectProject.vue";
|
|
|
+import {
|
|
|
+ getProjectReportTask,
|
|
|
+ uploadProjectReportCont,
|
|
|
+ getProjectReportResult,
|
|
|
+} from "@/api/allAnalysisPage";
|
|
|
+import { useRouter } from "vue-router";
|
|
|
+import { onBeforeMount, onMounted } from "vue";
|
|
|
+const router = useRouter();
|
|
|
+
|
|
|
+interface ProgressItemType {
|
|
|
+ title: string;
|
|
|
+ progress: number;
|
|
|
+ loading: boolean;
|
|
|
+}
|
|
|
+
|
|
|
+const props = defineProps<{
|
|
|
+ curProject: Project;
|
|
|
+}>();
|
|
|
+
|
|
|
+let selectProjectRef = $ref(null);
|
|
|
+let taskId = $ref(undefined as unknown as number);
|
|
|
+let compareProjectId = $ref(undefined as unknown as number);
|
|
|
+let curPaperId = $ref<number>();
|
|
|
+let paperIds = $shallowRef<number[]>([]);
|
|
|
+let finishPaperIds = $shallowRef<number[]>([]);
|
|
|
+let reportPreviewUrl = $ref<string>("");
|
|
|
+let setTs = $shallowRef<number[]>([]);
|
|
|
+let progressList = $ref<ProgressItemType[]>([]);
|
|
|
+let totalTaskCount = $ref(1);
|
|
|
+let loadModalVisible = $ref(false);
|
|
|
+
|
|
|
+function addProgress(data: ProgressItemType) {
|
|
|
+ progressList.push(data);
|
|
|
+}
|
|
|
+function updateProgress(progress: number) {
|
|
|
+ let data = progressList[progressList.length - 1];
|
|
|
+ data.progress = progress;
|
|
|
+ if (progress === 100) data.loading = false;
|
|
|
+}
|
|
|
+function getPaperProgress() {
|
|
|
+ return Math.floor((10000 * finishPaperIds.length) / totalTaskCount) / 100;
|
|
|
+}
|
|
|
+
|
|
|
+function closeLoadModal() {
|
|
|
+ loadModalVisible = false;
|
|
|
+ progressList = [];
|
|
|
+ paperIds = [];
|
|
|
+ finishPaperIds = [];
|
|
|
+ clearSetTs();
|
|
|
+}
|
|
|
+
|
|
|
+function clearSetTs() {
|
|
|
+ if (!setTs.length) return;
|
|
|
+ setTs.forEach((t) => clearTimeout(t));
|
|
|
+ setTs = [];
|
|
|
+}
|
|
|
+
|
|
|
+function exportReport() {
|
|
|
+ if (props.curProject && props.curProject.needCompute) {
|
|
|
+ void message.info("有数据更新请重新计算");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // @ts-ignore
|
|
|
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
|
+ selectProjectRef.showModal();
|
|
|
+}
|
|
|
+async function projectSelected(projectId: number) {
|
|
|
+ loadModalVisible = true;
|
|
|
+ compareProjectId = projectId;
|
|
|
+ addProgress({
|
|
|
+ title: "构建任务",
|
|
|
+ progress: 0,
|
|
|
+ loading: true,
|
|
|
+ });
|
|
|
+ const res = await getProjectReportTask({
|
|
|
+ projectId: props.curProject.id,
|
|
|
+ compareProjectId: projectId,
|
|
|
+ }).catch(() => {
|
|
|
+ closeLoadModal();
|
|
|
+ });
|
|
|
+ if (!res) return;
|
|
|
+ taskId = res.data.taskId;
|
|
|
+ paperIds = res.data.paperIds;
|
|
|
+ totalTaskCount = paperIds.length;
|
|
|
+
|
|
|
+ if (!paperIds.length) {
|
|
|
+ closeLoadModal();
|
|
|
+ void message.error("没有需要导出的报告!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ updateProgress(100);
|
|
|
+
|
|
|
+ addProgress({
|
|
|
+ title: "构建报告数据",
|
|
|
+ progress: 0,
|
|
|
+ loading: true,
|
|
|
+ });
|
|
|
+ await startTask();
|
|
|
+}
|
|
|
+
|
|
|
+async function startTask() {
|
|
|
+ if (!paperIds.length) {
|
|
|
+ addProgress({
|
|
|
+ title: "获取报告pdf",
|
|
|
+ progress: 0,
|
|
|
+ loading: true,
|
|
|
+ });
|
|
|
+ await finishTask();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ curPaperId = paperIds.shift();
|
|
|
+
|
|
|
+ const { href } = router.resolve({
|
|
|
+ name: "PaperReport",
|
|
|
+ params: {
|
|
|
+ projectId: props.curProject.id,
|
|
|
+ paperId: curPaperId,
|
|
|
+ compareProjectId,
|
|
|
+ viewType: "frame",
|
|
|
+ },
|
|
|
+ query: {
|
|
|
+ t: Date.now(),
|
|
|
+ },
|
|
|
+ });
|
|
|
+ reportPreviewUrl = href;
|
|
|
+}
|
|
|
+
|
|
|
+async function finishTask() {
|
|
|
+ clearSetTs();
|
|
|
+ const res = await getProjectReportResult(taskId as number).catch(() => {
|
|
|
+ closeLoadModal();
|
|
|
+ });
|
|
|
+ if (!res) return;
|
|
|
+ if (res.data.status === "SUCCESS" && res.data.filePath) {
|
|
|
+ updateProgress(100);
|
|
|
+ closeLoadModal();
|
|
|
+ void message.info("开始下载报告!");
|
|
|
+ window.open(res.data.filePath);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (res.data.status === "FAILED") {
|
|
|
+ closeLoadModal();
|
|
|
+ void message.error("报告导出失败,请重新尝试!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ setTs.push(setTimeout(finishTask, 3 * 1000));
|
|
|
+}
|
|
|
+
|
|
|
+function registWindowSubmit() {
|
|
|
+ // @ts-ignore
|
|
|
+ window.submitReportTemp = async (
|
|
|
+ success: boolean,
|
|
|
+ errorMsg: string,
|
|
|
+ htmlContent: string
|
|
|
+ ) => {
|
|
|
+ if (!success) {
|
|
|
+ void message.error(errorMsg);
|
|
|
+ reportPreviewUrl = "";
|
|
|
+ closeLoadModal();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const res = await uploadProjectReportCont({
|
|
|
+ taskId,
|
|
|
+ paperId: curPaperId as number,
|
|
|
+ htmlContent,
|
|
|
+ }).catch(() => false);
|
|
|
+ if (!res) return;
|
|
|
+
|
|
|
+ finishPaperIds.push(curPaperId as number);
|
|
|
+ updateProgress(getPaperProgress());
|
|
|
+ await startTask();
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ registWindowSubmit();
|
|
|
+});
|
|
|
+onBeforeMount(() => {
|
|
|
+ clearSetTs();
|
|
|
+ // @ts-ignore
|
|
|
+ delete window.submitReportTemp;
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<style>
|
|
|
+.report-load-body {
|
|
|
+ width: 200px;
|
|
|
+ margin: 0 auto;
|
|
|
+}
|
|
|
+.report-load-body > i {
|
|
|
+ display: block;
|
|
|
+ font-size: 100px;
|
|
|
+ margin: 0 auto 40px;
|
|
|
+}
|
|
|
+.report-load-body > p {
|
|
|
+ margin: 0;
|
|
|
+ line-height: 24px;
|
|
|
+ color: #fff;
|
|
|
+ font-size: 14px;
|
|
|
+}
|
|
|
+</style>
|