master
李小林 10 months ago
parent e96599b411
commit 20f28f2a55
  1. 55
      src/api/device-type-ver/index.ts
  2. 1
      src/api/device-type-ver/types.ts
  3. 8
      src/api/domain/index.ts
  4. 5
      src/api/domain/types.ts
  5. 34
      src/api/file/index.ts
  6. 13
      src/api/file/types.ts
  7. 2
      src/api/type-ver-ext/index.ts
  8. 73
      src/views/resources/device-type/components/AddDomianTree.vue
  9. 113
      src/views/resources/device-type/components/AddVendorProfile.vue
  10. 2
      src/views/resources/device-type/components/DeviceTypeToVer.vue
  11. 174
      src/views/resources/device-type/components/DeviceTypeVersionEdit.vue

@ -2,9 +2,12 @@ import {
DeviceTypeToVerPageResult,
DeviceTypeToVerQuery,
DeviceTypeVerForm,
GroupNamePageResult,
} from "@/api/device-type-ver/types";
import request from "@/utils/request";
import { AxiosPromise } from "axios";
import { VendorProfile } from "@/api/file/types";
import { FileListVO } from "@/api/file-list/types";
export function deviceTypeToVerPage(
data: DeviceTypeToVerQuery
@ -67,3 +70,55 @@ export function editDevTypeVerForm(data: DeviceTypeVerForm) {
data,
});
}
export function addVendorProfile(data: VendorProfile) {
return request({
url: "/api/device-type-ver/v1/add-vendor-profile",
method: "POST",
data,
});
}
export function listVendorProfile(
typeAndVerId: number
): AxiosPromise<FileListVO[]> {
return request({
url: `/api/device-type-ver/v1/list-vendor-profile/${typeAndVerId}`,
method: "GET",
});
}
export function deleteVendorProfile(
typeAndVerId: number,
fileId: number
): AxiosPromise<FileListVO[]> {
return request({
url: `/api/device-type-ver/v1/delete-vendor-profile/${fileId}/${typeAndVerId}`,
method: "DELETE",
});
}
export function pageSysDomain(
data: PageQuery,
typeAndVerId: number
): AxiosPromise<GroupNamePageResult> {
return request({
url: `/api/device-type-ver/v1/page-sys-domain/${typeAndVerId}`,
method: "GET",
params: {
pageNum: data.pageNum,
pageSize: data.pageSize,
},
});
}
export function listVerDomain(typeAndVerId: number): AxiosPromise<number[]> {
return request({
url: `/api/device-type-ver/v1/list-ver-domain/${typeAndVerId}`,
method: "GET",
});
}
export function editVerDomain(typeAndVerId: number, data: number[]) {
return request({
url: `/api/device-type-ver/v1/edit-ver-domain/${typeAndVerId}`,
method: "POST",
data,
});
};

@ -31,3 +31,4 @@ export interface DeviceTypeVerForm {
specVer?: string;
}
export type GroupNamePageResult = PageResult<string[]>;

@ -1,4 +1,4 @@
import { DomainForm, DomainQuery, DomainVo } from "@/api/domain/types";
import { DomainForm, DomainOption, DomainQuery, DomainVo } from "@/api/domain/types";
import request from "@/utils/request";
import { AxiosPromise } from "axios";
@ -47,3 +47,9 @@ export function getDomainByGroupId(groupId: number): AxiosPromise<DomainForm> {
method: "GET",
});
}
export function transferOption(): AxiosPromise<DomainOption[]> {
return request({
url: `/api/domain/v1/transfer-option`,
method: "GET",
});
}

@ -27,3 +27,8 @@ export interface DomainForm {
description?: string;
}
export interface DomainOption {
key: ?number;
label?: string;
}

@ -1,17 +1,27 @@
import request from "@/utils/request";
import { AxiosPromise } from "axios";
import { FileInfo } from "./types";
/**
*
*
* @param file
*
* @param fileId
*/
export function uploadFileApi(file: File): AxiosPromise<string> {
export function downloadFileApi(fileId: number) {
return request({
url: `/api/file-option/v1/download/${fileId}`,
method: "GET",
responseType: "blob",
});
}
export function uploadApi(
file: any,
fileName?: string,
fileType?: string
): AxiosPromise<string> {
const formData = new FormData();
formData.append("file", file);
return request({
url: "/api/file-option/v1/upload",
url: `/api/file-option/v1/upload/${fileName}/${fileType}`,
method: "POST",
data: formData,
headers: {
@ -19,15 +29,3 @@ export function uploadFileApi(file: File): AxiosPromise<string> {
},
});
}
/**
*
* @param fileId
*/
export function downloadFileApi(fileId: number) {
return request({
url: `/api/file-option/v1/download/${fileId}`,
method: "GET",
responseType: "blob",
});
}

@ -5,3 +5,16 @@ export interface FileInfo {
name: string;
url: string;
}
export interface VendorProfile {
typeAndVerId?:number;
fileName?: string;
fileDesc?: string;
fileType?: string;
fileUrl?: string;
}

@ -3,7 +3,7 @@ import { CapabilityForm } from "@/api/type-ver-ext/types";
import request from "@/utils/request";
export function getCapabilityForm(
typeAndVerId: string
typeAndVerId: number
): AxiosPromise<CapabilityForm> {
return request({
url: `/api/type-ver-ext/v1/${typeAndVerId}`,

@ -0,0 +1,73 @@
<template>
<el-dialog
class="com-dialog"
v-model="openDomainTreeFlag"
title="新增设备类型软件版本系统管理域"
>
<div style="display: flex; justify-content: center">
<el-transfer
:titles="['可选系统管理域', '已选系统管理域']"
v-model="target"
:data="resource"
v-loading="loading"
/>
</div>
<template #footer>
<el-button type="primary" @click="submit">确定</el-button>
<el-button>取消</el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { transferOption } from "@/api/domain";
import { DomainOption } from "@/api/domain/types";
import { editVerDomain, listVerDomain } from "@/api/device-type-ver";
const loading = ref<boolean>(false);
const openDomainTreeFlag = ref<boolean>(false);
const typeAndVerId = ref<number>(0);
const openDomainTree = (typeAndVerId_?: number) => {
openDomainTreeFlag.value = true;
typeAndVerId.value = typeAndVerId_;
loadResource();
loadTarget();
};
defineExpose({ openDomainTree });
const loadResource = async () => {
loading.value = true;
await transferOption()
.then(({ data }) => {
resource.value = data;
})
.finally(() => {
loading.value = false;
});
};
const loadTarget = async () => {
loading.value = true;
await listVerDomain(typeAndVerId.value)
.then(({ data }) => {
target.value = data;
})
.finally(() => {
loading.value = false;
});
};
const resource = ref<DomainOption[]>([]);
const target = ref<number[]>([]);
const emit = defineEmits(["success"]);
const submit = () => {
loading.value = true;
editVerDomain(typeAndVerId.value, target.value)
.then(() => {
emit("success");
openDomainTreeFlag.value = false;
})
.finally(() => {
loading.value = false;
});
};
</script>
<style scoped></style>

@ -0,0 +1,113 @@
<template>
<el-dialog
class="com-dialog"
v-model="vendorProfileFlag"
align-center
title="新增厂商配置文件信息"
>
<el-form
ref="addVendorProfileRef"
v-loading="loading"
:rules="rules"
:model="formData"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="厂商配置文件名称" prop="fileName">
<el-input v-model="formData.fileName" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="厂商配置文件描述信息">
<el-input v-model="formData.fileDesc" type="textarea" :rows="1" />
</el-form-item>
</el-col>
</el-row>
<el-upload
drag
action="#"
:limit="1"
:auto-upload="false"
v-model:file-list="fileList"
>
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">拖拽上传 <em>点击上传</em></div>
</el-upload>
</el-form>
<template #footer>
<el-button type="primary" @click="handleUpload(addVendorProfileRef)"
>保存</el-button
>
<el-button>取消</el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { UploadFilled } from "@element-plus/icons-vue";
import { VendorProfile } from "@/api/file/types";
import { FormInstance, FormRules, UploadUserFile } from "element-plus";
import { uploadApi } from "@/api/file";
import { addVendorProfile } from "@/api/device-type-ver";
const loading = ref<boolean>(false);
const vendorProfileFlag = ref<boolean>(false);
const addVendorProfileRef = ref();
const fileList = ref<UploadUserFile[]>([]);
const formData = ref<VendorProfile>({
fileType: "1",
});
const open = (typeAndVerId?: number) => {
resetForm(addVendorProfileRef.value);
fileList.value = [];
formData.value = {
fileType: "1",
};
vendorProfileFlag.value = true;
formData.value.typeAndVerId = typeAndVerId;
};
defineExpose({ open });
const rules = reactive<FormRules<VendorProfile>>({
fileName: [{ required: true, message: "请填写文件名称", trigger: "blur" }],
});
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return;
formEl.resetFields();
};
const emit = defineEmits(["success"]);
const handleUpload = async (formEl: FormInstance | undefined) => {
if (fileList.value.length === 0) {
ElMessage.error("请选择文件上传");
return;
}
if (!formEl) return;
await formEl.validate((valid, fields) => {
if (valid) {
loading.value = true;
const file = fileList.value[0].raw;
const dotIndex: any = file?.name.lastIndexOf(".");
if (dotIndex === -1) {
ElMessage.error("文件没有后缀,无法上传");
return;
}
const fileName = formData.value.fileName;
const fileType = formData.value.fileType;
formData.value.fileName =
fileName + "." + file?.name.substring(dotIndex + 1);
uploadApi(file, fileName, fileType)
.then(({ data }) => {
formData.value.fileUrl = data;
addVendorProfile(formData.value).then(() => {
emit("success");
vendorProfileFlag.value = false;
});
})
.finally(() => {
loading.value = false;
});
}
});
};
</script>
<style scoped></style>

@ -269,7 +269,7 @@ const handleDelVerFile = (row: any) => {
type: "warning",
}).then(() => {
loading.value = true;
deleteDeviceTypeVersionFile(row.row.typeAndVerId, fileId)
deleteDeviceTypeVersionFile(row.typeAndVerId, fileId)
.then(() => {
loadDeviceTypeToVerPage();
})

@ -205,7 +205,11 @@
</el-form>
<div class="mt-4">
<div class="capability">
<el-form :model="capabilityForm" ref="capabilityFormRef" v-loading="loadingCapability">
<el-form
:model="capabilityForm"
ref="capabilityFormRef"
v-loading="loadingCapability"
>
<el-descriptions title="设备能力信息" :column="2" border>
<template #extra>
<el-button @click="submitCapabilityForm" type="primary"
@ -220,7 +224,7 @@
class-name="my-content"
width="180px"
>
<el-form-item prop="lanNumber">
<el-form-item prop="lanNumber" style="margin-bottom: 0">
<dictionary
v-model="capabilityForm.lanNumber"
type-code="lan_number"
@ -235,7 +239,7 @@
class-name="my-content"
width="180px"
>
<el-form-item prop="voipPortNumber">
<el-form-item prop="voipPortNumber" style="margin-bottom: 0">
<dictionary
v-model="capabilityForm.voipPortNumber"
type-code="voip_port_number"
@ -250,7 +254,7 @@
class-name="my-content"
width="180px"
>
<el-form-item prop="gePortNumber">
<el-form-item prop="gePortNumber" style="margin-bottom: 0">
<dictionary
v-model="capabilityForm.gePortNumber"
type-code="ge_port_number"
@ -265,7 +269,7 @@
class-name="my-content"
width="180px"
>
<el-form-item prop="fePortNumber">
<el-form-item prop="fePortNumber" style="margin-bottom: 0">
<dictionary
v-model="capabilityForm.fePortNumber"
type-code="fe_port_number"
@ -280,7 +284,7 @@
class-name="my-content"
width="180px"
>
<el-form-item prop="wifiType">
<el-form-item prop="wifiType" style="margin-bottom: 0">
<dictionary
v-model="capabilityForm.wifiType"
type-code="wifi_type"
@ -295,7 +299,7 @@
class-name="my-content"
width="180px"
>
<el-form-item prop="wifiConfig">
<el-form-item prop="wifiConfig" style="margin-bottom: 0">
<dictionary
v-model="capabilityForm.wifiConfig"
type-code="wifi_config"
@ -310,7 +314,7 @@
class-name="my-content"
width="180px"
>
<el-form-item prop="voipProtocol">
<el-form-item prop="voipProtocol" style="margin-bottom: 0">
<dictionary
v-model="capabilityForm.voipProtocol"
type-code="voip_protocol"
@ -325,7 +329,7 @@
class-name="my-content"
width="180px"
>
<el-form-item prop="capability">
<el-form-item prop="capability" style="margin-bottom: 0">
<dictionary
v-model="capabilityForm.capability"
type-code="capability"
@ -340,7 +344,7 @@
class-name="my-content"
width="180px"
>
<el-form-item prop="mesh">
<el-form-item prop="mesh" style="margin-bottom: 0">
<dictionary
v-model="capabilityForm.mesh"
type-code="mesh"
@ -355,7 +359,7 @@
class-name="my-content"
width="180px"
>
<el-form-item prop="ywg">
<el-form-item prop="ywg" style="margin-bottom: 0">
<dictionary v-model="capabilityForm.ywg" type-code="ywg" />
</el-form-item>
</el-descriptions-item>
@ -367,7 +371,7 @@
class-name="my-content"
width="180px"
>
<el-form-item prop="tr143">
<el-form-item prop="tr143" style="margin-bottom: 0">
<dictionary
v-model="capabilityForm.tr143"
type-code="tr143"
@ -382,7 +386,7 @@
class-name="my-content"
width="180px"
>
<el-form-item prop="ipv6Enable">
<el-form-item prop="ipv6Enable" style="margin-bottom: 0">
<dictionary
v-model="capabilityForm.ipv6Enable"
type-code="ipv6_enable"
@ -397,7 +401,7 @@
class-name="my-content"
width="180px"
>
<el-form-item prop="reboot">
<el-form-item prop="reboot" style="margin-bottom: 0">
<dictionary
v-model="capabilityForm.reboot"
type-code="reboot"
@ -416,21 +420,108 @@
</el-form>
</div>
</div>
<div class="mt-4">
<div style="display: flex; justify-content: space-between">
<div style="font-weight: 700">
设备类型及设备软件版本支持的设备厂商配置文件列表
</div>
<div>
<el-button type="primary" @click="openVendorProfile"
><i-ep-plus />增加厂商配置文件</el-button
>
</div>
</div>
<div class="any-table mt-4">
<el-table :data="fileListVOList" v-loading="loadingVendorProfile">
<el-table-column
label="厂商配置文件"
prop="fileName"
align="center"
/>
<el-table-column
label="文件创建时间"
prop="fileCreateTime"
align="center"
/>
<el-table-column
label="文件描述内容"
prop="fileDesc"
align="center"
/>
<el-table-column label="操作" align="center">
<template #default="scope">
<el-popconfirm
confirm-button-text="Yes"
cancel-button-text="No"
:icon="InfoFilled"
width="200"
icon-color="#626AEF"
title="确认删除该文件吗?"
@confirm="handleDeleteFile(scope.row.fileId)"
>
<template #reference>
<el-button type="danger" link><i-ep-delete /></el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
</div>
</div>
<div class="mt-4">
<div style="display: flex; justify-content: space-between">
<div style="font-weight: 700">已绑定系统管理域</div>
<div>
<el-button type="primary" @click="openDomainTree"
><i-ep-plus />增加系统管理域</el-button
>
</div>
</div>
<div class="any-table mt-4">
<el-table
:data="domainNames"
v-loading="loadingDomain"
max-height="200"
>
<el-table-column label="系统管理域" align="center">
<template #default="scope">{{ scope.row }}</template>
</el-table-column>
</el-table>
<pagination
v-if="domainTotal > 0"
v-model:total="domainTotal"
v-model:page="domainQuery.pageNum"
v-model:limit="domainQuery.pageSize"
@pagination="loadDomainPage"
/>
</div>
</div>
</el-scrollbar>
</el-card>
<add-vendor-profile
ref="vendorProfileRef"
@success="loadVendorProfileList"
/>
<add-domian-tree ref="domainTreeRef" @success="loadDomainPage" />
</div>
</template>
<script setup lang="ts">
import { DeviceTypeVerForm } from "@/api/device-type-ver/types";
import {
deleteVendorProfile,
editDevTypeVerForm,
findDevTypeVerEditForm,
listVendorProfile,
pageSysDomain,
} from "@/api/device-type-ver";
import { EditPen } from "@element-plus/icons-vue";
import { EditPen, InfoFilled } from "@element-plus/icons-vue";
import { FormInstance, FormRules } from "element-plus";
import { editCapabilityForm, getCapabilityForm } from "@/api/type-ver-ext";
import { CapabilityForm } from "@/api/type-ver-ext/types";
import AddVendorProfile from "@/views/resources/device-type/components/AddVendorProfile.vue";
import { FileListVO } from "@/api/file-list/types";
import AddDomianTree from "@/views/resources/device-type/components/AddDomianTree.vue";
const loading = ref<boolean>(false);
const route = useRoute();
@ -441,7 +532,10 @@ const typeVerFormRef = ref<FormInstance>();
const capabilityForm = ref<CapabilityForm>({
typeAndVerId: typeAndVerId,
});
const fileListVOList = ref<FileListVO[]>([]);
const domainNames = ref<string[]>([]);
const loadingCapability = ref<boolean>(false);
const loadingVendorProfile = ref<boolean>(false);
const rules = reactive<FormRules<DeviceTypeVerForm>>({
softVer: [
{ required: true, message: "设备类型软件版本名称", trigger: "blur" },
@ -510,9 +604,59 @@ const loadFormData = async () => {
loading.value = false;
});
};
const vendorProfileRef = ref();
const openVendorProfile = () => {
vendorProfileRef.value.open(typeAndVerId);
};
const loadVendorProfileList = async () => {
loadingVendorProfile.value = true;
await listVendorProfile(typeAndVerId)
.then(({ data }) => {
fileListVOList.value = data;
})
.finally(() => {
loadingVendorProfile.value = false;
});
};
const handleDeleteFile = (fileId: number) => {
loadingVendorProfile.value = true;
deleteVendorProfile(typeAndVerId, fileId)
.then(() => {
ElMessage.success("删除成功");
loadVendorProfileList();
})
.finally(() => {
loadingVendorProfile.value = false;
});
};
//
const loadingDomain = ref<boolean>(false);
const domainTotal = ref<number>(0);
const domainTreeRef = ref();
const domainQuery = ref<PageQuery>({
pageNum: 1,
pageSize: 10,
});
const loadDomainPage = async () => {
loadingDomain.value = true;
await pageSysDomain(domainQuery.value, typeAndVerId)
.then(({ data }) => {
domainNames.value = data.list;
domainTotal.value = data.total;
})
.finally(() => {
loadingDomain.value = false;
});
};
const openDomainTree = () => {
domainTreeRef.value.openDomainTree(typeAndVerId);
};
onMounted(() => {
loadFormData();
loadCapabilityForm();
loadVendorProfileList();
loadDomainPage();
});
</script>

Loading…
Cancel
Save