Files
fe.ems.vue3/src/views/ne/neQuickSetup/components/StepActivate.vue
2024-04-16 19:37:37 +08:00

340 lines
9.3 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 setup lang="ts">
import { reactive, onMounted, toRaw, onUnmounted } from 'vue';
import { message, Modal, Upload } from 'ant-design-vue/lib';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { useClipboard } from '@vueuse/core';
import { FileType } from 'ant-design-vue/lib/upload/interface';
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
import { uploadFile } from '@/api/tool/file';
import {
codeNeLicense,
changeNeLicense,
stateNeLicense,
} from '@/api/ne/neLicense';
import useI18n from '@/hooks/useI18n';
import { stepState } from '../hooks/useStep';
import saveAs from 'file-saver';
const { copy } = useClipboard({ legacy: true });
const { t } = useI18n();
/**授权激活对象信息状态类型 */
type LicenseStateType = {
/**步骤 */
setp: 'license' | 'verify';
/**表单数据 */
from: {
neType: string;
neId: string;
activationRequestCode: string;
licensePath: string;
reload: boolean;
};
/**确定按钮 loading */
confirmLoading: boolean;
/**上传文件 */
uploadFiles: any[];
};
/**授权激活对象信息状态 */
const licenseState: LicenseStateType = reactive({
setp: 'license',
from: {
neType: '',
neId: '',
activationRequestCode: '',
licensePath: '',
reload: true,
},
confirmLoading: false,
uploadFiles: [],
});
/**表单上传前检查或转换压缩 */
function fnBeforeUploadFile(file: FileType) {
if (licenseState.confirmLoading) return false;
if (!file.name.endsWith('.ini')) {
message.error('只支持上传文件格式 .ini', 3);
return Upload.LIST_IGNORE;
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
message.error('文件必须小于2MB', 3);
return Upload.LIST_IGNORE;
}
return true;
}
/**表单上传文件 */
function fnUploadFile(up: UploadRequestOption) {
// 发送请求
const hide = message.loading(t('common.loading'), 0);
licenseState.confirmLoading = true;
let formData = new FormData();
formData.append('file', up.file);
formData.append('subPath', 'license');
uploadFile(formData)
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success('上传成功', 3);
// 改为完成状态
const file = licenseState.uploadFiles[0];
file.percent = 100;
file.status = 'done';
// 预置到表单
const { fileName } = res.data;
licenseState.from.licensePath = fileName;
} else {
message.error(res.msg, 3);
}
})
.finally(() => {
hide();
licenseState.confirmLoading = false;
});
}
/**复制授权申请码 */
function fnCopyCode() {
const code = licenseState.from.activationRequestCode;
if (!code) return;
copy(code).then(() => {
message.success('已成功复制', 3);
});
}
/**下载授权申请码文件 */
function fnDownCode() {
const { activationRequestCode, neType, neId } = licenseState.from;
if (!activationRequestCode) return;
Modal.confirm({
title: t('common.tipTitle'),
content: '确认将授权申请码下载为文件进行保存?',
onOk() {
const blob = new Blob([activationRequestCode], {
type: 'text/plain',
});
saveAs(blob, `${neType}_${neId}_code.txt`);
},
});
}
/**读取授权申请码 */
function fnGetCode() {
const { neType, neId } = licenseState.from;
licenseState.confirmLoading = true;
codeNeLicense(neType, neId).then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
licenseState.from.activationRequestCode = res.data;
licenseState.confirmLoading = false;
} else {
message.error(res.msg, 3);
}
});
}
/**启动服务验证 */
function fnRunCheck() {
if (licenseState.confirmLoading) return;
const form = toRaw(licenseState.from);
if (form.licensePath === '') {
message.error(t('common.errorFields', { num: 1 }), 3);
return;
}
licenseState.confirmLoading = true;
const hide = message.loading(t('common.loading'), 0);
changeNeLicense(form)
.then(res => {
if (res.code === RESULT_CODE_SUCCESS) {
message.success('网元开始进行校验', 3);
fnVerifyTask();
} else {
message.error(res.msg, 3);
}
})
.finally(() => {
hide();
licenseState.confirmLoading = false;
});
}
/**校验状态 */
const verifyState = reactive({
timer: null as any,
/**执行次数 */
count: 0,
/**信息日志 */
msgArr: [] as string[],
/**数据 sn expire */
data: null as any,
});
/**巡检校验任务 */
function fnVerifyTask() {
licenseState.setp = 'verify';
verifyState.timer = setInterval(() => {
if (verifyState.count > 15) {
clearTimeout(verifyState.timer);
verifyState.msgArr.unshift(
`${verifyState.count} 次:网元验证激活失败,请重新上传有效激活文件。`
);
return;
}
const { neType, neId } = licenseState.from;
stateNeLicense(neType, neId).then(res => {
if (res.code === RESULT_CODE_SUCCESS && res.data && res.data.sn) {
message.success(`${neType} ${neId} 网元激活成功`, 3);
verifyState.data = res.data;
// 记录当前步骤状态信息
stepState.states[stepState.current] = { from: res.data };
stepState.stepNext = true;
}
verifyState.count += 1;
verifyState.msgArr.unshift(`${verifyState.count} 次:${res.msg}`);
});
}, 2_000);
}
/**巡检重新校验 */
function fnVerifyTaskStop() {
clearTimeout(verifyState.timer);
verifyState.count = 0;
verifyState.msgArr = [];
licenseState.setp = 'license';
}
onMounted(() => {
// 读取步骤:网元信息
const stepPrevFrom = stepState.states[1].from;
const { neType, neId } = stepPrevFrom;
licenseState.from.neType = neType;
licenseState.from.neId = neId;
// 获取code
fnGetCode();
});
onUnmounted(() => {
clearTimeout(verifyState.timer);
});
</script>
<template>
<a-form
name="modalStateFrom"
layout="horizontal"
autocomplete="off"
:validate-on-rule-change="false"
:validateTrigger="[]"
:label-col="{ span: 3 }"
:wrapper-col="{ span: 12 }"
:label-wrap="true"
>
<div>---- 授权申请</div>
<template v-if="licenseState.setp === 'license'">
<a-form-item label="授权申请码" name="comment" :required="true">
<a-input-group compact>
<a-input
v-model:value="licenseState.from.activationRequestCode"
:disabled="true"
style="width: calc(100% - 64px)"
/>
<a-tooltip title="复制">
<a-button type="default" @click="fnCopyCode()">
<template #icon><CopyOutlined /></template>
</a-button>
</a-tooltip>
<a-tooltip title="下载">
<a-button type="primary" @click="fnDownCode()">
<template #icon><DownloadOutlined /></template>
</a-button>
</a-tooltip>
</a-input-group>
</a-form-item>
<a-form-item label="授权激活文件" name="file" :required="true">
<a-upload
name="file"
v-model:file-list="licenseState.uploadFiles"
accept=".ini"
list-type="text"
:max-count="1"
:show-upload-list="{
showPreviewIcon: false,
showRemoveIcon: false,
showDownloadIcon: false,
}"
:before-upload="fnBeforeUploadFile"
:custom-request="fnUploadFile"
:disabled="licenseState.confirmLoading"
>
<a-button type="default"> 上传文件 </a-button>
</a-upload>
</a-form-item>
<a-form-item name="check" :wrapper-col="{ span: 14, offset: 3 }">
<div style="align-items: center">
<a-button
type="primary"
shape="round"
@click="fnRunCheck()"
:loading="licenseState.confirmLoading"
>
<template #icon><LinkOutlined /></template>
授权校验
</a-button>
</div>
</a-form-item>
</template>
<div>---- 校验信息</div>
<template v-if="licenseState.setp === 'verify'">
<a-form-item
name="info"
label="巡检信息"
:label-col="{ span: 3 }"
:wrapper-col="{ span: 24 }"
:label-wrap="true"
>
<a-result
:status="verifyState.data ? 'success' : 'info'"
:title="verifyState.data ? '成功激活' : '请等待网元验证结果'"
>
<template #extra>
<a-button
@click="fnVerifyTaskStop()"
v-if="verifyState.data === null"
>
返回重新校验
</a-button>
</template>
<div class="verify-msg" v-if="verifyState.data === null">
<p
style="font-size: 16px"
v-for="(s, i) in verifyState.msgArr"
:key="i"
>
<close-circle-outlined :style="{ color: 'red' }" />
{{ s }}
</p>
</div>
<div v-else>
<p style="font-size: 16px">序列号{{ verifyState.data.sn }}</p>
<p style="font-size: 16px">
许可证到期时间{{ verifyState.data.expire }}
</p>
</div>
</a-result>
</a-form-item>
</template>
</a-form>
</template>
<style lang="less" scoped>
.verify-msg {
height: 200px;
overflow-y: auto;
}
</style>