浏览代码

feat: 添加预处理初始化任务的加载页面

Myon 2 年之前
父节点
当前提交
53fe1d5878

+ 1 - 1
frontend/quasar.conf.js

@@ -100,7 +100,7 @@ module.exports = configure((ctx) => ({
     // directives: [],
 
     // Quasar plugins
-    plugins: ['Dialog', 'Notify', 'AppFullscreen'],
+    plugins: ['Dialog', 'Notify', 'AppFullscreen', 'Loading'],
   },
 
   // animations: 'all', // --- includes all animations

+ 7 - 1
frontend/src/App.vue

@@ -6,6 +6,9 @@ import { getJobsStatus, systemState } from 'src/store/systemState';
 import useInterval from 'src/composables/use-interval';
 import { watch } from 'vue';
 import { userState } from 'src/store/userState';
+import { useAppStatusLoading } from 'src/composables/use-app-status-loading';
+
+const { startLoading } = useAppStatusLoading();
 
 const getSystemJobStatus = () => {
   if (userState.accessToken && systemState.systemInfo?.is_setup) {
@@ -19,8 +22,11 @@ useInterval(() => {
 
 watch(
   () => systemState.systemInfo?.is_setup,
-  () => {
+  (val) => {
     getSystemJobStatus();
+    if (val) {
+      startLoading();
+    }
   }
 );
 </script>

+ 1 - 1
frontend/src/api/SystemApi.js

@@ -3,6 +3,6 @@ import BaseApi from './BaseApi';
 class SystemApi extends BaseApi {
   getInfo = (params) => this.http('/system-status', params);
 
-  getStatus = (params) => this.http('/system/status', params);
+  getPrepareStatus = () => this.http('/pre-job', {}, 'POST');
 }
 export default new SystemApi();

+ 54 - 0
frontend/src/components/LoadingDialogAppPrepareError/LoadingDialogAppPrepareJobInit.vue

@@ -0,0 +1,54 @@
+<template>
+  <q-dialog ref="dialogRef" class="relative-position" persistent maximized transition-duration="0">
+    <q-card class="column full-height overflow-hidden">
+      <q-card-section class="bg-primary row items-center text-white">
+        <div class="col text-h6">初始化</div>
+      </q-card-section>
+
+      <q-card-section>
+        <div class="row items-center q-gutter-x-sm">
+          <q-spinner v-if="!isDone" color="primary" />
+          <q-icon v-else name="check_circle" color="primary" size="20px" />
+          <div class="text-h6">{{ prejobStatus.stage_name }}</div>
+        </div>
+        <div class="text-grey">{{ prejobStatus.now_process_info }}</div>
+      </q-card-section>
+
+      <q-card-section v-if="hasError" class="col column justify-center no-wrap">
+        <div class="text-bold">错误信息</div>
+        <pre class="col bg-grey-3 q-pa-sm q-ma-none overflow-auto">{{ prejobStatus.g_error_info }}</pre>
+        <template v-if="prejobStatus?.rename_err_results?.length">
+          <div class="text-bold q-mt-md">修改名称失败的字幕文件列表</div>
+          <pre class="col bg-grey-3 q-pa-sm q-ma-none overflow-auto">{{
+            prejobStatus.rename_err_results.join('\n')
+          }}</pre>
+        </template>
+      </q-card-section>
+
+      <q-card-section class="row justify-center" v-if="showCloseButton">
+        <q-btn color="negative" label="关闭" v-close-popup />
+      </q-card-section>
+    </q-card>
+  </q-dialog>
+</template>
+
+<script setup>
+import { useDialogPluginComponent } from 'quasar';
+import { computed, watch } from 'vue';
+import { systemState } from 'src/store/systemState';
+
+const { dialogRef } = useDialogPluginComponent();
+
+const prejobStatus = computed(() => systemState.preJobStatus);
+const isDone = computed(() => systemState.preJobStatus.is_done);
+const hasError = computed(
+  () => !!systemState.preJobStatus.g_error_info || systemState.preJobStatus.rename_err_results?.length > 0
+);
+const showCloseButton = computed(() => hasError.value);
+
+watch(isDone, (val) => {
+  if (val && !showCloseButton.value) {
+    dialogRef.value?.hide();
+  }
+});
+</script>

+ 54 - 25
frontend/src/composables/use-app-status-loading.js

@@ -1,36 +1,65 @@
 // 程序状态的hook接口
-import { Loading } from 'quasar';
+import { Dialog } from 'quasar';
 import SystemApi from 'src/api/SystemApi';
+import useInterval from 'src/composables/use-interval';
+import { computed, onBeforeUnmount, watch } from 'vue';
+import LoadingDialogAppPrepareJobInit from 'components/LoadingDialogAppPrepareError/LoadingDialogAppPrepareJobInit.vue';
+import { systemState } from 'src/store/systemState';
+
+let isPreJobLoadingDialogOpened = false;
+const openPreJobLoadingDialog = () => {
+  if (isPreJobLoadingDialogOpened) {
+    return;
+  }
+  isPreJobLoadingDialogOpened = true;
+  Dialog.create({
+    component: LoadingDialogAppPrepareJobInit,
+  }).onDismiss(() => {
+    isPreJobLoadingDialogOpened = false;
+  });
+};
 
 export const useAppStatusLoading = () => {
-  let timer = null;
+  const prepareStatus = computed(() => systemState.preJobStatus);
+
+  const updateDialog = () => {
+    if (prepareStatus.value?.is_done !== true) {
+      openPreJobLoadingDialog();
+    }
+  };
+
+  const getPrepareStatus = async () => {
+    const [res] = await SystemApi.getPrepareStatus();
+    systemState.preJobStatus = res;
+  };
+
+  const { resetInterval, stopInterval } = useInterval(
+    async () => {
+      await getPrepareStatus();
+      updateDialog();
+    },
+    1000,
+    false
+  );
 
   const startLoading = async () => {
-    Loading.show({
-      message: '正在应用程序配置',
-      html: true,
-    });
-
-    const sleep = (ms) =>
-      new Promise((resolve) => {
-        setTimeout(resolve, ms);
-      });
-    // 考虑保存配置后HTTP服务没有立即重启的情况,等待几秒再请求状态接口
-    await sleep(6000);
-
-    const handler = async () => {
-      const [res, err] = await SystemApi.getInfo();
-      if (res || err?.error?.status <= 401) {
-        clearInterval(timer);
-        Loading.hide();
+    await getPrepareStatus();
+    updateDialog();
+    resetInterval();
+  };
+
+  watch(
+    () => prepareStatus.value?.is_done,
+    (val) => {
+      if (val === true) {
+        stopInterval();
       }
-    };
+    }
+  );
 
-    timer = setInterval(async () => {
-      handler();
-    }, 1000);
-    handler();
-  };
+  onBeforeUnmount(() => {
+    stopInterval();
+  });
 
   return {
     startLoading,

+ 1 - 0
frontend/src/store/systemState.js

@@ -5,6 +5,7 @@ import JobApi from 'src/api/JobApi';
 export const systemState = reactive({
   systemInfo: null,
   jobStatus: null,
+  preJobStatus: null,
 });
 
 export const getInfo = async () => {