This commit is contained in:
康冉冉
2025-11-11 14:06:13 +08:00
parent ee295230ac
commit 54ab4046f6
387 changed files with 46032 additions and 0 deletions
+186
View File
@@ -0,0 +1,186 @@
<template>
<div class="app-container">
<Form ref="formRef" :formList="formList" :ruleFormData="ruleForm" :config="{labelWidth: '140px'}" @fnClick="callback"></Form>
</div>
</template>
<script setup>
import Form from '@/components/form/index.vue';
import {listAllSwitchName, resNameBtType, addTopology, getTopology, updateTopology, postInterFaceName,getRegistList} from "@/api/disRevenue/resource"
export default {
name: 'TopologyDetails',
components: {Form},
dicts: ['rm_topology_type'],
data() {
return {
loading: false,
ruleForm: {},
formList: [],
paramsData: {},
switchNameList: [],
serverNameList: [],
serverPortList: [],
interfaceNameList: [],
}
},
created() {
this.paramsData = this.$route && this.$route.query;
if (this.paramsData && this.paramsData.id) {
this.getFormDataList(this.paramsData.id);
} else {
this.switchList();
this.fnServerNameList();
}
this.fnFormList();
},
methods: {
// formList集合
fnFormList(objVal) {
this.formList = [{
config: {title: '基本信息',labelWidth: '140px'},
controls: {
id: {label: 'ID',hidden: true},
clientId: {label: '交换机名称', span: 12, type: 'select', eventName: 'change', options:[], required: true},
interfaceName: {label: '接口名称', span: 12, type: 'select', options:[],required: true},
connectedDeviceType: {label: '接口连接设备类型', span: 12, type: 'radio', options:this.dict.type.rm_topology_type, required: true},
serverClientId: {label: '服务器ClientID', span: 12, eventName: 'change', options:[], type: 'select'},
serverPort: {label: '服务器网口', span: 12, options:[], type: 'select'},
}
}];
},
// 获取交换机下拉
switchList() {
listAllSwitchName({}).then(val => {
if(val && val.data) {
this.switchNameList = val && val.data;
this.formList[0].controls.clientId['options'] = val && val.data.map(item => {
if (this.paramsData && this.paramsData.id) {
if (item.clientId === this.ruleForm.clientId) {
this.fnInterFaceNameList({clientId: item.clientId});
}
}
return Object.assign({label: item.switchName, value: item.clientId});
});
}
});
},
// 接口名称
fnInterFaceNameList(val) {
postInterFaceName(Object.assign({},{resourceType: 2}, val)).then(res => {
this.interfaceNameList = res;
this.formList[0].controls.interfaceName['options'] = res && res.map(item => {
return Object.assign({label: item.interfaceName, value: item.interfaceName});
});
});
},
// 获取服务器下拉
fnServerNameList(){
getRegistList({resourceType: 1}).then(val => {
this.serverNameList = val && val.data;
this.formList[0].controls.serverClientId['options'] = val && val.data.map(item => {
if (this.paramsData && this.paramsData.id) {
if (item.clientId === this.ruleForm.serverClientId) {
this.fnServerPortList({serverIp: item.ipAddress});
}
}
return Object.assign({label: item.clientId, value: item.clientId});
});
});
},
// 服务器网口
fnServerPortList(val) {
postInterFaceName(Object.assign({},{resourceType: 1}, val)).then(res => {
this.serverPortList = res;
this.formList[0].controls.serverPort['options'] = res && res.map(item => {
return Object.assign({label: item.interfaceName, value: item.interfaceName});
});
});
},
// 获取详情
getFormDataList(id) {
getTopology(id).then(val => {
this.ruleForm = val && val.data;
this.switchList();
this.fnServerNameList();
}).catch(() => {
this.$modal.msgError("操作失败")
});
},
// 监听事件
callback(result, dataVal, formVal) {
if (result && result.fnCode) {
switch (result.fnCode) {
case 'clientId':
this.ruleForm = Object.assign({}, this.ruleForm, this.$refs.formRef.$refs.ruleForm.model);
let clientId = '';
this.switchNameList.find(item => {
if (item.clientId === dataVal) {
clientId = item.clientId;
}
});
this.ruleForm['interfaceName'] = '';
this.fnInterFaceNameList({clientId: clientId});
break;
case 'serverClientId':
if (dataVal) {
// let serverIp = '';
// this.serverNameList.find(item => {
// if (item.clientId === dataVal) {
// serverIp = item.ipAddress;
// }
// });
this.fnServerPortList({clientId: dataVal});
}
break;
case 'submit':
this.switchNameList.find(item => {
if (item.clientId === dataVal['clientId']) {
dataVal['switchName'] = item.switchName;
}
});
this.serverNameList.find(item => {
if (item.clientId === dataVal['serverClientId']) {
dataVal['serverClientId'] = item.clientId;
dataVal['serverSn'] = item.hardwareSn;
}
});
this.serverPortList.find(item => {
if (item.id === dataVal['serverPort'] || item.interfaceName === dataVal['serverPort']) {
dataVal['serverPort'] = item.interfaceName;
}
});
this.interfaceNameList.find(item => {
if (item.id === dataVal['interfaceName'] || item.interfaceName === dataVal['interfaceName']) {
dataVal['interfaceName'] = item.interfaceName;
}
});
let fnType = addTopology;
if (dataVal && dataVal.id) {
fnType = updateTopology;
}
if(this.loading) return;
this.loading = true;
fnType(dataVal).then(response => {
this.$modal.msgSuccess(response.msg);
this.$router.push("/resource/topology");
this.loading = false;
}).catch(() => {
this.$modal.msgError("操作失败")
});
break;
case 'cancel':
this.$router.push("/resource/topology");
break;
default:
}
}
}
}
}
</script>
<style scoped>
::v-deep .el-radio {
margin-right: 15px!important;
}
</style>
+152
View File
@@ -0,0 +1,152 @@
<template>
<div style="width:100%;height: calc(100vh - 115px);margin: 30px auto 0;" class="textAlignCenter">
<div class="w100">
<el-input v-model="resName" placeholder="请输入你需要搜索的交换机名称或服务器节点名称入内容" style="width: 80%;" @keyup.enter.native="handleQuery"></el-input>
<el-button type="primary" class="ml10" icon="Search" @click="handleQuery(1)">搜索</el-button>
<el-button icon="Refresh" @click="handleQuery(2)">重置</el-button>
</div>
<div id="gplotChart" class="w100 h100"></div>
</div>
</template>
<script>
import * as echarts from 'echarts'
import {resNameBtType, listAllTopology} from "@/api/disRevenue/resource"
export default {
name: 'gplot',
data() {
return {
level1Img: require('@/assets/images/level1.png'),
level2Img: require('@/assets/images/level2.png'),
level3Img: require('@/assets/images/level3.png'),
level2ImgTrue: require('@/assets/images/level2True.png'),
level3ImgTrue: require('@/assets/images/level3True.png'),
switchNameList: {},
resName: '',
}
},
created() {
this.switchList();
},
mounted() {
// this.$nextTick(() => {
// this.getList();
// })
},
methods: {
// 获取详情
getList(res,lightVal) {
const gplotChartLine = echarts.init(document.getElementById('gplotChart'));
let seriesNodes = [
{
id: 'cloud',
name: '云',
// symbolSize: 80,
symbol: `image://${this.level1Img}`,
symbolSize: [40, 40], // 图片宽高
x: 250,
y: 300
},
];
let links = [];
if (res.params) {
Object.keys(res.params).forEach((item,index) => {
links.push({source: 'cloud', target: item, lineStyle: { width: 2 }});
seriesNodes.push({
id: item,
name: item,
// symbol: 'rect',
// symbolSize: 60,
symbol: `image://${lightVal && lightVal[item] ? this.level2ImgTrue : this.level2Img}`,
symbolSize: [40, 40], // 图片宽高
x: 400,
y: 200 * (index + 1)
});
res.params[item].forEach((val,indexVal) => {
if (val && val.serverName) {
links.push({source: item, target: val.serverName, lineStyle: { width: 2 }});
seriesNodes.push({
id: val.serverName,
name: val.serverName,
// symbol: 'rect',
// symbolSize: 60,
symbol: `image://${lightVal && lightVal[val.serverName] ? this.level3ImgTrue : this.level3Img}`,
symbolSize: [40, 40], // 图片宽高
x: 900,
y: 60 * (indexVal + 1)
});
}
});
});
}
let option = {
title: {
text: '',
left: 'center',
},
tooltip: {},
series: [
{
type: 'graph', // 关系图类型
layout: 'none', // 关闭力导向布局,使用固定位置
roam: true, // 不允许鼠标缩放和平移
label: {
show: false, // 显示节点标签
},
// 节点数据 - 增加了固定的x和y坐标
nodes: seriesNodes,
links: links
},
],
};
gplotChartLine.setOption(option);
},
// 获取交换机下拉
switchList(val) {
let params = {};
if (val && val.resourceName) {
params = val;
}
listAllTopology(params).then(res => {
let params = {};
res && res.data.forEach(item => {
if (params.hasOwnProperty(item.switchName)) {
params[item.switchName].push(item);
} else {
params[item.switchName] = [item];
}
});
if (val && val.resourceName) {
let newParam = {};
Object.keys(params).forEach(item => {
newParam[item] = true;
params[item].forEach(val => {
newParam[val.serverName] = true;
});
});
console.log('newParam==',newParam);
this.getList(this.switchNameList,newParam);
} else {
this.switchNameList = {params: params};
this.getList({params: params});
}
});
},
handleQuery(num){
if (num === 2) {
this.resName = '';
this.switchList();
} else {
let params = {};
if (this.resName) {
params = {resourceName: this.resName};
}
this.switchList(params);
}
},
}
}
</script>
<style scoped>
</style>
+163
View File
@@ -0,0 +1,163 @@
<template>
<div class="app-container pageTopForm">
<el-form :model="queryParams" ref="queryRef" v-show="showSearch" size="small" label-width="130px">
<el-col :span="6">
<el-form-item label="交换机名称" prop="switchName">
<el-input
v-model="queryParams.switchName"
placeholder="请输入交换机名称"
clearable
@keyup.enter.native="handleQuery"/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item class="lastBtnSty">
<el-button type="primary" size="mini" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-col>
</el-form>
<TableList :columns="columns" :config="config" :modelIdent="this.$options.name" :queryParams="queryParams" :tableList="roleList" @fnClick="callback" @fnRenderList="getList" @value-change="handleValueChange">
<template #tempType="{ row, column }">
<dict-tag :options="dict.type.rm_topology_type" :value="row.connectedDeviceType"/>
</template>
</TableList>
</div>
</template>
<script setup>
import TableList from "@/components/table/index.vue"
import {listTopology, delTopology} from "@/api/disRevenue/resource"
export default {
name: 'TopologyIndex',
components: {TableList},
dicts: ['rm_topology_type'],
data() {
return {
loading: true,
showSearch: true,
roleList: [],
queryParams: {
total: 0,
pageNum: 1,
pageSize: 10
},
// 列显隐信息
columns: {
id: { label: `ID`, width: '50', visible: false },
clientId: { label: `交换机ID`, minWidth: '320', visible: true},
switchName: { label: `交换机名称`, minWidth: '150', visible: true },
switchSn: { label: `交换机硬件SN`, minWidth: '200'},
interfaceName: { label: `接口名称`, minWidth: '100', visible: true },
connectedDeviceType: { label: `接口连接设备类型`, slotName: 'tempType', minWidth: '150', visible: true },
serverClientId: { label: `服务器ClientID`, minWidth: '320', visible: true},
serverSn: { label: `服务器硬件SN`, minWidth: '200', visible: false},
serverPort: { label: `服务器网口`, minWidth: '250', visible: true },
peerSwitchName: { label: `对端交换机名称`, minWidth: '250', visible: true },
peerSwitchInterface: { label: `对端交换机接口`, minWidth: '250', visible: true },
createTime: { label: `创建时间`, minWidth: '150'},
updateTime:{ label: `修改时间`, minWidth: '150'}
},
config: {
searcherForm: [
{label: '交换机名称', prop: 'roleName', type: 'selset', options: []}
],
tableButton: {
top: [
{content: '新增', fnCode: 'add', type: 'primary', icon: 'el-icon-plus', hasPermi: 'resource:topology:add'},
{content: '删除', fnCode: 'delete', type: 'danger', icon: 'el-icon-delete', hasPermi: 'resource:topology:detele'},
{content: '导出', fnCode: 'export', type: 'warning', icon: 'el-icon-download', hasPermi: 'resource:topology:export'},
{content: '拓扑展示', fnCode: 'echarts', type: 'warning', icon: 'el-icon-picture-outline-round', hasPermi: 'resource:topology:echarts'},
],
line: [
{content: '修改', fnCode: 'edit', type: 'text', icon: 'el-icon-edit', hasPermi: 'resource:topology:edit'},
]
}
}
}
},
created() {
this.getList();
},
methods: {
/** 查询列表 */
getList() {
this.loading = true;
listTopology(this.addDateRange(this.queryParams)).then(response => {
this.roleList = response.rows;
this.queryParams.total = response.total;
this.loading = false;
})
},
// 处理子组件传递的新值
handleValueChange(newValue) {
// 父组件更新自身数据,实现同步
this.showSearch = newValue;
// console.log('父组件拿到新值:', newValue);
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryRef");
this.handleQuery();
},
callback(result, rowData, selectChange) {
if (result && result.fnCode) {
switch (result.fnCode) {
case 'add':
this.$router.push({
path:'/resource/topology/edit/index'});
break;
case 'edit':
this.$router.push({
path:'/resource/topology/edit/index',
query:{
id: rowData.id
}
});
break;
case 'delete':
this.$modal.confirm('是否确认删除数据项?').then(function() {
return delTopology(selectChange)
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功")
}).catch(() => {});
break;
case 'echarts':
this.$router.push({
path:'/resource/topology/gplot/index',
query:{
id: rowData.id
}
});
break;
case 'export':
// let dataList = [];
// Object.keys(this.columns).forEach(item => {
// if (item.visible) {
// dataList.push(item.prop);
// }
// });
// this.download("/system/management/export", {properties: dataList,}, `拓扑管理_${new Date().getTime()}.xlsx`);
let paramsList = Object.assign({}, this.queryParams,rowData);
this.download("system/management/export", paramsList, `拓扑管理_${new Date().getTime()}.xlsx`, null, 'json');
break;
default:
}
}
}
}
}
</script>
<style scoped>
::v-deep .lastBtnSty .el-form-item__content{
margin-left: 10px!important;
}
</style>