340 lines
9.3 KiB
Vue
340 lines
9.3 KiB
Vue
<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>
|