473 lines
12 KiB
Vue
473 lines
12 KiB
Vue
<script setup lang="ts">
|
|
import { reactive, onMounted, toRaw, watch } from 'vue';
|
|
import { message, Form, Upload, notification } from 'ant-design-vue/lib';
|
|
import useI18n from '@/hooks/useI18n';
|
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
|
import { NE_EXPAND_LIST, NE_TYPE_LIST } from '@/constants/ne-constants';
|
|
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
|
|
import {
|
|
addNeSoftware,
|
|
getNeSoftware,
|
|
updateNeSoftware,
|
|
} from '@/api/ne/neSoftware';
|
|
import { FileType } from 'ant-design-vue/lib/upload/interface';
|
|
import { uploadFileChunk } from '@/api/tool/file';
|
|
const { t } = useI18n();
|
|
const emit = defineEmits(['ok', 'cancel', 'update:visible']);
|
|
const props = defineProps({
|
|
visible: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
editId: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
});
|
|
|
|
/**对话框对象信息状态类型 */
|
|
type ModalStateType = {
|
|
/**新增框或修改框是否显示 */
|
|
visibleByEdit: boolean;
|
|
/**标题 */
|
|
title: string;
|
|
/**表单数据 */
|
|
from: {
|
|
id: string;
|
|
neType: string;
|
|
name: string;
|
|
path: string;
|
|
version: string;
|
|
description: string;
|
|
};
|
|
/**确定按钮 loading */
|
|
confirmLoading: boolean;
|
|
/**上传文件 */
|
|
uploadFiles: any[];
|
|
/**上传文件-依赖包 */
|
|
uploadFilesDep: any[];
|
|
};
|
|
|
|
/**对话框对象信息状态 */
|
|
let modalState: ModalStateType = reactive({
|
|
visibleByEdit: false,
|
|
title: '软件包文件',
|
|
from: {
|
|
id: '',
|
|
neType: '',
|
|
name: '',
|
|
path: '',
|
|
version: '',
|
|
description: '',
|
|
},
|
|
confirmLoading: false,
|
|
uploadFiles: [],
|
|
uploadFilesDep: [],
|
|
});
|
|
|
|
/**对话框内表单属性和校验规则 */
|
|
const modalStateFrom = Form.useForm(
|
|
modalState.from,
|
|
reactive({
|
|
neType: [
|
|
{
|
|
required: true,
|
|
min: 1,
|
|
max: 32,
|
|
message: t('views.ne.common.neTypePlease'),
|
|
},
|
|
],
|
|
version: [
|
|
{
|
|
required: true,
|
|
min: 1,
|
|
max: 64,
|
|
message: t('views.ne.neSoftware.versionPlease'),
|
|
},
|
|
],
|
|
path: [
|
|
{
|
|
required: true,
|
|
message: t('views.ne.neSoftware.pathPlease'),
|
|
},
|
|
],
|
|
})
|
|
);
|
|
|
|
/**
|
|
* 对话框弹出确认执行函数
|
|
* 进行表达规则校验
|
|
*/
|
|
function fnModalOk() {
|
|
if (modalState.confirmLoading) return;
|
|
modalStateFrom
|
|
.validate()
|
|
.then(e => {
|
|
modalState.confirmLoading = true;
|
|
const hide = message.loading(t('common.loading'), 0);
|
|
const from = toRaw(modalState.from);
|
|
|
|
// 安装带依赖包
|
|
if (modalState.uploadFilesDep.length > 0) {
|
|
const depFiles = [];
|
|
for (const depFile of modalState.uploadFilesDep) {
|
|
if (depFile.status === 'done' && depFile.path) {
|
|
depFiles.push(depFile.path);
|
|
}
|
|
}
|
|
depFiles.push(from.path);
|
|
from.path = depFiles.join(',');
|
|
}
|
|
|
|
const software = from.id ? updateNeSoftware(from) : addNeSoftware(from);
|
|
software.then(res => {
|
|
if (res.code === RESULT_CODE_SUCCESS) {
|
|
message.success({
|
|
content: t('common.operateOk'),
|
|
duration: 3,
|
|
});
|
|
// 返回无引用信息
|
|
emit('ok', JSON.parse(JSON.stringify(from)));
|
|
fnModalCancel();
|
|
} else {
|
|
message.error({
|
|
content: `${res.msg}`,
|
|
duration: 3,
|
|
});
|
|
}
|
|
hide();
|
|
modalState.confirmLoading = false;
|
|
});
|
|
})
|
|
.catch(e => {
|
|
message.error(t('common.errorFields', { num: e.errorFields.length }), 3);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 对话框弹出关闭执行函数
|
|
* 进行表达规则校验
|
|
*/
|
|
function fnModalCancel() {
|
|
modalState.visibleByEdit = false;
|
|
modalState.confirmLoading = false;
|
|
modalStateFrom.resetFields();
|
|
modalState.uploadFiles = [];
|
|
modalState.uploadFilesDep = [];
|
|
emit('cancel');
|
|
emit('update:visible', false);
|
|
}
|
|
|
|
/**表单上传前检查或转换压缩 */
|
|
function fnBeforeUploadFile(file: FileType) {
|
|
if (modalState.confirmLoading) return false;
|
|
const fileName = file.name;
|
|
const suff = fileName.substring(fileName.lastIndexOf('.'));
|
|
if (!['.deb', '.rpm'].includes(suff)) {
|
|
message.error(
|
|
t('views.configManage.softwareManage.onlyAble', {
|
|
fileText: '(.deb、.rpm)',
|
|
}),
|
|
3
|
|
);
|
|
return Upload.LIST_IGNORE;
|
|
}
|
|
|
|
// 取网元类型判断是否支持
|
|
let neType = '';
|
|
const neTypeIndex = fileName.indexOf('-');
|
|
if (neTypeIndex !== -1) {
|
|
neType = fileName.substring(0, neTypeIndex).toUpperCase();
|
|
}
|
|
// 主包类型
|
|
if (!NE_TYPE_LIST.includes(neType)) {
|
|
notification.warning({
|
|
message: fileName,
|
|
description: t('views.ne.neSoftware.fileCheckType'),
|
|
});
|
|
return Upload.LIST_IGNORE;
|
|
}
|
|
modalState.from.neType = neType;
|
|
|
|
// 根据给定的软件名取版本号 ims-r2.2312.x-ub22.deb
|
|
const matches = fileName.match(/([0-9.]+[0-9x]+)/);
|
|
if (matches) {
|
|
modalState.from.version = matches[0];
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**表单上传文件 */
|
|
function fnUploadFile(up: UploadRequestOption) {
|
|
const uploadFile = modalState.uploadFiles.find(
|
|
item => item.uid === (up.file as any).uid
|
|
);
|
|
if (!uploadFile) return;
|
|
|
|
// 发送请求
|
|
uploadFileChunk(up.file as File, 5, 'software')
|
|
.then(res => {
|
|
if (res.code === RESULT_CODE_SUCCESS) {
|
|
// 改为完成状态
|
|
uploadFile.percent = 100;
|
|
uploadFile.status = 'done';
|
|
uploadFile.path = res.data.fileName;
|
|
// 预置到表单
|
|
const { fileName, originalFileName } = res.data;
|
|
modalState.from.name = originalFileName;
|
|
modalState.from.path = fileName;
|
|
} else {
|
|
message.error(res.msg, 3);
|
|
}
|
|
})
|
|
.catch(error => {
|
|
uploadFile.percent = 0;
|
|
uploadFile.status = 'error';
|
|
uploadFile.response = error.message;
|
|
})
|
|
.finally(() => {
|
|
modalState.confirmLoading = false;
|
|
});
|
|
}
|
|
|
|
/**表单上传前检查或转换压缩-依赖包 */
|
|
function fnBeforeUploadFileDep(file: FileType) {
|
|
if (modalState.confirmLoading) return false;
|
|
const fileName = file.name;
|
|
const suff = fileName.substring(fileName.lastIndexOf('.'));
|
|
if (!['.deb', '.rpm'].includes(suff)) {
|
|
message.error(
|
|
t('views.configManage.softwareManage.onlyAble', {
|
|
fileText: '(.deb、.rpm)',
|
|
}),
|
|
3
|
|
);
|
|
return Upload.LIST_IGNORE;
|
|
}
|
|
|
|
// 已存在同名文件
|
|
const hasItem = modalState.uploadFilesDep.find(
|
|
item => item.name === fileName
|
|
);
|
|
if (hasItem) {
|
|
notification.warning({
|
|
message: fileName,
|
|
description: t('views.ne.neSoftware.fileNameExists'),
|
|
});
|
|
return Upload.LIST_IGNORE;
|
|
}
|
|
|
|
// 取网元类型判断是否支持
|
|
let neType = '';
|
|
const neTypeIndex = fileName.indexOf('-');
|
|
if (neTypeIndex !== -1) {
|
|
neType = fileName.substring(0, neTypeIndex).toUpperCase();
|
|
}
|
|
// 依赖包类型
|
|
if (!NE_EXPAND_LIST.includes(neType)) {
|
|
notification.warning({
|
|
message: fileName,
|
|
description: t('views.ne.neSoftware.fileCheckTypeDep'),
|
|
});
|
|
return Upload.LIST_IGNORE;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**表单上传文件-依赖包 */
|
|
function fnUploadFileDep(up: UploadRequestOption) {
|
|
const uploadFile = modalState.uploadFilesDep.find(
|
|
item => item.uid === (up.file as any).uid
|
|
);
|
|
if (!uploadFile) return;
|
|
|
|
// 发送请求
|
|
uploadFileChunk(up.file as File, 5, 'software')
|
|
.then(res => {
|
|
if (res.code === RESULT_CODE_SUCCESS) {
|
|
// 改为完成状态
|
|
uploadFile.percent = 100;
|
|
uploadFile.status = 'done';
|
|
uploadFile.path = res.data.fileName;
|
|
} else {
|
|
message.error(res.msg, 3);
|
|
}
|
|
})
|
|
.catch(error => {
|
|
uploadFile.percent = 0;
|
|
uploadFile.status = 'error';
|
|
uploadFile.response = error.message;
|
|
})
|
|
.finally(() => {
|
|
modalState.confirmLoading = false;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 对话框弹出显示为 新增或者修改
|
|
* @param id id
|
|
*/
|
|
function fnModalVisibleByEdit(id?: string) {
|
|
if (id) {
|
|
const hide = message.loading(t('common.loading'), 0);
|
|
getNeSoftware(id)
|
|
.then(res => {
|
|
if (res.code === RESULT_CODE_SUCCESS) {
|
|
Object.assign(modalState.from, res.data);
|
|
modalState.title = t('views.ne.neSoftware.uploadTitle');
|
|
modalState.visibleByEdit = true;
|
|
} else {
|
|
message.error(res.msg, 3);
|
|
}
|
|
})
|
|
.finally(() => {
|
|
modalState.confirmLoading = false;
|
|
hide();
|
|
});
|
|
|
|
return;
|
|
}
|
|
modalState.title = t('views.ne.neSoftware.uploadTitle');
|
|
modalState.visibleByEdit = true;
|
|
}
|
|
|
|
/**监听是否显示,初始数据 */
|
|
watch(
|
|
() => props.visible,
|
|
val => {
|
|
if (val) fnModalVisibleByEdit(props.editId);
|
|
}
|
|
);
|
|
|
|
onMounted(() => {});
|
|
</script>
|
|
|
|
<template>
|
|
<ProModal
|
|
:drag="true"
|
|
:width="650"
|
|
:destroyOnClose="true"
|
|
:keyboard="false"
|
|
:mask-closable="false"
|
|
:visible="modalState.visibleByEdit"
|
|
:title="modalState.title"
|
|
:confirm-loading="modalState.confirmLoading"
|
|
@ok="fnModalOk"
|
|
@cancel="fnModalCancel"
|
|
>
|
|
<a-form
|
|
name="modalStateFrom"
|
|
layout="horizontal"
|
|
:wrapper-col="{ span: 16 }"
|
|
:label-col="{ span: 8 }"
|
|
:labelWrap="true"
|
|
>
|
|
<template v-if="modalState.from.id === ''">
|
|
<a-form-item
|
|
:label="t('views.ne.neSoftware.path')"
|
|
:help="t('views.ne.neSoftware.uploadFileName')"
|
|
name="file"
|
|
v-bind="modalStateFrom.validateInfos.path"
|
|
>
|
|
<a-upload
|
|
name="file"
|
|
v-model:file-list="modalState.uploadFiles"
|
|
accept=".rpm,.deb"
|
|
list-type="text"
|
|
:max-count="1"
|
|
:show-upload-list="{
|
|
showPreviewIcon: false,
|
|
showRemoveIcon: false,
|
|
showDownloadIcon: false,
|
|
}"
|
|
:before-upload="fnBeforeUploadFile"
|
|
:custom-request="fnUploadFile"
|
|
:disabled="modalState.confirmLoading"
|
|
>
|
|
<a-button type="primary">
|
|
<template #icon>
|
|
<UploadOutlined />
|
|
</template>
|
|
{{ t('views.ne.neSoftware.upload') }}
|
|
</a-button>
|
|
</a-upload>
|
|
</a-form-item>
|
|
|
|
<a-form-item
|
|
name="dep"
|
|
:label="t('views.ne.neSoftware.dependFile')"
|
|
:help="t('views.ne.neSoftware.dependFileTip')"
|
|
>
|
|
<a-upload
|
|
name="file"
|
|
v-model:file-list="modalState.uploadFilesDep"
|
|
accept=".rpm,.deb"
|
|
list-type="text"
|
|
:multiple="true"
|
|
:max-count="5"
|
|
:show-upload-list="{
|
|
showPreviewIcon: false,
|
|
showRemoveIcon: true,
|
|
showDownloadIcon: false,
|
|
}"
|
|
:before-upload="fnBeforeUploadFileDep"
|
|
:custom-request="fnUploadFileDep"
|
|
:disabled="modalState.confirmLoading"
|
|
>
|
|
<a-button type="dashed">
|
|
<template #icon>
|
|
<UploadOutlined />
|
|
</template>
|
|
{{ t('views.ne.neSoftware.upload') }}
|
|
</a-button>
|
|
</a-upload>
|
|
</a-form-item>
|
|
</template>
|
|
|
|
<a-form-item
|
|
:label="t('views.ne.common.neType')"
|
|
name="neType"
|
|
v-bind="modalStateFrom.validateInfos.neType"
|
|
>
|
|
<a-auto-complete
|
|
v-model:value="modalState.from.neType"
|
|
:options="NE_TYPE_LIST.map(v => ({ value: v }))"
|
|
:disabled="modalState.from.id !== ''"
|
|
>
|
|
<a-input
|
|
allow-clear
|
|
:placeholder="t('common.inputPlease')"
|
|
:maxlength="32"
|
|
:disabled="modalState.from.id !== ''"
|
|
>
|
|
</a-input>
|
|
</a-auto-complete>
|
|
</a-form-item>
|
|
|
|
<a-form-item
|
|
:label="t('views.ne.neSoftware.version')"
|
|
name="version"
|
|
v-bind="modalStateFrom.validateInfos.version"
|
|
>
|
|
<a-input
|
|
v-model:value="modalState.from.version"
|
|
allow-clear
|
|
:placeholder="t('common.inputPlease')"
|
|
></a-input>
|
|
</a-form-item>
|
|
|
|
<a-form-item :label="t('common.description')" name="description">
|
|
<a-textarea
|
|
v-model:value="modalState.from.description"
|
|
:maxlength="500"
|
|
:show-count="true"
|
|
:placeholder="t('common.inputPlease')"
|
|
/>
|
|
</a-form-item>
|
|
</a-form>
|
|
</ProModal>
|
|
</template>
|
|
|
|
<style lang="less" scoped></style>
|