bill 1 rok temu
rodzic
commit
87411ce1b5
3 zmienionych plików z 170 dodań i 1 usunięć
  1. 138 0
      src/view/case/download.vue
  2. 12 0
      src/view/case/editMenu.vue
  3. 20 1
      src/view/case/quisk.ts

+ 138 - 0
src/view/case/download.vue

@@ -0,0 +1,138 @@
+<template>
+  <!-- hideFloor: state === State.package -->
+  <div>
+    <div class="title">
+      {{ stateTitle[state] }}
+    </div>
+
+    <div v-if="state === State.package">
+      <div
+        class="text"
+        style="display: flex; justify-content: space-between; margin-top: 15px"
+      >
+        <span>{{ filename }}</span>
+        <span>{{ percent }}%</span>
+      </div>
+      <div style="pointer-events: none">
+        <el-slider v-model="percent" :show-tooltip="false" />
+      </div>
+    </div>
+    <div v-else-if="state === State.readDown">
+      <span>正在下载中……</span>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { computed, onMounted, onUnmounted, ref } from "vue";
+import saveAs from "@/util/file-serve";
+import { checkHasDownload, getDownloadProcess, downloadScene, axios } from "@/request";
+import { ElLoading, ElMessage } from "element-plus";
+import { QuoteScene, SceneType } from "@/store/scene";
+import { QuiskExpose } from "@/helper/mount";
+
+const props = defineProps<{ scene: QuoteScene }>();
+enum State {
+  uncreate,
+  package,
+  readDown,
+}
+const getState = (type: number) => {
+  const stateTypes = [
+    { codes: [0, 2], state: State.uncreate },
+    { codes: [1], state: State.package },
+    { codes: [3], state: State.readDown },
+  ];
+  return (
+    stateTypes.find((stateType) => stateType.codes.includes(type))?.state ||
+    State.uncreate
+  );
+};
+
+const state = ref<State>(State.uncreate);
+const count = ref<number>(0);
+const filename = ref<string>(props.scene.title + ".zip");
+const downloadURL = ref<string>();
+const percent = ref(0);
+
+const stateTitle = {
+  [State.uncreate]: "下载场景离线数据包,可在本地运行查看。",
+  [State.package]: "正在打包场景离线数据",
+  [State.readDown]: filename.value,
+};
+
+const params = {
+  num: props.scene.num,
+  isObj: Number(![SceneType.SWSS, SceneType.SWYDSS].includes(props.scene.type)),
+};
+// 初始化
+const initial = async () => {
+  const res = await axios.get(checkHasDownload, { params });
+  state.value = getState(res.data.downloadStatus);
+  count.value = res.data.count;
+  downloadURL.value = res.data.downloadUrl;
+
+  if (state.value === State.uncreate) {
+    const downRes = await axios.get(downloadScene, { params });
+    state.value = getState(downRes.data.downloadStatus);
+    // const unCountFlag =
+    //   count.value == 0 ||(await axios.get(downloadScene, { params })).data.downloadStatus !== 1;
+    if (state.value === State.uncreate) {
+      ElMessage.error("下载失败,请联系管理员");
+      throw "暂无剩余下载次数";
+    }
+  }
+
+  if (state.value === State.package) {
+    await new Promise<void>((resolve) => requestUpdateURL(resolve));
+  } else {
+    downloadURL.value = res.data.downloadUrl;
+  }
+};
+
+// 下载
+const download = () => {
+  if (!downloadURL.value) {
+    ElMessage.error("下载链接未生成,请稍等!");
+    throw "下载链接未生成,请稍等!";
+  } else {
+    if (!downloadURL.value.startsWith("/")) {
+      downloadURL.value = "/" + downloadURL.value;
+    }
+    console.error("downloadURL.value", downloadURL.value);
+    return saveAs(downloadURL.value, filename.value);
+  }
+};
+
+// 进度请求
+let timer: any;
+const requestUpdateURL = async (callback: () => void) => {
+  const res = await axios.get(getDownloadProcess, { params });
+
+  percent.value = parseInt(res.data.percent);
+  downloadURL.value = res.data.url;
+  if (downloadURL.value) {
+    state.value = State.readDown;
+    callback();
+  } else {
+    timer = setTimeout(() => requestUpdateURL(callback), 1000);
+  }
+};
+
+onUnmounted(() => clearTimeout(timer));
+
+defineExpose<QuiskExpose>({
+  submit: async () => {
+    await initial();
+    const loading = ElLoading.service({
+      lock: true,
+      text: "下载中",
+      background: "rgba(255, 255, 255, 0.4)",
+    });
+    await download();
+    loading.close();
+    ElMessage.success("下载完成");
+  },
+});
+</script>
+

+ 12 - 0
src/view/case/editMenu.vue

@@ -103,6 +103,18 @@ const menus = computed(() => {
         window.open(`mirror.html?caseId=${caseId}`);
       },
     },
+    {
+      key: "download",
+      label: "下载",
+      onClick: async () => {
+        const scenes = await getCaseSceneList(caseId);
+        if (!scenes.length) {
+          alert("当前案件下无场景,请先添加场景。");
+        } else {
+          shareCase({ caseId: caseId });
+        }
+      },
+    },
     ...(props.lastMenu || []).map((item) => ({
       ...item,
       onClick: () => item.onClick(caseId),

+ 20 - 1
src/view/case/quisk.ts

@@ -27,7 +27,6 @@ export const addCaseImgFileAll = quiskMountFactory(addPhotoFileAll, {
   width: 500,
 });
 
-
 export const addCaseScenes = quiskMountFactory(AddScenes, {
   title: "添加场景",
   width: 800,
@@ -64,3 +63,23 @@ export const shareCase = quiskMountFactory(ShareCase, {
   title: "分享",
   enterText: "复制链接及密码",
 })<string>;
+
+export type SceneDpwnloadProps = { scene: QuoteScene };
+export const downloadCase = async (props: SceneDpwnloadProps) => {
+  const params = {
+    num: props.scene.num,
+    isObj: Number(
+      ![SceneType.SWSS, SceneType.SWYDSS].includes(props.scene.type)
+    ),
+  };
+  const res = await axios.get(checkHasDownload, { params });
+  const hideFloor = Number(res.data.downloadStatus) !== 3;
+
+  const sceneDownloadDialog = quiskMountFactory(SceneDownload, {
+    title: "场景离线包下载",
+    width: 500,
+    hideFloor: hideFloor,
+    enterText: "下 载",
+  });
+  return await sceneDownloadDialog(props);
+};