1
0

sceneDownload.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. <template>
  2. <!-- hideFloor: state === State.package -->
  3. <div>
  4. <div class="title">
  5. {{ stateTitle[state] }}
  6. </div>
  7. <div v-if="state === State.package">
  8. <div
  9. class="text"
  10. style="display: flex; justify-content: space-between; margin-top: 15px"
  11. >
  12. <span>{{ filename }}</span>
  13. <span>{{ percent }}%</span>
  14. </div>
  15. <div style="pointer-events: none">
  16. <el-slider v-model="percent" :show-tooltip="false" />
  17. </div>
  18. </div>
  19. <div v-else-if="state === State.readDown">
  20. <span>正在下载中……</span>
  21. </div>
  22. </div>
  23. </template>
  24. <script setup lang="ts">
  25. import { computed, onMounted, onUnmounted, ref } from "vue";
  26. import saveAs from "@/util/file-serve";
  27. import { checkHasDownload, getDownloadProcess, downloadScene, axios } from "@/request";
  28. import { ElLoading, ElMessage } from "element-plus";
  29. import { QuoteScene, SceneType } from "@/store/scene";
  30. import { QuiskExpose } from "@/helper/mount";
  31. const props = defineProps<{ scene: QuoteScene }>();
  32. enum State {
  33. uncreate,
  34. package,
  35. readDown,
  36. }
  37. const getState = (type: number) => {
  38. const stateTypes = [
  39. { codes: [0, 2], state: State.uncreate },
  40. { codes: [1], state: State.package },
  41. { codes: [3], state: State.readDown },
  42. ];
  43. return (
  44. stateTypes.find((stateType) => stateType.codes.includes(type))?.state ||
  45. State.uncreate
  46. );
  47. };
  48. const state = ref<State>(State.uncreate);
  49. const count = ref<number>(0);
  50. const filename = ref<string>(props.scene.title + ".zip");
  51. const downloadURL = ref<string>();
  52. const percent = ref(0);
  53. const stateTitle = {
  54. [State.uncreate]: "下载场景离线数据包,可在本地运行查看。",
  55. [State.package]: "正在打包场景离线数据",
  56. [State.readDown]: filename.value,
  57. };
  58. const params = {
  59. num: props.scene.num,
  60. isObj: Number(![SceneType.SWSS, SceneType.SWYDSS].includes(props.scene.type)),
  61. };
  62. // 初始化
  63. const initial = async () => {
  64. const res = await axios.get(checkHasDownload, { params });
  65. state.value = getState(res.data.downloadStatus);
  66. count.value = res.data.count;
  67. downloadURL.value = res.data.downloadUrl;
  68. if (state.value === State.uncreate) {
  69. const downRes = await axios.get(downloadScene, { params });
  70. state.value = getState(downRes.data.downloadStatus);
  71. // const unCountFlag =
  72. // count.value == 0 ||(await axios.get(downloadScene, { params })).data.downloadStatus !== 1;
  73. if (state.value === State.uncreate) {
  74. ElMessage.error("下载失败,请联系管理员");
  75. throw "暂无剩余下载次数";
  76. }
  77. }
  78. if (state.value === State.package) {
  79. await new Promise<void>((resolve) => requestUpdateURL(resolve));
  80. } else {
  81. downloadURL.value = res.data.downloadUrl;
  82. }
  83. };
  84. // 下载
  85. const download = () => {
  86. if (!downloadURL.value) {
  87. ElMessage.error("下载链接未生成,请稍等!");
  88. throw "下载链接未生成,请稍等!";
  89. } else {
  90. // if (!downloadURL.value.startsWith("/")) {
  91. downloadURL.value = downloadURL.value;
  92. // }
  93. console.error("downloadURL.value", downloadURL.value);
  94. return saveAs(downloadURL.value, filename.value);
  95. }
  96. };
  97. // 进度请求
  98. let timer: any;
  99. const requestUpdateURL = async (callback: () => void) => {
  100. const res = await axios.get(getDownloadProcess, { params });
  101. percent.value = parseInt(res.data.percent);
  102. downloadURL.value = res.data.url;
  103. if (downloadURL.value) {
  104. state.value = State.readDown;
  105. callback();
  106. } else {
  107. timer = setTimeout(() => requestUpdateURL(callback), 1000);
  108. }
  109. };
  110. onUnmounted(() => clearTimeout(timer));
  111. defineExpose<QuiskExpose>({
  112. submit: async () => {
  113. await initial();
  114. const loading = ElLoading.service({
  115. lock: true,
  116. text: "下载中",
  117. background: "rgba(255, 255, 255, 0.4)",
  118. });
  119. await download();
  120. loading.close();
  121. ElMessage.success("下载完成");
  122. },
  123. });
  124. </script>