|
@@ -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>
|
|
|
+
|