Files
agt-web/apps/web-antd/src/views/license/license/generate/index.vue
2025-08-04 10:22:21 +08:00

159 lines
3.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script lang="ts" setup>
import type { LicenseApi } from '#/api/license/license';
import { onBeforeUnmount, ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useAccess } from '@vben/access';
import { Page } from '@vben/common-ui';
import { useTabs } from '@vben/hooks';
import { downloadFileFromBlobPart } from '@vben/utils';
import { Button, message } from 'ant-design-vue';
import { generateLicense, getLicense } from '#/api/license/license';
import { $t } from '#/locales';
import Detail from '../components/detail.vue';
const { hasAccessByCodes } = useAccess();
const route = useRoute();
const router = useRouter();
const loading = ref(false);
const formData = ref<LicenseApi.License>();
// 定时器引用
let checkInterval: null | number = null;
let timeoutTimer: null | number = null;
/** 获取详情数据 */
async function getDetail(id: any) {
if (!id) {
return;
}
loading.value = true;
try {
const details = await getLicense(id);
formData.value = details;
} finally {
loading.value = false;
}
return formData.value;
}
const tabs = useTabs();
/** 返回列表 */
function close() {
tabs.closeCurrentTab();
router.push('/license');
}
/** 生成文件 */
async function onGenerate() {
if (!formData.value?.id) {
return;
}
const hideLoading = message.loading({
content: $t('license.generating'),
duration: 0,
key: 'action_process_msg',
});
await generateLicense(formData.value.id);
// 设置超时3分钟
timeoutTimer = window.setTimeout(() => {
stopProcess(hideLoading);
}, 180_000);
// 首次立即检查
await checkStatus(hideLoading);
// 设置定期检查每5秒
checkInterval = window.setInterval(async () => {
await checkStatus(hideLoading);
}, 5000);
}
const checkStatus = async (hideLoading: () => void) => {
if (!formData.value?.id) {
return;
}
const result = await getDetail(formData.value.id);
if (result?.status === 3) {
message.success($t('license.generateSuccess'));
stopProcess(hideLoading);
}
};
// 停止处理流程
const stopProcess = (hideLoading: () => void): void => {
if (checkInterval) clearInterval(checkInterval);
if (timeoutTimer) clearTimeout(timeoutTimer);
hideLoading();
// 重置定时器引用
checkInterval = null;
timeoutTimer = null;
};
/** 下载License */
async function onDownload() {
if (!formData.value?.fileUrl) {
return;
}
const fileName = `${formData.value.fileUrl?.slice(
Math.max(0, formData.value.fileUrl.lastIndexOf('/') + 1),
formData.value.fileUrl.lastIndexOf('_'),
)}.zip`;
const res = await fetch(formData.value.fileUrl);
if (!res.ok) {
message.error($t('license.downloadFailed'));
return;
}
const blob = await res.blob();
downloadFileFromBlobPart({ fileName, source: blob });
}
// 组件卸载前清理
onBeforeUnmount(() => {
if (checkInterval) clearInterval(checkInterval);
if (timeoutTimer) clearTimeout(timeoutTimer);
});
// 初始化
getDetail(route.query.id);
</script>
<template>
<Page auto-content-height v-loading="loading">
<div class="bg-card flex h-[100%] flex-col rounded-md p-4">
<Detail :form-data="formData" />
<div class="mt-4 flex justify-center space-x-2">
<Button @click="close"> {{ $t('common.back') }}</Button>
<Button
v-if="
hasAccessByCodes(['license:license:generate']) &&
(formData?.status === 1 || formData?.status === 4)
"
type="primary"
:loading="loading"
@click="onGenerate"
>
{{ $t('license.generate') }}
</Button>
<Button
v-if="formData?.status === 3"
type="primary"
:loading="loading"
@click="onDownload"
>
{{ $t('license.downloadAll') }}
</Button>
</div>
</div>
</Page>
</template>