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
@@ -0,0 +1,183 @@
<template>
<div class="app-container pageTopForm">
<el-form :model="queryParams" ref="queryRef" size="small" v-show="showSearch" label-width="auto">
<el-col :span="8">
<el-form-item label="ClientID" prop="clientId">
<el-input
v-model="queryParams.clientId"
placeholder="请输入ClientID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="更新结果" prop="lastUpdateResult">
<el-select
v-model="queryParams.lastUpdateResult"
placeholder="请选择更新结果"
clearable>
<el-option
v-for="dict in dict.type.agent_update_result"
:key="dict.value"
:label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item class="lastBtnSty">
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-col>
</el-form>
<TableList :columns="columns" :config="config" :modelIdent="this.$options.name" :queryParams="queryParams" :tableList="tableList" @fnClick="callback" @fnRenderList="getList" @value-change="handleValueChange">
<template #tempMethod="{ row, column }">
<dict-tag :options="dict.type.policy_method" :value="row.method"/>
</template>
<template #tempStatus="{ row, column }">
<dict-tag :options="dict.type.rm_register_online_state" :value="row.status"/>
</template>
<template #tempResult="{ row, column }">
<dict-tag :options="dict.type.agent_update_result" :value="row.lastUpdateResult"/>
</template>
</TableList>
</div>
</template>
<script setup>
import TableList from "@/components/table/index.vue"
import {listAgentManage, delAgentManage} from "@/api/disRevenue/resource"
export default {
name: 'AgentUpdate',
components: {TableList},
dicts: ['rm_register_online_state','eps_bandwidth_type', 'agent_update_result', 'policy_method'],
data() {
return {
loading: true,
showSearch: true,
tableList: [],
queryParams: {
total: 0,
pageNum: 1,
pageSize: 10,
queryName: '',
lastUpdateResult: ''
},
// 列显隐信息
columns: {
id: { label: `ID`,width: '50'},
hardwareSn: { label: `硬件SN`, minWidth: '150'},
// resourceName: { label: `资源名称`, minWidth: '250', visible: true },
// internalIp: { label: `内网IP`,minWidth: '100', visible: true},
clientId: { label: `ClientID`, minWidth: '320', visible: true },
managePublicIp: { label: `管理网-公网IP`,minWidth: '120', visible: true},
status: { label: `状态`, minWidth: '100', slotName: 'tempStatus'},
agentVersion: { label: `AGENT版本`,minWidth: '150', visible: true },
method: { label: `更新方式`,minWidth: '200', slotName: 'tempMethod'},
scheduledUpdateTime: { label: `定时执行时间`,minWidth: '160'},
// fileUrlType: { label: `文件地址格式`,minWidth: '200'},
fileUrl: { label: `文件地址`,minWidth: '200'},
lastUpdateResult: { label: `最后一次更新结果`,minWidth: '160', slotName: 'tempResult', visible: true},
lastUpdateTime: { label: `最后一次更新时间`,minWidth: '160', visible: true},
},
config: {
tableButton: {
top: [
{content: '配置更新策略', fnCode: 'add', type: 'primary', icon: 'el-icon-plus', hasPermi: 'resource:agentUpdate:add'},
],
line: [
{content: '详情', fnCode: 'details', type: 'text', icon: 'el-icon-view', hasPermi: 'resource:agentUpdate:details'},
{content: '修改更新策略', fnCode: 'edit', type: 'text', icon: 'el-icon-edit', hasPermi: 'resource:agentUpdate:edit'},
// {content: '手动更新', fnCode: 'update', type: 'text', icon: 'el-icon-refresh-right', hasPermi: 'disRevenue:resource:agentUpdate:update'},
{}
]
}
}
}
},
created() {
this.getList();
},
activated() {
this.$nextTick(() => {
this.getList();
});
},
methods: {
/** 查询列表 */
getList() {
this.loading = true;
listAgentManage(this.queryParams).then(response => {
this.tableList = 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/agentUpdate/view'});
break;
case 'edit':
this.$router.push({
path:'/resource/agentUpdate/view',
query:{
id: rowData.id
}
});
break;
case 'details':
this.$router.push({
path:'/resource/agentUpdate/view',
query:{
id: rowData.id,
readonly: true
}
});
break;
case 'delete':
this.$modal.confirm('是否确认删除数据项?').then(function() {
return delAgentManage(selectChange)
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功")
}).catch(() => {});
break;
case 'export':
let paramsList = Object.assign({}, this.queryParams,rowData);
this.download("system/agentManagement/export", paramsList, `AGENT更新_${new Date().getTime()}.xlsx`, null, 'json');
break;
default:
}
}
}
}
}
</script>
<style scoped>
::v-deep .lastBtnSty .el-form-item__content{
margin-left: 10px!important;
}
</style>
@@ -0,0 +1,142 @@
<template>
<div class="app-container">
<Form :formList="formList" :ruleFormData="ruleForm" :config="config" @fnClick="callback"></Form>
</div>
</template>
<script setup name="Handle">
import Form from '@/components/form/index.vue';
import {addAgentManage, getAgentManage, updateAgentManage, getRegistList} from "@/api/disRevenue/resource"
export default {
name: 'AgentUpdateView',
components: {Form},
dicts: ['policy_method', 'rm_register_online_state', 'agent_update_result'],
data() {
return {
ruleForm: {fileUrlType: '1'},
formList: [],
paramsData: {},
config: {},
includeList: {}
}
},
created() {
this.paramsData = this.$route && this.$route.query;
if (this.paramsData && this.paramsData.id) {
this.getFormDataList(this.paramsData.id);
} else {
this.fnFormList();
// this.getResNameList();
}
if (this.paramsData && this.paramsData.readonly) {
this.config = {
buttonGroup: [{title: '返回', fnCode: 'goBack'}]
};
}
},
methods: {
// formList集合
fnFormList(objVal) {
this.formList = [{
config: {title: '配置更新策略', colSpan: '', readonly: this.paramsData.readonly},
controls: {
id: {label: 'ID',hidden: true},
hardwareSn: {label: '硬件SN', span: 18, type: 'input', disabled: true, hidden: this.paramsData && this.paramsData.readonly ? false : true},
// resourceName: {label: '资源名称', span: 18, type: 'input', disabled: true, hidden: this.paramsData && this.paramsData.id ? false : true},
// internalIp: {label: '内网IP', span: 18, type: 'input', disabled: true, hidden: this.paramsData && this.paramsData.id ? false : true},
clientId: {label: 'ClientID', span: 18, type: 'input', disabled: true, hidden: this.paramsData && this.paramsData.readonly ? false : true},
managePublicIp: {label: '管理网-公网IP', span: 18, type: 'input', disabled: true, hidden: this.paramsData && this.paramsData.readonly ? false : true},
status: {label: '状态', span: 18, type: 'select', options: this.dict.type.rm_register_online_state, disabled: true, hidden: this.paramsData && this.paramsData.readonly ? false : true},
agentVersion: {label: 'AGENT版本', span: 18, type: 'input', disabled: true, hidden: this.paramsData && this.paramsData.readonly ? false : true},
method: {label: '更新方式', span: 18, type: 'select', options: this.dict.type.policy_method, eventName: 'change', required: true, disabled: this.paramsData && this.paramsData.id ? true : false,},
scheduledUpdateTime: {label: '定时执行时间', span: 18, type: 'datetime', required: true, hidden: objVal && objVal.method === '1' ? false: true, disabled: this.paramsData && this.paramsData.id ? true : false,},
// fileUrlType: {label: '文件格式', span: 18, type: 'radio', required: true,options: [{label: '外网HTTP(S)',value: '1'}], warningTitle: '注意:当文件大小超过100M时,请选择【外网HTTP(S)】地址格式'},
fileUrl: {label: '文件地址', span: 18, type: 'input', required: true, placeholder: '请输入外网地址', warningTitle: '如:http://www.tr.com/server-1.1.1.jar'},
fileMd5: {label: '文件MD5', span: 18, type: 'input', required: true},
deployDevice: {label: '部署设备', span: 18, type: 'textarea', rows:15, placeholder: '请粘贴/输入ClientID列表,如\nClientID1\nClientID2\n...', required: true, disabled: this.paramsData && this.paramsData.id ? true : false, hidden: this.paramsData && this.paramsData.readonly ? true : false},
clientAllId: {label: '加载全部ClientID', span: 3, type: 'button', style: 'vertical-align: top', hidden: this.paramsData && this.paramsData.readonly ? true : this.paramsData && this.paramsData.id ? true : false},
// includeIds: {label: '生效服务器', span: 24,required: true, type: 'transfer',options: [],hidden: this.paramsData && this.paramsData.id ? true : false},
lastUpdateResult: {label: '最后一次更新结果', span: 18, type: 'select', options: this.dict.type.agent_update_result, disabled: true, hidden: this.paramsData && this.paramsData.readonly ? false : true},
lastUpdateTime: {label: '最后一次更新时间', span: 18, type: 'datetime', disabled: true, hidden: this.paramsData && this.paramsData.readonly ? false : true},
}
}];
},
// 获取详情
getFormDataList(id) {
getAgentManage(id).then(val => {
if (val && val.data) {
val.data['method'] = val.data && val.data['method'] || val.data['method'] === 0 ? val.data['method'].toString() : val.data['method'];
// val.data['fileUrlType'] = val.data['fileUrlType'].toString();
this.fnFormList(val.data);
this.ruleForm = val.data;
}
}).catch(() => {
// this.$modal.msgError("操作失败")
});
},
// // 包含设备
// getResNameList() {
// resNameList().then(val => {
// this.formList[0].controls['includeIds']['options']= val && val.map(item => {
// this.includeList[item.id] = item;
// return Object.assign({label: item.resourceName, key: item.id});
// });
// }).catch(() => {
// this.$modal.msgError("操作失败")
// });
// },
// 监听事件
callback(result, dataVal, formVal) {
if (result && result.fnCode) {
switch (result.fnCode) {
case 'method':
if (dataVal === '1') {
this.formList[0].controls.scheduledUpdateTime['hidden'] = false;
} else {
this.formList[0].controls.scheduledUpdateTime['hidden'] = true;
}
break;
case 'clientAllId':
this.$set(this.ruleForm, 'deployDevice', '');
getRegistList({resourceType: 1}).then(res => {
let str = '';
if (res && res.data) {
res && res.data.map(item => {
str+= item.clientId + '\n';
});
}
this.$set(this.ruleForm, 'deployDevice', str);
// this.formList[0].controls.clientId['options'] = res && res.data.map(item => {
// return Object.assign({label: item.clientId, value: item.id});
// });
});
break;
case 'submit':
// if (dataVal && !dataVal.id) {
// dataVal['includeNames'] = dataVal && dataVal['includeIds'].map(id => this.includeList[id].resourceName);
// dataVal['includeIds'] = dataVal['includeIds'].join();
// dataVal['includeNames'] = dataVal['includeNames'].join();
// }
let fnType = addAgentManage;
if (dataVal && dataVal.id) {
fnType = updateAgentManage;
}
fnType(dataVal).then(response => {
this.$modal.msgSuccess(response.msg);
this.$router.push("/resource/agentUpdate")
}).catch(() => {
this.$modal.msgError("操作失败")
});
break;
case 'cancel':
this.$router.push("/resource/agentUpdate");
break;
default:
}
}
}
}
}
</script>
<style>
</style>
+170
View File
@@ -0,0 +1,170 @@
<template>
<div class="app-container pageTopForm">
<el-form :model="queryParams" ref="queryRef" size="small" v-show="showSearch" label-width="auto">
<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 label="资源名称" prop="bandwidthType">
<el-select
v-model="queryParams.bandwidthType"
placeholder="请选择资源名称"
clearable>
<el-option
v-for="dict in dict.type.eps_bandwidth_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="状态" prop="type">
<el-select
v-model="queryParams.bandwidthType"
placeholder="请选择状态"
clearable>
<el-option
v-for="dict in dict.type.eps_bandwidth_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item class="lastBtnSty">
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-col>
</el-form>
<TableList :columns="columns" :config="config" :modelIdent="this.$options.name" :queryParams="queryParams" :tableList="tableList" @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 {listMonitorTemp, delMonitorTemp} from "@/api/disRevenue/resource"
export default {
name: 'AlarmLog',
components: {TableList},
dicts: ['rm_topology_type','eps_bandwidth_type'],
data() {
return {
loading: true,
showSearch: true,
tableList: [],
queryParams: {
total: 0,
pageNum: 1,
pageSize: 10
},
// 列显隐信息
columns: {
id: { label: `ID`,width: '50'},
switchName: { label: `资源名称`, minWidth: '250', visible: true },
switchSn: { label: `源IP`,minWidth: '200',visible: false},
createTime: { label: `发生时间`,minWidth: '160'},
interfaceName: { label: `内容`,minWidth: '250', visible: true },
serverName: { label: `状态`,minWidth: '100',visible: true },
},
config: {
tableButton: {
top: [
{content: '导出', fnCode: 'export', type: 'warning', icon: 'el-icon-download', hasPermi: 'resource:alarmManage:export'},
],
line: [
{content: '详情', fnCode: 'details', type: 'text', icon: 'el-icon-view', hasPermi: 'resource:alarmManage:details'},
{content: '处理', fnCode: 'handle', type: 'text', icon: 'el-icon-document-copy', hasPermi: 'resource:alarmManage:handle'},
]
}
}
}
},
created() {
this.getList();
},
methods: {
/** 查询列表 */
getList() {
this.loading = true;
listMonitorTemp(this.queryParams).then(response => {
this.tableList = 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 'details':
this.$router.push({
path:'/resource/alarmLog/details',
query:{
id: rowData.id
}
});
break;
case 'handle':
break;
case 'delete':
this.$modal.confirm('是否确认删除数据项?').then(function() {
return delMonitorTemp(selectChange)
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功")
}).catch(() => {});
break;
case 'export':
// let dataList = [];
// Object.keys(this.columns).forEach(item => {
// if (item.visible) {
// dataList.push(item.prop);
// }
// });
// this.download("/system/alarmManage/export", {properties: dataList,}, `拓扑管理_${new Date().getTime()}.xlsx`);
let paramsList = Object.assign({}, this.queryParams,rowData);
this.download("system/alarmManage/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>
@@ -0,0 +1,72 @@
<template>
<div class="app-container">
<Form :formList="formList" :ruleFormData="ruleForm" :config="config" @fnClick="callback"></Form>
</div>
</template>
<script setup name="Handle">
import Form from '@/components/form/index.vue';
import {addGroup, getGroup, updateGroup, resNameList} from "@/api/disRevenue/resource"
export default {
name: 'AlarmLogDetails',
components: {Form},
data() {
return {
ruleForm: {},
formList: [],
config: {
buttonGroup: [{title: '返回', fnCode: 'goBack'}]
},
paramsData: {}
}
},
created() {
this.paramsData = this.$route && this.$route.query;
if (this.paramsData && this.paramsData.id) {
this.getFormDataList(this.paramsData.id);
}
this.fnFormList();
},
methods: {
// formList集合
fnFormList(objVal) {
this.formList = [{
config: {title: '基本信息',readonly: true},
controls: {
id: {label: 'ID',hidden: true},
groupName: {label: '资源名称', span: 24, type: 'input', rules: [{required: true, message: '请输入名称', trigger: 'blur'}]},
ip: {label: '源IP', span: 24, type: 'input'},
time: {label: '发生时间', span: 24, type: 'date'},
num: {label: '重复次数', span: 24, type: 'input'},
type: {label: '状态', span: 24, type: 'input'},
description: {label: '内容', span: 24, type: 'textarea'}
}
}];
},
// 获取详情
getFormDataList(id) {
getGroup(id).then(val => {
if (val && val.data) {
val.data['includedDevices'] = val.data['includedDevices'].split(',');
this.ruleForm = val.data;
}
}).catch(() => {
this.$modal.msgError("操作失败")
});
},
// 监听事件
callback(result, dataVal, formVal) {
if (result && result.fnCode) {
switch (result.fnCode) {
case 'cancel':
this.$router.push("/resource/alarmLog");
break;
default:
}
}
}
}
}
</script>
<style>
</style>
@@ -0,0 +1,178 @@
<template>
<div class="app-container pageTopForm">
<el-form :model="queryParams" ref="queryRef" size="small" v-show="showSearch" label-width="auto">
<el-col :span="8">
<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 label="策略状态" prop="bandwidthType">
<el-select
v-model="queryParams.bandwidthType"
placeholder="请选择策略状态"
clearable>
<el-option
v-for="dict in dict.type.eps_bandwidth_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item class="lastBtnSty">
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-col>
</el-form>
<TableList :columns="columns" :config="config" :modelIdent="this.$options.name" :queryParams="queryParams" :tableList="tableList" @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 {listMonitorTemp, delMonitorTemp} from "@/api/disRevenue/resource"
export default {
name: 'AlarmManage',
components: {TableList},
dicts: ['rm_topology_type','eps_bandwidth_type'],
data() {
return {
loading: true,
showSearch: true,
tableList: [],
queryParams: {
total: 0,
pageNum: 1,
pageSize: 10
},
// 列显隐信息
columns: {
id: { label: `ID`,width: '50'},
switchName: { label: `策略名称`, minWidth: '250', visible: true },
switchSn: { label: `描述`,minWidth: '200',visible: false},
interfaceName: { label: `监关联资源组控项`,minWidth: '150', visible: true },
serverName: { label: `包含设备`,minWidth: '200'},
connectedDeviceType: { label: `关联监控模版`,minWidth: '150', visible: true },
connected: { label: `策略内容`,minWidth: '200'},
type: { label: `策略状态`, minWidth: '100', visible: true },
conType: { label: `下发策略时间`,minWidth: '160'},
createTime: { label: `创建时间`,minWidth: '160'},
updateTime:{ label: `修改时间`,minWidth: '160'}
},
config: {
searcherForm: [
{label: '模版名称', prop: 'roleName', type: 'selset', options: []}
],
tableButton: {
top: [
{content: '新增', fnCode: 'add', type: 'primary', icon: 'el-icon-plus', hasPermi: 'resource:alarmManage:add'},
{content: '删除', fnCode: 'delete', type: 'danger', icon: 'el-icon-delete', hasPermi: 'resource:alarmManage:detele'},
{content: '导出', fnCode: 'export', type: 'warning', icon: 'el-icon-download', hasPermi: 'resource:alarmManage:export'},
],
line: [
{content: '修改', fnCode: 'edit', type: 'text', icon: 'el-icon-edit', hasPermi: 'resource:alarmManage:edit'},
{content: '详情', fnCode: 'details', type: 'text', icon: 'el-icon-view', hasPermi: 'resource:alarmManage:details'},
{content: '复制', fnCode: 'copy', type: 'text', icon: 'el-icon-document-copy', hasPermi: 'resource:alarmManage:copy'},
{content: '下发策略', fnCode: 'strategy', type: 'text', icon: 'el-icon-sort-down', hasPermi: 'resource:alarmManage:strategy'},
]
}
}
}
},
created() {
this.getList();
},
methods: {
/** 查询列表 */
getList() {
this.loading = true;
listMonitorTemp(this.queryParams).then(response => {
this.tableList = 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/alarmManage/details'});
break;
case 'edit':
this.$router.push({
path:'/resource/alarmManage/details',
query:{
id: rowData.id
}
});
break;
case 'details':
// this.$router.push({
// path:'/disRevenue/resource/alarmManage/view/index',
// query:{
// id: rowData.id
// }
// });
break;
case 'delete':
this.$modal.confirm('是否确认删除数据项?').then(function() {
return delMonitorTemp(selectChange)
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功")
}).catch(() => {});
break;
case 'export':
// let dataList = [];
// Object.keys(this.columns).forEach(item => {
// if (item.visible) {
// dataList.push(item.prop);
// }
// });
// this.download("/system/alarmManage/export", {properties: dataList,}, `拓扑管理_${new Date().getTime()}.xlsx`);
let paramsList = Object.assign({}, this.queryParams,rowData);
this.download("system/alarmManage/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>
@@ -0,0 +1,202 @@
<template>
<div class="app-container">
<div class="w100">
<el-steps :active="active" finish-status="success">
<el-step title="基本信息"></el-step>
<el-step title="告警策略"></el-step>
<el-step title="策略确认"></el-step>
</el-steps>
<!-- 内容区 -->
<div style="margin-top: 30px;height: 90%;">
<!-- active:0 -->
<div v-show="active === 0">
<Form ref="formRef" style="text-align: center;" :formList="formList" :ruleFormData="ruleFormData" :config="config" @fnClick="callback"></Form>
</div>
<!-- active:2 -->
<div v-show="active === 1" class="w100" style="height: 94%;">
<el-tabs type="border-card" class="w100 h100">
<!-- 2-1 -->
<el-tab-pane v-if="ruleFormData.monitorTemp === 1" label="Linux系统" class="w100 h100">
<div v-for="(item,index) of linuxSystem" class="plr-50">
<template v-for="city in item.checkList">
<div class="w100 h100 mt10">
<el-checkbox v-model="city.checked" :label="city.name" :key="city.name" class="disInlineBlock" style="width: 56%;margin-right: 0px!important;white-space: break-spaces;">
{{ city.name }}
</el-checkbox>
<div v-if="city && (city.num || city.towName)" class="disInlineBlock" style="color: #606266; width: 44%;">
<template v-if="city.num">
<el-select v-model="city['typeSelect']" size="small" placeholder="选择操作" style="width: 120px;" class="mr10">
<el-option v-for="val in option" :key="val.value" :label="val.label" :value="val.value"></el-option>
</el-select>
<el-input-number v-model="city['num']" :min="1" label="描述文字" size="small" class="mr10"></el-input-number>
<el-link :underline="false"><span v-if="city && city.numType === 'percent'">%</span>上报告警信息</el-link>
</template>
<template v-else>
<el-link :underline="false">{{city.towName}}: </el-link>
<el-input v-model="city.typeInput" style="width: 120px;margin-left: 5px"></el-input>
<el-link :underline="false" style="color: #e1e1e2;font-size: 12px;">{{city.title}}: </el-link>
</template>
</div>
</div>
</template>
</div>
</el-tab-pane>
<!-- 2-2 -->
<el-tab-pane v-if="ruleFormData.monitorTemp === 2" label="华为交换机" class="w100 h100">
<div style="padding: 50px">
接收来自交换机的snmp Trap信息:
<el-radio-group v-model="switchType">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</div>
</el-tab-pane>
</el-tabs>
</div>
<!-- active:3 -->
<div v-if="active === 2" class="w100" style="height: 94%;margin-top: -15px;">
<AlarmManageView :ruleForm="ruleFormData" :otherList="synthesisList"></AlarmManageView>
</div>
</div>
</div>
<el-button type="primary" v-show="active > 1" style="float: right;margin-top: 12px;margin-left: 10px;" @click="submit">提交</el-button>
<el-button type="primary" v-show="active < 2" style="float: right;margin-top: 12px;" @click="next('1')">下一步</el-button>
<el-button type="primary" v-show="active > 0" style="float: right;margin-top: 12px;" @click="next('-1')">上一步</el-button>
<el-button type="primary" style="float: right;margin-top: 12px;" @click="goBack">返回</el-button>
</div>
</template>
<script setup>
import Form from '@/components/form/index.vue';
import TableList from "@/components/table/index.vue"
import AlarmManageView from './alarmManageView'
export default {
name: 'AlarmManageDetails',
components: {Form, TableList, AlarmManageView},
data() {
return {
active: 0,
checkParams: {other: []},
synthesisList: {},
// 第一节点
ruleFormData: {
monitorTemp: 1,
},
config: {
buttonGroup: []
},
formList: [{
config: {title: ''},
controls: {
id: {label: 'ID',hidden: true},
switchName: {label: '策略名称', span: 12, type: 'input', style: 'display: block;margin: 0 auto;', rules: [{required: true, message: '请输入模版名称', trigger: 'blur'}]},
serverPort: {label: '描述', span: 12, type: 'textarea', style: 'display: block;margin: 0 auto;'},
// monitorTemp: {label: '关联监控模版', span: 12, type: 'select', style: 'display: block;margin: 0 auto;'},
monitorTemp: {label: '关联资源组', span: 12, type: 'select'}
}
}],
// 第二节点 1栏
option: [{label: '大于', value: '大于'},{label: '大于且等于', value: '大于且等于'},{label: '小于', value: '小于'},{label: '小于且等于', value: '小于且等于'}],
linuxSystem: [{
firstTitle: 'Linux系统', modelName: 'other',
checkList: [
{id: '1', name: 'Linux服务器的CPU使用率(system.cpu.uti)', checked: false, typeSelect: '大于', num: '9', numType: 'percent'},
{id: '2', name: 'Linux服务器的内存利用率(memory.utilization)', checked: false, typeSelect: '大于', num: '9', numType: 'percent'},
{id: '3', name: 'Linux服务器的可用交换空间百分比(system.swap.size.percent)', checked: false, typeSelect: '大于', num: '9', numType: 'percent'},
{id: '4', name: 'Linux服务器的登录用户数(system.users.num)', checked: false, typeSelect: '大于', num: '9'},
{id: '5', name: 'Linux服务器的所有挂载点的空间利用率(vfs.fs.util)', checked: false, typeSelect: '大于', num: '9', numType: 'percent'},
{id: '6', name: 'Linux服务器的所有网络接口的运行状态由UP转为DOWN(net.if.status)上报告警信息', checked: false,},
{id: '7', name: 'Linux服务器的所有的网络接口类型为【Ethernet】的且运行状态为【已连接】的网络接口的发送流量带宽使用率', checked: false, typeSelect: '大于', num: '9', numType: 'percent'},
{id: '8', name: 'Linux服务器的所有的容器的内存使用率(container.mem.util)', checked: false, typeSelect: '大于', num: '9', numType: 'percent'},
{id: '9', name: 'Linux服务器开放多余的端口上报告警信息', checked: false, towName: '端口白名单', typeInput: '', title: '以;分割,可以使用-表示连续范围,例如1-1024'},
]
}],
// 第二节点 2栏 列显隐信息
switchType: '',
}
},
created() {},
methods: {
async next(num) {
if (num === '-1') {
this.active--;
} else {
if (this.active === 0) {
if (!await this.fnFormValid()) {
return;
}
}
if (this.active === 1) {
this.selectAllChange();
}
this.active++;
}
},
// form验证
fnFormValid() {
return new Promise((resolve) => {
this.ruleFormData = {};
const formValid = this.$refs.formRef.$refs.ruleForm;
// 3. 操作form(如验证)
formValid.validate((valid) => {
if (valid) {
this.ruleFormData = formValid.model;
resolve(true);
} else {
resolve(false);
}
});
});
},
// 点击下一步,获取多个table列表中所选中的行数据
selectAllChange () {
this.lastStepView();
},
// 最后一步展示
lastStepView() {
this.synthesisList = Object.assign({}, {data: this.linuxSystem}, {switchType: this.switchType});
},
// 提交
submit() {
console.log('ruleFormData==',this.ruleFormData);
console.log('synthesisList==',this.synthesisList);
},
// 返回
goBack() {
this.$router.push({path:'/resource/alarmManage'});
},
// 监听事件
callback(result, dataVal, formVal) {
if (result && result.fnCode) {
switch (result.fnCode) {
case 'submit':
console.log('dataVal===',dataVal);
break;
default:
}
}
}
}
}
</script>
<style scoped>
::v-deep .el-collapse-item__header {
background-color: #d4e3fc!important;
/*color: #fff!important;*/
padding-left: 20px;
font-size: 1rem;
}
.el-tabs__content {
height: 90%;
}
::v-deep .el-checkbox__label {
width: 97%!important;
vertical-align: top;
}
.el-link.el-link--default:hover {
color: #606266;
}
.el-link.el-link--default {
vertical-align: sub;
}
</style>
@@ -0,0 +1,74 @@
<template>
<div class="app-container">
<Form :config="{buttonGroup: []}" :formList="formList" :ruleFormData="ruleForm" @fnClick="callback"></Form>
<div class="form-header h4" style="background: #d4e3fc;padding: 15px 10px;border-radius: 5px">
<div class="disInlineBlock w30" style="color: #000;font-weight: 600;">
策略内容
</div>
</div>
<template v-if="ruleForm.monitorTemp === 1">
<div v-for="(item, index) of otherList['data']" style="margin-top: 10px">
<div style="width: 90%;margin: auto;">
<div v-for="city in item.checkList" class="mt20">
{{city.name}}
<template v-if="city && (city.num || city.towName)">
<span v-if="city.towName">{{city.towName}} {{city.typeInput}}</span>
<span v-if="city.num">{{city.typeSelect}}{{city.num}}<span v-if="city && city.numType === 'percent'">%</span>上报告警信息</span>
</template>
</div>
</div>
</div>
</template>
<template v-else>
<div style="padding: 50px">
接收来自交换机的snmp Trap信息:
<el-radio-group v-model="otherList.switchType">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</div>
</template>
</div>
</template>
<script setup>
import Form from '@/components/form/index.vue';
export default {
name: 'AlarmManageView',
components: {Form},
props: {
ruleForm: {
type: Object,
default: () => ({})
},
otherList: {
type: Object,
default: () => ({})
}
},
data() {
return {
formList: [{
config: {title: '基本信息',readonly: true},
controls: {
id: {label: 'ID',hidden: true},
switchName: {label: '策略名称', span: 12, type: 'input'},
serverPort: {label: '描述', span: 12, type: 'textarea'},
resourceGroup: {label: '关联资源组', span: 12, type: 'select'},
time: {label: '修改时间', span: 12, type: 'date'}
}
}],
paramsData: {},
}
},
created() {
this.paramsData = this.$route && this.$route.query;
},
methods: {
// 监听事件
callback(result, dataVal, formVal) {}
}
}
</script>
<style>
</style>
@@ -0,0 +1,359 @@
<template>
<div class="app-container">
<el-row :gutter="20">
<splitpanes :horizontal="this.$store.getters.device === 'mobile'" class="default-theme">
<!--部门数据-->
<pane size="16">
<el-col>
<div class="head-container">
<el-input v-model="deptName" placeholder="请输入部门名称" clearable size="small" prefix-icon="el-icon-search" style="margin-bottom: 20px" />
</div>
<div class="head-container">
<el-tree :data="deptOptions" :props="defaultProps" :expand-on-click-node="false" :filter-node-method="filterNode" ref="tree" node-key="id" default-expand-all highlight-current @node-click="handleNodeClick" />
</div>
</el-col>
</pane>
<!--用户数据-->
<pane size="84">
<el-form :model="queryParams" ref="queryRef" v-show="showSearch" size="small" label-width="80px">
<el-col :span="7">
<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 label="类型" prop="bandwidthType">
<el-select
v-model="queryParams.bandwidthType"
placeholder="请选择类型"
clearable>
<el-option
v-for="dict in dict.type.rm_topology_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item class="lastBtnSty">
<el-button type="primary" size="mini" icon="Search" @click="handleQuery(1)">搜索</el-button>
<el-button icon="Refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-col>
</el-form>
<input type="file" ref="fileInput" @change="handleFileChange" style="display: none;">
<TableList :columns="columns" :modelIdent="this.$options.name" :config="config" :queryParams="queryParams" :tableList="roleList" @fnClick="callback" @fnRenderList="getList" @value-change="handleValueChange"></TableList>
<!-- 新建文件夹 -->
<el-dialog title="新建文件夹" :visible.sync="open" width="500px" append-to-body>
<el-form ref="noticeRef" :rules="rules" :model="formList" label-width="90px">
<el-row>
<el-col :span="20">
<el-form-item label="名称" prop="switchName">
<el-input v-model="formList.switchName" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="20">
<el-form-item label="描述" prop="remarks">
<el-input v-model="formList.remarks" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm(1)"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
<!-- 移动 -->
<el-dialog class="towDialog" :title="title" :visible.sync="openMove" width="700px" append-to-body>
<div class="w100" style="height: 300px">
<div>
<template v-for="(item,index) of moveList">
<span>{{item.switchName}}<span v-if="index !== moveList.length - 1"></span></span>
</template>
</div>
<div class="w100 mt10">
<span style="width: 13%;">{{title}}</span>
<treeselect v-model="catalogList" :options="deptOptions" class="disInlineBlock" style="width: 87%;vertical-align: middle;" :show-count="true" placeholder="请选择目录" />
</div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm(2)"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
</pane>
</splitpanes>
</el-row>
</div>
</template>
<script setup>
import TableList from "@/components/table/index.vue"
import EchartsPie from "@/components/echartsList/pie.vue"
import {listTopology, delTopology} from "@/api/disRevenue/resource"
import {deptTreeSelect } from "@/api/system/user"
import { Splitpanes, Pane } from "splitpanes"
import Treeselect from "@riophae/vue-treeselect"
import "@riophae/vue-treeselect/dist/vue-treeselect.css"
import "splitpanes/dist/splitpanes.css"
export default {
name: 'Filemanage',
components: {TableList,EchartsPie, Splitpanes, Pane, Treeselect},
dicts: ['rm_topology_type'],
data() {
return {
loading: true,
// 部门名称
deptName: undefined,
// 所有部门树选项
deptOptions: undefined,
defaultProps: {
children: "children",
label: "label",
disabled: true
},
showSearch: true,
roleList: [],
queryParams: {
total: 0,
pageNum: 1,
pageSize: 10
},
// 列显隐信息
columns: {
id: { label: `ID`, width: '50', visible: false },
switchName: { label: `名称`, minWidth: '250', visible: true },
switchSn: { label: `类型`, minWidth: '200', visible: true},
interfaceName: { label: `大小(KB)`, minWidth: '100', visible: true },
connectedDeviceType: { label: `路径`, minWidth: '200', visible: true },
serverName: { label: `描述`, minWidth: '200', visible: true},
md5: { label: `md5值`, minWidth: '160', visible: true},
createBy: { label: `创建人`, minWidth: '160', visible: true},
createTime: { label: `创建时间`, minWidth: '160', visible: true},
serverPort: { label: `修改时间`,minWidth: '160', visible: true }
},
config: {
searcherForm: [
{label: '交换机名称', prop: 'roleName', type: 'selset', options: []}
],
tableButton: {
top: [
{content: '上传文件', fnCode: 'upload', type: 'success', icon: 'el-icon-upload2', hasPermi: 'resource:fileManage:upload'},
{content: '新建文件夹', fnCode: 'newFile', type: 'primary', icon: 'el-icon-plus', hasPermi: 'resource:fileManage:file'},
{content: '移动', fnCode: 'move', type: 'warning', icon: 'el-icon-sort', hasPermi: 'resource:fileManage:move'},
],
line: [
{content: '详情', fnCode: 'details', type: 'text', icon: 'el-icon-view', hasPermi: 'resource:fileManage:details'},
{content: '修改', fnCode: 'edit', type: 'text', icon: 'el-icon-edit', hasPermi: 'resource:fileManage:edit'},
{content: '删除', fnCode: 'delete', type: 'text', icon: 'el-icon-delete', hasPermi: 'resource:fileManage:delete'},
{content: '移动', fnCode: 'move', type: 'text', icon: 'el-icon-sort', hasPermi: 'resource:fileManage:move'},
{content: '复制', fnCode: 'copy', type: 'text', icon: 'el-icon-document-copy', hasPermi: 'resource:fileManage:copy'},
{content: '下载', fnCode: 'download', type: 'text', icon: 'el-icon-download', hasPermi: 'resource:fileManage:download'},
]
}
},
open: false,
openMove: false,
title: '',
moveList: [],
catalogList: null,
formList:{
switchName: '',
remarks: ''
},
rules: {
switchName: [
{ required: true, message: '请输入名称', trigger: 'blur' },
]
}
}
},
watch: {
// 根据名称筛选部门树
deptName(val) {
this.$refs.tree.filter(val)
}
},
created() {
this.getList();
this.getDeptTree();
},
methods: {
// 处理文件选择
handleFileChange(e) {
console.log('e====',e);
// const file = e.target.files[0] // 获取第一个选中的文件
// if (file) {
// selectedFile = file
// selectedFileName = file.name // 显示文件名
// // 可选:自动上传
// // uploadFile()
// } else {
// clearFile() // 未选择文件时清空
// }
},
/** 查询部门下拉树结构 */
getDeptTree() {
deptTreeSelect().then(response => {
this.deptOptions = response.data;
})
},
// 筛选节点
filterNode(value, data) {
if (!value) return true
return data.label.indexOf(value) !== -1
},
// 节点单击事件
handleNodeClick(data) {
this.queryParams.deptId = data.id;
this.handleQuery();
},
/** 查询列表 */
getList() {
this.loading = true;
listTopology(this.addDateRange(this.queryParams)).then(response => {
this.roleList = response.rows;
this.queryParams.total = response.total;
this.loading = false;
})
},
fnDetails(row,type) {
if (type && type === '1') {
this.$router.push({
path:'/resource/resMonitor/digitalSuper',
query:{
id: row.id
}
});
} else {
this.$router.push({
path:'/resource/resMonitor/digitalAutoFind',
query:{
id: row.id
}
});
}
},
// 处理子组件传递的新值
handleValueChange(newValue) {
// 父组件更新自身数据,实现同步
this.showSearch = newValue;
// console.log('父组件拿到新值:', newValue);
},
/** 搜索按钮操作 */
handleQuery(val) {
if (val && val === 1) {
delete this.queryParams.deptId;
}
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryRef");
this.handleQuery();
},
submitForm(num){
if (num === 1) {
this.$refs['noticeRef'].validate((valid) => {
if (!valid) {
return false;
}
this.open = false;
});
} else {
console.log('ddd==',this.catalogList);
this.openMove = false;
}
},
/** 取消按钮 */
cancel() {
this.open = false;
this.openMove = false;
},
callback(result, rowData, selectChange, selectList) {
if (result && result.fnCode) {
switch (result.fnCode) {
case 'upload':
this.$refs.fileInput.click();
break;
case 'newFile':
this.open = true;
this.$nextTick(() => {
this.$refs['noticeRef'].resetFields();
});
break;
case 'move':
this.title = '移动';
if (rowData && rowData.id) {
this.moveList = [rowData];
} else {
if (selectList && selectList.length <= 0) {
this.$modal.msgWarning("请选择数据!");
return;
}
this.moveList = selectList;
}
this.openMove = true;
break;
case 'copy':
this.title = '复制';
this.moveList = [rowData];
this.openMove = true;
break;
case 'edit':
this.$router.push({
path:'/resource/fileManage/view',
query:{
id: rowData.id
}
});
break;
case 'details':
this.$router.push({
path:'/resource/fileManage/view',
query:{
id: rowData.id,
readonly: true
}
});
break;
case 'download':
break;
case 'delete':
this.$modal.confirm('是否确认删除数据项?').then(function() {
return delTopology(selectChange)
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功")
}).catch(() => {});
break;
default:
}
}
}
}
}
</script>
<style scoped>
::v-deep .lastBtnSty .el-form-item__content{
margin-left: 10px!important;
}
</style>
@@ -0,0 +1,133 @@
<template>
<div class="app-container mt20">
<Form :formList="formList" :ruleFormData="ruleForm" :config="paramsData && paramsData.readonly === 'true' ? {buttonGroup: []} : {}" @fnClick="callback"></Form>
<div v-if="paramsData && paramsData.readonly === 'true'" class="w100 mt50">
<p style="font-size: 1.2rem;font-weight: 500;border-bottom: 1px solid #e7e7e7;">{{netWorkCard.title}}</p>
<div v-for="item of netWorkCard.list" class="mt50">
<div v-for="(val,index) of item.data" style="width: 80%;margin: auto;" :class="index + 1 === item.data.length ? 'border' : 'borderType'">
<div style="width: 20%;border-right: 1px solid #e7e7e7;" class="ml10 disInlineBlock"><p>{{val.name}}</p></div>
<p style="width: 75%" class="ml10 disInlineBlock">{{val.content}}</p>
</div>
</div>
</div>
<el-button v-if="paramsData && paramsData.readonly === 'true'" class="mb20 mt20" style="float: right;" @click="callback({fnCode: 'cancel'})">返回</el-button>
</div>
</template>
<script setup name="Handle">
import Form from '@/components/form/index.vue';
import {addGroup, getGroup, updateGroup, resNameList} from "@/api/disRevenue/resource"
export default {
name: 'FileManageView',
components: {Form},
data() {
return {
ruleForm: {},
formList: [],
paramsData: {},
netWorkCard: {
title: '网卡信息',
list: [
{
data: [
{name: '接口名称', content: 'eno1(Intel Corporation Ethernet Connection X722 for 10GbE SFP+)'},
{name: 'MAC地址', content: '7c:c3:85:b6:61:bf'},
{name: '接口类型', content: 'Ethernet'},
{name: 'IPv4地址', content: '172.16.15.103'}
]
},
{
data: [
{name: '接口名称', content: 'eno1(Intel Corporation Ethernet Connection X722 for 10GbE SFP+)'},
{name: 'MAC地址', content: '7c:c3:85:b6:61:bf'},
{name: '接口类型', content: 'Ethernet'},
{name: 'IPv4地址', content: '172.16.15.103'}
]
},
]
}
}
},
created() {
this.paramsData = this.$route && this.$route.query;
if (this.paramsData && this.paramsData.id) {
this.getFormDataList(this.paramsData.id);
}
this.fnFormList();
this.getResNameList();
},
methods: {
// formList集合
fnFormList(objVal) {
this.formList = [{
config: {title: '', colSpan: 'disBlock', readonly: this.paramsData.readonly},
controls: {
id: {label: 'ID',hidden: true},
groupName: {label: '名称', span: 12, type: 'input'},
type: {label: '类型', span: 12, type: 'input', disabled: true},
description: {label: '描述', span: 12, type: 'textarea'},
createTime: {label: '创建时间', span: 12, type: 'date', disabled: true},
includedDevices: {label: '修改时间', span: 12, type: 'date', disabled: true},
num: {label: '大小(KB)', span: 12, type: 'input', disabled: true},
md5: {label: 'MD5值', span: 12, type: 'input', disabled: true},
router: {label: '路径', span: 12, type: 'input', disabled: true},
createBy: {label: '创建人', span: 12, type: 'input', disabled: true},
}
}];
},
// 获取详情
getFormDataList(id) {
getGroup(id).then(val => {
if (val && val.data) {
this.ruleForm = val.data;
}
}).catch(() => {
this.$modal.msgError("操作失败")
});
},
// 包含设备
getResNameList() {
resNameList().then(val => {
this.formList[0].controls['includedDevices']['options']= val && val.map(item => {
return Object.assign({label: item.resourceName, key: item.resourceName});
});
}).catch(() => {
this.$modal.msgError("操作失败")
});
},
// 监听事件
callback(result, dataVal, formVal) {
if (result && result.fnCode) {
switch (result.fnCode) {
case 'submit':
let fnType = addGroup;
if (dataVal && dataVal.id) {
fnType = updateGroup;
}
fnType(dataVal).then(response => {
this.$modal.msgSuccess(response.msg);
this.$router.push("/resource/fileManage")
}).catch(() => {
this.$modal.msgError("操作失败")
});
break;
case 'cancel':
this.$router.push("/resource/fileManage");
break;
default:
}
}
}
}
}
</script>
<style scoped>
.borderType {
border-top: 1px solid #e7e7e7;
border-left: 1px solid #e7e7e7;
border-right: 1px solid #e7e7e7;
}
.border {
border: 1px solid #e7e7e7;
}
</style>
+116
View File
@@ -0,0 +1,116 @@
<template>
<div class="app-container">
<Form ref="formRef" :formList="formList" :ruleFormData="ruleForm" @fnClick="callback"></Form>
</div>
</template>
<script setup name="Handle">
import Form from '@/components/form/index.vue';
import {addGroup, getGroup, updateGroup, resNameList,exitsResourceById} from "@/api/disRevenue/resource"
export default {
name: 'GroupDetails',
components: {Form},
data() {
return {
ruleForm: {},
formList: [],
paramsData: {},
includedDevicesList: {},
}
},
created() {
this.paramsData = this.$route && this.$route.query;
if (this.paramsData && this.paramsData.id) {
this.getFormDataList(this.paramsData.id);
}
this.fnFormList();
this.getResNameList();
},
methods: {
// formList集合
fnFormList(objVal) {
this.formList = [{
config: {title: '基本信息'},
controls: {
id: {label: 'ID',hidden: true},
groupName: {label: '名称', span: 24, type: 'input', rules: [{required: true, message: '请输入名称', trigger: 'blur'}]},
description: {label: '描述', span: 24, type: 'textarea'},
includedDevicesId: {label: '包含设备', span: 24, type: 'transfer',options: [], eventName: 'change'}
}
}];
},
// 获取详情
getFormDataList(id) {
getGroup(id).then(val => {
if (val && val.data) {
if (val.data && val.data['includedDevicesId']) {
let newArr = val.data['includedDevicesId'].split(',');
val.data['includedDevicesId'] = newArr.map(id => Number(id));
}
this.ruleForm = val.data;
}
}).catch(() => {
// this.$modal.msgError("操作失败")
});
},
// 包含设备
getResNameList() {
resNameList().then(val => {
if (val) {
this.formList[0].controls['includedDevicesId']['options']= val && val.map(item => {
this.includedDevicesList[item.id] = item;
return Object.assign({label: item.resourceName, key: item.id});
});
}
}).catch(() => {
this.$modal.msgError("操作失败")
});
},
// 监听事件
callback(result, dataVal, formVal) {
console.log('result===',formVal);
if (result && result.fnCode) {
switch (result.fnCode) {
case 'submit':
dataVal['includedDevicesName'] = (dataVal['includedDevicesId'].map(id => this.includedDevicesList[id].resourceName)).join();
dataVal['includedDevicesId'] = dataVal['includedDevicesId'].join();
let fnType = addGroup;
if (dataVal && dataVal.id) {
fnType = updateGroup;
}
fnType(dataVal).then(response => {
this.$modal.msgSuccess(response.msg);
this.$router.push("/resource/group")
}).catch(() => {
this.$modal.msgError("操作失败")
});
break;
case 'cancel':
this.$router.push("/resource/group");
break;
// case 'includedDevicesId':
// console.log('dataVal==',dataVal);
// if (formVal && formVal === 'right') {
// exitsResourceById({resourceIds: dataVal.join(',')}).then(res => {
// console.log('res=',res.msg);
// if (res.msg) {
// let content = '<p style="font-size: 1rem;font-weight: 600;">资源从其他分组移动到此组</p>' +
// '<p style="height: 0px;margin:10px 0 50px;">资源移动到此组后,将在原来到组中消失,相关的监控策略也会消失</p>';
// this.$modal.confirm(content).then(() => {
// console.log('vvv===',this.$refs.formRef.$refs.ruleForm.model.includedDevicesId);
// }).catch(() => {
// console.log('cccccc====');
// });
// }
// });
// }
// break;
default:
}
}
}
}
}
</script>
<style>
</style>
+152
View File
@@ -0,0 +1,152 @@
<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="groupName">
<el-input
v-model="queryParams.groupName"
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 #tempTooltip="{ row, column }">-->
<!-- <span class="verticalAlign">{{column.label}}</span>-->
<!-- <el-tooltip trigger="click" effect="dark" placement="top">-->
<!-- <template #content><div style="width: 300px">{{column.tooltip}}</div></template>-->
<!-- <el-icon><QuestionFilled /></el-icon>-->
<!-- </el-tooltip>-->
<!-- </template>-->
</TableList>
</div>
</template>
<script setup name="Topology">
import TableList from "@/components/table/index.vue"
import {listGroup, delGroup} from "@/api/disRevenue/resource"
export default {
name: 'GroupIndex',
components: {TableList},
data() {
return {
loading: true,
showSearch: true,
roleList: [],
queryParams: {
total: 0,
pageNum: 1,
pageSize: 10
},
// 列显隐信息
columns: {
id: { label: `ID`, visible: false },
groupName: { label: `名称`, visible: true},
description: { label: `描述`, visible: true},
includedDevicesName: { label: `包含设备`, visible: true },
createTime: { label: `创建时间`},
updateTime: { label: `修改时间`, visible: true}
},
config: {
searcherForm: [
{label: '资源组名称', prop: 'groupName', type: 'input'}
],
tableButton: {
top: [
{content: '新增', fnCode: 'add', type: 'primary', icon: 'el-icon-plus', hasPermi: 'resource:register:add'},
{content: '删除', fnCode: 'delete', type: 'danger', icon: 'el-icon-delete', hasPermi: 'resource:register:detele'},
{content: '导出', fnCode: 'export', type: 'warning', icon: 'el-icon-download', hasPermi: 'resource:register:export'},
],
line: [
{content: '修改', fnCode: 'edit', type: 'text', icon: 'el-icon-edit', hasPermi: 'resource:register:edit'},
]
}
}
}
},
created() {
this.getList();
},
methods: {
// 处理子组件传递的新值
handleValueChange(newValue) {
// 父组件更新自身数据,实现同步
this.showSearch = newValue;
// console.log('父组件拿到新值:', newValue);
},
/** 查询列表 */
getList() {
this.loading = true;
listGroup(this.queryParams).then(response => {
this.roleList = response.rows;
this.queryParams.total = response.total;
this.loading = false;
})
},
/** 搜索按钮操作 */
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/group/edit/index'});
break;
case 'edit':
this.$router.push({
path:'/resource/group/edit/index',
query:{
id: rowData.id
}
});
break;
case 'delete':
this.$modal.confirm('是否确认删除数据项?').then(function() {
return delGroup(selectChange)
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功")
}).catch(() => {});
break;
case 'export':
// let dataList = [];
// Object.keys(this.columns).forEach(item => {
// if (item.visible) {
// dataList.push(item.prop);
// }
// });
// this.download("/system/group/export", {properties: dataList,}, `资源分组_${new Date().getTime()}.xlsx`);
let paramsList = Object.assign({}, this.queryParams,rowData);
this.download("system/group/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>
@@ -0,0 +1,558 @@
<template>
<div class="app-container">
<div>
<el-steps :active="active" finish-status="success">
<el-step title="基本信息"></el-step>
<el-step title="监控策略"></el-step>
<el-step title="信息确认"></el-step>
</el-steps>
<!-- 内容区 -->
<div style="margin-top: 30px;">
<!-- active:0 -->
<div v-show="active === 0">
<Form ref="formRef" style="text-align: center;" :formList="formList" :ruleFormData="ruleFormData" :config="config" @fnClick="callback"></Form>
</div>
<!-- active:2 -->
<div v-show="active === 1">
<el-tabs type="border-card">
<!-- 2-1 -->
<el-tab-pane v-if="resourceType === 'linux'" label="Linux系统">
<el-tabs v-model="linuxActiveName">
<!-- 2-1-1 -->
<el-tab-pane label="监控项" name="first">
<el-collapse v-model="activeNames">
<el-collapse-item v-for="(item,index) of linuxSystem.monitorItem" :title="item.title" :name="index">
<template v-if="item.modelName === 'other'">
<div class="plr-50">
<div v-for="city of item.checkList" class="w100 mt10 mb10 disInlineBlock fontSize15">
<div class="disInlineBlock w45">
<span style="width: 200px" class="disInlineBlock">{{ city.metricKey }}</span>
<span>{{city.metricName}}</span>
</div>
<div class="disInlineBlock" style="color: #606266">
采集周期<el-select v-model="city['time']" placeholder="请选择" clearable @change="(changeVal) => handleCheckedCitiesChange(changeVal, item)">
<el-option v-for="val in option" :key="val.value" :label="val.label" :value="val.value"></el-option>
</el-select>
</div>
</div>
</div>
</template>
<template v-else>
<template slot="title">
{{item.title}}
<div style="font-size: 13px;margin-left: 15%;">
采集周期<el-select v-model="item['time']" placeholder="请选择" clearable @change="(changeVal) => handleCheckedCitiesChange(changeVal, item)">
<el-option v-for="val in option" :key="val.value" :label="val.label" :value="val.value"></el-option>
</el-select>
</div>
</template>
<div class="plr-50">
<div v-for="city of item.checkList" class="w45 mt10 mb10 disInlineBlock fontSize15">
<span style="width: 200px" class="disInlineBlock">{{ city.metricKey }}</span>
<span>{{city.metricName}}</span>
</div>
</div>
</template>
</el-collapse-item>
</el-collapse>
</el-tab-pane>
<!-- 2-1-2 -->
<el-tab-pane label="自动发现项" name="second">
<el-collapse v-model="activeNames">
<el-collapse-item v-for="(item,index) of linuxSystem.autodiscoverItem" :title="item.title" :name="index">
<template slot="title">
{{item.title}}
<div style="font-size: 13px;margin-left: 15%;">
采集周期<el-select v-model="item['time']" id="selDisabled" clearable :disabled="item.modelName === 'net' ? true : false" placeholder="请选择" @change="(changeVal) => handleCheckedCitiesChange(changeVal, item)">
<el-option v-for="val in option" :key="val.value" :label="val.label" :value="val.value"></el-option>
</el-select>
</div>
</template>
<div style="display: flex;justify-content: center;">
<div class="plr-50">
<div v-for="city of item.checkList" class="w100 mt10 mb10 disBlock fontSize15">
<span style="width: 200px" class="disInlineBlock">{{city.metricKey}}</span>
<span>{{city.metricName}}</span>
</div>
</div>
</div>
</el-collapse-item>
</el-collapse>
</el-tab-pane>
</el-tabs>
</el-tab-pane>
<!-- 2-2 -->
<el-tab-pane v-if="resourceType === 'switch'" label="华为交换机">
<span slot="label">
华为交换机
<el-tooltip trigger="click" effect="dark" placement="top">
<template #content>针对CloudEngine 58&68&78&88&98系列</template>
<i class="el-icon-question"></i>
</el-tooltip>
</span>
<el-tabs v-model="hwActiveName">
<!-- 2-2-1 -->
<el-tab-pane label="监控项" name="first">
<template v-for="(item,index) of monitorTable['nodeOne']">
<div class="plr-50">
<div v-for="city of item.checkList" class="w100 mt10 mb10 disInlineBlock fontSize15">
<div class="disInlineBlock w60">
<span style="width: 200px" class="disInlineBlock">{{ city.metricKey }}</span>
<span>{{city.metricName}}</span>
</div>
<div class="disInlineBlock" style="color: #606266">
采集周期<el-select v-model="city['time']" placeholder="请选择" clearable @change="(changeVal) => handleCheckedCitiesChange(changeVal, item)">
<el-option v-for="val in option" :key="val.value" :label="val.label" :value="val.value"></el-option>
</el-select>
</div>
</div>
</div>
</template>
</el-tab-pane>
<!-- 2-2-2 -->
<el-tab-pane label="自动发现项" name="second">
<el-collapse v-model="activeNames">
<el-collapse-item v-for="(item,index) of monitorTable['nodeTow']" :title="item.title" :name="index">
<template slot="title">
{{item.title}}
<div style="font-size: 13px;margin-left: 15%;">
采集周期<el-select v-model="item['time']" id="selDisabled" clearable :disabled="item.modelName === 'switchNet' ? true : false" placeholder="请选择" @change="(changeVal) => handleCheckedCitiesChange(changeVal, item)">
<el-option v-for="val in option" :key="val.value" :label="val.label" :value="val.value"></el-option>
</el-select>
</div>
</template>
<div style="display: flex;justify-content: center;">
<div class="plr-50">
<div v-for="city of item.checkList" class="w100 mt10 mb10 disBlock fontSize15">
<span style="width: 200px" class="disInlineBlock">{{city.metricKey}}</span>
<span>{{city.metricName}}</span>
</div>
</div>
</div>
</el-collapse-item>
</el-collapse>
</el-tab-pane>
</el-tabs>
</el-tab-pane>
</el-tabs>
</div>
<!-- active:3 -->
<div v-if="active === 2">
<MonitorStategyView :ruleForm="ruleFormData" :otherList="synthesisList"></MonitorStategyView>
</div>
</div>
</div>
<el-button type="primary" v-show="active > 1" style="float: right;margin-top: 12px;margin-left: 10px;" @click="submit">提交</el-button>
<el-button type="primary" v-show="active < 2" style="float: right;margin-top: 12px;" @click="next('1')">下一步</el-button>
<el-button type="primary" v-show="active > 0" style="float: right;margin-top: 12px;" @click="next('-1')">上一步</el-button>
<el-button type="primary" style="float: right;margin-top: 12px;" @click="goBack">返回</el-button>
</div>
</template>
<script setup>
import Form from '@/components/form/index.vue';
import TableList from "@/components/table/index.vue"
import MonitorStategyView from './view'
import {addMonitorPolicy, updateMonitorPolicy,getMonitorTemp, getMonitorPolicy, getMonitorPolicyTemp, getResMonitorGroup} from "@/api/disRevenue/resource"
export default {
name: 'MonitorStategyDetails',
components: {Form, TableList, MonitorStategyView},
dicts: ['collection_cycle'],
data() {
return {
active: 0,
activeNames: [0, 1,2,3,4],
linuxActiveName: 'first',
hwActiveName: 'first',
resourceType: '',
checkAllParams: {},
checkParams: {week: '',cpu: [], other: [], mount: [], netPort:[]},
allSelectedData: {},
synthesisList: {},
tempContent: {},
// 第一节点
ruleFormData: {},
config: {
buttonGroup: []
},
policyTemp: {},
formList: [],
paramsList: [],
// 第二节点 1栏
option: [],
linuxSystem: {
monitorItem: [
{firstTitle: 'Linux系统', secondTitle: '监控项', title: 'CPU监控', modelName: 'cpu',time: '', checkList: []},
{firstTitle: 'Linux系统', secondTitle: '监控项', title: '其他监控', modelName: 'other', checkList: []}
],
autodiscoverItem: [
{firstTitle: 'Linux系统', secondTitle: '自动发现项', title: '发现挂载文件系统', modelName: 'vfs', time: '', checkList: []},
{firstTitle: 'Linux系统', secondTitle: '自动发现项', title: '发现网络接口', modelName: 'net', time: '300', checkList: []},
{firstTitle: 'Linux系统', secondTitle: '自动发现项', title: '发现硬盘设备', modelName: 'disk', time: '', checkList: []},
{firstTitle: 'Linux系统', secondTitle: '自动发现项', title: '发现docker', modelName: 'docker', time: '', checkList: []}
],
},
// 第二节点 2栏 列显隐信息
monitorTable: {
nodeOne: [{firstTitle: '华为交换机', secondTitle: '监控项', modelName: 'switchOther', checkList: []}],
nodeTow: [
{firstTitle: '华为交换机', secondTitle: '自动发现项', title: '网络端口发现', modelName: 'switchNet', time: '300', checkList: []},
{firstTitle: '华为交换机', secondTitle: '自动发现项',title: '光模块发现', modelName: 'switchModule', time: '', checkList: []},
{firstTitle: '华为交换机', secondTitle: '自动发现项',title: 'MPU发现', modelName: 'switchMpu', time: '', checkList: []},
{firstTitle: '华为交换机', secondTitle: '自动发现项',title: '电源发现', modelName: 'switchPwr', time: '', checkList: []},
{firstTitle: '华为交换机', secondTitle: '自动发现项',title: '风扇发现', modelName: 'switchFan', time: '', checkList: []},
]},
}
},
created() {
this.option = this.dict.type.collection_cycle;
this.paramsData = this.$route && this.$route.query;
// console.log('paramsData===',this.paramsData);
if (this.paramsData && this.paramsData.id) {
this.getFormDataList(this.paramsData.id);
}
this.fnFormList();
this.fnResMonitorGroup();
this.fnMonitorPolicyTemp();
},
methods: {
fnFormList(){
this.formList = [{
config: {title: ''},
controls: {
id: {label: 'ID',hidden: true},
policyName: {label: '策略名称', span: 12, type: 'input', style: 'display: block;margin: 0 auto;', required: true},
description: {label: '描述', span: 12, type: 'textarea', style: 'display: block;margin: 0 auto;'},
templateId: {label: '关联监控模版', span: 12, type: 'select', required: true, options: [], eventName: 'change', style: 'display: block;margin: 0 auto;'},
resourceGroupId: {label: '关联资源组', span: 12, type: 'select', required: true, options:[]}
}
}];
},
// 资源组
fnResMonitorGroup(){
getResMonitorGroup().then(res => {
if (res && res.data) {
this.formList[0].controls['resourceGroupId']['options']= res && res.data.map(item => {
return Object.assign({label: item.groupName, value: item.id});
});
}
});
},
// 监控模版
fnMonitorPolicyTemp(){
getMonitorPolicyTemp().then(res => {
if (res && res.data) {
this.policyTemp = {};
this.formList[0].controls['templateId']['options']= res && res.data.map(item => {
this.policyTemp[item.id] = item;
return Object.assign({label: item.templateName, value: item.id});
});
}
});
},
// 获取详情
getFormDataList(id) {
this.tempContent = {};
getMonitorPolicy(id).then(val => {
if (val && val.data) {
this.ruleFormData = val.data.policy;
this.resourceType = val.data.resourceType;
this.tempContent[val.data.resourceType] = val.data[val.data.resourceType];
}
}).catch(() => {
// this.$modal.msgError("操作失败")
});
},
// 通过监控模版选项 查询监控策略展示项
fnGetMonitorTempList(id) {
getMonitorTemp(id).then(res => {
if (res && res.data) {
if (this.resourceType === 'linux') {
// cpu 详情
this.linuxSystem.monitorItem[0].checkList = res.data && res.data['linux'] && res.data['linux'].cpu || [];
if (this.tempContent['linux'] && this.tempContent['linux'].cpu && this.tempContent['linux'].cpu.length > 0) {
if (this.tempContent['linux'].cpu[0] && this.tempContent['linux'].cpu[0].collectionCycle) {
this.linuxSystem.monitorItem[0].time = this.tempContent['linux'].cpu[0].collectionCycle.toString();
this.handleCheckedCitiesChange(this.linuxSystem.monitorItem[0].time, this.linuxSystem.monitorItem[0]);
}
}
// other
if (this.tempContent['linux'] && this.tempContent['linux'].other && this.tempContent['linux'].other.length > 0) {
this.tempContent['linux'].other.forEach(item => {
if (item && item.collectionCycle) {
item.time = item.collectionCycle.toString();
}
});
this.linuxSystem.monitorItem[1].checkList = this.tempContent['linux'].other;
this.handleCheckedCitiesChange(null, this.linuxSystem.monitorItem[1]);
} else {
this.linuxSystem.monitorItem[1].checkList = res.data && res.data['linux'] && res.data['linux'].other || [];
}
// 自动发现项
let linuxArr = [];
// 1
if (res.data && res.data['linux'] && res.data['linux'].vfs && res.data['linux'].vfs.length > 0) {
this.linuxSystem.autodiscoverItem[0].checkList = res.data && res.data['linux'] && res.data['linux'].vfs;
// 详情
if (this.tempContent['linux'] && this.tempContent['linux'].vfs && this.tempContent['linux'].vfs.length > 0) {
if (this.tempContent['linux'].vfs[0] && this.tempContent['linux'].vfs[0].collectionCycle) {
this.linuxSystem.autodiscoverItem[0].time = this.tempContent['linux'].vfs[0].collectionCycle.toString();
this.handleCheckedCitiesChange(this.linuxSystem.autodiscoverItem[0].time, this.linuxSystem.autodiscoverItem[0]);
}
}
linuxArr.push(this.linuxSystem.autodiscoverItem[0]);
}
// 2
if (res.data && res.data['linux'] && res.data['linux'].net && res.data['linux'].net.length > 0) {
this.linuxSystem.autodiscoverItem[1].checkList = res.data && res.data['linux'] && res.data['linux'].net;
linuxArr.push(this.linuxSystem.autodiscoverItem[1]);
// 带有默认时间的情况下,调用指定方法进行存储
if (this.linuxSystem.autodiscoverItem[1].time) {
this.handleCheckedCitiesChange(this.linuxSystem.autodiscoverItem[1].time, this.linuxSystem.autodiscoverItem[1]);
}
}
// 3
if (res.data && res.data['linux'] && res.data['linux'].disk && res.data['linux'].disk.length > 0) {
this.linuxSystem.autodiscoverItem[2].checkList = res.data && res.data['linux'] && res.data['linux'].disk;
if (this.tempContent['linux'] && this.tempContent['linux'].disk && this.tempContent['linux'].disk.length > 0) {
if (this.tempContent['linux'].disk[0] && this.tempContent['linux'].disk[0].collectionCycle) {
this.linuxSystem.autodiscoverItem[2].time = this.tempContent['linux'].disk[0].collectionCycle.toString();
this.handleCheckedCitiesChange(this.linuxSystem.autodiscoverItem[2].time, this.linuxSystem.autodiscoverItem[2]);
}
}
linuxArr.push(this.linuxSystem.autodiscoverItem[2]);
}
// 4
if (res.data && res.data['linux'] && res.data['linux'].docker && res.data['linux'].docker.length > 0) {
this.linuxSystem.autodiscoverItem[3].checkList = res.data && res.data['linux'] && res.data['linux'].docker;
if (this.tempContent['linux'] && this.tempContent['linux'].docker && this.tempContent['linux'].docker.length > 0) {
if (this.tempContent['linux'].docker[0] && this.tempContent['linux'].docker[0].collectionCycle) {
this.linuxSystem.autodiscoverItem[3].time = this.tempContent['linux'].docker[0].collectionCycle.toString();
this.handleCheckedCitiesChange(this.linuxSystem.autodiscoverItem[3].time, this.linuxSystem.autodiscoverItem[3]);
}
}
linuxArr.push(this.linuxSystem.autodiscoverItem[3]);
}
this.linuxSystem.autodiscoverItem = linuxArr;
} else {
// one
if (res.data && res.data['switch'] && res.data['switch'].switchOther && res.data['switch'].switchOther.length > 0) {
if (this.tempContent['switch'] && this.tempContent['switch'].switchOther && this.tempContent['switch'].switchOther.length > 0) {
this.tempContent['switch'].switchOther.forEach(item => {
if (item && item.collectionCycle) {
item.time = item.collectionCycle.toString();
}
});
this.monitorTable.nodeOne[0].checkList = this.tempContent['switch'].switchOther;
this.handleCheckedCitiesChange(null, this.monitorTable.nodeOne[0]);
} else {
this.monitorTable.nodeOne[0].checkList = res.data && res.data['switch'] && res.data['switch'].switchOther || [];
}
}
let newArr = [];
// tow-1
if (res.data && res.data['switch'] && res.data['switch'].switchNet && res.data['switch'].switchNet.length > 0) {
this.monitorTable.nodeTow[0].checkList = res.data && res.data['switch'] && res.data['switch'].switchNet;
if (this.tempContent['switch'] && this.tempContent['switch'].switchNet && this.tempContent['switch'].switchNet.length > 0) {
if (this.tempContent['switch'].switchNet[0] && this.tempContent['switch'].switchNet[0].collectionCycle) {
this.monitorTable.nodeTow[0].time = this.tempContent['switch'].switchNet[0].collectionCycle.toString();
}
}
newArr.push(this.monitorTable.nodeTow[0]);
if (this.monitorTable.nodeTow[0].time) {
this.handleCheckedCitiesChange(this.monitorTable.nodeTow[0].time, this.monitorTable.nodeTow[0]);
}
}
// tow-2
if (res.data && res.data['switch'] && res.data['switch'].switchModule && res.data['switch'].switchModule.length > 0) {
this.monitorTable.nodeTow[1].checkList = res.data && res.data['switch'] && res.data['switch'].switchModule;
if (this.tempContent['switch'] && this.tempContent['switch'].switchModule && this.tempContent['switch'].switchModule.length > 0) {
if (this.tempContent['switch'].switchModule[0] && this.tempContent['switch'].switchModule[0].collectionCycle) {
this.monitorTable.nodeTow[1].time = this.tempContent['switch'].switchModule[0].collectionCycle.toString();
this.handleCheckedCitiesChange(this.monitorTable.nodeTow[1].time, this.monitorTable.nodeTow[1]);
}
}
newArr.push(this.monitorTable.nodeTow[1]);
}
// tow-3
if (res.data && res.data['switch'] && res.data['switch'].switchMpu && res.data['switch'].switchMpu.length > 0) {
this.monitorTable.nodeTow[2].checkList = res.data && res.data['switch'] && res.data['switch'].switchMpu;
if (this.tempContent['switch'] && this.tempContent['switch'].switchMpu && this.tempContent['switch'].switchMpu.length > 0) {
if (this.tempContent['switch'].switchMpu[0] && this.tempContent['switch'].switchMpu[0].collectionCycle) {
this.monitorTable.nodeTow[2].time = this.tempContent['switch'].switchMpu[0].collectionCycle.toString();
this.handleCheckedCitiesChange(this.monitorTable.nodeTow[2].time, this.monitorTable.nodeTow[2]);
}
}
newArr.push(this.monitorTable.nodeTow[2]);
}
// tow-4
if (res.data && res.data['switch'] && res.data['switch'].switchPwr && res.data['switch'].switchPwr.length > 0) {
this.monitorTable.nodeTow[3].checkList = res.data && res.data['switch'] && res.data['switch'].switchPwr;
if (this.tempContent['switch'] && this.tempContent['switch'].switchPwr && this.tempContent['switch'].switchPwr.length > 0) {
if (this.tempContent['switch'].switchPwr[0] && this.tempContent['switch'].switchPwr[0].collectionCycle) {
this.monitorTable.nodeTow[3].time = this.tempContent['switch'].switchPwr[0].collectionCycle.toString();
this.handleCheckedCitiesChange(this.monitorTable.nodeTow[3].time, this.monitorTable.nodeTow[3]);
}
}
newArr.push(this.monitorTable.nodeTow[3]);
}
// tow-5
if (res.data && res.data['switch'] && res.data['switch'].switchFan && res.data['switch'].switchFan.length > 0) {
this.monitorTable.nodeTow[4].checkList = res.data && res.data['switch'] && res.data['switch'].switchFan;
if (this.tempContent['switch'] && this.tempContent['switch'].switchFan && this.tempContent['switch'].switchFan.length > 0) {
if (this.tempContent['switch'].switchFan[0] && this.tempContent['switch'].switchFan[0].collectionCycle) {
this.monitorTable.nodeTow[4].time = this.tempContent['switch'].switchFan[0].collectionCycle.toString();
this.handleCheckedCitiesChange(this.monitorTable.nodeTow[4].time, this.monitorTable.nodeTow[4]);
}
}
newArr.push(this.monitorTable.nodeTow[4]);
}
this.monitorTable.nodeTow = newArr;
}
}
});
},
async next(num) {
if (num === '-1') {
this.active--;
} else {
if (this.active === 0) {
if (!await this.fnFormValid()) {
return;
} else {
this.dataProcess();
this.fnGetMonitorTempList(this.ruleFormData.templateId);
}
}
if (this.active === 1) {
this.selectAllChange();
}
this.active++;
}
},
// 数据处理
dataProcess() {
let typeVal = {};
if (this.resourceType === 'linux') {
typeVal = this.linuxSystem;
} else {
typeVal = this.monitorTable;
}
Object.keys(typeVal).forEach(res => {
typeVal[res].forEach(item => {
this.checkParams[item.modelName] = [];
this.checkAllParams[item.modelName] = {
firstTitle: item.firstTitle,
secondTitle: item.secondTitle,
lastTitle: item.title,
data: []
};
});
})
},
// form验证
fnFormValid() {
return new Promise((resolve) => {
this.ruleFormData = {};
const formValid = this.$refs.formRef.$refs.ruleForm;
// 3. 操作form(如验证)
formValid.validate((valid) => {
if (valid) {
this.ruleFormData = formValid.model;
resolve(true);
} else {
resolve(false);
}
});
});
},
// 点击下一步,获取多个table列表中所选中的行数据
selectAllChange () {
let obj = {};
this.option.forEach(item => {
obj[item.value] = item.label;
});
this.paramsList = [];
Object.keys(this.checkAllParams).forEach(item => {
if (this.checkAllParams[item].data && this.checkAllParams[item].data.length > 0) {
if (this.checkAllParams[item].time) {
this.checkAllParams[item]['timeLabel'] = obj[this.checkAllParams[item].time];
// 摘取数据 {id: '', collectionCycle: ''}
this.checkAllParams[item].data.forEach(val => {
this.paramsList.push({id: val.id,collectionCycle: this.checkAllParams[item].time});
});
} else {
let lastTimeList = [];
this.checkAllParams[item].data.forEach(val => {
if (val && val.time) {
val['timeLabel'] = obj[val.time];
lastTimeList.push(val);
this.paramsList.push({id: val.id,collectionCycle: val.time});
}
});
this.checkAllParams[item].data = lastTimeList;
}
}
});
this.synthesisList = Object.assign({}, this.checkAllParams);
},
// 单个选择按钮
handleCheckedCitiesChange(changeVal,iteListAll) {
if ('time' in iteListAll) {
if (changeVal) {
this.checkAllParams[iteListAll.modelName]['time'] = iteListAll && iteListAll.time;
this.checkAllParams[iteListAll.modelName].data = iteListAll['checkList'];
} else {
delete this.checkAllParams[iteListAll.modelName];
}
} else {
this.checkAllParams[iteListAll.modelName].data = iteListAll['checkList'];
}
},
// 提交
submit() {
let params = Object.assign(this.ruleFormData, {resourceType: this.resourceType}, {collectionAndIdList: this.paramsList});
let fnType = addMonitorPolicy;
if (this.paramsData && this.paramsData.id) {
fnType = updateMonitorPolicy;
}
this.$modal.loading();
fnType(params).then(response => {
this.$modal.msgSuccess(response.msg);
this.$router.push("/resource/monitorStategy");
this.$modal.closeLoading();
}).catch(error => {
this.$modal.closeLoading();
});
},
// 返回
goBack() {
this.$router.push({path:'/resource/monitorStategy'});
},
// 监听事件
callback(result, dataVal, formVal) {
if (result && result.fnCode) {
switch (result.fnCode) {
case 'templateId':
if (dataVal) {
this.resourceType = this.policyTemp[dataVal].resourceType;
}
break;
default:
}
}
}
}
}
</script>
<style scoped>
::v-deep .el-collapse-item__header {
background-color: #d4e3fc!important;
/*color: #fff!important;*/
padding-left: 20px;
font-size: 1rem;
}
::v-deep #selDisabled{
color: #303133!important;
}
</style>
+203
View File
@@ -0,0 +1,203 @@
<template>
<div class="app-container pageTopForm">
<el-form :model="queryParams" ref="queryRef" size="small" v-show="showSearch" label-width="auto">
<el-col :span="8">
<el-form-item label="搜索" prop="queryName">
<el-input
v-model="queryParams.queryName"
placeholder="请输入策略名称/资源组名/监控模版名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="策略状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="请选择策略状态"
clearable>
<el-option
v-for="dict in dict.type.policy_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item class="lastBtnSty">
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-col>
</el-form>
<TableList :columns="columns" :config="config" :modelIdent="this.$options.name" :queryParams="queryParams" :tableList="tableList" @fnClick="callback" @fnRenderList="getList" @value-change="handleValueChange">
<template #tempStatus="{ row, column }">
<dict-tag :options="dict.type.policy_status" :value="row.status"/>
</template>
</TableList>
</div>
</template>
<script setup>
import TableList from "@/components/table/index.vue"
import {listMonitorPolicy, delMonitorPolicy, getMonitorPolicyList} from "@/api/disRevenue/resource"
export default {
name: 'MonitorStategy',
components: {TableList},
dicts: ['rm_topology_type','eps_bandwidth_type', 'policy_status'],
data() {
return {
loading: true,
showSearch: true,
tableList: [],
queryParams: {
total: 0,
pageNum: 1,
pageSize: 10
},
// 列显隐信息
columns: {
id: { label: `ID`,width: '50'},
policyName: { label: `策略名称`, minWidth: '250', visible: true },
description: { label: `描述`,minWidth: '200',visible: false},
resourceGroupName: { label: `关联资源组`,minWidth: '150', visible: true },
includedDevicesName: { label: `包含设备`,minWidth: '200'},
templateName: { label: `关联监控模版`,minWidth: '150', visible: true },
connected: { label: `策略内容`,minWidth: '200'},
status: { label: `策略状态`, minWidth: '100', slotName: 'tempStatus', visible: true },
deployTime: { label: `下发策略时间`,minWidth: '160'},
createTime: { label: `创建时间`,minWidth: '160'},
updateTime:{ label: `修改时间`,minWidth: '160'}
},
config: {
searcherForm: [
{label: '模版名称', prop: 'roleName', type: 'selset', options: []}
],
tableButton: {
top: [
{content: '新增', fnCode: 'add', type: 'primary', icon: 'el-icon-plus', hasPermi: 'resource:monitorStategy:add'},
{content: '删除', fnCode: 'delete', type: 'danger', icon: 'el-icon-delete', hasPermi: 'resource:monitorStategy:detele'},
{content: '导出', fnCode: 'export', type: 'warning', icon: 'el-icon-download', hasPermi: 'resource:monitorStategy:export'},
],
line: [
{content: '修改', fnCode: 'edit', type: 'text', icon: 'el-icon-edit', hasPermi: 'resource:monitorStategy:edit'},
{content: '详情', fnCode: 'details', type: 'text', icon: 'el-icon-view', hasPermi: 'resource:monitorStategy:details'},
// {content: '复制', fnCode: 'copy', type: 'text', icon: 'el-icon-document-copy', hasPermi: 'disRevenue:resource:monitorStategy:copy'},
{content: '下发策略', fnCode: 'strategy', type: 'text', showName: 'status', showVal: '0', icon: 'el-icon-sort-down', hasPermi: 'resource:monitorStategy:strategy'},
{}
]
}
}
}
},
created() {
this.getList();
},
activated() {
this.$nextTick(() => {
this.getList();
});
},
methods: {
/** 查询列表 */
getList() {
// this.$modal.loading();
listMonitorPolicy(this.queryParams).then(response => {
this.tableList = response.rows;
this.queryParams.total = response.total;
// this.$modal.closeLoading();
}).catch(err => {
// this.$modal.closeLoading();
})
},
// 处理子组件传递的新值
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, selectList) {
if (result && result.fnCode) {
switch (result.fnCode) {
case 'add':
this.$router.push({
path:'/resource/monitorStategy/details/index'});
break;
case 'edit':
this.$router.push({
path:'/resource/monitorStategy/details/index',
query:{
id: rowData.id
}
});
break;
case 'details':
this.$router.push({
path:'/resource/monitorStategy/view/index',
query:{
id: rowData.id,
readonly: true
}
});
break;
case 'delete':
if (selectList && selectList.length <= 0) {
this.$modal.msgWarning("请选择数据!");
return;
}
this.$modal.confirm('是否确认删除数据项?').then(function() {
return delMonitorPolicy(selectChange)
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功")
}).catch(() => {});
break;
case 'strategy':
this.$modal.confirm('是否确认下发策略?').then(() => {
this.$modal.loading();
getMonitorPolicyList(rowData.id).then(res => {
this.getList();
this.$modal.msgSuccess(res.msg);
this.$modal.closeLoading();
}).catch(error => {
this.$modal.closeLoading();
});
}).catch(() => {});
break;
case 'export':
// let dataList = [];
// Object.keys(this.columns).forEach(item => {
// if (item.visible) {
// dataList.push(item.prop);
// }
// });
// this.download("/system/monitorStategy/export", {properties: dataList,}, `拓扑管理_${new Date().getTime()}.xlsx`);
let paramsList = Object.assign({}, this.queryParams,rowData);
this.download("rocketmq/monitorPolicy/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>
+229
View File
@@ -0,0 +1,229 @@
<template>
<div class="app-container">
<Form :config="{buttonGroup: []}" :formList="formList" :ruleFormData="this.paramsData && this.paramsData.readonly ? ruleFormData : ruleForm" @fnClick="callback"></Form>
<div v-for="(item, key, index) of renderList" style="margin-top: 50px">
<div v-if="item.data && item.data.length > 0">
<!-- {{item}}-->
<div class="form-header h4" style="background: #d4e3fc;padding: 15px 10px;border-radius: 5px">
<div class="disInlineBlock w30" style="color: #000;font-weight: 600;">
{{item.firstTitle}}>>{{item.secondTitle}}<span v-if="item && item.lastTitle">>>{{item.lastTitle}}</span>
</div>
<span class="disInlineBlock" style="font-size: 14px;color: #000;" v-if="item.hasOwnProperty('timeLabel')">当前所有子项的采集周期均为{{item.timeLabel || 0}}</span>
</div>
<div class="w70" style="margin: auto;">
<div class="plr-50">
<div v-for="city of item.data" class="w100 mt10 mb10 disInlineBlock fontSize15">
<div class="disInlineBlock w80">
<span style="width: 200px" class="disInlineBlock">{{ city.metricKey }}</span>
<span>{{city.metricName}}</span>
</div>
<div v-if="city && city['timeLabel']" class="disInlineBlock" style="color: #606266">
采集周期为{{city['timeLabel']}}
</div>
</div>
</div>
</div>
</div>
</div>
<el-button v-if="this.paramsData && this.paramsData.readonly" type="primary" @click="handleReset" class="fr mb10">返回</el-button>
</div>
</template>
<script setup>
import Form from '@/components/form/index.vue';
import TableList from "@/components/table/index.vue"
import {getMonitorPolicyTemp, getResMonitorGroup,getMonitorPolicy} from "@/api/disRevenue/resource"
export default {
name: 'MonitorStategyView',
dicts: ['collection_cycle'],
components: {Form,TableList},
props: {
ruleForm: {
type: Object,
default: () => ({})
},
otherList: {
type: Object,
default: () => ({})
}
},
data() {
return {
formList: [],
paramsData: {},
ruleFormData: {},
option: [],
resourceType: '',
checkAllParams: {},
otherListData: {},
linuxSystem: {
monitorItem: [
{firstTitle: 'Linux系统', secondTitle: '监控项', title: 'CPU监控', modelName: 'cpu',time: '', checkList: []},
{firstTitle: 'Linux系统', secondTitle: '监控项', title: '其他监控', modelName: 'other', checkList: []}
],
autodiscoverItem: [
{firstTitle: 'Linux系统', secondTitle: '自动发现项', title: '发现挂载文件系统', modelName: 'vfs', time: '', checkList: []},
{firstTitle: 'Linux系统', secondTitle: '自动发现项', title: '发现网络接口', modelName: 'net', time: '300', checkList: []},
{firstTitle: 'Linux系统', secondTitle: '自动发现项', title: '发现硬盘设备', modelName: 'disk', time: '', checkList: []},
{firstTitle: 'Linux系统', secondTitle: '自动发现项', title: '发现docker', modelName: 'docker', time: '', checkList: []}
],
},
// 第二节点 2栏 列显隐信息
monitorTable: {
nodeOne: [{firstTitle: '华为交换机', secondTitle: '监控项', modelName: 'switchOther', checkList: []}],
nodeTow: [
{firstTitle: '华为交换机', secondTitle: '自动发现项', title: '网络端口发现', modelName: 'switchNet', time: '300', checkList: []},
{firstTitle: '华为交换机', secondTitle: '自动发现项',title: '光模块发现', modelName: 'switchModule', time: '', checkList: []},
{firstTitle: '华为交换机', secondTitle: '自动发现项',title: 'MPU发现', modelName: 'switchMpu', time: '', checkList: []},
{firstTitle: '华为交换机', secondTitle: '自动发现项',title: '电源发现', modelName: 'switchPwr', time: '', checkList: []},
{firstTitle: '华为交换机', secondTitle: '自动发现项',title: '风扇发现', modelName: 'switchFan', time: '', checkList: []},
]},
}
},
computed: {
renderList() {
// 优先用 props 传入的 otherList,其次用接口加载的 otherListData
const sourceList = this.paramsData && this.paramsData.readonly ? this.otherListData : this.otherList;
// 将 Object 转为 Array(键名作为 key,值作为 item),避免循环顺序问题
return sourceList;
}
},
created() {
this.option = this.dict.type.collection_cycle;
this.paramsData = this.$route && this.$route.query;
if (this.paramsData && this.paramsData.readonly) {
this.getFormDataList(this.paramsData.id);
} else {
this.fnFormList();
this.fnResMonitorGroup();
}
// this.fnMonitorPolicyTemp();
},
methods: {
fnFormList(){
this.formList = [{
config: {title: '', readonly: true},
controls: {
id: {label: 'ID',hidden: true},
policyName: {label: '策略名称', span: this.paramsData && this.paramsData.readonly ? 12 : 24, type: 'input', required: true},
// templateId: {label: '关联监控模版', span: 24, type: 'select',options: [], eventName: 'change', style: 'display: block;margin: 0 auto;'},
resourceGroupId: {label: '关联资源组', span: this.paramsData && this.paramsData.readonly ? 12 : 24, type: 'select', options:[]},
updateTime: {label: '修改时间', span: this.paramsData && this.paramsData.readonly ? 12 : 24, type: 'date'},
deployTime: {label: '下发策略时间', span: 12, type: 'date',hidden: !(this.resourceType === 'switch' && this.paramsData && this.paramsData.readonly)},
includedDevicesName: {label: '包含设备', span: 24, type: 'input', hidden: !(this.resourceType === 'switch' && this.paramsData && this.paramsData.readonly)},
description: {label: '描述', span: 24, type: 'textarea'},
}
}];
},
// 获取详情
getFormDataList(id) {
getMonitorPolicy(id).then(val => {
if (val && val.data) {
this.ruleFormData = val.data.policy;
this.resourceType = val.data.resourceType;
this.fnFormList();
this.fnResMonitorGroup();
this.dataProcess();
let obj = {};
this.option.forEach(item => {
obj[item.value] = item.label;
});
if (val.data.resourceType === 'linux') {
Object.keys(this.checkAllParams).forEach(item => {
if (item === 'other' && val.data['linux'] && val.data['linux'][item] && val.data['linux'][item].length > 0) {
let otherTimes = [];
val.data['linux'] && val.data['linux'][item].forEach(timeVal => {
if (timeVal && timeVal.collectionCycle) {
timeVal['timeLabel'] = obj[timeVal.collectionCycle.toString()];
otherTimes.push(timeVal);
}
});
this.checkAllParams[item].data = otherTimes || [];
} else {
if(item && val.data['linux'][item] && val.data['linux'][item].length > 0) {
if (val.data['linux'][item][0] && val.data['linux'][item][0].collectionCycle) {
this.checkAllParams[item]['timeLabel'] = obj[val.data['linux'][item][0].collectionCycle.toString()];
this.checkAllParams[item].data = val.data['linux'][item];
}
}
}
});
} else {
Object.keys(this.checkAllParams).forEach(item => {
if (item === 'switchOther' && val.data['switch'] && val.data['switch'][item] && val.data['switch'][item].length > 0) {
let switchOtherTime = [];
val.data['switch'] && val.data['switch'][item].forEach(timeVal => {
if (timeVal && timeVal.collectionCycle) {
timeVal['timeLabel'] = obj[timeVal.collectionCycle.toString()];
switchOtherTime.push(timeVal);
}
});
this.checkAllParams[item].data = switchOtherTime || [];
} else {
if(item && val.data['switch'][item] && val.data['switch'][item].length > 0) {
if (val.data['switch'][item][0] && val.data['switch'][item][0].collectionCycle) {
this.checkAllParams[item]['timeLabel'] = obj[val.data['switch'][item][0].collectionCycle.toString()];
this.checkAllParams[item].data = val.data['switch'][item];
}
}
}
});
}
this.otherListData = {...this.checkAllParams};
}
}).catch(() => {
// this.$modal.msgError("操作失败")
});
},
// 数据处理
dataProcess() {
let typeVal = {};
if (this.resourceType === 'linux') {
typeVal = this.linuxSystem;
} else {
typeVal = this.monitorTable;
}
Object.keys(typeVal).forEach(res => {
typeVal[res].forEach(item => {
this.checkAllParams[item.modelName] = {
firstTitle: item.firstTitle,
secondTitle: item.secondTitle,
lastTitle: item.title,
data: []
};
});
})
},
// 资源组
fnResMonitorGroup(){
getResMonitorGroup().then(res => {
if (res && res.data) {
this.formList[0].controls['resourceGroupId']['options']= res && res.data.map(item => {
return Object.assign({label: item.groupName, value: item.id});
});
}
});
},
// // 监控模版
// fnMonitorPolicyTemp(){
// getMonitorPolicyTemp().then(res => {
// if (res && res.data) {
// this.policyTemp = {};
// this.formList[0].controls['templateId']['options']= res && res.data.map(item => {
// this.policyTemp[item.id] = item;
// return Object.assign({label: item.templateName, value: item.id});
// });
// }
// });
// },
// 返回
handleReset() {
this.$router.push("/resource/monitorStategy");
},
// 监听事件
callback(result, dataVal, formVal) {}
}
}
</script>
<style>
</style>
+551
View File
@@ -0,0 +1,551 @@
<template>
<div class="app-container">
<div>
<el-steps :active="active" finish-status="success">
<el-step title="基本信息"></el-step>
<el-step title="监控信息"></el-step>
<el-step title="信息确认"></el-step>
</el-steps>
<!-- 内容区 -->
<div style="margin-top: 30px;">
<!-- active:0 -->
<div v-show="active === 0">
<Form ref="formRef" style="text-align: center;" :formList="formList" :ruleFormData="ruleFormData" :config="config" @fnClick="callback"></Form>
</div>
<!-- active:2 -->
<div v-show="active === 1">
<el-tabs type="border-card" v-model="activeTypeName" @tab-click="handleClick">
<!-- 2-1 -->
<el-tab-pane label="Linux系统" name="linux">
<el-tabs v-model="linuxActiveName">
<!-- 2-1-1 -->
<el-tab-pane label="监控项" name="monitorItem">
<el-collapse v-model="activeNames">
<el-collapse-item v-for="(item,index) of linuxSystem.monitorItem['dataList']" :title="item.title" :name="index">
<template slot="title">
{{item.title}}
<el-checkbox :indeterminate="item.isIndeterminate" v-model="item.checkAll" class="ml20" @change="(checked) => handleCheckAllChange(checked,item)">全选</el-checkbox>
</template>
<el-checkbox-group v-model="checkParams[item.modelName]" @change="(checkValList) => handleCheckedCitiesChange(checkValList, item)" style="padding: 0 20px;">
<el-checkbox v-for="city of item.checkList" :label="city.metricKey" :key="city.metricKey" :disabled="item.disabled" class="w45 mt10 mb10">
<span style="width: 200px" class="disInlineBlock">{{city.metricKey}}</span>
<span>{{city.metricName}}</span>
</el-checkbox>
</el-checkbox-group>
</el-collapse-item>
</el-collapse>
</el-tab-pane>
<!-- 2-1-2 -->
<el-tab-pane label="自动发现项" name="autodiscoverItem">
<el-collapse v-model="activeNames">
<el-collapse-item v-for="(item,index) of linuxSystem.autodiscoverItem['dataList']" :title="item.title" :name="index">
<template slot="title">
{{item.title}}
<el-checkbox :indeterminate="item.isIndeterminate" v-model="item.checkAll" class="ml20" @change="(checked) => handleCheckAllChange(checked,item)">全选</el-checkbox>
</template>
<div style="display: flex;justify-content: center;">
<el-checkbox-group v-model="checkParams[item.modelName]" style="padding: 0 20px;">
<el-checkbox v-for="city of item.checkList" :disabled="item.disabled" :label="city.metricKey" :key="city.metricKey" class="mt10 mb10 disBlock">
<span style="width: 200px" class="disInlineBlock">{{city.metricKey}}</span>
<span>{{city.metricName}}</span>
</el-checkbox>
</el-checkbox-group>
</div>
</el-collapse-item>
</el-collapse>
</el-tab-pane>
</el-tabs>
</el-tab-pane>
<!-- 2-2 -->
<el-tab-pane label="华为交换机" name="switch">
<span slot="label">
华为交换机
<el-tooltip trigger="click" effect="dark" placement="top">
<template #content>针对CloudEngine 58&68&78&88&98系列</template>
<i class="el-icon-question"></i>
</el-tooltip>
</span>
<el-tabs v-model="hwActiveName">
<!-- 2-2-1 -->
<el-tab-pane label="监控项" name="monitorItem">
<template v-for="(item,index) of monitorTable['nodeOne']">
<TableList :ref="`tableRef_${item.config.tableKey}`" :config="item.config" :columns="switchColumns" :queryParams="{total: 0}" :tableList="item.tableList" @fnClick="callback"></TableList>
</template>
</el-tab-pane>
<!-- 2-2-2 -->
<el-tab-pane label="自动发现项" name="autodiscoverItem">
<el-collapse v-model="activeNames">
<el-collapse-item v-for="(val,index) of monitorTable['nodeTow']" :title="val.title" :name="index">
<TableList :class="val && val.classType" :ref="`tableRef_${val.config.tableKey}`" :config="val.config" :columns="switchColumns" :queryParams="{total: 0}" :tableList="val.tableList" @fnClick="callback"></TableList>
</el-collapse-item>
</el-collapse>
</el-tab-pane>
</el-tabs>
</el-tab-pane>
</el-tabs>
</div>
<!-- active:3 -->
<div v-show="active === 2">
<MonitorTempView :ruleForm="ruleFormData" :otherList="synthesisList"></MonitorTempView>
</div>
</div>
</div>
<el-button type="primary" v-show="active > 1" style="float: right;margin-top: 12px;margin-left: 10px;" @click="submit">提交</el-button>
<el-button type="primary" v-show="active < 2" style="float: right;margin-top: 12px;" @click="next('1')">下一步</el-button>
<el-button type="primary" v-show="active > 0" style="float: right;margin-top: 12px;" @click="next('-1')">上一步</el-button>
<el-button type="primary" style="float: right;margin-top: 12px;" @click="goBack">返回</el-button>
</div>
</template>
<script setup>
import Form from '@/components/form/index.vue';
import TableList from "@/components/table/index.vue"
import {getMonitorTempList, addMonitorTemp, updateMonitorTemp, getMonitorTemp} from "@/api/disRevenue/resource"
import MonitorTempView from './view'
export default {
name: 'MonitorTempDetails',
components: {Form, TableList, MonitorTempView},
data() {
return {
paramsData: {},
tempContent: {},
active: 0,
activeNames: [0, 1,2,3, 4],
activeTypeName: 'linux', // 两个系统
linuxActiveName: 'monitorItem', // linux系统下的两个栏
hwActiveName: 'monitorItem', // 华为交换机下的两个栏
dataListMap: {}, // 存储监控字段
checkAllParams: {},
checkParams: {cpu: [], other: [], point: [], net:[], disk: [], docker: []},
allSelectedData: {},
synthesisList: {},
// 第一节点
ruleFormData: {},
config: {
buttonGroup: []
},
formList: [{
config: {title: ''},
controls: {
id: {label: 'ID',hidden: true},
templateName: {label: '模版名称', span: 12, type: 'input', style: 'display: block;margin: 0 auto;', rules: [{required: true, message: '请输入模版名称', trigger: 'blur'}]},
description: {label: '描述', span: 12, type: 'textarea'}
}
}],
// 第二节点 1栏
linuxSystem: {
monitorItem: {
firstTitle: 'Linux系统', title: '监控项',
dataList: [{
title: 'CPU监控', modelName: 'cpu', checkAll: true, isIndeterminate: false, disabled: true,
checkList: [
{id: '1', name: 'system.cpu.load.avg1', towName: 'CPU的1分钟负载'},
{id: '2', name: 'system.cpu.util.normal', towName: 'CPU正常运行时间'},
{id: '3', name: 'system.cpu.load.avg5', towName: 'CPU的5分钟负载'},
{id: '4', name: 'system.cpu.utilee.idle', towName: 'CPU空闲时间'},
{id: '5', name: 'system.cpu.load.avg15', towName: 'CPU的15分钟负载'},
]},
{
title: '其他监控', modelName: 'other', checkAll: false, isIndeterminate: false,
checkList: []
}
],
},
autodiscoverItem: {
firstTitle: 'Linux系统', title: '自动发现项',
dataList:[{
title: '发现挂载文件系统', modelName: 'vfs', checkAll: true, isIndeterminate: false, disabled: true,
checkList: []
}, {
title: '发现网络接口', modelName: 'net', checkAll: true, isIndeterminate: false, disabled: true,
checkList: []
}, {
title: '发现硬盘设备', modelName: 'disk', checkAll: true, isIndeterminate: false, disabled: true,
checkList: []
}, {
title: '发现docker', modelName: 'docker', checkAll: true, isIndeterminate: false, disabled: true,
checkList: []
}
]
},
},
// 第二节点 2栏 列显隐信息
switchColumns: {
id: { label: `ID`, visible: true},
metricKey: { label: `监控标识`, visible: true},
metricName: { label: `监控名称`, visible: true},
oid: { label: `监控OID`, visible: true },
filterValue: { label: `过滤值`, visible: true},
monitorDescription: { label: `自动监控说明`, visible: true}
},
monitorTable: {
nodeOne: [{
firstTitle: '华为交换机', secondTitle: '监控项',
tableList: [],
config: {tableKey: 'web', colTopHiddenIcon: true}
}],
nodeTow: [
{
firstTitle: '华为交换机', secondTitle: '自动发现项', title: '网络端口发现', classType: 'checkHidden',
tableList: [],
config: {tableKey: 'web1', colTopHiddenIcon: true, selectable: true}
},
{
firstTitle: '华为交换机', secondTitle: '自动发现项',title: '光模块发现', classType: 'checkHidden',
tableList: [],
config: {tableKey: 'web2', colTopHiddenIcon: true, selectable: true}
},
{
firstTitle: '华为交换机', secondTitle: '自动发现项',title: 'MPU发现', classType: 'checkHidden',
tableList: [],
config: {tableKey: 'web3', colTopHiddenIcon: true, selectable: true}
},
{
firstTitle: '华为交换机', secondTitle: '自动发现项',title: '电源发现', classType: 'checkHidden',
tableList: [],
config: {tableKey: 'web4', colTopHiddenIcon: true, selectable: true}
},
{
firstTitle: '华为交换机', secondTitle: '自动发现项',title: '风扇发现', classType: 'checkHidden',
tableList: [],
config: {tableKey: 'web5', colTopHiddenIcon: true, selectable: true}
},
]},
}
},
created() {
this.paramsData = this.$route && this.$route.query;
// console.log('paramsData===',this.paramsData);
if (this.paramsData && this.paramsData.id) {
this.getFormDataList(this.paramsData.id);
}
Object.keys(this.linuxSystem).forEach(res => {
this.linuxSystem[res]['dataList'].forEach(item => {
this.checkAllParams[item.modelName] = {
firstTitle: this.linuxSystem[res].firstTitle,
secondTitle: this.linuxSystem[res].title,
lastTitle: item.title,
data: []
}
});
})
},
methods: {
// 获取详情
getFormDataList(id) {
this.tempContent = {};
getMonitorTemp(id).then(val => {
if (val && val.data) {
this.activeTypeName = val.data.template.resourcyType;
this.ruleFormData = val.data.template;
this.tempContent[val.data.template.resourcyType] = val.data[val.data.template.resourcyType];
}
}).catch(() => {
// this.$modal.msgError("操作失败")
});
},
fnGetMonitorTempList(params) {
this.$modal.loading();
getMonitorTempList(params).then(res => {
// console.log('data====',res,'params==',params);
if (this.activeTypeName === 'linux') {
if (params.itemType === 'monitorItem'){
this.linuxSystem[params.itemType].dataList[0].checkList = res.data && res.data.cpu;
this.linuxSystem[params.itemType].dataList[1].checkList = res.data && res.data.other;
if (this.tempContent && this.tempContent['linux']) {
// cpu
if (this.tempContent['linux'] && this.tempContent['linux'].cpu && this.tempContent['linux'].cpu.length > 0) {
this.linuxSystem[params.itemType].dataList[0].checkAll = true;
// 全选操作
this.handleCheckAllChange(true, this.linuxSystem[params.itemType].dataList[0]);
} else {
this.linuxSystem[params.itemType].dataList[0].checkAll = false;
// let newLinuxOne = {...this.linuxSystem[params.itemType].dataList[0]};
// newLinuxOne['checkList'] = this.tempContent['linux'] && this.tempContent['linux'].cpu;
// let checkData = this.tempContent && this.tempContent['linux'] ? newLinuxOne : this.linuxSystem[params.itemType].dataList[0];
// // 全选操作 this.tempContent['linux'].cpu
// this.handleCheckAllChange(true, checkData);
}
// other
if (res.data && res.data.other && res.data.other.length === this.tempContent['linux'] && this.tempContent['linux'].other && this.tempContent['linux'].other.length) {
this.linuxSystem[params.itemType].dataList[1].checkAll = true;
// 全选操作
this.handleCheckAllChange(true, this.linuxSystem[params.itemType].dataList[1]);
} else {
this.linuxSystem[params.itemType].dataList[1].checkAll = false;
let newLinuxOne = {...this.linuxSystem[params.itemType].dataList[1]};
newLinuxOne['checkList'] = [];
this.tempContent['linux'].other.some(item => {
this.linuxSystem[params.itemType].dataList[1].checkList.some(val => {
if (item.metricKey === val.metricKey){
newLinuxOne['checkList'].push(val);
return true;
}
});
});
// 全选操作
this.handleCheckAllChange(true, newLinuxOne, true);
}
} else {
this.handleCheckAllChange(true, this.linuxSystem[params.itemType].dataList[0]);
}
} else {
this.linuxSystem[params.itemType].dataList[0].checkList = res.data && res.data.vfs;
this.linuxSystem[params.itemType].dataList[1].checkList = res.data && res.data.net;
this.linuxSystem[params.itemType].dataList[2].checkList = res.data && res.data.disk;
this.linuxSystem[params.itemType].dataList[3].checkList = res.data && res.data.docker;
if (this.paramsData && this.paramsData.id) {
// vfs
if (this.tempContent['linux'] && this.tempContent['linux'].vfs && this.tempContent['linux'].vfs.length > 0) {
this.linuxSystem[params.itemType].dataList[0].checkAll = true;
this.handleCheckAllChange(true, this.linuxSystem[params.itemType].dataList[0]);
} else {
this.linuxSystem[params.itemType].dataList[0].checkAll = false;
}
// net
if (this.tempContent['linux'] && this.tempContent['linux'].net && this.tempContent['linux'].net.length > 0) {
this.linuxSystem[params.itemType].dataList[1].checkAll = true;
this.handleCheckAllChange(true, this.linuxSystem[params.itemType].dataList[1]);
} else {
this.linuxSystem[params.itemType].dataList[1].checkAll = false;
}
// disk
if (this.tempContent['linux'] && this.tempContent['linux'].disk && this.tempContent['linux'].disk.length > 0) {
this.linuxSystem[params.itemType].dataList[2].checkAll = true;
this.handleCheckAllChange(true, this.linuxSystem[params.itemType].dataList[2]);
} else {
this.linuxSystem[params.itemType].dataList[2].checkAll = false;
}
// docker
if (this.tempContent['linux'] && this.tempContent['linux'].docker && this.tempContent['linux'].docker.length > 0) {
this.linuxSystem[params.itemType].dataList[3].checkAll = true;
this.handleCheckAllChange(true, this.linuxSystem[params.itemType].dataList[3]);
} else {
this.linuxSystem[params.itemType].dataList[3].checkAll = false;
}
} else {
this.handleCheckAllChange(true, this.linuxSystem[params.itemType].dataList[0]);
this.handleCheckAllChange(true, this.linuxSystem[params.itemType].dataList[1]);
this.handleCheckAllChange(true, this.linuxSystem[params.itemType].dataList[2]);
this.handleCheckAllChange(true, this.linuxSystem[params.itemType].dataList[3]);
}
}
} else {
if (params.itemType === 'monitorItem') {
let defaultNum = 0;
let relevance = {id: []};
res.data.switchOther.forEach((item,index) => {
if (item && item.filterValue === '9') {
defaultNum = index;
}
if (item && item.monitorDescription === '如果需要设备索引,当选中此项的时候,设备索引项自动选中') {
relevance['id'].push(item.id);
}
});
res.data.switchOther[defaultNum]['relevance'] = relevance;
this.monitorTable.nodeOne[0].tableList = res.data.switchOther;
if (this.paramsData && this.paramsData.id) {
let tabDefSel = [];
this.tempContent['switch'].switchOther.some(item => {
res.data.switchOther.some(val => {
if (item.metricKey === val.metricKey) {
tabDefSel.push(val);
return;
}
});
});
setTimeout(() => {
this.$refs[`tableRef_web`][0].defaultSelectRows(tabDefSel);
},500);
}
} else {
if (this.paramsData && this.paramsData.id) {
// 网络
this.monitorTable.nodeTow[0].tableList = res.data.switchNet;
if (this.tempContent['switch'] && this.tempContent['switch'].switchNet && this.tempContent['switch'].switchNet.length > 0) {
setTimeout(() => {
this.$refs[`tableRef_web1`][0].selectAllRows();
},500);
}
// 光模块
this.monitorTable.nodeTow[1].tableList = res.data.switchModule;
if (this.tempContent['switch'] && this.tempContent['switch'].switchModule && this.tempContent['switch'].switchModule.length > 0) {
setTimeout(() => {
this.$refs[`tableRef_web2`][0].selectAllRows();
},500);
}
// MPU
this.monitorTable.nodeTow[2].tableList = res.data.switchMpu;
if (this.tempContent['switch'] && this.tempContent['switch'].switchMpu && this.tempContent['switch'].switchMpu.length > 0) {
setTimeout(() => {
this.$refs[`tableRef_web3`][0].selectAllRows();
},500);
} else {
}
// 电源
this.monitorTable.nodeTow[3].tableList = res.data.switchPwr;
if (this.tempContent['switch'] && this.tempContent['switch'].switchPwr && this.tempContent['switch'].switchPwr.length > 0) {
setTimeout(() => {
this.$refs[`tableRef_web4`][0].selectAllRows();
},500);
}
// 风扇
this.monitorTable.nodeTow[4].tableList = res.data.switchFan;
if (this.tempContent['switch'] && this.tempContent['switch'].switchFan && this.tempContent['switch'].switchFan.length > 0) {
setTimeout(() => {
this.$refs[`tableRef_web5`][0].selectAllRows();
},500);
}
} else {
this.monitorTable.nodeTow[0].tableList = res.data.switchNet;
this.monitorTable.nodeTow[1].tableList = res.data.switchModule;
this.monitorTable.nodeTow[2].tableList = res.data.switchMpu;
this.monitorTable.nodeTow[3].tableList = res.data.switchPwr;
this.monitorTable.nodeTow[4].tableList = res.data.switchFan;
setTimeout(() => {
this.$refs[`tableRef_web1`][0].selectAllRows();
this.$refs[`tableRef_web2`][0].selectAllRows();
this.$refs[`tableRef_web3`][0].selectAllRows();
this.$refs[`tableRef_web4`][0].selectAllRows();
this.$refs[`tableRef_web5`][0].selectAllRows();
},500);
}
}
}
this.$modal.closeLoading();
});
},
async next(num) {
// console.log('num====',num,'this.active===',this.active);
if (num === '-1') {
this.active--;
} else {
if (this.active === 0 && !await this.fnFormValid()) {
return;
} else if (this.active === 1) {
this.selectAllChange();
} else {
this.handleClick();
}
this.active++;
}
},
handleClick() {
let itemTypeList = ['monitorItem', 'autodiscoverItem'];
itemTypeList.forEach(item => {
let params = {resourceType: this.activeTypeName, itemType: item};
this.fnGetMonitorTempList(params);
});
},
// form验证
fnFormValid() {
return new Promise((resolve) => {
this.ruleFormData = {};
const formValid = this.$refs.formRef.$refs.ruleForm;
// 3. 操作form(如验证)
formValid.validate((valid) => {
if (valid) {
this.ruleFormData = formValid.model;
resolve(true);
} else {
resolve(false);
}
});
});
},
// 点击下一步,获取多个table列表中所选中的行数据
selectAllChange () {
this.allSelectedData = {};
Object.keys(this.monitorTable).forEach(res => {
this.monitorTable[res].forEach(item => {
// 获取子组件的ref(格式:tableRef_${tableKey}
const tableRef = this.$refs[`tableRef_${item.config.tableKey}`];
if (tableRef && tableRef.length && tableRef[0].ids.length) {
// 调用子组件的方法获取选中数据
const selectedData = tableRef[0].getSelectedData();
// firstTitle: '华为交换机', secondTitle: '监控项',
selectedData['firstTitle'] = item.firstTitle;
selectedData['secondTitle'] = item.secondTitle;
selectedData['lastTitle'] = item.title;
this.allSelectedData[selectedData.tableKey] = selectedData;
}
});
});
this.lastStepView();
},
// 最后一步展示
lastStepView() {
if (this.activeTypeName === 'linux') {
this.synthesisList = Object.assign({}, this.checkAllParams);
} else {
this.synthesisList = Object.assign({}, this.allSelectedData);
}
},
// 全选按钮
handleCheckAllChange(checked, itemAll, isIndetBool) {
// console.log('itemAll===',itemAll.checkList);
let arrList = itemAll && itemAll.checkList && itemAll.checkList.map(item => {return item.metricKey});
this.checkParams[itemAll.modelName] = checked ? arrList : [];
this.checkAllParams[itemAll.modelName].data = checked ? itemAll.checkList : [];
itemAll.isIndeterminate = isIndetBool ? true : false;
},
// 单个选择按钮
handleCheckedCitiesChange(checkValList, iteListAll) {
iteListAll.checkAll = checkValList.length === iteListAll['checkList'].length;
iteListAll.isIndeterminate = checkValList.length > 0 && checkValList.length < iteListAll['checkList'].length;
// this.checkParams[iteListAll.modelName] = checkValList;
this.checkAllParams[iteListAll.modelName].data = iteListAll['checkList'].filter(item =>
checkValList.includes(item.metricKey)
);
},
// 提交
submit() {
let params = Object.assign({}, {monitorIds: '', resourceType: this.activeTypeName}, this.ruleFormData);
let idList = [];
Object.keys(this.synthesisList).forEach(item => {
idList = idList.concat(this.synthesisList[item].data.map(val => val.id));
});
params['monitorIds'] = idList;
this.$modal.loading();
let fnType = addMonitorTemp;
if (this.paramsData && this.paramsData.id) {
fnType = updateMonitorTemp;
}
fnType(params).then(response => {
this.$modal.msgSuccess(response.msg);
this.$router.push("/resource/monitorTemp");
this.$modal.closeLoading();
}).catch(() => {
this.$modal.closeLoading();
this.$modal.msgError("操作失败")
});
// console.log('ruleFormData==',this.ruleFormData);
// console.log('synthesisList==',this.synthesisList);
},
// 返回
goBack() {
this.$router.push({path:'/resource/monitorTemp'});
},
// 监听事件
callback(result, dataVal, formVal) {
if (result && result.fnCode) {
switch (result.fnCode) {
case 'submit':
console.log('dataVal===',dataVal);
break;
default:
}
}
}
}
}
</script>
<style scoped>
::v-deep .el-collapse-item__header {
background-color: #d4e3fc!important;
/*color: #fff!important;*/
padding-left: 20px;
font-size: 1rem;
}
</style>
+169
View File
@@ -0,0 +1,169 @@
<template>
<div class="app-container pageTopForm">
<el-form :model="queryParams" ref="queryRef" v-show="showSearch" size="small" label-width="130px">
<el-col :span="12">
<el-form-item label="模版名称" prop="templateName">
<el-input
v-model="queryParams.templateName"
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="tableList" @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 {listMonitorTemp, delMonitorTemp} from "@/api/disRevenue/resource"
export default {
name: 'MonitorTemp',
components: {TableList},
dicts: ['rm_topology_type'],
data() {
return {
loading: true,
showSearch: true,
tableList: [],
queryParams: {
total: 0,
pageNum: 1,
pageSize: 10
},
// 列显隐信息
columns: {
id: { label: `ID`,width: '50'},
templateName: { label: `模版名称`,minWidth: '150', visible: true },
description: { label: `描述`,visible: false, minWidth: '200'},
monitorItems: { label: `监控项`, minWidth: '100', visible: true },
discoveryRules: { label: `自动发现项`, minWidth: '100', visible: true },
resourceGroupName: { label: `包含资源`, minWidth: '200'},
createTime: { label: `创建时间`, minWidth: '160'},
updateTime:{ label: `修改时间`, minWidth: '160'}
},
config: {
searcherForm: [
{label: '模版名称', prop: 'roleName', type: 'selset', options: []}
],
tableButton: {
top: [
{content: '新增', fnCode: 'add', type: 'primary', icon: 'el-icon-plus', hasPermi: 'resource:monitorTemp:add'},
{content: '删除', fnCode: 'delete', type: 'danger', icon: 'el-icon-delete', hasPermi: 'resource:monitorTemp:detele'},
{content: '导出', fnCode: 'export', type: 'warning', icon: 'el-icon-download', hasPermi: 'resource:monitorTemp:export'},
],
line: [
{content: '修改', fnCode: 'edit', type: 'text', icon: 'el-icon-edit', hasPermi: 'resource:monitorTemp:edit'},
{content: '详情', fnCode: 'details', type: 'text', icon: 'el-icon-view', hasPermi: 'resource:monitorTemp:details'},
// {content: '复制', fnCode: 'copy', type: 'text', icon: 'el-icon-document-copy', hasPermi: 'disRevenue:resource:monitorTemp:copy'},
]
}
}
}
},
created() {
this.getList();
},
activated() {
this.$nextTick(() => {
this.getList();
});
},
methods: {
/** 查询列表 */
getList() {
// this.$modal.loading();
listMonitorTemp(this.queryParams).then(response => {
this.tableList = response.rows;
this.queryParams.total = response.total;
// this.$modal.closeLoading();
})
},
// 处理子组件传递的新值
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, selectList) {
if (result && result.fnCode) {
switch (result.fnCode) {
case 'add':
this.$router.push({
path:'/resource/monitorTemp/details/index'});
break;
case 'edit':
this.$router.push({
path:'/resource/monitorTemp/details/index',
query:{
id: rowData.id
}
});
break;
case 'details':
this.$router.push({
path:'/resource/monitorTemp/view/index',
query:{
id: rowData.id,
readonly: true
}
});
break;
case 'delete':
if (selectList && selectList.length <= 0) {
this.$modal.msgWarning("请选择数据!");
return;
}
this.$modal.confirm('是否确认删除数据项?').then(function() {
return delMonitorTemp(selectChange)
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功")
}).catch(() => {});
break;
case 'export':
// let dataList = [];
// Object.keys(this.columns).forEach(item => {
// if (item.visible) {
// dataList.push(item.prop);
// }
// });
// this.download("/system/monitorTemp/export", {properties: dataList}, `拓扑管理_${new Date().getTime()}.xlsx`);
let paramsList = Object.assign({}, this.queryParams,rowData);
this.download("rocketmq/template/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>
+227
View File
@@ -0,0 +1,227 @@
<template>
<div class="app-container">
<Form :config="{buttonGroup: []}" :formList="formList" :ruleFormData="this.paramsData && this.paramsData.readonly ? ruleFormData : ruleForm" @fnClick="callback"></Form>
<div v-for="(item, key, index) of renderList" style="margin-top: 20px">
<div v-if="item.data && item.data.length > 0">
<!-- {{item}}-->
<div v-if="item && item.lastTitle && item.tableKey" class="form-header h4" style="background: #d4e3fc;padding: 15px 10px;border-radius: 5px;margin: unset;">
{{item.lastTitle}}
</div>
<div v-else class="form-header h4" style="padding: 15px 10px;margin: unset;">
{{item.firstTitle}}-{{item && item.lastTitle ? item.lastTitle : item.secondTitle}}
</div>
<div class="mt10 mb10">
<div v-if="item && item.tableKey">
<template v-if="item.lastTitle">
<!-- <div class="form-header">{{item.lastTitle}}</div>-->
<TableList :config="config" :columns="columns" :queryParams="{total: 0}" :tableList="item.data" @fnClick="callback"></TableList>
</template>
<template v-else>
<TableList :config="config" :columns="columns" :queryParams="{total: 0}" :tableList="item.data" @fnClick="callback"></TableList>
</template>
</div>
<div v-else class="w80 plr-20 m0Auto">
<div v-for="(val,valIndex) of item.data" class="disInlineBlock w100 mb10">
<span style="width: 45%;color: #b3b3b3;" class="disInlineBlock">{{val.metricName}}</span>
<span>{{val.metricKey}}</span>
</div>
</div>
</div>
</div>
</div>
<el-button v-if="this.paramsData && this.paramsData.readonly" type="primary" @click="handleReset" class="fr mb10">返回</el-button>
</div>
</template>
<script setup>
import Form from '@/components/form/index.vue';
import TableList from "@/components/table/index.vue";
import {getMonitorTemp} from "@/api/disRevenue/resource";
export default {
name: 'MonitorTempView',
components: {Form,TableList},
props: {
ruleForm: {
type: Object,
default: () => ({})
},
otherList: {
type: Object,
default: () => ({})
}
},
data() {
return {
ruleFormData: {},
otherListData: {},
paramsData: {},
formList: [],
columns: {
id: { label: `ID`, visible: false },
metricKey: { label: `监控标识`, visible: true},
metricName: { label: `监控名称`, visible: true},
oid: { label: `监控OID`, visible: true },
filterValue: { label: `过滤值`, visible: true},
monitorDescription: { label: `自动监控说明`, visible: true}
},
config: {colHiddenCheck: true, colTopHiddenIcon: true},
linuxSystem: {
monitorItem: {
firstTitle: 'Linux系统', title: '监控项',
dataList: [{
title: 'CPU监控', modelName: 'cpu', checkAll: true, isIndeterminate: false, disabled: true,
checkList: [
{id: '1', name: 'system.cpu.load.avg1', towName: 'CPU的1分钟负载'},
{id: '2', name: 'system.cpu.util.normal', towName: 'CPU正常运行时间'},
{id: '3', name: 'system.cpu.load.avg5', towName: 'CPU的5分钟负载'},
{id: '4', name: 'system.cpu.utilee.idle', towName: 'CPU空闲时间'},
{id: '5', name: 'system.cpu.load.avg15', towName: 'CPU的15分钟负载'},
]},
{
title: '其他监控', modelName: 'other', checkAll: false, isIndeterminate: false,
checkList: []
}
],
},
autodiscoverItem: {
firstTitle: 'Linux系统', title: '自动发现项',
dataList:[{
title: '发现挂载文件系统', modelName: 'vfs', checkAll: true, isIndeterminate: false, disabled: true,
checkList: []
}, {
title: '发现网络接口', modelName: 'net', checkAll: true, isIndeterminate: false, disabled: true,
checkList: []
}, {
title: '发现硬盘设备', modelName: 'disk', checkAll: true, isIndeterminate: false, disabled: true,
checkList: []
}, {
title: '发现docker', modelName: 'docker', checkAll: true, isIndeterminate: false, disabled: true,
checkList: []
}
]
},
},
checkAllParams: {},
checkSwitchParams: {},
monitorTable: {
nodeOne: [{
firstTitle: '华为交换机', secondTitle: '监控项',
tableList: [],
config: {tableKey: 'web', colTopHiddenIcon: true}
}],
nodeTow: [
{
firstTitle: '华为交换机', secondTitle: '自动发现项', title: '网络端口发现', classType: 'checkHidden',
tableList: [],
config: {tableKey: 'web1', colTopHiddenIcon: true, selectable: true}
},
{
firstTitle: '华为交换机', secondTitle: '自动发现项',title: 'MPU发现', classType: 'checkHidden',
tableList: [],
config: {tableKey: 'web2', colTopHiddenIcon: true, selectable: true}
},
// {
// firstTitle: '华为交换机', secondTitle: '自动发现项',title: '电源发现', classType: 'checkHidden',
// tableList: [
// {id: 1, ident: 'sysDescr', name: '系统描述', monitor: '1.3.6.1.2.1.1.1', filter: '', explain: ''},
// {id: 2, ident: 'sysObjectID', name: '系统Object ID', monitor: '1.3.6.1.2.1.1.2', filter: '', explain: ''},
// {id: 3, ident: 'sysUpTime', name: '系统运行时间', monitor: '1.3.6.1.2.1.1.1', filter: '', explain: ''},
// {id: 4, ident: 'sysContact', name: '系统联系信息', monitor: '1.3.6.1.2.1.1.1', filter: '', explain: '', relevance: {id: [2]}},
// {id: 5, ident: 'sysName', name: '系统名称', monitor: '1.3.6.1.2.1.1.1', filter: '', explain: ''},
// ],
// config: {tableKey: 'web3', colTopHiddenIcon: true, selectable: true}
// },
{
firstTitle: '华为交换机', secondTitle: '自动发现项',title: '风扇发现', classType: 'checkHidden',
tableList: [],
config: {tableKey: 'web3', colTopHiddenIcon: true, selectable: true}
},
]},
}
},
computed: {
renderList() {
// 优先用 props 传入的 otherList,其次用接口加载的 otherListData
const sourceList = this.paramsData && this.paramsData.readonly ? this.otherListData : this.otherList;
// 将 Object 转为 Array(键名作为 key,值作为 item),避免循环顺序问题
return sourceList;
}
},
created() {
this.paramsData = this.$route && this.$route.query;
if (this.paramsData && this.paramsData.readonly) {
this.getFormDataList(this.paramsData.id);
}
this.fnFormList();
// linux
Object.keys(this.linuxSystem).forEach(res => {
this.linuxSystem[res]['dataList'].forEach(item => {
this.checkAllParams[item.modelName] = {
firstTitle: this.linuxSystem[res].firstTitle,
secondTitle: this.linuxSystem[res].title,
lastTitle: item.title,
data: []
}
});
});
// switch
Object.keys(this.monitorTable).forEach(res => {
this.monitorTable[res].forEach(item => {
this.checkSwitchParams[item.config.tableKey] = {
firstTitle: item.firstTitle,
secondTitle: item.secondTitle,
lastTitle: item.title,
tableKey: item.config.tableKey,
data: []
}
});
});
},
methods: {
fnFormList(){
this.formList = [{
config: {title: '基本信息',readonly: true},
controls: {
id: {label: 'ID',hidden: true},
templateName: {label: '模版名称', span: 24, type: 'input', required: true},
description: {label: '描述', span: 24, type: 'textarea'},
includedDevicesName: {label: '包含设备', span: 24, type: 'input', hidden: this.paramsData && this.paramsData.readonly ? false : true}
}
}]
},
// 获取详情
getFormDataList(id) {
this.$modal.loading();
getMonitorTemp(id).then(val => {
if (val && val.data) {
this.ruleFormData = val.data.template;
if (val.data.template.resourcyType === 'linux') {
Object.keys(this.checkAllParams).forEach(item => {
this.checkAllParams[item].data = item && val.data['linux'][item] || [];
});
this.otherListData = {...this.checkAllParams};
} else {
this.checkSwitchParams['web'].data = val.data['switch'].switchOther;
this.checkSwitchParams['web1'].data = val.data['switch'].switchNet;
this.checkSwitchParams['web2'].data = val.data['switch'].switchModule;
this.checkSwitchParams['web3'].data = val.data['switch'].switchFan;
this.otherListData = {...this.checkSwitchParams};
}
}
this.$modal.closeLoading();
}).catch(() => {
this.$modal.closeLoading();
// this.$modal.msgError("操作失败")
});
},
// 返回
handleReset() {
this.$router.push("/resource/monitorTemp");
},
// 监听事件
callback(result, dataVal, formVal) {}
}
}
</script>
<style>
</style>
+129
View File
@@ -0,0 +1,129 @@
<template>
<div class="app-container">
<Form :formList="formList" :config="{labelWidth: '140px'}" :ruleFormData="ruleForm" @fnClick="callback"></Form>
</div>
</template>
<script setup name="Handle">
import Form from '@/components/form/index.vue';
import {addHandle, getHandle, updateHandle} from "@/api/disRevenue/resource"
export default {
name: 'RegisterHandle',
components: {Form},
dicts: ['rm_register_resource_type', 'rm_register_protocol', 'rm_register_snmp_detect','rm_register_version', 'rm_register_security_level', 'rm_register_permission', 'rm_register_encryption'],
data() {
return {
ruleForm: {
resourceType: '1',
snmpDetect: '1',
protocol: '2',
resourceVersion: '1',
securityLevel: '1',
rwPermission: '1',
encryption: '1',
// agentWeek: '5秒',
// agentNum: '3次',
// agentOID: '1.3.6.1.2.1.1.5'
},
formList: [],
paramsData: {}
}
},
created() {
this.paramsData = this.$route && this.$route.query;
if (this.paramsData && this.paramsData.id) {
this.getFormDataList(this.paramsData.id);
} else {
this.fnFormList(this.ruleForm);
}
},
methods: {
// formList集合
fnFormList(objVal) {
this.formList = [{
config: {title: '基本信息'},
controls: {
id: {label: 'ID',hidden: true},
hardwareSn: {label: '硬件SN', span: 12, type: 'input',
disabled: objVal && objVal.id ? true : false, required: true},
resourceName: {label: '资源名称', span: 12, type: 'input',required: true},
resourceType: {label: '资源类型', span: 12, type: 'radio', options: this.dict.type.rm_register_resource_type, disabled: objVal && objVal.registrationStatus === '1' ? true : false},
ipAddress: {label: 'IP地址', span: 12, type: 'input',required: true, disabled: objVal && objVal.registrationStatus === '1' ? true : false},
protocol: {label: '协议', span: 12, type: 'radio', options: this.dict.type.rm_register_protocol, required: true, disabled: objVal && objVal.registrationStatus === '1' ? true : false},
resourcePort: {label: '端口', span: 12, type: 'input',required: true, disabled: objVal && objVal.registrationStatus === '1' ? true : false},
// otherPortName: {label: ' ', span: 4, type: 'input',
// hidden: objVal && objVal.resourcePort === '2' ? false : true},
snmpDetect: {label: 'SNMP探测', span: 12, type: 'radio', eventName: 'change',required: true, options: this.dict.type.rm_register_snmp_detect, disabled: objVal && objVal.registrationStatus === '1' ? true : false},
resourceVersion: {label: 'SNMP版本', span: 12, type: 'radio',required: true, options: this.dict.type.rm_register_version,hidden: objVal && objVal.snmpDetect === '1' ? false : true, disabled: objVal && objVal.registrationStatus === '1' ? true : false},
rwPermission: {label: '读写权限', span: 12, type: 'radio', options: this.dict.type.rm_register_permission,hidden: objVal && objVal.snmpDetect === '1' ? false : true, disabled: objVal && objVal.registrationStatus === '1' ? true : false},
securityLevel: {label: '安全级别', span: 12, type: 'radio', options: this.dict.type.rm_register_security_level,hidden: objVal && objVal.id ? false : true, disabled: objVal && objVal.registrationStatus === '1' ? true : false},
encryption: {label: '加密方式', span: 12, type: 'radio', options: this.dict.type.rm_register_encryption,hidden: objVal && objVal.id ? false : true, disabled: objVal && objVal.registrationStatus === '1' ? true : false},
teamName: {label: '团体名称', span: 12, type: 'input', hidden: objVal && objVal.snmpDetect === '1' ? false : true,disabled: objVal && objVal.registrationStatus === '1' ? true : false},
snmpCollectAddr: {label: 'SNMP采集地址', span: 12, type: 'input',required: true, hidden: objVal && objVal.snmpDetect === '1' ? false : true, disabled: objVal && objVal.registrationStatus === '1' ? true : false},
snmpCollectPort: {label: 'SNMP采集端口', span: 12, type: 'input',required: true, hidden: objVal && objVal.snmpDetect === '1' ? false : true, disabled: objVal && objVal.registrationStatus === '1' ? true : false},
resourceUserName: {label: '用户名', span: 12, type: 'input', hidden: objVal && objVal.id ? false : true, disabled: objVal && objVal.registrationStatus === '1' ? true : false},
resourcePwd: {label: '密码', span: 12, type: 'input', hidden: objVal && objVal.id ? false : true, disabled: objVal && objVal.registrationStatus === '1' ? true : false},
description: {label: '描述', span: 12, type: 'textarea',disabled: objVal && objVal.registrationStatus === '1' ? true : false},
agentVersion: {label: 'AGENT版本', span: 12, type: 'input',hidden: objVal && objVal.id ? false : true, disabled: objVal && objVal.id ? true : false},
// customerName: {label: '设备业务客户', span: 12, type: 'input'},
// serviceNumber: {label: '业务号', span: 12, type: 'input'},
// agentWeek: {label: 'Agent与交换机心跳检测周期', span: 12, type: 'input', disabled: true},
// agentNum: {label: 'Agent与交换机心跳检测次数', span: 12, type: 'input', disabled: true},
// agentOID: {label: 'Agent与交换机心跳检测OID', span: 12, type: 'input', disabled: true},
}
}];
},
// 获取详情
getFormDataList(id) {
getHandle(id).then(val => {
this.ruleForm = val && val.data;
this.fnFormList(this.ruleForm);
}).catch(() => {
this.fnFormList(this.ruleForm);
this.$modal.msgError("操作失败")
});
},
// 监听事件
callback(result, dataVal, formVal) {
if (result && result.fnCode) {
switch (result.fnCode) {
case 'snmpDetect':
if (dataVal === '1') {
this.formList[0].controls.resourceVersion['hidden'] = false;
this.formList[0].controls.rwPermission['hidden'] = false;
this.formList[0].controls.snmpCollectAddr['hidden'] = false;
this.formList[0].controls.snmpCollectPort['hidden'] = false;
this.formList[0].controls.teamName['hidden'] = false;
} else {
this.formList[0].controls.resourceVersion['hidden'] = true;
this.formList[0].controls.rwPermission['hidden'] = true;
this.formList[0].controls.snmpCollectAddr['hidden'] = true;
this.formList[0].controls.snmpCollectPort['hidden'] = true;
this.formList[0].controls.teamName['hidden'] = true;
}
break;
case 'submit':
let fnType = addHandle;
if (dataVal && dataVal.id) {
fnType = updateHandle;
}
fnType(dataVal).then(response => {
this.$modal.msgSuccess(response.msg);
this.$router.push("/resource/register")
}).catch(() => {
this.$modal.msgError("操作失败")
});
break;
case 'cancel':
this.$router.push("/resource/register")
break;
default:
}
}
}
}
}
</script>
<style>
</style>
+248
View File
@@ -0,0 +1,248 @@
<template>
<div class="app-container pageTopForm">
<el-form :model="queryParams" ref="queryRef" v-show="showSearch" size="small" label-width="auto">
<el-col :span="6">
<el-form-item label="资源名称" prop="resourceName">
<el-input
v-model="queryParams.resourceName"
placeholder="请输入交换机名称/服务器名称"
clearable
@keyup.enter.native="handleQuery"/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="资源类型" prop="resourceType">
<el-select
v-model="queryParams.resourceType"
placeholder="请选择资源类型"
clearable>
<el-option
v-for="dict in dict.type.rm_register_resource_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="Agent注册状态" title="Agent注册状态" prop="registrationStatus">
<el-select
v-model="queryParams.registrationStatus"
placeholder="请选择Agent注册状态"
clearable>
<el-option
v-for="dict in dict.type.rm_register_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="Agent在线状态" title="Agent在线状态" prop="onlineStatus">
<el-select
v-model="queryParams.onlineStatus"
placeholder="请选择Agent在线状态"
clearable>
<el-option
v-for="dict in dict.type.rm_register_online_state"
:key="dict.value"
:label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="交换机在线状态" title="交换机在线状态" prop="switchStatus">
<el-select
v-model="queryParams.switchStatus"
placeholder="请选择交换机在线状态"
clearable>
<el-option
v-for="dict in dict.type.rm_register_online_state"
:key="dict.value"
:label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<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_register_resource_type" :value="row.resourceType"/>
</template>
<!-- 端口 -->
<template #tempPort="{ row, column }">
<dict-tag :options="dict.type.rm_register_port" :value="row.resourcePort"/>
</template>
<!-- 协议 -->
<template #tempProtocol="{ row, column }">
<dict-tag :options="dict.type.rm_register_protocol" :value="row.protocol"/>
</template>
<!-- 注册状态 -->
<template #tempStatus="{ row, column }">
<dict-tag :options="dict.type.rm_register_status" :value="row.registrationStatus"/>
</template>
<!-- 在线状态 -->
<template #tempOnlineStatus="{ row, column }">
<dict-tag :options="dict.type.rm_register_online_state" :value="row.onlineStatus"/>
</template>
</TableList>
</div>
</template>
<script setup name="Register">
import {listHandle, updateregisterType} from "@/api/disRevenue/resource"
import TableList from "@/components/table/index.vue"
export default {
name: 'RegisterIndex',
components: {TableList},
dicts: ['rm_register_resource_type', 'rm_register_protocol', 'rm_register_status', 'rm_register_port', 'rm_register_online_state'],
data() {
return {
roleList: [],
loading: true,
showSearch: true,
ids: [],
single: true,
meltiple: true,
// 列显隐信息
columns: {
id: { label: `ID`,width: '80'},
hardwareSn: { label: `硬件SN`,minWidth: '250', visible: true },
resourceType: { label: `资源类型`, minWidth: '100', slotName: 'tempType', visible: true },
resourceName: { label: `资源名称`, visible: true, minWidth: '200'},
ipAddress: { label: `IP地址`, minWidth: '200', visible: true },
resourcePort: { label: `端口`, slotName: 'tempPort', minWidth: '80', visible: true },
protocol: { label: `协议`, minWidth: '80', slotName: 'tempProtocol', visible: true },
registrationStatus: { label: `Agent注册状态`, slotName: 'tempStatus', minWidth: '120', visible: true },
onlineStatus: { label: `Agent在线状态`, slotName: 'tempOnlineStatus', minWidth: '120', visible: true },
switchStatus: { label: `交换机在线状态`, slotName: 'tempOnlineStatus', minWidth: '120', visible: true }
},
config: {
searcherForm: [
{label: '交换机名称', prop: 'roleName', type: 'selset', options: []}
],
tableButton: {
top: [
{content: '新增', fnCode: 'add', type: 'primary', icon: 'el-icon-plus', hasPermi: 'resource:register:add'},
{content: '导出', fnCode: 'export', type: 'warning', icon: 'el-icon-download', hasPermi: 'resource:register:export'},
],
line: [
{content: '修改', fnCode: 'edit', type: 'text', icon: 'el-icon-edit', hasPermi: 'resource:register:edit'},
{content: '注册', fnCode: 'enroll', showName: 'registrationStatus', showVal: '0', type: 'text', icon: 'el-icon-circle-check', hasPermi: 'resource:register:enroll'},
{content: '取消注册', fnCode: 'unenroll', showName: 'registrationStatus', showVal: '1', type: 'text', icon: 'el-icon-circle-close', hasPermi: 'resource:register:unenroll'},
]
}
},
queryParams: {
pageNum: 1,
pageSize: 10,
total: 0
}
}
},
created() {
this.getList();
},
methods: {
// 处理子组件传递的新值
handleValueChange(newValue) {
// 父组件更新自身数据,实现同步
this.showSearch = newValue;
// console.log('父组件拿到新值:', newValue);
},
/** 查询角色列表 */
getList() {
this.loading = true
listHandle(this.addDateRange(this.queryParams)).then(response => {
this.roleList = response.rows;
this.queryParams.total = response.total;
this.loading = false;
})
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.$refs['queryRef'].resetFields();
this.queryParams = {pageNum: 1, pageSize: 10,total: 0};
// this.resetForm("queryRef");
this.handleQuery();
},
/** 多选框选中数据 */
handleSelectionChange(selection) {
this.ids = selection.map(item => item.roleId);
this.single = selection.length != 1;
this.multiple = !selection.length;
},
callback(result, rowData, selectChange) {
if (result && result.fnCode) {
switch (result.fnCode) {
case 'add':
this.$router.push("/resource/register/edit/index")
break;
case 'edit':
this.$router.push({
path:'/resource/register/edit/index/',
query: {id: rowData.id}
});
break;
case 'enroll':
rowData['registrationStatus'] = '1';
updateregisterType(rowData).then(res => {
this.$modal.msgSuccess("注册成功!");
this.getList();
});
break;
case 'unenroll':
let content = '<p style="font-size: 1rem;font-weight: 600;">资源进行取消注册操作</p>' +
'<p style="height: 0px;margin:10px 0 50px;">相关的服务器收益或者交换机带宽收益记录中将不在统计相关信息,拓扑中也会将相关的连接删除</p>';
this.$modal.confirm(content).then(() => {
rowData['registrationStatus'] = '0';
updateregisterType(rowData).then(res => {
this.$modal.msgSuccess("取消注册成功!");
this.getList();
});
}).catch(() => {});
break;
case 'export':
// let dataList = [];
// Object.keys(this.columns).forEach(item => {
// if (item.visible) {
// dataList.push(item.prop);
// }
// });
// this.download("/system/registration/export", {properties: dataList,}, `资源管理_${new Date().getTime()}.xlsx`);
let paramsList = Object.assign({}, this.queryParams,rowData);
this.download("system/registration/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>
@@ -0,0 +1,319 @@
<template>
<div class="app-container">
<el-row :gutter="20">
<splitpanes :horizontal="this.$store.getters.device === 'mobile'" class="default-theme">
<!--部门数据-->
<pane size="23">
<el-col>
<div class="head-container">
<span class="mb10 disInlineBlock">资源分组</span>
<!-- <el-input v-model="deptName" placeholder="请输入部门名称" clearable size="small" prefix-icon="el-icon-search" style="margin-bottom: 20px" />-->
</div>
<div class="head-container">
<el-tree :data="deptOptions" :props="defaultProps" :current-node-key="currentNodeKey" :expand-on-click-node="false" :filter-node-method="filterNode" ref="tree" node-key="id" default-expand-all highlight-current @node-click="handleNodeClick" />
</div>
</el-col>
</pane>
<!--用户数据-->
<pane size="77">
<el-form :model="queryParams" ref="queryRef" v-show="showSearch" size="small" label-width="80px">
<el-col :span="9">
<el-form-item label="资源名称" prop="queryName">
<el-input
v-model="queryParams.queryName"
placeholder="请输入资源名称/硬件SN"
clearable
@keyup.enter.native="handleQuery(1)"
/>
</el-form-item>
</el-col>
<el-col :span="9">
<el-form-item label="资源类型" prop="resourceType">
<el-select
v-model="queryParams.resourceType"
placeholder="请选择资源类型"
clearable>
<el-option
v-for="dict in dict.type.rm_register_resource_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item class="lastBtnSty">
<el-button type="primary" size="mini" icon="Search" @click="handleQuery(1)">搜索</el-button>
<el-button icon="Refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-col>
</el-form>
<input type="file" ref="fileInput" @change="handleFileChange" style="display: none;">
<TableList :columns="columns" :config="config" :modelIdent="this.$options.name" :queryParams="queryParams" :tableList="roleList" @fnClick="callback" @fnRenderList="getList" @value-change="handleValueChange">
<!-- <template v-slot:tableExpand="slotProps">-->
<!-- <div v-for="(val, key) of expandList" style="padding: 5px 0 5px 70px;">-->
<!-- <div style="width: 150px;" class="ml10 disInlineBlock">{{val}}</div>-->
<!-- <div class="ml10 disInlineBlock">{{slotProps.row[key]}}</div>-->
<!-- </div>-->
<!-- </template>-->
<!-- 资源类型 -->
<template #tempResType="{ row, column }">
<dict-tag :options="dict.type.rm_register_resource_type" :value="row.resourceType"/>
</template>
<!-- 在线状态 -->
<template #tempOnlineStatus="{ row, column }">
<dict-tag :options="dict.type.rm_register_online_state" :value="row.onlineStatus"/>
</template>
</TableList>
<!-- 新建文件夹 -->
<el-dialog title="命令执行结果" :visible.sync="open" width="800px" append-to-body>
<div class="block">
<el-timeline :reverse="true">
<el-timeline-item v-for="item of timelineList" :timestamp="item.createTime" placement="top">
<pre>{{item.content}}</pre>
</el-timeline-item>
</el-timeline>
</div>
</el-dialog>
</pane>
</splitpanes>
</el-row>
</div>
</template>
<script setup>
import TableList from "@/components/table/index.vue"
import EchartsPie from "@/components/echartsList/pie.vue"
import {listRegisterList, delTopology, getResGroupList, getScriptResultBySn} from "@/api/disRevenue/resource"
import { Splitpanes, Pane } from "splitpanes"
import Treeselect from "@riophae/vue-treeselect"
import "@riophae/vue-treeselect/dist/vue-treeselect.css"
import "splitpanes/dist/splitpanes.css"
export default {
name: 'RemoteManage',
components: {TableList,EchartsPie, Splitpanes, Pane, Treeselect},
dicts: ['rm_register_online_state', 'rm_register_resource_type'],
data() {
return {
loading: true,
// 部门名称
deptName: undefined,
// 所有部门树选项
deptOptions: undefined,
defaultProps: {
children: "children",
label: "label",
disabled: true
},
currentNodeKey: 0, // 默认选中
showSearch: true,
roleList: [],
queryParams: {
total: 0,
pageNum: 1,
pageSize: 10,
queryName: '',
resourceType: ''
},
// 列显隐信息
columns: {
id: { label: `ID`, width: '50', visible: false },
resourceName: { label: `资源名称`, minWidth: '250', visible: true },
hardwareSn: { label: `硬件SN`, minWidth: '200'},
description: { label: `描述`, minWidth: '200'},
resourceType: { label: `资源类型`, minWidth: '100', slotName: 'tempResType'},
inIp: { label: `内网IP`, minWidth: '160', visible: true},
ipAddress: { label: `公网IP`, minWidth: '200', visible: true },
resourcePort: { label: `管理端口`, minWidth: '160', visible: true},
onlineStatus: { label: `在线状态`, minWidth: '160', slotName: 'tempOnlineStatus'},
},
config: {
// expand: true, // 表格下拉
tableButton: {
line: [
{content: '详情', fnCode: 'details', type: 'text', icon: 'el-icon-view', hasPermi: 'resource:fileManage:details'},
// {content: '修改', fnCode: 'edit', type: 'text', icon: 'el-icon-edit', hasPermi: 'disRevenue:resource:fileManage:edit'},
{content: '查看脚本执行结果', fnCode: 'result', type: 'text', icon: 'el-icon-s-check', hasPermi: 'resource:fileManage:result'},
{}
]
}
},
expandList: {
switchName: '接口名称',
switchSn: 'MAC地址',
interfaceName: '接口类型',
serverName: 'IPv4地址',
},
timelineList: [
{content: '【服务器节点名称1】执行脚本命令', time: '2025-12-12 12:12:12'},
{content: '【服务器节点名称1】执行脚本命令', time: '2025-12-11 12:12:12'},
{content: '【服务器节点名称1】执行脚本命令', time: '2025-12-10 12:12:12'}
],
open: false,
title: '',
moveList: [],
catalogList: null,
formList:{
switchName: '',
remarks: ''
}
}
},
watch: {
// 根据名称筛选部门树
deptName(val) {
this.$refs.tree.filter(val)
}
},
created() {
this.getDeptTree();
},
methods: {
// 处理文件选择
handleFileChange(e) {
// console.log('e====',e);
// const file = e.target.files[0] // 获取第一个选中的文件
// if (file) {
// selectedFile = file
// selectedFileName = file.name // 显示文件名
// // 可选:自动上传
// // uploadFile()
// } else {
// clearFile() // 未选择文件时清空
// }
},
/** 查询部门下拉树结构 */
getDeptTree() {
getResGroupList().then(res => {
if (res && res.data) {
let treeList = [{id: 0, label: '所有资源', disabled: false}];
res.data && res.data.forEach(item => {
treeList.push({id: item.id, label: item.groupName, disabled: false});
});
this.deptOptions = treeList;
this.$refs.tree.setCurrentKey(0);
this.getList();
}
})
},
// 筛选节点
filterNode(value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1
},
// 节点单击事件
handleNodeClick(data) {
if (data.id === 0) {
delete this.queryParams.id;
} else {
this.queryParams.id = data.id;
}
this.handleQuery();
},
/** 查询列表 */
getList() {
this.loading = true;
listRegisterList(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(val) {
if (val && val === 1) {
delete this.queryParams.id;
this.$refs.tree.setCurrentKey(0);
}
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryRef");
this.handleQuery(1);
},
submitForm(num){
if (num === 1) {
this.$refs['noticeRef'].validate((valid) => {
if (!valid) {
return false;
}
this.open = false;
});
}
},
/** 取消按钮 */
cancel(val) {
this.open = false;
},
callback(result, rowData, selectChange, selectList) {
if (result && result.fnCode) {
switch (result.fnCode) {
case 'edit':
this.$router.push({
path:'/resource/remoteManage/view',
query:{
id: rowData.id
}
});
break;
case 'details':
this.$router.push({
path:'/resource/remoteManage/view',
query:{
hardwareSn: rowData.hardwareSn,
readonly: true
}
});
break;
case 'result':
this.open = true;
// 获取详情
getScriptResultBySn({hardwareSn: rowData.hardwareSn}).then(val => {
this.timelineList = val && val.data && val.data.scriptResult || [];
}).catch(() => {
this.$modal.msgError("操作失败")
});
break;
case 'delete':
this.$modal.confirm('是否确认删除数据项?').then(function() {
return delTopology(selectChange)
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功")
}).catch(() => {});
break;
default:
}
}
}
}
}
</script>
<style scoped>
::v-deep .lastBtnSty .el-form-item__content{
margin-left: 10px!important;
}
::v-deep .el-table__expanded-cell {
background: #f2f2f2!important;
}
::v-deep .el-timeline .el-timeline-item:last-child .el-timeline-item__tail {
display: block!important;
}
::v-deep .el-tree-node__label {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>
@@ -0,0 +1,139 @@
<template>
<div class="app-container mt20">
<Form :formList="formList" :ruleFormData="ruleForm" :config="paramsData && paramsData.readonly === 'true' ? {buttonGroup: []} : {}" @fnClick="callback"></Form>
<div v-if="paramsData && paramsData.readonly === 'true'" class="w100 mt50">
<!-- <p style="font-size: 1.2rem;font-weight: 500;border-bottom: 1px solid #e7e7e7;">{{netWorkCard.title}}</p>-->
<!-- <div v-for="item of netWorkCard.list" class="mt50">-->
<!-- <div v-for="(val,index) of item.data" style="width: 80%;margin: auto;" :class="index + 1 === item.data.length ? 'border' : 'borderType'">-->
<!-- <div style="width: 20%;border-right: 1px solid #e7e7e7;" class="ml10 disInlineBlock"><p>{{val.name}}</p></div>-->
<!-- <p style="width: 75%" class="ml10 disInlineBlock">{{val.content}}</p>-->
<!-- </div>-->
<!-- </div>-->
<p style="font-size: 1.2rem;font-weight: 500;border-bottom: 1px solid #e7e7e7;">命令执行结果</p>
<el-timeline reverse="true">
<el-timeline-item v-for="item of timelineList" :timestamp="item.createTime" placement="top">
<pre>{{item.content}}</pre>
</el-timeline-item>
</el-timeline>
</div>
<el-button v-if="paramsData && paramsData.readonly === 'true'" type="primary" class="mb20 mt20" style="float: right;" @click="callback({fnCode: 'cancel'})">返回</el-button>
</div>
</template>
<script setup name="Handle">
import Form from '@/components/form/index.vue';
import {addGroup, getScriptResultBySn, updateGroup, resNameList} from "@/api/disRevenue/resource"
export default {
name: 'RemoteManageView',
components: {Form},
dicts: ['rm_register_online_state', 'rm_register_resource_type'],
data() {
return {
ruleForm: {},
formList: [],
paramsData: {},
netWorkCard: {
title: '网卡信息',
list: [
{
data: [
{name: '接口名称', content: 'eno1(Intel Corporation Ethernet Connection X722 for 10GbE SFP+)'},
{name: 'MAC地址', content: '7c:c3:85:b6:61:bf'},
{name: '接口类型', content: 'Ethernet'},
{name: 'IPv4地址', content: '172.16.15.103'}
]
},
{
data: [
{name: '接口名称', content: 'eno1(Intel Corporation Ethernet Connection X722 for 10GbE SFP+)'},
{name: 'MAC地址', content: '7c:c3:85:b6:61:bf'},
{name: '接口类型', content: 'Ethernet'},
{name: 'IPv4地址', content: '172.16.15.103'}
]
},
]
},
timelineList: [
{content: '【服务器节点名称1】执行脚本命令', time: '2025-12-12 12:12:12'},
{content: '【服务器节点名称1】执行脚本命令', time: '2025-12-11 12:12:12'},
{content: '【服务器节点名称1】执行脚本命令', time: '2025-12-10 12:12:12'}
],
}
},
created() {
this.paramsData = this.$route && this.$route.query;
if (this.paramsData && this.paramsData.hardwareSn) {
this.getFormDataList(this.paramsData.hardwareSn);
}
this.fnFormList();
},
methods: {
// formList集合
fnFormList(objVal) {
this.formList = [{
config: {title: '', colSpan: 'disBlock', readonly: this.paramsData.readonly},
controls: {
id: {label: 'ID',hidden: true},
hardwareSn: {label: '硬件SN', span: 12, type: 'input', disabled: true},
resourceType: {label: '资源类型', span: 12, type: 'select', options: this.dict.type.rm_register_resource_type, disabled: false},
resourceName: {label: '资源名称', span: 12, type: 'input', disabled: true},
description: {label: '描述', span: 12, type: 'textarea'},
inIp: {label: '内网IP', span: 12, type: 'input'},
ipAddress: {label: '外网IP', span: 12, type: 'input'},
resourcePort: {label: '管理端口', span: 12, type: 'input'},
onlineStatus: {label: '在线状态', span: 12, type: 'select', options: this.dict.type.rm_register_online_state, disabled: true},
md5: {label: '连接方式', span: 12, type: 'select'},
}
}];
},
// 获取详情
getFormDataList(id) {
getScriptResultBySn({hardwareSn: id}).then(val => {
if (val && val.data && val.data.resourceMsg) {
// val.data.resourceMsg.resourceType = Number(val.data.resourceMsg.resourceType);
this.ruleForm = val.data.resourceMsg;
}
this.timelineList = val && val.data && val.data.scriptResult || [];
}).catch(() => {
this.$modal.msgError("操作失败")
});
},
// 监听事件
callback(result, dataVal, formVal) {
if (result && result.fnCode) {
switch (result.fnCode) {
// case 'submit':
// let fnType = addGroup;
// if (dataVal && dataVal.id) {
// fnType = updateGroup;
// }
// fnType(dataVal).then(response => {
// this.$modal.msgSuccess(response.msg);
// this.$router.push("/resource/fileManage")
// }).catch(() => {
// this.$modal.msgError("操作失败")
// });
// break;
case 'cancel':
this.$router.push("/resource/remoteManage");
break;
default:
}
}
}
}
}
</script>
<style scoped>
.borderType {
border-top: 1px solid #e7e7e7;
border-left: 1px solid #e7e7e7;
border-right: 1px solid #e7e7e7;
}
.border {
border: 1px solid #e7e7e7;
}
::v-deep .el-timeline .el-timeline-item:last-child .el-timeline-item__tail {
display: block!important;
}
</style>
+173
View File
@@ -0,0 +1,173 @@
<template>
<div class="app-container app-viewContent">
<Form :formList="formList" :ruleFormData="ruleForm" :config="{buttonGroup: []}" @fnClick="callback"></Form>
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="监控项" name="first">
<ResMonitorDigitalSuper></ResMonitorDigitalSuper>
</el-tab-pane>
<el-tab-pane label="自动发现项" name="second">
<ResMonitorDigitalAutoFind v-if="activeName === 'second'"></ResMonitorDigitalAutoFind>
</el-tab-pane>
<el-tab-pane label="告警信息" name="third">
<TableList style="height: 500px" class="w100" :config="{colHiddenCheck: true, colTopHiddenIcon: true}" :columns="columns" :queryParams="queryParams" :tableList="tableList" @fnRenderList="getList"></TableList>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script setup>
import Form from '@/components/form/index.vue';
import TableList from "@/components/table/index.vue"
import {listAllBusinessList, calculateAvg} from "@/api/disRevenue/earnManage"
import {listAllResourList, listTopology} from "@/api/disRevenue/resource"
import EchartsLine from "@/components/echartsList/line.vue";
import ResMonitorDigitalSuper from "./digitalSuper";
import ResMonitorDigitalAutoFind from "./digitalAutoFind";
export default {
name: 'ResMonitorDetails',
components: {Form, TableList, EchartsLine, ResMonitorDigitalSuper, ResMonitorDigitalAutoFind},
dicts: ['rm_topology_type', 'rm_register_online_state', 'rm_register_resource_type'],
data() {
return {
ruleForm: {},
formList: [],
ruleFormTow: {},
formListTow: [],
paramsData: {},
activeName: 'first',
linuxSystem: [],
columns: {
id: { label: `ID`, width: '50', visible: false },
switchSn: { label: `源IP`, minWidth: '200', visible: true},
switchName: { label: `发生时间`, minWidth: '250', visible: true },
interfaceName: { label: `状态`, minWidth: '100', visible: true },
connectedDeviceType: { label: `内容`, minWidth: '250', visible: true },
},
queryParams: {
pageNum: 1,
pageSize: 10,
total: 0,
},
tableList: []
}
},
created() {
// this.paramsData = this.$route && this.$route.query;
this.fnFormList('1');
// this.switchList();
},
methods: {
handleClick(tab, event) {
if (tab && tab.index === '1') {
// this.secondList();
} else if (tab && tab.index === '2') {
this.getList();
}
},
// formList集合
fnFormList(num) {
this.formList = [{
config: {title: '基本信息'},
controls: {
id: {label: 'ID',hidden: true},
hardwareSn: {label: '硬件SN', span: 12, type: 'input',disabled: true},
resourceType: {label: '资源类型', span: 12, type: 'select',disabled: true, options: this.dict.type.rm_register_resource_type},
resourceName: {label: '资源名称', span: 12, type: 'input', disabled: true},
ipAddress: {label: 'IP地址', span: 12, type: 'input',disabled: true},
onlineStatus: {label: '在线状态', span: 12, type: 'select',disabled: true, options: this.dict.type.rm_register_online_state},
switchName: {label: '关联监控模版', span: 12, type: 'select',disabled: true},
resourceGroup: {label: '所属资源组', span: 12, type: 'select',disabled: true},
cpu: {label: 'CPU使用率%', span: 12, type: 'input',disabled: true},
neicun: {label: '内存使用率%', span: 12, type: 'input',disabled: true},
gaojing: {label: '未处理告警数', span: 12, type: 'input',disabled: true},
}
}];
let formFirst = [
{name: '系统描述', value: 'aaa'},
{name: '系统位置', value: 'aaa'},
{name: '系统Object ID', value: 'aaa'},
{name: '系统MAC地址', value: 'aaa'},
{name: '系统运行时间', value: 'aaa'},
{name: '设备名称', value: 'aaa'},
{name: '系统联系信息', value: 'aaa'},
{name: '设备软件版本', value: 'aaa'},
{name: '系统名称', value: 'aaa'},
];
let formSecond = [
{name: '总内存', value: 'aaa'},
{name: '操作系统', value: 'aaa'},
{name: '操作系统架构', value: 'aaa'},
{name: '最大进程数', value: 'aaa'},
{name: '硬盘总可用空间', value: 'aaa'},
{name: '系统启动时间', value: 'aaa'},
{name: '系统描述', value: 'aaa'},
{name: '系统正常运行时间', value: 'aaa'},
{name: '系统本地时间', value: 'aaa'},
{name: 'CPU数量', value: 'aaa'},
];
this.formListTow = num && num === '1' ? formFirst : formSecond;
},
getList() {
this.loading = true;
listTopology(this.addDateRange(this.queryParams)).then(response => {
this.tableList = response.rows;
this.queryParams.total = response.total;
this.loading = false;
})
},
// 获取交换机下拉
switchList() {
listAllResourList({resourceType: this.paramsData.resourceType}).then(val => {
this.formList[0].controls.nodeName['options'] = val && val.map(item => {
return Object.assign({label: item.resourceName, value: item.resourceName});
});
});
listAllBusinessList().then(val => {
this.formList[0].controls.businessName['options'] = val && val.data.map(item => {
return Object.assign({label: item.businessName, value: item.id});
});
});
},
// 监听事件
callback(result, dataVal, formVal) {
if (result && result.fnCode) {
switch (result.fnCode) {
case 'businessName':
if (dataVal) {
formVal.options.forEach(item => {
if (item.value === dataVal) {
this.$set(this.ruleForm, 'businessName', item.label);
}
});
this.$set(this.ruleForm, 'code', dataVal);
}
break;
case 'submit':
dataVal['resourceType'] = this.paramsData.resourceType;
calculateAvg(dataVal).then(response => {
this.$modal.msgSuccess(response.msg);
if (this.paramsData && this.paramsData.resourceType === '1') {
this.$router.push("/earnManage/server");
}
// else {
// this.$router.push("/disRevenue/earnManage/switch");
// }
}).catch(() => {
this.$modal.msgError("操作失败")
});
break;
case 'cancel':
if (this.paramsData && this.paramsData.resourceType === '1') {
this.$router.push("/earnManage/server");
}
// else {
// this.$router.push("/disRevenue/earnManage/switch");
// }
break;
default:
}
}
}
}
}
</script>
@@ -0,0 +1,126 @@
<template>
<div style="padding: 8px 20px 20px;">
<el-collapse v-model="activeNames">
<el-collapse-item v-for="(val,index) of linuxSystem" :title="val.title" :name="index">
<div class="mt10 w100">
<!-- <Form :formList="val.formList" :ruleFormData="val.formModel" :config="val.config" @fnClick="callback"></Form>-->
<div class="w100 plr-20" style="font-size: 14px">
<div v-for="item of val.formList" class="w50 disInlineBlock p10">
<span class="w50 disInlineBlock">{{item.name}}</span><span class="w50">{{item.value}}</span>
</div>
</div>
<div v-for="item of val.echartList" class="w100 mt20 mb20" style="height: 200px;border-top: 1px solid #d8dce5">
<EchartsLine class="w100 h100" :sideIcon="{iconName: [{name: '添加到首页',type: 'add'}]}" :lineData="item.dataVal" :title="item.title" :chartData="(valData) => chartDataEvent(valData, item)"></EchartsLine>
</div>
</div>
</el-collapse-item>
</el-collapse>
</div>
</template>
<script setup>
import EchartsLine from "@/components/echartsList/line.vue";
export default {
name: 'ResMonitorDigitalAutoFind',
components: {EchartsLine},
data() {
return {
activeNames: [0, 1],
linuxSystem: [],
}
},
created() {
// this.$nextTick(() => {
this.secondList();
// });
},
methods: {
// 第二节点 自动发现项
secondList(){
this.linuxSystem = [{
title: '网络端口GE1/0/1',
formList: [
{name: '端口名称', value: 'aaa'},
{name: '端口类型', value: 'aaa'},
{name: '端口状态', value: 'aaa'},
{name: '端口适配速率(Mbps)', value: 'aaa'},
],
formModel: {},
config: {labelWidth: '160px', buttonGroup: []},
echartList: [{
title: '设备CPU使用率(%)',
dataVal: {
titleVal: {textAlign: 'left', left: '1%'},
gridTop: '35%',
legend: {top: '15%', left: '10%'},
lineXData: ['2025-9-1', '2025-9-2', '2025-9-3', '2025-9-4', '2025-9-5', '2025-9-6', '2025-9-7'],
dataList: [{
name: '设备CPU使用率',
data: [120, 132, 101, 134, 90, 230, 210],
}]
}
},{
title: '设备内存使用率(%)',
dataVal: {
titleVal: {textAlign: 'left', left: '1%'},
gridTop: '35%',
legend: {top: '15%', left: '10%'},
lineXData: ['2025-9-1', '2025-9-2', '2025-9-3', '2025-9-4', '2025-9-5', '2025-9-6', '2025-9-7'],
dataList: [{
name: '设备内存使用率',
data: [120, 132, 101, 134, 90, 230, 210],
},{
name: 'CPU运行用户进程所花费的时间',
data: [220, 182, 191, 234, 290, 330, 310]
}]
}
}]
},{
title: '光模块sabc',
formList: [{name: '光模块端口名称', value: 'aaa'}],
formModel: {},
config: {buttonGroup: []},
echartList: [{
title: '设备CPU使用率(%)',
dataVal: {
titleVal: {textAlign: 'left', left: '1%'},
gridTop: '35%',
legend: {top: '15%', left: '10%'},
lineXData: ['2025-9-1', '2025-9-2', '2025-9-3', '2025-9-4', '2025-9-5', '2025-9-6', '2025-9-7'],
dataList: [{
name: '设备CPU使用率',
data: [120, 132, 101, 134, 90, 230, 210],
}]
}
},{
title: '设备内存使用率(%)',
dataVal: {
titleVal: {textAlign: 'left', left: '1%'},
gridTop: '35%',
legend: {top: '15%', left: '10%'},
lineXData: ['2025-9-1', '2025-9-2', '2025-9-3', '2025-9-4', '2025-9-5', '2025-9-6', '2025-9-7'],
dataList: [{
name: '设备内存使用率',
data: [120, 132, 101, 134, 90, 230, 210],
},{
name: 'CPU运行用户进程所花费的时间',
data: [220, 182, 191, 234, 290, 330, 310]
}]
}
}]
}];
},
chartDataEvent(val, itemVal) {
console.log('val===',val);
}
}
}
</script>
<style scoped>
::v-deep .el-collapse-item__header {
background-color: #d4e3fc!important;
/*color: #fff!important;*/
padding-left: 20px;
font-size: 1rem;
}
</style>
@@ -0,0 +1,91 @@
<template>
<div style="padding: 8px 20px 20px;">
<div class="w100 plr-20" style="font-size: 14px">
<div v-for="item of formListTow" class="w50 disInlineBlock p10">
<span class="w50 disInlineBlock">{{item.name}}</span><span class="w50">{{item.value}}</span>
</div>
</div>
<div v-for="item of resultData" class="w100 mt20 mb20" style="height: 200px;border-top: 1px solid #d8dce5">
<EchartsLine class="w100 h100" :sideIcon="{iconName: [{name: '添加到首页',type: 'add'}]}" :lineData="item.dataVal" :title="item.title" :chartData="(valData) => chartDataEvent(valData, item)"></EchartsLine>
</div>
</div>
</template>
<script setup>
import EchartsLine from "@/components/echartsList/line.vue";
export default {
name: 'ResMonitorDigitalSuper',
components: {EchartsLine},
data() {
return {
formListTow: [],
paramsData: {},
resultData: [{
title: '设备CPU使用率(%)',
dataVal: {
titleVal: {textAlign: 'left', left: '1%'},
gridTop: '35%',
legend: {top: '15%', left: '10%'},
lineXData: ['2025-9-1', '2025-9-2', '2025-9-3', '2025-9-4', '2025-9-5', '2025-9-6', '2025-9-7'],
dataList: [{
name: '设备CPU使用率',
data: [120, 132, 101, 134, 90, 230, 210],
}]
}
},{
title: '设备内存使用率(%)',
dataVal: {
titleVal: {textAlign: 'left', left: '1%'},
gridTop: '35%',
legend: {top: '15%', left: '10%'},
lineXData: ['2025-9-1', '2025-9-2', '2025-9-3', '2025-9-4', '2025-9-5', '2025-9-6', '2025-9-7'],
dataList: [{
name: '设备内存使用率',
data: [120, 132, 101, 134, 90, 230, 210],
},{
name: 'CPU运行用户进程所花费的时间',
data: [220, 182, 191, 234, 290, 330, 310]
}]
}
}],
}
},
created() {
// this.paramsData = this.$route && this.$route.query;
this.fnFormList('1');
// this.switchList();
},
methods: {
// formList集合
fnFormList(num) {
let formFirst = [
{name: '系统描述', value: 'aaa'},
{name: '系统位置', value: 'aaa'},
{name: '系统Object ID', value: 'aaa'},
{name: '系统MAC地址', value: 'aaa'},
{name: '系统运行时间', value: 'aaa'},
{name: '设备名称', value: 'aaa'},
{name: '系统联系信息', value: 'aaa'},
{name: '设备软件版本', value: 'aaa'},
{name: '系统名称', value: 'aaa'},
];
let formSecond = [
{name: '总内存', value: 'aaa'},
{name: '操作系统', value: 'aaa'},
{name: '操作系统架构', value: 'aaa'},
{name: '最大进程数', value: 'aaa'},
{name: '硬盘总可用空间', value: 'aaa'},
{name: '系统启动时间', value: 'aaa'},
{name: '系统描述', value: 'aaa'},
{name: '系统正常运行时间', value: 'aaa'},
{name: '系统本地时间', value: 'aaa'},
{name: 'CPU数量', value: 'aaa'},
];
this.formListTow = num && num === '1' ? formFirst : formSecond;
},
chartDataEvent(val, itemVal) {
console.log('val===1111',val);
}
}
}
</script>
+288
View File
@@ -0,0 +1,288 @@
<template>
<div class="app-container pageTopForm">
<div class="w100 mb10" style="height: 125px;font-size: 14px">
<div v-for="(item,index) of headerList" class="disInlineBlock h100 verticalAlign" :style="`margin-right:${index + 1 === headerList.length ? 'none' : '1%'}`"
style="width: 32.66%; border: 1px solid #d8dce6;border-radius: 10px;padding: 10px 20px;">
<div>{{item.title}}</div>
<div class="mtb10">{{item.percent}}%</div>
<el-progress :percentage="item.percent" :show-text="false"></el-progress>
<div class="mt10" style="font-size: 12px">
<span><span class="mr10">{{item.btmOne}}</span>{{item.numOne}}</span>
<template v-if="index + 1 === headerList.length">
<br/>
<span><span class="mr10">{{item.btmTow}}</span>{{item.numTow}}</span>
</template>
<span v-else class="ml20"><span class="mr10">{{item.btmTow}}</span>{{item.numTow}}</span>
</div>
</div>
</div>
<el-row :gutter="20">
<splitpanes :horizontal="this.$store.getters.device === 'mobile'" class="default-theme">
<!--部门数据-->
<pane size="16">
<el-col>
<div class="head-container">
<el-input v-model="deptName" placeholder="请输入部门名称" clearable size="small" prefix-icon="el-icon-search" style="margin-bottom: 20px" />
</div>
<div class="head-container">
<el-tree :data="deptOptions" :props="defaultProps" :expand-on-click-node="false" :filter-node-method="filterNode" ref="tree" node-key="id" default-expand-all highlight-current @node-click="handleNodeClick" />
</div>
</el-col>
</pane>
<!--用户数据-->
<pane size="84">
<el-form :model="queryParams" ref="queryRef" v-show="showSearch" size="small" label-width="80px">
<el-col :span="7">
<el-form-item label="搜索" prop="switchName">
<el-input
v-model="queryParams.switchName"
placeholder="请输入硬件SN/资源名称/IP地址"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="资源类型" prop="bandwidthType">
<el-select
v-model="queryParams.bandwidthType"
placeholder="请选择资源类型"
clearable>
<el-option
v-for="dict in dict.type.rm_topology_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="在线状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="请选择在线状态"
clearable>
<el-option
v-for="dict in dict.type.rm_topology_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="5">
<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 }">
<div @click="fnDetails(row, '1')">
<a href="javascript:;" style="color: #51afff;text-decoration: underline;">{{row.connectedDeviceType}}</a>
</div>
</template>
<template #tempAuto="{ row, column }">
<div @click="fnDetails(row)">
<a href="javascript:;" style="color: #51afff;text-decoration: underline;">{{row.connectedDeviceType}}</a>
</div>
</template>
</TableList>
</pane>
</splitpanes>
</el-row>
</div>
</template>
<script setup>
import TableList from "@/components/table/index.vue"
import EchartsPie from "@/components/echartsList/pie.vue"
import {listTopology, delTopology} from "@/api/disRevenue/resource"
import {deptTreeSelect } from "@/api/system/user"
import { Splitpanes, Pane } from "splitpanes"
import "splitpanes/dist/splitpanes.css"
export default {
name: 'ResMonitor',
components: {TableList,EchartsPie, Splitpanes, Pane},
dicts: ['rm_topology_type'],
data() {
return {
loading: true,
// 部门名称
deptName: undefined,
// 所有部门树选项
deptOptions: undefined,
defaultProps: {
children: "children",
label: "label"
},
showSearch: true,
roleList: [],
queryParams: {
total: 0,
pageNum: 1,
pageSize: 10
},
// 列显隐信息
columns: {
id: { label: `ID`, width: '50', visible: false },
switchSn: { label: `硬件SN`, minWidth: '200', visible: true},
switchName: { label: `资源名称`, minWidth: '250', visible: true },
interfaceName: { label: `ip地址`, minWidth: '100', visible: true },
connectedDeviceType: { label: `监控项`, minWidth: '100', slotName: 'tempType', visible: true },
serverName: { label: `自动发现项`, minWidth: '120', slotName: 'tempAuto', visible: true},
serverSn: { label: `CPU使用率%`, minWidth: '120', visible: true},
serverPort: { label: `内存使用率`,minWidth: '120', visible: true }
},
config: {
searcherForm: [
{label: '交换机名称', prop: 'roleName', type: 'selset', options: []}
],
tableButton: {
// top: [
// {content: '导出', fnCode: 'export', type: 'warning', icon: 'el-icon-download', hasPermi: 'disRevenue:resource:resMonitor:export'},
// ],
line: [
{content: '详情', fnCode: 'details', type: 'text', icon: 'el-icon-view', hasPermi: 'resource:resMonitor:details'},
]
}
},
headerList: [
{title: '服务器在线率', percent: 50, btmOne: '服务器在线数', numOne: '1000', btmTow: '服务器总数', numTow: '2000'},
{title: '交换机在线率', percent: 50, btmOne: '交换机在线数', numOne: '1000', btmTow: '交换机总数', numTow: '2000'},
{title: '服务器整体发送带宽利用率', percent: 50, btmOne: '服务器发送带宽总量', numOne: '10020 Mbps', btmTow: '服务器总带宽', numTow: '2000000 Mbps'},
],
dataList: [{
centerVal: '56',
unit: '台',
center: ['20%', '50%'],
color: ['#31bb42', '#f96602'],
data: [
{ value: 36, name: '在线服务器' },
{ value: 20, name: '离线服务器' }
]
},{
centerVal: '10',
unit: '台',
center: ['20%', '50%'],
color: ['#1c7dbc', '#f80a4f'],
data: [
{ value: 8, name: '在线交换机' },
{ value: 2, name: '离线交换机' }
]
},{
centerVal: '82',
unit: '%',
center: ['20%', '50%'],
color: ['#1a7aff', '#f96602'],
data: [
{ value: 82, name: '服务器整体带宽利用率' },
{ value: 18, name: '离线交换机' }
]
}]
}
},
watch: {
// 根据名称筛选部门树
deptName(val) {
this.$refs.tree.filter(val)
}
},
created() {
this.getList();
this.getDeptTree();
},
methods: {
/** 查询部门下拉树结构 */
getDeptTree() {
deptTreeSelect().then(response => {
this.deptOptions = response.data;
})
},
// 筛选节点
filterNode(value, data) {
if (!value) return true
return data.label.indexOf(value) !== -1
},
// 节点单击事件
handleNodeClick(data) {
this.queryParams.deptId = data.id;
this.handleQuery();
},
/** 查询列表 */
getList() {
this.loading = true;
listTopology(this.addDateRange(this.queryParams)).then(response => {
this.roleList = response.rows;
this.queryParams.total = response.total;
this.loading = false;
})
},
fnDetails(row,type) {
if (type && type === '1') {
this.$router.push({
path:'/resource/resMonitor/digitalSuper',
query:{
id: row.id
}
});
} else {
this.$router.push({
path:'/resource/resMonitor/digitalAutoFind',
query:{
id: row.id
}
});
}
},
// 处理子组件传递的新值
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 'details':
this.$router.push({
path:'/resource/resMonitor/details/index',
query:{
id: rowData.id
}
});
break;
case 'delete':
this.$modal.confirm('是否确认删除数据项?').then(function() {
return delTopology(selectChange)
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功")
}).catch(() => {});
break;
default:
}
}
}
}
}
</script>
<style scoped>
::v-deep .lastBtnSty .el-form-item__content{
margin-left: 10px!important;
}
</style>
@@ -0,0 +1,448 @@
<template>
<div class="app-container">
<div style="display: flex; justify-content: center;">
<div class="w100">
<Form ref="formRef" :formList="formList" :config="{labelWidth: '140px',buttonGroup: []}" :ruleFormData="ruleFormData" @fnClick="callback"></Form>
</div>
</div>
<div>
<h3 style="padding: 15px 10px;border-bottom: 1px solid #ddd;">策略内容</h3>
<template v-if="!(paramsData && paramsData.readonly)">
<el-tabs v-model="activeName" class="plr-20">
<el-tab-pane label="监控项" name="first">
<el-collapse v-model="activeTwoName">
<el-collapse-item v-for="(item,key,index) of firstData" :title="item.title" :name="index">
<template v-if="key === 'cpu'">
<template slot="title">
<span class="disInlineBlock" style="width: 15%;">{{item.title}}</span>
<div style="font-size: 13px;margin-left: 10%;">
采集周期<el-select v-model="item['time']" id="selDisabled" :disabled="key === 'switchNet' ? true : false" clearable placeholder="请选择">
<el-option v-for="val in timeOptions" :key="val.value" :label="val.label" :value="val.value"></el-option>
</el-select>
</div>
</template>
<div class="plr-50">
<div v-for="city of item.checkList" class="w50 mt10 mb10 disInlineBlock fontSize15">
<span style="width: 250px" class="disInlineBlock">{{city.metricKey}}</span>
<span>{{city.metricName}}</span>
</div>
</div>
</template>
<template v-else>
<template slot="title">
<span class="disInlineBlock" style="width: 15%;">{{item.title}}</span>
<div style="font-size: 13px;margin-left: 10%;">
采集周期<el-select v-model="item.groupTime" id="selDisabled" clearable placeholder="请选择" @change="handleChangeTime(item)">
<el-option v-for="val in timeOptions" :key="val.value" :label="val.label" :value="val.value"></el-option>
</el-select>
</div>
</template>
<div>
<div class="plr-50">
<div v-for="city of item.checkList" class="w100 mt10 mb10 disInlineBlock fontSize15">
<div class="disInlineBlock w50">
<span style="width: 200px" class="disInlineBlock">{{ city.metricKey }}</span>
<span>{{city.metricName}}</span>
</div>
<div class="disInlineBlock" style="color: #606266">
采集周期<el-select v-model="city['time']" placeholder="请选择" clearable>
<el-option v-for="val in timeOptions" :key="val.value" :label="val.label" :value="val.value"></el-option>
</el-select>
</div>
</div>
</div>
</div>
</template>
</el-collapse-item>
</el-collapse>
</el-tab-pane>
<el-tab-pane label="自动发现项" name="second">
<el-collapse v-model="activeTwoName">
<el-collapse-item v-for="(item,key,index) of secondData" :title="item.title" :name="index">
<template slot="title">
<span class="disInlineBlock" style="width: 15%;">{{item.title}}</span>
<div style="font-size: 13px;margin-left: 10%;">
采集周期<el-select v-model="item['time']" id="selDisabled" :disabled="key === 'net' ? true : false" clearable placeholder="请选择">
<el-option v-for="val in timeOptions" :key="val.value" :label="val.label" :value="val.value"></el-option>
</el-select>
</div>
</template>
<div class="plr-50">
<div v-for="city of item.checkList" class="w100 mt10 mb10 disBlock fontSize15">
<span style="width: 300px" class="disInlineBlock">{{city.metricKey}}</span>
<span>{{city.metricName}}</span>
</div>
</div>
</el-collapse-item>
</el-collapse>
</el-tab-pane>
</el-tabs>
</template>
<template v-else>
<el-collapse v-model="activeTwoName">
<template v-for="(item,key,index) of firstData">
<el-collapse-item v-if="item.checkList && item.checkList.length > 0" :title="'监控项'" :name="index">
<template slot="title">
<span><span v-if="ruleFormData.priority === '1'">监控项>></span>{{item.title}}</span>
</template>
<div v-if="key === 'cpu'" class="plr-50">
<div class="plr-50">
<div>当前所有子项的采集周期均为{{item.timeLabel}}</div>
<div v-for="city of item.checkList" class="w50 mt10 mb10 disInlineBlock fontSize15">
<span style="width: 250px" class="disInlineBlock">{{city.metricKey}}</span>
<span>{{city.metricName}}</span>
</div>
</div>
</div>
<div v-else>
<div class="plr-50">
<div v-for="city of item.checkList" class="w100 mt10 mb10 disInlineBlock fontSize15">
<div class="disInlineBlock w50">
<span style="width: 200px" class="disInlineBlock">{{ city.metricKey }}</span>
<span>{{city.metricName}}</span>
</div>
<div class="disInlineBlock" style="color: #606266">
采集周期为{{city.timeLabel}}
</div>
</div>
</div>
</div>
</el-collapse-item>
</template>
<template v-for="(item,key,index) of secondData">
<el-collapse-item v-if="item.checkList && item.checkList.length > 0" :title="item.title" :name="index">
<template slot="title">
<span>自动发现项>>{{item.title}}</span>
</template>
<div class="plr-50">
当前所有子项的采集周期均为{{item.timeLabel}}
<div v-for="city of item.checkList" class="w100 mt10 mb10 disBlock fontSize15">
<span style="width: 300px" class="disInlineBlock">{{city.metricKey}}</span>
<span>{{city.metricName}}</span>
</div>
</div>
</el-collapse-item>
</template>
</el-collapse>
</template>
</div>
<el-button v-if="!(paramsData && paramsData.readonly)" style="float: right;margin-top: 12px;margin-left: 10px;" @click="cancel">取消</el-button>
<el-button v-if="!(paramsData && paramsData.readonly)" type="primary" style="float: right;margin-top: 12px;" @click="submit">提交</el-button>
<el-button v-if="paramsData && paramsData.readonly" style="float: right;margin-top: 12px;margin-left: 10px;" @click="cancel">返回</el-button>
</div>
</template>
<script>
import Form from '@/components/form/index.vue';
import {addResourcePolicy, updateResourcePolicy,getMonitorTempList, getMonitorPolicy, listAllSwitchName, getResMonitorGroup} from "@/api/disRevenue/resource"
export default {
name: "LinuxMonitorStratEdit",
components: {Form},
dicts: ['collection_cycle', 'policy_status'],
props: {
open: {
type: String,
default: () => {}
},
dialogRowData: {
type: Object,
default: (() => {})
}
},
watch: {
open: {
handler(val) {
if (val === 'type_true') {
this.paramsData = {};
this.$set(this.ruleFormData, 'deployDevice', this.dialogRowData.clientId);
} else if (val === 'type_false') {
// 清空form
this.$refs['formRef'].$refs.ruleForm.resetFields();
}
},
deep: true,
immediate: true
},
},
data() {
return {
activeName: 'first',
firstChangeTime: '',
activeTwoName: [0,1,2,3,4,5],
timeOptions: [],
ruleFormData: {},
formList: [],
firstData: {
cpu: {title: 'CPU监控', time: '',
checkList: []
},
other: {title: '其他监控', groupTime: '',
checkList: []
},
},
tempContent: {},
paramsData: {},
secondData: {
vfs: {title: '发现挂载文件系统', time: '',
checkList: []
},
net: {title: '发现网络接口', time: '300',
checkList: []
},
disk: {title: '发现硬盘设备', time: '',
checkList: []
},
docker: {title: '发现docker', time: '',
checkList: []
},
}
}
},
created() {
this.timeOptions = this.dict.type.collection_cycle;
this.paramsData = this.$route && this.$route.query;
if (this.open) {
this.paramsData = {};
this.$set(this.ruleFormData, 'deployDevice', this.dialogRowData.clientId);
}
if (this.paramsData && this.paramsData.id) {
this.getFormDataList(this.paramsData.id);
} else {
this.getDataList();
}
this.fnFormList();
},
methods: {
// formList集合
fnFormList(objVal) {
if (this.open) {
this.formList = [{
config: {},
controls: {
id: {label: 'ID',hidden: true},
policyName: {label: '策略名称', span: 18, type: 'input', required: true},
description: {label: '描述', span: 18, type: 'textarea'},
deployDevice: {label: '部署设备', span: 18, type: 'textarea', rows: 2, required: true},
}
}];
} else {
this.formList = [{
config: {readonly: this.paramsData && this.paramsData.readonly, colSpan: this.paramsData && this.paramsData.readonly ? '' : 'disBlock'},
controls: {
id: {label: 'ID',hidden: true},
policyName: {label: '策略名称', span: 12, type: 'input', required: true},
priority: {label: '优先级', span: 12, type: 'input', hidden: this.paramsData && this.paramsData.readonly ? false : true},
status: {label: '策略状态', span: 12, type: 'select',options: this.dict.type.policy_status, hidden: this.paramsData && this.paramsData.readonly ? false : true},
deployTime: {label: '下发策略时间', span: 12, type: 'datetime', hidden: this.paramsData && this.paramsData.readonly ? false : true},
createTime: {label: '创建时间', span: 12, type: 'datetime', hidden: this.paramsData && this.paramsData.readonly ? false : true},
createBy: {label: '创建人', span: 12, type: 'input',hidden: this.paramsData && this.paramsData.readonly ? false : true},
deployDevice: {label: '部署设备', span: 12, type: 'textarea', rows:15, required: true},
description: {label: '描述', span: 12, type: 'textarea'},
}
}];
}
},
// 获取详情
getFormDataList(id) {
this.tempContent = {};
getMonitorPolicy(id).then(val => {
if (val && val.data) {
if (val.data && val.data.policy){
if (this.paramsData && this.paramsData.readonly) {
val.data.policy.deployDevice = val.data.policy.deployDevice.replace(/\n/g, '<br>');
}
this.ruleFormData = val.data.policy;
}
this.tempContent = val.data['linux'];
}
this.getDataList();
}).catch(() => {
this.getDataList();
// this.$modal.msgError("操作失败")
});
},
getDataList() {
let itemTypeList = ['monitorItem', 'autodiscoverItem'];
itemTypeList.forEach(item => {
let params = {resourceType: 'linux', itemType: item};
this.fnGetMonitorTempList(params);
});
},
// 通过监控模版选项 查询监控策略展示项
fnGetMonitorTempList(params) {
let obj = {};
this.timeOptions.forEach(item => {
obj[item.value] = item.label;
});
getMonitorTempList(params).then(res => {
if (res && res.data) {
if (params.itemType === 'monitorItem') {
// cpu
if (this.tempContent?.cpu && this.tempContent?.cpu.length > 0) {
this.firstData['cpu'].time = this.tempContent.cpu[0].collectionCycle.toString();
this.firstData['cpu'].timeLabel = obj[this.tempContent.cpu[0].collectionCycle.toString()];
this.tempContent['cpu'].timeLabel = obj[this.tempContent.cpu[0].collectionCycle.toString()];
}
this.firstData['cpu'].checkList = this.paramsData && this.paramsData.readonly ? this.tempContent?.cpu : res.data?.cpu || [];
// other
let otherData = res.data?.other || [];
if (this.tempContent?.other) {
this.tempContent['other'].forEach(item => {
otherData.some(val => {
if (item.metricKey === val.metricKey) {
val['time'] = item.collectionCycle.toString();
val['timeLabel'] = obj[item.collectionCycle.toString()];
item['timeLabel'] = obj[item.collectionCycle.toString()];
return true;
}
})
});
}
this.firstData['other'].checkList = this.paramsData && this.paramsData.readonly ? this.tempContent['other'] : otherData;
// 假设从接口获取firstData后,初始化每个city的time属性
this.firstData['other'].checkList.forEach(city => {
// 显式初始化time(若原本没有),确保响应式
if (city.time === undefined) {
this.$set(city, 'time', ''); // 用$set添加响应式属性
}
});
}
if (params.itemType === 'autodiscoverItem') {
if (this.tempContent?.vfs && this.tempContent?.vfs.length > 0) {
this.secondData['vfs'].time = this.tempContent.vfs[0].collectionCycle.toString();
this.secondData['vfs'].timeLabel = obj[this.tempContent.vfs[0].collectionCycle.toString()];
this.tempContent['vfs'].timeLabel = obj[this.tempContent.vfs[0].collectionCycle.toString()];
}
this.secondData['vfs'].checkList = this.paramsData && this.paramsData.readonly ? this.tempContent?.vfs : res.data?.vfs || [];
if (this.tempContent?.net && this.tempContent?.net.length > 0) {
this.secondData['net'].time = this.tempContent.net[0].collectionCycle.toString();
this.secondData['net'].timeLabel = obj[this.tempContent.net[0].collectionCycle.toString()];
}
this.secondData['net'].checkList = this.paramsData && this.paramsData.readonly ? this.tempContent?.net : res.data?.net || [];
if (this.tempContent?.disk && this.tempContent?.disk.length > 0) {
this.secondData['disk'].time = this.tempContent.disk[0].collectionCycle.toString();
this.secondData['disk'].timeLabel = obj[this.tempContent.disk[0].collectionCycle.toString()];
}
this.secondData['disk'].checkList = this.paramsData && this.paramsData.readonly ? this.tempContent?.disk : res.data?.disk || [];
if (this.tempContent?.docker && this.tempContent?.docker.length > 0) {
this.secondData['docker'].time = this.tempContent.docker[0].collectionCycle.toString();
this.secondData['docker'].timeLabel = obj[this.tempContent.docker[0].collectionCycle.toString()];
}
this.secondData['docker'].checkList = this.paramsData && this.paramsData.readonly ? this.tempContent?.docker : res.data?.docker || [];
}
}
})
},
// 同步所有city的time为firstChangeTime的值
handleChangeTime(item) {
// 遍历firstData中的每一项
item.checkList.forEach(city => {
// 遍历当前项的checkList中的每个city 直接赋值,因为city是响应式对象
city.time = item.groupTime;
});
},
// form验证
fnFormValid() {
return new Promise((resolve) => {
this.ruleFormData = {};
const formValid = this.$refs.formRef.$refs.ruleForm;
// 3. 操作form(如验证)
formValid.validate((valid) => {
if (valid) {
this.ruleFormData = formValid.model;
resolve(true);
} else {
resolve(false);
}
});
});
},
async submit() {
if (!await this.fnFormValid()) return;
// 监控项
let idsList = [];
Object.keys(this.firstData).forEach(key => {
if (key === 'other') {
this.firstData[key] && this.firstData[key].checkList.forEach(ids => {
if (ids && ids.time) {
idsList.push({id: ids.id, collectionCycle: ids.time});
}
});
} else {
if (this.firstData[key].time) {
this.firstData[key] && this.firstData[key].checkList.forEach(ids => {
idsList.push({id: ids.id, collectionCycle: this.firstData[key].time});
});
}
}
});
// 自动发现项
let autoIds = [];
Object.keys(this.secondData).forEach(key => {
if (this.secondData[key].time) {
this.secondData[key] && this.secondData[key].checkList.forEach(ids => {
autoIds.push({id: ids.id, collectionCycle: this.secondData[key].time});
});
}
});
// console.log('ruleFormData===',this.ruleFormData);
// console.log('idsList===',idsList);
// console.log('autoIds===',autoIds);
let paramsList = idsList.concat(autoIds);
let params = Object.assign(this.ruleFormData, {resourceType: 'linux'},{collectionAndIdList: paramsList});
let fnType = addResourcePolicy;
if (this.paramsData && this.paramsData.id) {
fnType = updateResourcePolicy;
}
this.$modal.loading();
fnType(params).then(response => {
this.$modal.msgSuccess(response.msg);
if (this.open) {
this.$emit("dialogResult", {open: false});
} else {
this.$router.push("/resource/serverMonitorStrat");
}
this.$modal.closeLoading();
}).catch(error => {
this.$modal.closeLoading();
});
},
cancel() {
if (this.open) {
this.$emit("dialogResult", {open: false});
} else {
this.$router.push("/resource/serverMonitorStrat");
}
},
// 监听事件
callback(result, dataVal, formVal) {
if (result && result.fnCode) {
switch (result.fnCode) {
case 'submit':
break;
case 'cancel':
break;
default:
}
}
},
}
}
</script>
<style scoped>
::v-deep #selDisabled{
color: #303133!important;
}
::v-deep .el-collapse-item__header {
background-color: #d4e3fc!important;
/*color: #fff!important;*/
padding-left: 20px;
font-size: 1rem;
}
</style>
@@ -0,0 +1,194 @@
<template>
<div class="app-container pageTopForm">
<el-form :model="queryParams" ref="queryRef" size="small" v-show="showSearch" label-width="auto">
<el-col :span="8">
<el-form-item label="搜索" prop="queryName">
<el-input
v-model="queryParams.queryName"
placeholder="请输入策略名称/ClientID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="策略状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="请选择策略状态"
clearable>
<el-option
v-for="dict in dict.type.policy_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item class="lastBtnSty">
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-col>
</el-form>
<TableList :columns="columns" :config="config" :modelIdent="this.$options.name" :queryParams="queryParams" :tableList="tableList" @fnClick="callback" @fnRenderList="getList" @value-change="handleValueChange">
<template #tempStatus="{ row, column }">
<dict-tag :options="dict.type.policy_status" :value="row.status"/>
</template>
</TableList>
</div>
</template>
<script setup>
import TableList from "@/components/table/index.vue"
import {listMonitorPolicy, delMonitorPolicy, getMonitorPolicyList} from "@/api/disRevenue/resource"
export default {
name: 'serverMonitorStrat',
components: {TableList},
dicts: ['policy_status'],
data() {
return {
loading: true,
showSearch: true,
tableList: [],
queryParams: {
total: 0,
pageNum: 1,
pageSize: 10,
status: ''
},
// 列显隐信息
columns: {
id: { label: `ID`,width: '50'},
policyName: { label: `策略名称`, minWidth: '250', visible: true },
description: { label: `描述`,minWidth: '200',visible: true},
deployDevice: { label: `部署设备`,minWidth: '200',visible: true},
priority: { label: `优先级`,minWidth: '150', visible: true },
connected: { label: `策略内容`,minWidth: '200'},
status: { label: `策略状态`, minWidth: '100', slotName: 'tempStatus', visible: true },
deployTime: { label: `下发策略时间`,minWidth: '160'},
createBy:{ label: `创建人`,minWidth: '160'},
createTime: { label: `创建时间`,minWidth: '160'},
},
config: {
tableButton: {
top: [
{content: '新增', fnCode: 'add', type: 'primary', icon: 'el-icon-plus', hasPermi: 'resource:serverMonitorStrat:add'},
{content: '导出', fnCode: 'export', type: 'warning', icon: 'el-icon-download', hasPermi: 'resource:serverMonitorStrat:export'},
],
line: [
{content: '修改', fnCode: 'edit', type: 'text', showName: 'status', showVal: '0', icon: 'el-icon-edit', hasPermi: 'resource:serverMonitorStrat:edit'},
{content: '详情', fnCode: 'details', type: 'text', icon: 'el-icon-view', hasPermi: 'resource:serverMonitorStrat:details'},
{content: '删除', fnCode: 'delete', type: 'text', showName: 'status', showVal: '0', icon: 'el-icon-delete', hasPermi: 'resource:serverMonitorStrat:detele'},
{}
]
}
}
}
},
created() {
this.getList();
},
activated() {
this.$nextTick(() => {
this.getList();
});
},
methods: {
/** 查询列表 */
getList() {
// this.$modal.loading();
listMonitorPolicy(Object.assign({}, this.queryParams, {resourceType: 'linux'})).then(response => {
this.tableList = response.rows;
this.queryParams.total = response.total;
// this.$modal.closeLoading();
}).catch(err => {
// this.$modal.closeLoading();
})
},
// 处理子组件传递的新值
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, selectList) {
if (result && result.fnCode) {
switch (result.fnCode) {
case 'add':
this.$router.push({
path:'/resource/serverMonitorStrat/details/index'});
break;
case 'edit':
this.$router.push({
path:'/resource/serverMonitorStrat/details/index',
query:{
id: rowData.id
}
});
break;
case 'details':
this.$router.push({
path:'/resource/serverMonitorStrat/details/index',
query:{
id: rowData.id,
readonly: true
}
});
break;
case 'delete':
this.$modal.confirm('是否确认删除数据项?').then(function() {
return delMonitorPolicy(rowData.id)
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功")
}).catch(() => {});
break;
case 'strategy':
this.$modal.confirm('是否确认下发策略?').then(() => {
this.$modal.loading();
getMonitorPolicyList(rowData.id).then(res => {
this.getList();
this.$modal.msgSuccess(res.msg);
this.$modal.closeLoading();
}).catch(error => {
this.$modal.closeLoading();
});
}).catch(() => {});
break;
case 'export':
// let dataList = [];
// Object.keys(this.columns).forEach(item => {
// if (item.visible) {
// dataList.push(item.prop);
// }
// });
// this.download("/system/monitorStategy/export", {properties: dataList,}, `拓扑管理_${new Date().getTime()}.xlsx`);
let paramsList = Object.assign({}, this.queryParams,rowData);
this.download("rocketmq/monitorPolicy/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>
@@ -0,0 +1,40 @@
<template>
<div style="padding: 8px 20px 20px;">
<div class="w100 plr-20" style="font-size: 14px">
<div v-for="(item, key, index) of formData['formFirst']" class="w50 disInlineBlock p10">
<div class="disInlineBlock" style="width: 135px;color: #C0C4CC;">{{item}}</div>
<div style="width: calc(100% - 135px);vertical-align: top;" class="disInlineBlock">{{formData['formValue'] && formData['formValue'][key]}}</div>
</div>
</div>
<div v-for="item of chartList" class="w100 mt10 mb10" style="height: 200px;border-top: 1px solid #d8dce5">
<EchartsLine class="w100 h100" :lineData="item && item.dataVal" :dateDataTrans="item && item.dateDataTrans" :dateShowType="item && item.dateShowType" :title="item && item.title" :chartData="(valData) => chartDataEvent(valData, item.fnEvent)"></EchartsLine>
</div>
</div>
</template>
<script setup>
import EchartsLine from "@/components/echartsList/line.vue";
export default {
name: 'FirstMonitor',
components: {EchartsLine},
props: {
chartList: {
type: Array,
default: () => []
},
formData: {
type: Object,
default: () => {}
}
},
data() {
return {}
},
created() {},
methods: {
chartDataEvent(valData, funcName) {
this.$emit("chartFnEvent", valData, funcName);
},
}
}
</script>
@@ -0,0 +1,190 @@
<template>
<div class="app-container">
<Form :formList="formList" :ruleFormData="ruleForm" :config="this.paramsData && this.paramsData.readonly ? {labelWidth: '140px', buttonGroup: []} : {labelWidth: '140px'}" @fnClick="callback"></Form>
<el-button v-if="this.paramsData && this.paramsData.readonly" style="float: right;margin-top: 12px;margin-left: 10px;" @click="callback({fnCode: 'cancel'})">返回</el-button>
</div>
</template>
<script setup>
import Form from '@/components/form/index.vue';
import {addMachine, getHandle, updateTopology, getRegistList, bindBusByClient} from "@/api/disRevenue/resource";
import {listAllBusinessList} from "@/api/disRevenue/earnManage";
export default {
name: 'serverRegister_Edit',
components: {Form},
dicts: ['rm_register_status','rm_register_online_state'],
data() {
return {
loading: false,
ruleForm: {},
formList: [],
paramsData: {},
switchNameList: [],
serverNameList: [],
serverPortList: [],
interfaceNameList: [],
busNameList: {},
}
},
created() {
this.paramsData = this.$route && this.$route.query;
if (this.paramsData && this.paramsData.id) {
this.getFormDataList(this.paramsData.id);
}
if (this.paramsData && this.paramsData.type && this.paramsData.type === 'edit') {
this.fnBusNameList();
} else {
this.registList();
}
this.fnFormList();
},
methods: {
// formList集合
fnFormList(objVal) {
if (this.paramsData && this.paramsData.type && this.paramsData.type === 'edit') {
this.$set(this.ruleForm, 'deployDevice', this.paramsData.clientIdList);
this.formList = [{
config: {title: '基本信息',labelWidth: '140px', colSpan: 'disBlock'},
controls: {
id: {label: 'ID',hidden: true},
businessName: {label: '业务名称', span: 12, type: 'select', options:[], required: true},
deployDevice: {label: '服务器列表', span: 12, type: 'textarea', rows: 15, required: true},
}
}];
} else if (this.paramsData && this.paramsData.readonly) {
this.formList = [{
config: {title: '基本信息',labelWidth: '140px', readonly: true},
controls: {
id: {label: 'ID',hidden: true},
clientId: {label: 'ClientID', span: 12, type: 'select', options:[]},
hardwareSn: {label: '设备SN', span: 12, type: 'input'},
ip1Isp: {label: 'IP1-运营商', span: 12, type: 'input'},
ip1Province: {label: 'IP1-省', span: 12, type: 'input'},
ip1City: {label: 'IP1-市', span: 12, type: 'input'},
ip1PublicIp: {label: 'IP1-业务公网', span: 12, type: 'input'},
ip1InterfaceName: {label: 'IP1-接口名称', span: 12, type: 'input'},
ip1MacAddress: {label: 'IP1-mac地址', span: 12, type: 'input'},
ip1InterfaceType: {label: 'IP1-接口类型', span: 12, type: 'input'},
ip1Ipv4Address: {label: 'IP1-IPv4地址', span: 12, type: 'input'},
ip1Gateway: {label: 'IP1-网关', span: 12, type: 'input'},
ip2Isp: {label: 'IP2-运营商', span: 12, type: 'input'},
ip2Province: {label: 'IP2-省', span: 12, type: 'input'},
ip2City: {label: 'IP2-市', span: 12, type: 'input'},
ip2PublicIp: {label: 'IP2-业务公网', span: 12, type: 'input'},
ip2InterfaceName: {label: 'IP2-接口名称', span: 12, type: 'input'},
ip2MacAddress: {label: 'IP2-mac地址', span: 12, type: 'input'},
ip2InterfaceType: {label: 'IP2-接口类型', span: 12, type: 'input'},
ip2Ipv4Address: {label: 'IP2-IPv4地址', span: 12, type: 'input'},
ip2Gateway: {label: 'IP2-网关', span: 12, type: 'input'},
ip3Isp: {label: 'IP3-运营商', span: 12, type: 'input'},
ip3Province: {label: 'IP3-省', span: 12, type: 'input'},
ip3City: {label: 'IP3-市', span: 12, type: 'input'},
ip3PublicIp: {label: 'IP3-业务公网', span: 12, type: 'input'},
ip3InterfaceName: {label: 'IP3-接口名称', span: 12, type: 'input'},
ip3MacAddress: {label: 'IP3-mac地址', span: 12, type: 'input'},
ip3InterfaceType: {label: 'IP3-接口类型', span: 12, type: 'input'},
ip3Ipv4Address: {label: 'IP3-IPv4地址', span: 12, type: 'input'},
ip3Gateway: {label: 'IP3-网关', span: 12, type: 'input'},
mgmtIsp: {label: '管理网-运营商', span: 12, type: 'input'},
mgmtProvince: {label: '管理网-省', span: 12, type: 'input'},
mgmtCity: {label: '管理网-市', span: 12, type: 'input'},
mgmtPublicIp: {label: '管理网-公网IP', span: 12, type: 'input'},
mgmtInterfaceName: {label: '管理网-接口名称', span: 12, type: 'input'},
mgmtMacAddress: {label: '管理网-mac地址', span: 12, type: 'input'},
mgmtInterfaceType: {label: '管理网-接口类型', span: 12, type: 'input'},
mgmtIpv4Address: {label: '管理网-IPv4地址', span: 12, type: 'input'},
mgmtGateway: {label: '管理网-网关', span: 12, type: 'input'},
heartbeatInterval: {label: '心跳时间间隔', span: 12, type: 'input'},
heartbeatCount: {label: '心跳次数', span: 12, type: 'input'},
businessName: {label: '业务名称', span: 12, type: 'input'},
logicalNodeId: {label: '逻辑节点标识', span: 12, type: 'input'},
onlineStatus: {label: '在线状态', span: 12, type: 'select', options: this.dict.type.rm_register_online_state},
registrationStatus: {label: '注册状态', span: 12, type: 'select', options: this.dict.type.rm_register_status},
createTime: {label: '注册时间', span: 12, type: 'input'},
onboardTime: {label: '上机时间', span: 12, type: 'input'},
agentVersion: {label: 'agent版本', span: 12, type: 'input'},
machineCode: {label: '金山machineCode', span: 12, type: 'input'},
}
}];
} else {
this.formList = [{
config: {title: '基本信息',labelWidth: '140px', colSpan: 'disBlock'},
controls: {
id: {label: 'ID',hidden: true},
clientId: {label: 'ClientID', span: 12, type: 'select', options:[], required: true},
machineCode: {label: '金山machineCode', span: 12, type: 'input', required: true},
}
}];
}
},
// clientId
registList() {
getRegistList({resourceType: 1}).then(res => {
this.formList[0].controls.clientId['options'] = res && res.data.map(item => {
return Object.assign({label: item.clientId, value: item.clientId});
});
});
},
// 业务名称
fnBusNameList() {
listAllBusinessList().then(res => {
this.formList[0].controls.businessName['options'] = res && res.data.map(item => {
this.busNameList[item.businessName] = item;
return Object.assign({label: item.businessName, value: item.businessName});
});
});
},
// 获取详情
getFormDataList(id) {
getHandle(id).then(val => {
this.ruleForm = val && val.data;
}).catch(() => {
this.$modal.msgError("操作失败")
});
},
// 监听事件
callback(result, dataVal, formVal) {
if (result && result.fnCode) {
switch (result.fnCode) {
case 'submit':
if (this.paramsData && this.paramsData.type && this.paramsData.type === 'edit') {
dataVal['businessCode'] = this.busNameList[dataVal.businessName].id;
bindBusByClient(dataVal).then(res => {
this.$modal.msgSuccess(res.msg);
this.$router.push("/resource/serverRegister");
});
} else {
let content = '<p style="font-size: 1rem;font-weight: 600;">确认添加machineCode</p>' +
'<p style="height: 0px;margin-bottom: 50px;">一旦添加machineCode后,将不能修改</p>';
this.$modal.confirm(content, {submitTitle: '确认添加'}).then(() => {
let fnType = addMachine;
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/serverRegister");
this.loading = false;
}).catch(() => {
this.$modal.msgError("操作失败")
});
}).catch(() => {});
}
break;
case 'cancel':
this.$router.push("/resource/serverRegister");
break;
default:
}
}
}
}
}
</script>
<style scoped>
::v-deep .el-radio {
margin-right: 15px!important;
}
</style>
+551
View File
@@ -0,0 +1,551 @@
<template>
<div class="app-container pageTopForm">
<el-form :model="queryParams" ref="queryRef" v-show="showSearch" size="small" label-width="auto">
<el-col :span="6">
<el-form-item label="搜索" title="搜索" prop="queryParam">
<el-input
v-model="queryParams.queryParam"
placeholder="请输入公网IP/私网IP/设备SN/clientID"
clearable
@keyup.enter.native="handleQuery"/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="在线状态" title="在线状态" prop="onlineStatus">
<el-select
v-model="queryParams.onlineStatus"
placeholder="请选择在线状态"
clearable>
<el-option
v-for="dict in dict.type.rm_register_online_state"
:key="dict.value"
:label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="多公网IP状态" title="多公网IP状态" prop="multiPublicIpStatus">
<el-select
v-model="queryParams.multiPublicIpStatus"
placeholder="请选择多公网IP状态"
clearable>
<el-option
v-for="dict in dict.type.rm_moreip_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="注册状态" title="注册状态" prop="registrationStatus">
<el-select
v-model="queryParams.registrationStatus"
placeholder="请选择注册状态"
clearable>
<el-option
v-for="dict in dict.type.rm_register_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="业务名称" title="业务名称" prop="businessName">
<el-select
v-model="queryParams.businessName"
placeholder="请选择业务名称"
clearable>
<el-option
v-for="item in busNameList"
:key="item.value"
:label="item.label"
:value="item.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="逻辑节点标识" title="逻辑节点标识" prop="logicalNodeId">
<el-select
v-model="queryParams.logicalNodeId"
placeholder="请选择逻辑节点标识"
clearable>
<el-option
v-for="item in logicalNodeList"
:key="item.value"
:label="item.label"
:value="item.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<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 #tempCopy="{ row, column}">
{{row.clientId}}<el-link :underline="false" icon="el-icon-document-copy" title="复制" v-clipboard:copy="row.clientId" v-clipboard:success="clipboardSuccess" style="margin-left: 10px;color: #409EFF;"></el-link>
</template>
<!-- 多公网IP状态 -->
<template #tempMultipubStatus="{ row, column }">
<dict-tag :options="dict.type.rm_moreip_status" :value="row.multiPublicIpStatus"/>
</template>
<!-- 注册状态 -->
<template #tempStatus="{ row, column }">
<dict-tag :options="dict.type.rm_register_status" :value="row.registrationStatus"/>
</template>
<!-- 在线状态 -->
<template #tempOnlineStatus="{ row, column }">
<dict-tag :options="dict.type.rm_register_online_state" :value="row.onlineStatus"/>
</template>
</TableList>
<!-- 查看执行结果弹窗 -->
<el-dialog title="命令执行结果" :visible.sync="open" width="800px" height="300px" append-to-body>
<div class="block" style="max-height: calc(100vh - 125px);overflow: auto;">
<template v-if="timelineList && timelineList.length > 0">
<el-timeline :reverse="true">
<el-timeline-item v-for="item of timelineList" :timestamp="item.createTime" placement="top">
<pre>{{item.content}}</pre>
</el-timeline-item>
</el-timeline>
</template>
<el-empty v-else :image-size="200"></el-empty>
</div>
</el-dialog>
<!-- 下发业务 -->
<el-dialog :title="title" :visible.sync="issueOpen" width="800px" append-to-body style="padding-bottom: 20px;">
<BusinessIssuedDetails :open="`type_${issueOpen}`" :dialogRowData="dialogRowData" @dialogResult="fnDialogResult"></BusinessIssuedDetails>
</el-dialog>
<!-- 下发脚本策略 -->
<el-dialog :title="title" :visible.sync="scriptOpen" width="800px" append-to-body style="padding-bottom: 20px;">
<severScriptStratDetails :open="`type_${scriptOpen}`" :dialogRowData="dialogRowData" @dialogResult="fnDialogResult"></severScriptStratDetails>
</el-dialog>
<!-- 添加监控策略 -->
<el-dialog title="添加监控策略" :visible.sync="stratOpen" width="1200px" append-to-body>
<MonitorStrategy :open="`type_${stratOpen}`" :dialogRowData="dialogRowData" @dialogResult="fnDialogResult"></MonitorStrategy>
</el-dialog>
<!-- 选择公网业务IP -->
<el-dialog title="选择公网业务IP" :visible.sync="pubilcNetOpen" width="800px" append-to-body style="padding-bottom: 20px;">
<Form ref="publicNetFormRef" :formList="pubilcNetFormList" :ruleFormData="pubilcNetRuleForm" :config="{labelWidth: '140px', buttonGroup: []}" @fnClick="callback"></Form>
<div style="text-align: right;margin-right: 20px;margin-bottom: 20px;">
<el-button type="primary" style="margin-left: 10px;" @click="submitPubilc">提交</el-button>
<el-button @click="callback({fnCode: 'cancel'})">取消</el-button>
</div>
</el-dialog>
</div>
</template>
<script setup name="Register">
import Form from '@/components/form/index.vue';
import {listHandle, networkList, getScriptResultBySn, getLogicalNode} from '@/api/disRevenue/resource';
import {listAllBusinessList} from "@/api/disRevenue/earnManage"
import TableList from '@/components/table/index.vue';
import MonitorStrategy from '../serverMonitorStrat/monitorStrategy';
import severScriptStratDetails from '../serverScriptStrat/details';
import BusinessIssuedDetails from '../../earnManage/businessIssued/details';
export default {
name: 'ServerRegister',
components: {TableList, MonitorStrategy,Form, BusinessIssuedDetails, severScriptStratDetails},
dicts: ['rm_moreip_status', 'rm_register_status', 'rm_register_online_state', 'policy_method'],
data() {
return {
open: false,
stratOpen: false,
roleList: [],
busNameList: [],
loading: true,
showSearch: true,
ids: [],
single: true,
meltiple: true,
// 列显隐信息
columns: {
id: { label: `ID`,width: '50'},
clientId: { label: `clientID`, minWidth: '320', slotName: 'tempCopy'},
hardwareSn: { label: `设备SN`,minWidth: '200'},
ip1Isp: { label: `IP1-运营商`, visible: true, minWidth: '90'},
ip1Province: { label: `IP1-省`, visible: true, minWidth: '80'},
ip1City: { label: `IP1-市`, minWidth: '80'},
ip1PublicIp:{ label: `IP1-业务公网`,visible: true,minWidth: '120'},
ip1InterfaceName: { label: `IP1-接口名称`, minWidth: '100'},
ip1MacAddress: { label: `IP1-mac地址`, minWidth: '150'},
ip1InterfaceType: { label: `IP1-接口类型`, minWidth: '100'},
ip1Ipv4Address: { label: `IP1-IPv4地址`, minWidth: '120'},
ip1Gateway: { label: `IP1-网关`, minWidth: '120'},
ip2Isp: { label: `IP2-运营商`, minWidth: '90'},
ip2Province: { label: `IP2-省`,minWidth: '80'},
ip2City: { label: `IP2-市`, minWidth: '80'},
ip2PublicIp:{ label: `IP2-业务公网`,minWidth: '120'},
ip2InterfaceName: { label: `IP2-接口名称`, minWidth: '100'},
ip2MacAddress: { label: `IP2-mac地址`, minWidth: '150'},
ip2InterfaceType: { label: `IP2-接口类型`, minWidth: '100'},
ip2Ipv4Address: { label: `IP2-IPv4地址`, minWidth: '120'},
ip2Gateway: { label: `IP2-网关`, minWidth: '120'},
ip3Isp: { label: `IP3-运营商`, minWidth: '90'},
ip3Province: { label: `IP3-省`, minWidth: '80'},
ip3City: { label: `IP3-市`, minWidth: '80'},
ip3PublicIp:{ label: `IP3-业务公网`,minWidth: '120'},
ip3InterfaceName: { label: `IP3-接口名称`, minWidth: '100'},
ip3MacAddress: { label: `IP3-mac地址`, minWidth: '150'},
ip3InterfaceType: { label: `IP3-接口类型`, minWidth: '100'},
ip3Ipv4Address: { label: `IP3-IPv4地址`, minWidth: '120'},
ip3Gateway: { label: `IP3-网关`, minWidth: '120'},
mgmtIsp: { label: `管理网-运营商`, minWidth: '110'},
mgmtProvince: { label: `管理网-省`,minWidth: '80'},
mgmtCity: { label: `管理网-市`, minWidth: '80'},
mgmtPublicIp:{ label: `管理网-业务公网`,minWidth: '120'},
mgmtInterfaceName: { label: `管理网-接口名称`, minWidth: '120'},
mgmtMacAddress: { label: `管理网-mac地址`, minWidth: '150'},
mgmtInterfaceType: { label: `管理网-接口类型`, minWidth: '120'},
mgmtIpv4Address: { label: `管理网-IPv4地址`, minWidth: '120'},
mgmtGateway: { label: `管理网-网关`, minWidth: '120'},
heartbeatInterval: { label: `心跳时间间隔`, minWidth: '100'},
heartbeatCount: { label: `心跳次数`, minWidth: '80'},
registrationStatus: { label: `注册状态`, slotName: 'tempStatus', minWidth: '80', visible: true },
businessName: { label: `业务名称`, minWidth: '100', visible: true},
logicalNodeId: { label: `逻辑节点标识`, minWidth: '120', visible: true},
onlineStatus: { label: `在线状态`, slotName: 'tempOnlineStatus', minWidth: '100', visible: true },
multiPublicIpStatus: { label: `多公网IP状态`, slotName: 'tempMultipubStatus', minWidth: '120', visible: true },
createTime:{ label: `注册时间`,minWidth: '160'},
onboardTime:{ label: `上机时间`,minWidth: '160'},
agentVersion:{ label: `agent版本`,minWidth: '90'},
machineCode:{ label: `金山machineCode`,minWidth: '160'},
},
config: {
tableButton: {
top: [
{content: '添加金山machineCode', fnCode: 'add', type: 'primary', icon: 'el-icon-plus', hasPermi: 'resource:serverRegister:add'},
{content: '修改业务名称', fnCode: 'edit', type: 'success', icon: 'el-icon-edit', hasPermi: 'resource:serverRegister:edit'},
{content: '导出', fnCode: 'export', type: 'warning', icon: 'el-icon-download', hasPermi: 'resource:serverRegister:export'},
],
line: [
{content: '选择业务IP', fnCode: 'pubilcNet', type: 'text', icon: 'el-icon-thumb', showName: 'multiPublicIpStatus', showVal: '0', hasPermi: 'resource:serverRegister:pubilcNet'},
{content: '图形监控', fnCode: 'echartView', type: 'text', icon: 'el-icon-data-analysis', hasPermi: 'resource:serverRegister:graphicAnalysis'},
{content: '详情', fnCode: 'details', type: 'text', icon: 'el-icon-view', hasPermi: 'resource:serverRegister:details'},
{title: '更多', more: [
{content: '下发业务', fnCode: 'issueBusiness', type: 'text', icon: 'el-icon-circle-check', hasPermi: 'resource:serverRegister:issueBusiness'},
{content: '下发脚本策略', fnCode: 'issueScript', type: 'text', icon: 'el-icon-circle-check', hasPermi: 'resource:serverRegister:issueScript'},
{content: '下发监控策略', fnCode: 'issueMonitor', type: 'text', icon: 'el-icon-circle-check', hasPermi: 'resource:serverRegister:issueMonitor'},
{content: '查看执行结果', fnCode: 'result', type: 'text', icon: 'el-icon-s-check', hasPermi: 'resource:serverRegister:result'},
]
}
// {content: '注册', fnCode: 'enroll', showName: 'registrationStatus', showVal: '0', type: 'text', icon: 'el-icon-circle-check', hasPermi: 'resource:register:enroll'},
// {content: '取消注册', fnCode: 'unenroll', showName: 'registrationStatus', showVal: '1', type: 'text', icon: 'el-icon-circle-close', hasPermi: 'resource:register:unenroll'},
]
}
},
queryParams: {
pageNum: 1,
pageSize: 10,
total: 0
},
timelineList: [
{content: '【服务器节点名称1】执行脚本命令', time: '2025-12-12 12:12:12'},
{content: '【服务器节点名称1】执行脚本命令', time: '2025-12-11 12:12:12'},
{content: '【服务器节点名称1】执行脚本命令', time: '2025-12-10 12:12:12'}
],
issueOpen: false,
scriptOpen: false,
title: '',
formList: [],
ruleForm: {},
pubilcNetOpen: false,
pubilcNetFormList: [{
config: {title: '',labelWidth: '140px', colSpan: 'disBlock m0Auto'},
controls: {
id: {label: 'ID',hidden: true},
publicIp: {label: '业务公网IP', span: 18, eventName:'change', type: 'select',multiple: true, multipleLimit: 3, options: [], required: true},
descriptionOne: {label: '', span: 18, type: 'textarea',rows: 15, disabled: true},
mgmtIp: {label: '管理网-公网IP', eventName:'change', span: 18, type: 'select',options: [], required: true},
descriptionTwo: {label: '', span: 18, type: 'textarea', rows: 15, disabled: true}
}
}],
pubilcNetRuleForm: {publicIp: []},
ipContentList: {},
dialogRowData: {},
logicalNodeList: [],
}
},
created() {
this.getList();
this.fnBusNameList();
this.fnLogicalNode();
},
activated() {
this.$nextTick(() => {
this.getList();
});
},
methods: {
fnBusNameList() {
listAllBusinessList().then(val => {
this.busNameList = val && val.data.map(item => {
return Object.assign({label: item.businessName, value: item.businessName});
});
});
},
fnLogicalNode() {
getLogicalNode().then(val => {
this.logicalNodeList = val && val.map(item => {
return Object.assign({label: item.logicalNodeId, value: item.logicalNodeId});
});
});
},
// 处理子组件传递的新值
handleValueChange(newValue) {
// 父组件更新自身数据,实现同步
this.showSearch = newValue;
// console.log('父组件拿到新值:', newValue);
},
/** 查询角色列表 */
getList() {
this.loading = true;
listHandle(this.addDateRange(this.queryParams)).then(response => {
this.roleList = response.rows;
this.queryParams.total = response.total;
this.loading = false;
})
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.$refs['queryRef'].resetFields();
this.queryParams = {pageNum: 1, pageSize: 10,total: 0};
// this.resetForm("queryRef");
this.handleQuery();
},
/** 多选框选中数据 */
handleSelectionChange(selection) {
this.ids = selection.map(item => item.roleId);
this.single = selection.length != 1;
this.multiple = !selection.length;
},
/** 复制代码成功 */
clipboardSuccess() {
this.$modal.msgSuccess("复制成功")
},
fnDialogResult(res){
this.stratOpen = false;
this.issueOpen = false;
this.scriptOpen = false;
},
callback(result, rowData, selectChange, selectList) {
this.dialogRowData = {};
if (result && result.fnCode) {
switch (result.fnCode) {
case 'add':
this.$router.push("/resource/serverRegister/edit");
break;
case 'edit':
let clientIdList = '';
if (selectList && selectList.length > 0) {
selectList.map(item => {
clientIdList+=item.clientId + '\n';
});
}
this.$router.push({
path:'/resource/serverRegister/edit',
query: {id: rowData.id, type: 'edit', clientIdList: clientIdList}
});
break;
case 'details':
this.$router.push({
path:'/resource/serverRegister/edit',
query: {id: rowData.id, readonly: true}
});
break;
case 'echartView':
this.$router.push({
path:'/resource/serverRegister/monitorChart',
query: {clientId: rowData.clientId}
});
break;
case 'result':
this.timelineList = [];
// 获取详情
getScriptResultBySn({clientId: rowData.clientId}).then(val => {
this.open = true;
this.timelineList = val && val.data && val.data.scriptResult || [];
}).catch(() => {
this.open = true;
this.$modal.msgError("操作失败")
});
break;
case 'pubilcNet':
this.pubilcNetOpen = true;
this.pubilcNetRuleForm = {publicIp: [],mgmtIp: '', descriptionOne: '', descriptionTwo: ''};
this.$nextTick(() => {
// 5. 最后执行重置
if (this.$refs['publicNetFormRef']?.$refs.ruleForm) {
this.$refs['publicNetFormRef'].$refs.ruleForm.resetFields();
}
});
networkList({clientId: rowData.clientId}).then(res => {
let ipList = [];
res && res.data.map(item => {
this.ipContentList[item.id] = item;
ipList.push({label: item.publicIp, value: item.id});
});
this.pubilcNetFormList[0].controls.publicIp['options'] = ipList;
this.pubilcNetFormList[0].controls.mgmtIp['options'] = ipList;
});
break;
case 'publicIp':
let content = '';
this.pubilcNetRuleForm = Object.assign({}, this.pubilcNetRuleForm, this.$refs.publicNetFormRef.$refs.ruleForm.model);
if (rowData && rowData.length > 0) {
rowData.forEach(item => {
content+= '运营商:' + this.ipContentList[item].isp + '<br>' + '省:' + this.ipContentList[item].province + '<br>'
+ '市:' + this.ipContentList[item].city + '<br>' + '公网IP' + this.ipContentList[item].publicIp + '<br>'
+ '接口名称:' + this.ipContentList[item].interfaceName + '<br>' + 'mac地址:' + this.ipContentList[item].macAddress + '<br>'
+ '接口类型:' + this.ipContentList[item].interfaceType + '<br>' + 'IPv4地址:' + this.ipContentList[item].ipv4Address + '<br>'
+ '网关:' + this.ipContentList[item].gateway + '<br><br>';
});
}
this.$set(this.pubilcNetRuleForm, 'descriptionOne', content);
break;
case 'mgmtIp':
let contentTow = '';
this.pubilcNetRuleForm = Object.assign({}, this.pubilcNetRuleForm, this.$refs.publicNetFormRef.$refs.ruleForm.model);
if (rowData) {
contentTow+= '运营商:' + this.ipContentList[rowData].isp + '<br>' + '省:' + this.ipContentList[rowData].province + '<br>'
+ '市:' + this.ipContentList[rowData].city + '<br>' + '公网IP' + this.ipContentList[rowData].publicIp + '<br>'
+ '接口名称:' + this.ipContentList[rowData].interfaceName + '<br>' + 'mac地址:' + this.ipContentList[rowData].macAddress + '<br>'
+ '接口类型:' + this.ipContentList[rowData].interfaceType + '<br>' + 'IPv4地址:' + this.ipContentList[rowData].ipv4Address + '<br>'
+ '网关:' + this.ipContentList[rowData].gateway + '<br><br>';
}
this.$set(this.pubilcNetRuleForm, 'descriptionTwo', contentTow);
break;
case 'issueBusiness':
this.issueOpen = true;
this.title = '下发业务任务';
this.dialogRowData = rowData;
break;
case 'issueScript':
this.dialogRowData = rowData;
this.title = '添加脚本策略';
this.scriptOpen = true;
break;
case 'executionMethod':
if (rowData && rowData === '1') {
this.formList[0].controls.scheduledTime['hidden'] = false;
} else {
this.formList[0].controls.scheduledTime['hidden'] = true;
}
break;
case 'issueMonitor':
this.stratOpen = true;
this.dialogRowData = rowData;
break;
case 'submit':
break;
case 'cancel':
this.issueOpen = false;
this.pubilcNetOpen = false;
break;
case 'export':
// let dataList = [];
// Object.keys(this.columns).forEach(item => {
// if (item.visible) {
// dataList.push(item.prop);
// }
// });
// this.download("/system/registration/export", {properties: dataList,}, `资源管理_${new Date().getTime()}.xlsx`);
let paramsList = Object.assign({}, this.queryParams,rowData);
this.download("system/registration/export", paramsList, `服务器管理_${new Date().getTime()}.xlsx`, null, 'json');
break;
default:
}
}
},
// form验证
fnFormValid(val, model) {
return new Promise((resolve) => {
this.ruleFormData = {};
const formValid = this.$refs[`${val}`].$refs.ruleForm;
// 3. 操作form(如验证)
formValid.validate((valid) => {
if (valid) {
if (formValid.model?.deployDevice) {
formValid.model.deployDevice = formValid.model.deployDevice.join('/n');
}
this[`${model}`] = formValid.model;
resolve(true);
} else {
resolve(false);
}
});
});
},
async submit(){
if (!await this.fnFormValid('formRef', 'ruleFormData')) return;
let fnType = addMachine;
if (dataVal && dataVal.id) {
fnType = updateTopology;
}
if(this.loading) return;
this.loading = true;
fnType(dataVal).then(response => {
this.$modal.msgSuccess(response.msg);
this.issueOpen = false;
this.loading = false;
}).catch(() => {
this.$modal.msgError("操作失败")
});
},
async submitPubilc() {
if (!await this.fnFormValid('publicNetFormRef', 'pubilcNetRuleForm')) return;
let params = [];
this.pubilcNetRuleForm.publicIp.forEach(item => {
if (item && item === this.pubilcNetRuleForm.mgmtIp) {
params.push({id: item, status: 3, interfaceName: this.ipContentList[item].interfaceName});
delete this.pubilcNetRuleForm.mgmtIp;
} else {
params.push({id: item, status: 1, interfaceName: this.ipContentList[item].interfaceName});
}
});
if (this.pubilcNetRuleForm && this.pubilcNetRuleForm.mgmtIp) {
params.push({id: this.pubilcNetRuleForm.mgmtIp, status: 2, interfaceName: this.ipContentList[this.pubilcNetRuleForm.mgmtIp].interfaceName});
}
networkList({bindNetworkMsg: params}).then(res => {
this.$modal.msgSuccess(res.msg);
this.pubilcNetOpen = false;
this.getList();
});
},
}
}
</script>
<style scoped>
::v-deep .lastBtnSty .el-form-item__content{
margin-left: 10px!important;
}
::v-deep .el-dialog__body {
padding: 0 0 10px!important;
}
::v-deep .el-timeline .el-timeline-item:last-child .el-timeline-item__tail {
display: block!important;
}
::v-deep .el-tree-node__label {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>
@@ -0,0 +1,956 @@
<template>
<div class="app-container">
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="自动发现项" name="second">
<template v-if="activeName === 'second'">
<SecondAutoFind v-if="loading" :secondChartList="secondChartList" :activeNames="activeNames" @collapseChangeData="collapseChangeData" @chartFnEvent="chartFnEvent"></SecondAutoFind>
</template>
</el-tab-pane>
<el-tab-pane label="监控项" name="first">
<template v-if="activeName === 'first'">
<FirstMonitor v-if="loading" :formData="formData" :chartList="firstChartList" @chartFnEvent="chartFnEvent"></FirstMonitor>
</template>
</el-tab-pane>
</el-tabs>
<div style="float: right;margin-top: 20px;">
<el-button type="primary" @click="goBack">返回</el-button>
</div>
</div>
</template>
<script>
import FirstMonitor from "./firstMonitor";
import SecondAutoFind from "./secondAutoFind";
import {serverMonitorData, cpuLoadData, cpuTimeData, procNum, serverUserNum, swapSizeFree, memoryUtilization, swapSizePercent,
memorySizeAvailable, memorySizePercent, mountNameList, pointDetails, spaceEcharts, spaceRate, postInterFaceName,
netDetails, trafficEcharts, droppedEcharts, diskAllNames, diskDetails, speedEcharts, timesEcharts, bytesEcharts,
dockerAllNames, dockerDetails, cpuUtilEcharts, dockerMemEcharts, dockerSpeedEcharts} from "@/api/disRevenue/resource"
export default {
name: "serverMonitorChart",
components: {FirstMonitor, SecondAutoFind},
data() {
return {
loading: false,
currTimeList: {},
defaultTimes: [],
firstTabTime: {},
firstTabTimeArr: [],
activeName: 'second',
paramsData: {},
// 第一栏
firstChartTrans: {},
formFirst: {
memorySizeTotalCollect: '总内存(GB)', systemCpuNum: 'CPU数量', systemSwOsCollect: '操作系统', systemSwArchCollect: '操作系统架构', kernelMaxprocCollect: '最大进程数', systemDiskSizeTotalCollect: '硬盘-总可用空间(GB)',
systemBoottimeCollect: '系统启动时间', systemUptimeCollect: '系统正确运行时间', systemLocaltimeCollect: '系统本地时间', systemUnameCollect: '系统描述'
},
formData: {},
firstChartList: [],
resultData: [
{
title: 'CPU负载(%)',
dateShowType: 'datetimerange',
dateDataTrans: {transList: true},
dataVal: {
titleVal: {textAlign: 'left', left: '1%'},
yAxisName: ' ',
gridTop: '35%',
legend: {top: '15%', left: '10%'},
lineXData: [],
dataList: [
{name: 'CPU的1分钟负载', data: []},
{name: 'CPU的5分钟负载', data: []},
{name: 'CPU的15分钟负载', data: []},
{name: 'CPU使用率', data: []},
]
}
},{
title: 'CPU时间(s)',
dateShowType: 'datetimerange',
dateDataTrans: {transList: true},
dataVal: {
titleVal: {textAlign: 'left', left: '1%'},
yAxisName: ' ',
gridTop: '35%',
legend: {top: '22%', left: '10%'},
lineXData: [],
dataList: [
{name: 'CPU正常运行时间', data: []},
{name: 'CPU空闲时间', data: []},
{name: 'CPU等待响应时间', data: []},
{name: 'CPU系统时间', data: []},
{name: 'CPU软件无响应时间', data: []},
{name: 'CPU运行用户进程所花费的时间', data: []},
]
}
},{
title: '正在运行的进程数(个)',
dateShowType: 'datetimerange',
dateDataTrans: {transList: true},
dataVal: {
titleVal: {textAlign: 'left', left: '1%'},
yAxisName: ' ',
gridTop: '35%',
legend: {top: '15%', left: '10%'},
lineXData: [],
dataList: [
{name: '正在运行的进程数', data: []},
// {name: '进程数', data: []}
]
}
},{
title: '登录用户数(个)',
dateShowType: 'datetimerange',
dateDataTrans: {transList: true},
dataVal: {
titleVal: {textAlign: 'left', left: '1%'},
yAxisName: ' ',
gridTop: '35%',
legend: {top: '15%', left: '10%'},
lineXData: [],
dataList: [
{name: '登录用户数', data: []}
]
}
},{
title: '交换卷/文件的可用空间(字节)',
dateShowType: 'datetimerange',
dateDataTrans: {transList: true},
dataVal: {
titleVal: {textAlign: 'left', left: '1%'},
yAxisName: ' ',
gridTop: '35%',
legend: {top: '15%', left: '10%'},
lineXData: [],
dataList: [
{name: '交换卷/文件的可用空间', data: []}
]
}
},{
title: '内存利用率(%)',
dateShowType: 'datetimerange',
dateDataTrans: {transList: true},
dataVal: {
titleVal: {textAlign: 'left', left: '1%'},
yAxisName: ' ',
gridTop: '35%',
legend: {top: '15%', left: '10%'},
lineXData: [],
dataList: [
{name: '内存利用率', data: []}
]
}
},{
title: '可用交换空间百分比(%)',
dateShowType: 'datetimerange',
dateDataTrans: {transList: true},
dataVal: {
titleVal: {textAlign: 'left', left: '1%'},
yAxisName: ' ',
gridTop: '35%',
legend: {top: '15%', left: '10%'},
lineXData: [],
dataList: [
{name: '可用交换空间百分比', data: []}
]
}
},{
title: '可用内存(G)',
dateShowType: 'datetimerange',
dateDataTrans: {transList: true},
dataVal: {
titleVal: {textAlign: 'left', left: '1%'},
yAxisName: ' ',
gridTop: '35%',
legend: {top: '15%', left: '10%'},
lineXData: [],
dataList: [
{name: '可用内存', data: []}
]
}
},{
title: '可用内存百分比(%)',
dateShowType: 'datetimerange',
dateDataTrans: {transList: true},
dataVal: {
titleVal: {textAlign: 'left', left: '1%'},
yAxisName: ' ',
gridTop: '35%',
legend: {top: '15%', left: '10%'},
lineXData: [],
dataList: [
{name: '可用内存百分比', data: []}
]
}
}
],
// 第二栏
activeNames: [],
matchNum: {num: ''},
secondChartList: {},
eventDataMap: {},
echartData: {
title: 'GE1/0/1的丢包数',
dateShowType: 'datetimerange',
dateDataTrans: {transList: true},
dataVal: {
titleVal: {textAlign: 'left', left: '1%'},
yAxisName: ' ',
gridTop: '35%',
legend: {top: '15%', left: '10%'},
lineXData: ['2025-9-1', '2025-9-2', '2025-9-3', '2025-9-4', '2025-9-5', '2025-9-6', '2025-9-7'],
dataList: [{
name: '入站丢包',
data: [120, 132, 101, 134, 90, 230, 210],
},{
name: '出站丢包',
data: [220, 182, 191, 234, 290, 330, 310]
}]
}
},
linuxSystem: {
mount: {
title: '挂载文件系统',
type: 'mount',
formList: {vfsType: '文件系统类型'},
formModel: {},
echartFors: [
{title: '的空间(G)', oneName: '可用空间', twoName: '总空间'},
{title: '的空间利用率(%)', oneName: '空间利用率'},
],
echartList: []
},
net: {
title: '网络接口interface eth0',
type: 'net',
formList: {type: '接口类型', status: '运行状态', speed: '速度', mac: '网卡MAC信息'},
formModel: {},
echartFors: [
{title: '的流量', oneName: '入站流量', twoName: '出站流量', unitSel: [{label: 'Kb', value: 'Kb'},{label: 'Mb', value: 'Mb'}, {label: 'Gb', value: 'Gb'}]},
{title: '的丢包数(个)', oneName: '入站丢包', twoName: '出站丢包'},
],
echartList: []
},
disk: {
title: '硬盘',
type: 'disk',
formList: {total: '磁盘大小(G)', writeTimesStr: '写入次数', readTimesStr: '读取次数', writeBytesStr: '写入字节', readBytesStr: '读取字节'},
formModel: {},
echartFors: [
{title: '的读写速率(KB/s)', oneName: '磁盘写入速率', twoName: '磁盘读取速率'},
// {title: '的读写次数(次)', oneName: '磁盘写入次数', twoName: '磁盘读取次数'},
// {title: '的读写字节(Bytes/s)', oneName: '磁盘写入字节', twoName: '磁盘读取字节'},
],
echartList: []
},
dock: {
title: '容器',
type: 'dock',
formList: {id: '容器ID', name: '容器名称'},
formModel: {},
echartFors: [
{title: '的CPU利用率(%)', oneName: 'CPU利用率'},
{title: '的内存利用率(%)', oneName: '内存利用率'},
{title: '的网络速率(Kbps)', oneName: '网络接收速率', twoName: '网络发送速率'},
],
echartList: []
},
},
}
},
created() {
let startData = '';
let endData = '';
let todyTime = '';
const year = new Date().getFullYear();
const month = String(new Date().getMonth() + 1).padStart(2, '0'); // 0=1月,11=12月
const day = String(new Date().getDate()).padStart(2, '0'); // 当前日(如8
const prevDay = String(new Date().getDate() - 1).padStart(2, '0');
startData = `${year}-${month}-${prevDay} 00:00:00`;
endData = `${year}-${month}-${day} 23:59:59`;
todyTime = `${year}-${month}-${day}`;
this.firstTabTime = {startTime: todyTime + ' 00:00:00', endTime: todyTime + ' 23:59:59'};
this.firstTabTimeArr = [todyTime + ' 00:00:00', todyTime + ' 23:59:59'];
this.currTimeList = {startTime: startData, endTime: endData};
this.defaultTimes = [startData, endData];
this.paramsData = this.$route && this.$route.query;
this.handleClick();
},
methods: {
async handleClick(tab, event) {
this.loading = false;
if (this.activeName === 'first') {
await Promise.all([
this.getMonitorData(),
this.getCpuLoadData(this.firstTabTime),
this.getCpuTimeData(this.firstTabTime),
this.getProcNumData(this.firstTabTime),
this.getUserNumData(this.firstTabTime),
this.getSwapSizeFreeData(this.firstTabTime),
this.getMemoryUtilizationData(this.firstTabTime),
this.getSwapSizePercentData(this.firstTabTime),
this.getMemorySizeAvailableData(this.firstTabTime),
this.getMemorySizePercentData(this.firstTabTime),
]);
this.loading = true;
} else {
this.secondChartList = {};
this.eventDataMap = {};
this.activeNames = [];
await this.fnInterFaceNameList();
this.loading = true;
}
},
getMonitorData() {
this.formData = {formFirst: this.formFirst};
serverMonitorData({clientId: this.paramsData.clientId}).then(res => {
if (res && res.data) {
this.$set(this.formData, 'formValue', res.data);
}
});
},
getCpuLoadData(val) {
let cpuData = JSON.parse(JSON.stringify(this.resultData[0]));
cpuLoadData(Object.assign({},{clientId: this.paramsData.clientId}, val)).then(res => {
cpuData['fnEvent'] = 'getCpuLoadData';
cpuData.dateDataTrans['dateRange'] = this.firstTabTimeArr;
if (res && res.data) {
cpuData.dataVal.lineXData = res && res.data && res.data['xData'] && res.data['xData'].length > 0 ? res.data['xData'] :
this.firstChartTrans && this.firstChartTrans['timeList'] && this.firstChartTrans['timeList'].length > 0 ? this.firstChartTrans['timeList'] : [];
cpuData.dataVal.dataList[0].data = res && res.data && res.data['yData'] && res.data['yData']['load1Data'] && res.data['yData']['load1Data'].length > 0 ? res.data['yData']['load1Data'] : [];
cpuData.dataVal.dataList[1].data = res && res.data && res.data['yData'] && res.data['yData']['load5Data'] && res.data['yData']['load5Data'].length > 0 ? res.data['yData']['load5Data'] : [];
cpuData.dataVal.dataList[2].data = res && res.data && res.data['yData'] && res.data['yData']['load15Data'] && res.data['yData']['load15Data'].length > 0 ? res.data['yData']['load15Data'] : [];
cpuData.dataVal.dataList[3].data = res && res.data && res.data['yData'] && res.data['yData']['utiData'] && res.data['yData']['utiData'].length > 0 ? res.data['yData']['utiData'] : [];
}
// this.firstChartList[0] = cpuData;
this.$set(this.firstChartList, 0, cpuData);
}).catch(() => {
this.firstChartList[0] = cpuData;
});
},
getCpuTimeData(val) {
let memData = JSON.parse(JSON.stringify(this.resultData[1]));
cpuTimeData(Object.assign({},{clientId: this.paramsData.clientId}, val)).then(res => {
memData['fnEvent'] = 'getCpuTimeData';
memData.dateDataTrans['dateRange'] = this.firstTabTimeArr;
if (res && res.data) {
memData.dataVal.lineXData = res && res.data && res.data['xData'] && res.data['xData'].length > 0 ? res.data['xData'] :
this.firstChartTrans && this.firstChartTrans['timeList'] && this.firstChartTrans['timeList'].length > 0 ? this.firstChartTrans['timeList'] : [];
memData.dataVal.dataList[0].data = res && res.data && res.data['yData'] && res.data['yData']['normalData'] && res.data['yData']['normalData'].length > 0 ? res.data['yData']['normalData'] : [];
memData.dataVal.dataList[1].data = res && res.data && res.data['yData'] && res.data['yData']['idleData'] && res.data['yData']['idleData'].length > 0 ? res.data['yData']['idleData'] : [];
memData.dataVal.dataList[2].data = res && res.data && res.data['yData'] && res.data['yData']['iowaitData'] && res.data['yData']['iowaitData'].length > 0 ? res.data['yData']['iowaitData'] : [];
memData.dataVal.dataList[3].data = res && res.data && res.data['yData'] && res.data['yData']['norespData'] && res.data['yData']['norespData'].length > 0 ? res.data['yData']['norespData'] : [];
memData.dataVal.dataList[4].data = res && res.data && res.data['yData'] && res.data['yData']['switchMemUse'] && res.data['yData']['switchMemUse'].length > 0 ? res.data['yData']['switchMemUse'] : [];
memData.dataVal.dataList[5].data = res && res.data && res.data['yData'] && res.data['yData']['userpData'] && res.data['yData']['userpData'].length > 0 ? res.data['yData']['userpData'] : [];
}
// this.firstChartList[1] = memData;
this.$set(this.firstChartList, 1, memData);
}).catch(() => {
this.firstChartList[1] = memData;
});
},
getProcNumData(val) {
let procData = JSON.parse(JSON.stringify(this.resultData[2]));
procNum(Object.assign({},{clientId: this.paramsData.clientId}, val)).then(res => {
procData['fnEvent'] = 'getProcNumData';
procData.dateDataTrans['dateRange'] = this.firstTabTimeArr;
if (res && res.data) {
procData.dataVal.lineXData = res && res.data && res.data['xData'] && res.data['xData'].length > 0 ? res.data['xData'] :
this.firstChartTrans && this.firstChartTrans['timeList'] && this.firstChartTrans['timeList'].length > 0 ? this.firstChartTrans['timeList'] : [];
procData.dataVal.dataList[0].data = res && res.data && res.data['yData'] && res.data['yData']['procNumRunData'] && res.data['yData']['procNumRunData'].length > 0 ? res.data['yData']['procNumRunData'] : [];
// procData.dataVal.dataList[1].data = res && res.data && res.data['yData'] && res.data['yData']['procNumData'] && res.data['yData']['procNumData'].length > 0 ? res.data['yData']['procNumData'] : [];
}
// this.firstChartList[2] = powerData;
this.$set(this.firstChartList, 2, procData);
}).catch(() => {
this.firstChartList[2] = procData;
});
},
getUserNumData(val) {
let userNumData = JSON.parse(JSON.stringify(this.resultData[3]));
serverUserNum(Object.assign({},{clientId: this.paramsData.clientId}, val)).then(res => {
userNumData['fnEvent'] = 'getUserNumData';
userNumData.dateDataTrans['dateRange'] = this.firstTabTimeArr;
if (res && res.data) {
userNumData.dataVal.lineXData = res && res.data && res.data['xData'] && res.data['xData'].length > 0 ? res.data['xData'] :
this.firstChartTrans && this.firstChartTrans['timeList'] && this.firstChartTrans['timeList'].length > 0 ? this.firstChartTrans['timeList'] : [];
userNumData.dataVal.dataList[0].data = res && res.data && res.data['yData'] && res.data['yData']['usersNumData'] && res.data['yData']['usersNumData'].length > 0 ? res.data['yData']['usersNumData'] : [];
}
// this.firstChartList[2] = powerData;
this.$set(this.firstChartList, 3, userNumData);
}).catch(() => {
this.firstChartList[3] = userNumData;
});
},
getSwapSizeFreeData(val) {
let swapSizeFreeData = JSON.parse(JSON.stringify(this.resultData[4]));
swapSizeFree(Object.assign({},{clientId: this.paramsData.clientId}, val)).then(res => {
swapSizeFreeData['fnEvent'] = 'getSwapSizeFreeData';
swapSizeFreeData.dateDataTrans['dateRange'] = this.firstTabTimeArr;
if (res && res.data) {
swapSizeFreeData.dataVal.lineXData = res && res.data && res.data['xData'] && res.data['xData'].length > 0 ? res.data['xData'] :
this.firstChartTrans && this.firstChartTrans['timeList'] && this.firstChartTrans['timeList'].length > 0 ? this.firstChartTrans['timeList'] : [];
swapSizeFreeData.dataVal.dataList[0].data = res && res.data && res.data['yData'] && res.data['yData']['swapSizeFreeData'] && res.data['yData']['swapSizeFreeData'].length > 0 ? res.data['yData']['swapSizeFreeData'] : [];
}
// this.firstChartList[2] = powerData;
this.$set(this.firstChartList, 4, swapSizeFreeData);
}).catch(() => {
this.firstChartList[4] = swapSizeFreeData;
});
},
getMemoryUtilizationData(val) {
let memoryUtilizaData = JSON.parse(JSON.stringify(this.resultData[5]));
memoryUtilization(Object.assign({},{clientId: this.paramsData.clientId}, val)).then(res => {
memoryUtilizaData['fnEvent'] = 'getMemoryUtilizationData';
memoryUtilizaData.dateDataTrans['dateRange'] = this.firstTabTimeArr;
if (res && res.data) {
memoryUtilizaData.dataVal.lineXData = res && res.data && res.data['xData'] && res.data['xData'].length > 0 ? res.data['xData'] :
this.firstChartTrans && this.firstChartTrans['timeList'] && this.firstChartTrans['timeList'].length > 0 ? this.firstChartTrans['timeList'] : [];
memoryUtilizaData.dataVal.dataList[0].data = res && res.data && res.data['yData'] && res.data['yData']['memoryUtilizationData'] && res.data['yData']['memoryUtilizationData'].length > 0 ? res.data['yData']['memoryUtilizationData'] : [];
if (memoryUtilizaData.dataVal.dataList[0].data.length > 0 && memoryUtilizaData.dataVal.dataList[0].data.some(num => num < 0)) {
memoryUtilizaData.dataVal.gridLeft = '-7%';
}
}
// this.firstChartList[2] = powerData;
this.$set(this.firstChartList, 5, memoryUtilizaData);
}).catch(() => {
this.firstChartList[5] = memoryUtilizaData;
});
},
getSwapSizePercentData(val) {
let swapSizePercentData = JSON.parse(JSON.stringify(this.resultData[6]));
swapSizePercent(Object.assign({},{clientId: this.paramsData.clientId}, val)).then(res => {
swapSizePercentData['fnEvent'] = 'getSwapSizePercentData';
swapSizePercentData.dateDataTrans['dateRange'] = this.firstTabTimeArr;
if (res && res.data) {
swapSizePercentData.dataVal.lineXData = res && res.data && res.data['xData'] && res.data['xData'].length > 0 ? res.data['xData'] :
this.firstChartTrans && this.firstChartTrans['timeList'] && this.firstChartTrans['timeList'].length > 0 ? this.firstChartTrans['timeList'] : [];
swapSizePercentData.dataVal.dataList[0].data = res && res.data && res.data['yData'] && res.data['yData']['swapSizePercentData'] && res.data['yData']['swapSizePercentData'].length > 0 ? res.data['yData']['swapSizePercentData'] : [];
}
// this.firstChartList[2] = powerData;
this.$set(this.firstChartList, 6, swapSizePercentData);
}).catch(() => {
this.firstChartList[6] = swapSizePercentData;
});
},
getMemorySizeAvailableData(val) {
let memorySizeAvailData = JSON.parse(JSON.stringify(this.resultData[7]));
memorySizeAvailable(Object.assign({},{clientId: this.paramsData.clientId}, val)).then(res => {
memorySizeAvailData['fnEvent'] = 'getMemorySizeAvailableData';
memorySizeAvailData.dateDataTrans['dateRange'] = this.firstTabTimeArr;
if (res && res.data) {
memorySizeAvailData.dataVal.lineXData = res && res.data && res.data['xData'] && res.data['xData'].length > 0 ? res.data['xData'] :
this.firstChartTrans && this.firstChartTrans['timeList'] && this.firstChartTrans['timeList'].length > 0 ? this.firstChartTrans['timeList'] : [];
memorySizeAvailData.dataVal.dataList[0].data = res && res.data && res.data['yData'] && res.data['yData']['memorySizeAvailableData'] && res.data['yData']['memorySizeAvailableData'].length > 0 ? res.data['yData']['memorySizeAvailableData'] : [];
}
// this.firstChartList[2] = powerData;
this.$set(this.firstChartList, 7, memorySizeAvailData);
}).catch(() => {
this.firstChartList[7] = memorySizeAvailData;
});
},
getMemorySizePercentData(val) {
let memorySizePercentData = JSON.parse(JSON.stringify(this.resultData[8]));
memorySizePercent(Object.assign({},{clientId: this.paramsData.clientId}, val)).then(res => {
memorySizePercentData['fnEvent'] = 'getMemorySizePercentData';
memorySizePercentData.dateDataTrans['dateRange'] = this.firstTabTimeArr;
if (res && res.data) {
memorySizePercentData.dataVal.lineXData = res && res.data && res.data['xData'] && res.data['xData'].length > 0 ? res.data['xData'] :
this.firstChartTrans && this.firstChartTrans['timeList'] && this.firstChartTrans['timeList'].length > 0 ? this.firstChartTrans['timeList'] : [];
memorySizePercentData.dataVal.dataList[0].data = res && res.data && res.data['yData'] && res.data['yData']['memorySizePercentData'] && res.data['yData']['memorySizePercentData'].length > 0 ? res.data['yData']['memorySizePercentData'] : []
}
// this.firstChartList[2] = powerData;
this.$set(this.firstChartList, 8, memorySizePercentData);
}).catch(() => {
this.firstChartList[8] = memorySizePercentData;
});
},
// two
// //第一模块 挂载 === 接口名称
fnInterFaceNameList(val) {
this.activeNames = [];
mountNameList({clientId: this.paramsData.clientId}).then(res => {
if (res && res.data && res.data.length > 0) {
let tabNameList = {};
res && res.data.forEach(async(item,index) => {
let oneData = JSON.parse(JSON.stringify(this.linuxSystem['mount']));
oneData.title = item && item.mount;
tabNameList[item.mount] = oneData;
});
this.secondChartList = {...tabNameList};
this.activeNames = [Object.keys(tabNameList)[0]];
this.fnSwitchNetNames(); // 第二模块名称
setTimeout(() => {
this.fnDiskNames(); // 第三模块名称
setTimeout(() => {
this.fnDockerNames(); // 第四模块名称
},500);
},500);
// this.getPointDetailsData(this.currTimeList, Object.keys(tabNameList)[0]);
} else {
this.fnSwitchNetNames(); // 第二模块名称
setTimeout(() => {
this.fnDiskNames(); // 第三模块名称
setTimeout(() => {
this.fnDockerNames(); // 第四模块名称
},500);
},500);
}
}).catch(error =>{
this.fnSwitchNetNames();
setTimeout(() => {
this.fnDiskNames(); // 第三模块名称
setTimeout(() => {
this.fnDockerNames(); // 第四模块名称
},500);
},500);
// this.$modal.closeLoading();
// console.error('获取接口名称列表失败:', error);
// 可添加错误提示,如this.$message.error('数据加载失败')
});
},
// 基本信息
getPointDetailsData(times, titleName) {
this.eventDataMap[titleName] = true;
pointDetails({clientId: this.paramsData.clientId, mount: titleName}).then(res => {
this.secondChartList[titleName].formModel = res && res.data || [];
this.getSpaceEcharts(times ,titleName);
setTimeout(() => {
this.getSpaceRate(times, titleName);
},500)
}).catch(() => {
this.getSpaceEcharts(times, titleName);
setTimeout(() => {
this.getSpaceRate(times, titleName);
},500)
});
},
// 空间
getSpaceEcharts(times,titleName) {
let mountCollect = JSON.parse(JSON.stringify(this.secondChartList[titleName]));
let mountEcharts = JSON.parse(JSON.stringify(this.echartData));
let content = JSON.parse(JSON.stringify(this.linuxSystem['mount']));
mountEcharts.dateDataTrans['dateRange'] = this.defaultTimes;
mountEcharts.fnEvent = 'getSpaceEcharts';
spaceEcharts(Object.assign({}, {mount : titleName,clientId: this.paramsData.clientId}, times)).then(res => {
if (res && res.data) {
mountEcharts.title = titleName + content.echartFors[0].title;
mountEcharts.dataVal.yAxisName = res && res.data && res.data.unit ? '单位' + res.data.unit : ' ';
mountEcharts.dataVal.lineXData = res.data && res.data.xData.length > 0 ? res.data.xData : this.firstChartTrans && this.firstChartTrans['timeList'] || [];
mountEcharts.dataVal.dataList[0] = {
name: content.echartFors[0].oneName,
data: res.data && res.data.yData['vfsFreeData'] || []
};
mountEcharts.dataVal.dataList[1] = {
name: content.echartFors[0].twoName,
data: res.data && res.data.yData['vfsTotalData'] || []
};
}
mountCollect['echartList'][0] = mountEcharts;
this.$set(this.secondChartList, titleName, mountCollect);
this.$modal.closeLoading();
}).catch(() => {
this.$modal.closeLoading();
});
},
// 空间利用率
getSpaceRate(times,titleName) {
let mountCollect = JSON.parse(JSON.stringify(this.secondChartList[titleName]));
let mountEcharts = JSON.parse(JSON.stringify(this.echartData));
let content = JSON.parse(JSON.stringify(this.linuxSystem['mount']));
mountEcharts.dateDataTrans['dateRange'] = this.defaultTimes;
mountEcharts.fnEvent = 'getSpaceRate';
spaceRate(Object.assign({}, {mount : titleName,clientId: this.paramsData.clientId}, times)).then(res => {
if (res && res.data) {
mountEcharts.title = titleName + content.echartFors[1].title;
mountEcharts.dataVal.yAxisName = res && res.data && res.data.unit ? '单位' + res.data.unit : ' ';
mountEcharts.dataVal.lineXData = res.data && res.data.xData.length > 0 ? res.data.xData : this.firstChartTrans && this.firstChartTrans['timeList'] || [];
mountEcharts.dataVal.dataList[0] = {
name: content.echartFors[1].oneName,
data: res.data && res.data.yData['vfsUtilData'] || []
};
}
mountCollect['echartList'][1] = mountEcharts;
this.$set(this.secondChartList, titleName, mountCollect);
this.$modal.closeLoading();
}).catch(() => {
this.$modal.closeLoading();
});
},
// 第二模块 网络接口 ---所有网络接口名称
fnSwitchNetNames (){
postInterFaceName({clientId: this.paramsData.clientId,resourceType: 1}).then(res => {
if (res && res.length > 0) {
let tabNameList = {};
res && res.forEach(async(item,index) => {
let oneData = JSON.parse(JSON.stringify(this.linuxSystem['net']));
oneData.title = item && item.interfaceName;
oneData.serverIp = item && item.serverIp;
tabNameList[item.interfaceName] = oneData;
this.$set(this.secondChartList, item.interfaceName, oneData);
});
if (this.activeNames && this.activeNames.length <= 0) {
this.activeNames = [res[0].interfaceName];
// this.getNetDetailsData(this.currTimeList, res[0].interfaceName);
}
}
});
},
// 基本信息
getNetDetailsData(times, titleName) {
this.eventDataMap[titleName] = true;
netDetails({clientId: this.paramsData.clientId, name: titleName}).then(async res => {
this.secondChartList[titleName].formModel = res && res.data || [];
if (await this.getNetEcharts(times, titleName)) {
this.getNetDropped(times ,titleName);
}
}).catch(async () => {
if (await this.getNetEcharts(times, titleName)) {
this.getNetDropped(times ,titleName);
}
});
},
// 流量
getNetEcharts(times, titleName, unitData) {
let mountCollect = JSON.parse(JSON.stringify(this.secondChartList[titleName]));
let netEcharts = JSON.parse(JSON.stringify(this.echartData));
let content = JSON.parse(JSON.stringify(this.linuxSystem['net']));
netEcharts.dateDataTrans['dateRange'] = this.defaultTimes;
netEcharts.fnEvent = 'getNetEcharts';
return trafficEcharts(Object.assign(unitData || {}, {name : titleName,clientId: this.paramsData.clientId}, times)).then(res => {
if (res && res.data) {
netEcharts.title = titleName + content.echartFors[0].title;
netEcharts.dataVal.yAxisName = res && res.data && res.data.unit ? '单位' + res.data.unit : ' ';
netEcharts.dataVal.lineXData = res.data && res.data.xData.length > 0 ? res.data.xData : this.firstChartTrans && this.firstChartTrans['timeList'] || [];
netEcharts.dataVal.dataList[0] = {
name: content.echartFors[0].oneName,
data: res.data && res.data.yData['netInSpeedData'] || []
};
if (content.echartFors[0].unitSel) {
netEcharts.dataVal['unitModel'] = res && res.data && res.data.unit || '';
netEcharts.dataVal['unitSelList'] = content.echartFors[0].unitSel;
}
netEcharts.dataVal.dataList[1] = {
name: content.echartFors[0].twoName,
data: res.data && res.data.yData['netOutSpeedData'] || []
};
mountCollect['echartList'][0] = netEcharts;
this.$set(this.secondChartList, titleName, mountCollect);
}
return true;
}).catch(() => {
return true;
});
},
// 丢包数
getNetDropped(times, titleName) {
let mountCollect = JSON.parse(JSON.stringify(this.secondChartList[titleName]));
let netEcharts = JSON.parse(JSON.stringify(this.echartData));
let content = JSON.parse(JSON.stringify(this.linuxSystem['net']));
netEcharts.dateDataTrans['dateRange'] = this.defaultTimes;
netEcharts.fnEvent = 'getNetDropped';
return droppedEcharts(Object.assign({}, {name : titleName,clientId: this.paramsData.clientId}, times)).then(res => {
if (res && res.data) {
netEcharts.title = titleName + content.echartFors[1].title;
netEcharts.dataVal.yAxisName = res && res.data && res.data.unit ? '单位' + res.data.unit : ' ';
netEcharts.dataVal.lineXData = res.data && res.data.xData.length > 0 ? res.data.xData : this.firstChartTrans && this.firstChartTrans['timeList'] || [];
netEcharts.dataVal.dataList[0] = {
name: content.echartFors[1].oneName,
data: res.data && res.data.yData['inDroppedData'] || []
};
netEcharts.dataVal.dataList[1] = {
name: content.echartFors[1].twoName,
data: res.data && res.data.yData['outDroppedData'] || []
};
mountCollect['echartList'][1] = netEcharts;
this.$set(this.secondChartList, titleName, mountCollect);
}
this.$modal.closeLoading();
return true;
}).catch(() => {
this.$modal.closeLoading();
return true;
});
},
// 第三模块 硬盘设备 ---所有名称 diskAllNames, diskDetails, speedEcharts, timesEcharts, bytesEcharts
fnDiskNames (){
diskAllNames({clientId: this.paramsData.clientId}).then(res => {
if (res && res.data.length > 0) {
let tabNameList = {};
res && res.data.forEach(async(item,index) => {
let oneData = JSON.parse(JSON.stringify(this.linuxSystem['disk']));
oneData.title = item && item.name;
tabNameList[item.name] = oneData;
this.$set(this.secondChartList, item.name, oneData);
});
if (this.activeNames && this.activeNames.length <= 0) {
this.activeNames = [res.data[0].name];
// this.getDiskDetailsData(this.currTimeList, res.data[0].name);
}
}
});
},
// 基本信息
getDiskDetailsData(times, titleName) {
this.eventDataMap[titleName] = true;
diskDetails({clientId: this.paramsData.clientId, name: titleName}).then(async res => {
this.secondChartList[titleName].formModel = res && res.data || [];
this.getSpeedEcharts(times, titleName);
// if (await this.getSpeedEcharts(times, titleName)) {
// if (await this.getDiskTimes(times ,titleName)) {
// this.getDiskBytes(times ,titleName);
// }
// }
}).catch(async () => {
this.getSpeedEcharts(times, titleName);
// if (await this.getSpeedEcharts(times, titleName)) {
// if (await this.getDiskTimes(times ,titleName)) {
// this.getDiskBytes(times ,titleName);
// }
// }
});
},
//
getSpeedEcharts(times, titleName) {
let mountCollect = JSON.parse(JSON.stringify(this.secondChartList[titleName]));
let netEcharts = JSON.parse(JSON.stringify(this.echartData));
let content = JSON.parse(JSON.stringify(this.linuxSystem['disk']));
netEcharts.dateDataTrans['dateRange'] = this.defaultTimes;
netEcharts.fnEvent = 'getSpeedEcharts';
return speedEcharts(Object.assign({}, {name : titleName,clientId: this.paramsData.clientId}, times)).then(res => {
if (res && res.data) {
netEcharts.title = titleName + content.echartFors[0].title;
netEcharts.dataVal.yAxisName = res && res.data && res.data.unit ? '单位' + res.data.unit : ' ';
netEcharts.dataVal.lineXData = res.data && res.data.xData.length > 0 ? res.data.xData : this.firstChartTrans && this.firstChartTrans['timeList'] || [];
netEcharts.dataVal.dataList[0] = {
name: content.echartFors[0].oneName,
data: res.data && res.data.yData['writeSpeedData'] || []
};
netEcharts.dataVal.dataList[1] = {
name: content.echartFors[0].twoName,
data: res.data && res.data.yData['readSpeedData'] || []
};
mountCollect['echartList'][0] = netEcharts;
this.$set(this.secondChartList, titleName, mountCollect);
}
this.$modal.closeLoading();
return true;
}).catch(() => {
this.$modal.closeLoading();
return true;
});
},
//
// getDiskTimes(times, titleName) {
// let mountCollect = JSON.parse(JSON.stringify(this.secondChartList[titleName]));
// let netEcharts = JSON.parse(JSON.stringify(this.echartData));
// let content = JSON.parse(JSON.stringify(this.linuxSystem['disk']));
// netEcharts.dateDataTrans['dateRange'] = this.defaultTimes;
// netEcharts.fnEvent = 'getDiskTimes';
// return timesEcharts(Object.assign({}, {name : titleName,clientId: this.paramsData.clientId}, times)).then(res => {
// if (res && res.data) {
// netEcharts.title = titleName + content.echartFors[1].title;
// netEcharts.dataVal.yAxisName = res && res.data && res.data.unit ? '单位' + res.data.unit : ' ';
// netEcharts.dataVal.lineXData = res.data && res.data.xData.length > 0 ? res.data.xData : this.firstChartTrans && this.firstChartTrans['timeList'] || [];
// netEcharts.dataVal.dataList[0] = {
// name: content.echartFors[1].oneName,
// data: res.data && res.data.yData['writeTimesData'] || []
// };
// netEcharts.dataVal.dataList[1] = {
// name: content.echartFors[1].twoName,
// data: res.data && res.data.yData['readTimesData'] || []
// };
// mountCollect['echartList'][1] = netEcharts;
// this.$set(this.secondChartList, titleName, mountCollect);
// }
// return true;
// }).catch(() => {
// return true;
// });
// },
// //
// getDiskBytes(times, titleName) {
// let mountCollect = JSON.parse(JSON.stringify(this.secondChartList[titleName]));
// let netEcharts = JSON.parse(JSON.stringify(this.echartData));
// let content = JSON.parse(JSON.stringify(this.linuxSystem['disk']));
// netEcharts.dateDataTrans['dateRange'] = this.defaultTimes;
// netEcharts.fnEvent = 'getDiskBytes';
// return bytesEcharts(Object.assign({}, {name : titleName,clientId: this.paramsData.clientId}, times)).then(res => {
// if (res && res.data) {
// netEcharts.title = titleName + content.echartFors[2].title;
// netEcharts.dataVal.yAxisName = res && res.data && res.data.unit ? '单位' + res.data.unit : ' ';
// netEcharts.dataVal.lineXData = res.data && res.data.xData.length > 0 ? res.data.xData : this.firstChartTrans && this.firstChartTrans['timeList'] || [];
// netEcharts.dataVal.dataList[0] = {
// name: content.echartFors[2].oneName,
// data: res.data && res.data.yData['writeBytesData'] || []
// };
// netEcharts.dataVal.dataList[1] = {
// name: content.echartFors[2].twoName,
// data: res.data && res.data.yData['readBytesData'] || []
// };
// mountCollect['echartList'][2] = netEcharts;
// this.$set(this.secondChartList, titleName, mountCollect);
// }
// this.$modal.closeLoading();
// return true;
// }).catch(() => {
// this.$modal.closeLoading();
// return true;
// });
// },
// 第四模块 容器 ---所有名称 dockerAllNames, dockerDetails, cpuUtilEcharts, dockerMemEcharts, dockerSpeedEcharts
fnDockerNames (){
dockerAllNames({clientId: this.paramsData.clientId}).then(res => {
if (res && res.data.length > 0) {
let tabNameList = {};
res && res.data.forEach(async(item,index) => {
let oneData = JSON.parse(JSON.stringify(this.linuxSystem['dock']));
oneData.title = item && item.id;
tabNameList[item.id] = oneData;
this.$set(this.secondChartList, item.id, oneData);
});
if (this.activeNames && this.activeNames.length <= 0) {
this.activeNames = [res.data[0].id];
// this.getDockerDetailsData(this.currTimeList, res.data[0].id);
}
}
});
},
// 基本信息
getDockerDetailsData(times, titleName) {
this.eventDataMap[titleName] = true;
dockerDetails({clientId: this.paramsData.clientId, id: titleName}).then(async res => {
this.secondChartList[titleName].formModel = res && res.data || [];
if (await this.getCpuEcharts(times, titleName)) {
if (await this.getDockerMem(times ,titleName)) {
this.getDockerSpeed(times ,titleName);
}
}
}).catch(async () => {
if (await this.getCpuEcharts(times, titleName)) {
if (await this.getDockerMem(times ,titleName)) {
this.getDockerSpeed(times ,titleName);
}
}
});
},
//
getCpuEcharts(times, titleName) {
let mountCollect = JSON.parse(JSON.stringify(this.secondChartList[titleName]));
let netEcharts = JSON.parse(JSON.stringify(this.echartData));
let content = JSON.parse(JSON.stringify(this.linuxSystem['dock']));
netEcharts.dateDataTrans['dateRange'] = this.defaultTimes;
netEcharts.fnEvent = 'getCpuEcharts';
return cpuUtilEcharts(Object.assign({}, {id : titleName,clientId: this.paramsData.clientId}, times)).then(res => {
if (res && res.data) {
netEcharts.title = titleName + content.echartFors[0].title;
netEcharts.dataVal.yAxisName = res && res.data && res.data.unit ? '单位' + res.data.unit : ' ';
netEcharts.dataVal.lineXData = res.data && res.data.xData.length > 0 ? res.data.xData : this.firstChartTrans && this.firstChartTrans['timeList'] || [];
netEcharts.dataVal.dataList[0] = {
name: content.echartFors[0].oneName,
data: res.data && res.data.yData['writeSpeedData'] || []
};
mountCollect['echartList'][0] = netEcharts;
this.$set(this.secondChartList, titleName, mountCollect);
}
return true;
}).catch(() => {
return true;
});
},
//
getDockerMem(times, titleName) {
let mountCollect = JSON.parse(JSON.stringify(this.secondChartList[titleName]));
let netEcharts = JSON.parse(JSON.stringify(this.echartData));
let content = JSON.parse(JSON.stringify(this.linuxSystem['dock']));
netEcharts.dateDataTrans['dateRange'] = this.defaultTimes;
netEcharts.fnEvent = 'getDockerMem';
return dockerMemEcharts(Object.assign({}, {id : titleName,clientId: this.paramsData.clientId}, times)).then(res => {
if (res && res.data) {
netEcharts.title = titleName + content.echartFors[1].title;
netEcharts.dataVal.yAxisName = res && res.data && res.data.unit ? '单位' + res.data.unit : ' ';
netEcharts.dataVal.lineXData = res.data && res.data.xData.length > 0 ? res.data.xData : this.firstChartTrans && this.firstChartTrans['timeList'] || [];
netEcharts.dataVal.dataList[0] = {
name: content.echartFors[1].oneName,
data: res.data && res.data.yData['writeTimesData'] || []
};
mountCollect['echartList'][1] = netEcharts;
this.$set(this.secondChartList, titleName, mountCollect);
}
return true;
}).catch(() => {
return true;
});
},
//
getDockerSpeed(times, titleName) {
let mountCollect = JSON.parse(JSON.stringify(this.secondChartList[titleName]));
let netEcharts = JSON.parse(JSON.stringify(this.echartData));
let content = JSON.parse(JSON.stringify(this.linuxSystem['dock']));
netEcharts.dateDataTrans['dateRange'] = this.defaultTimes;
netEcharts.fnEvent = 'getDockerSpeed';
return dockerSpeedEcharts(Object.assign({}, {id : titleName,clientId: this.paramsData.clientId}, times)).then(res => {
if (res && res.data) {
netEcharts.title = titleName + content.echartFors[2].title;
netEcharts.dataVal.yAxisName = res && res.data && res.data.unit ? '单位' + res.data.unit : ' ';
netEcharts.dataVal.lineXData = res.data && res.data.xData.length > 0 ? res.data.xData : this.firstChartTrans && this.firstChartTrans['timeList'] || [];
netEcharts.dataVal.dataList[0] = {
name: content.echartFors[2].oneName,
data: res.data && res.data.yData['writeBytesData'] || []
};
netEcharts.dataVal.dataList[1] = {
name: content.echartFors[2].twoName,
data: res.data && res.data.yData['readBytesData'] || []
};
mountCollect['echartList'][2] = netEcharts;
this.$set(this.secondChartList, titleName, mountCollect);
}
this.$modal.closeLoading();
return true;
}).catch(() => {
this.$modal.closeLoading();
return true;
});
},
collapseChangeData(valList) {
valList && valList.forEach(item => {
if (item && !this.eventDataMap[item]) {
this.$modal.loading();
if (this.secondChartList[item].type === 'mount') {
this.getPointDetailsData(this.currTimeList, item);
} else if (this.secondChartList[item].type === 'net') {
this.getNetDetailsData(this.currTimeList, item);
} else if (this.secondChartList[item].type === 'disk') {
this.getDiskDetailsData(this.currTimeList, item);
} else if (this.secondChartList[item].type === 'dock') {
this.getDockerDetailsData(this.currTimeList, item);
}
}
});
},
chartFnEvent(valData, fnName, tabName, unit) {
this.firstChartTrans = valData;
// 检查函数是否存在,避免报错
if (typeof this[fnName] === 'function') {
this.defaultTimes = valData.timeArr;
this.firstTabTimeArr = valData.timeArr;
let unitData = unit ? {unit: unit} : {};
// 调用实际函数,并传递参数(如选中的值、当前项)
this[fnName]({startTime: valData.timeArr[0], endTime: valData.timeArr[1]}, tabName, unitData);
} else {
console.warn(`函数 ${fnName} 未定义`);
}
},
goBack() {
this.$router.push("/resource/serverRegister");
}
}
}
</script>
<style scoped>
</style>
@@ -0,0 +1,113 @@
<template>
<div style="padding: 8px 20px 20px;">
<el-collapse v-model="activeShowList" @change="collapseChange">
<template v-for="(val,key, index) of chartDataLit">
<el-collapse-item :title="`【${val && val.title || ''}】${val && val.serverIp || ''}`" :name="val && val.title || ''">
<div class="mt10 w100">
<div class="w100 plr-20" style="font-size: 14px">
<div v-for="(item,key,index) of val && val.formList || []" :key="`${key}-${index}`" class="w50 disInlineBlock p10">
<!-- <span class="w50 disInlineBlock" style="color: #C0C4CC;">{{item}}</span><span class="w50">{{val && val.formModel[key] || '-'}}</span>-->
<div class="disInlineBlock" style="width: 120px;color: #C0C4CC;">{{item}}</div>
<div style="width: calc(100% - 120px);vertical-align: top;" class="disInlineBlock">{{val && val.formModel[key] || '-'}}</div>
</div>
</div>
<div v-for="item of val && val.echartList || []" :key="`div-${val && val.title || ''}-${item && item.title || ''}-${index}`" class="w100 mt20 mb20" style="height: 200px;border-top: 1px solid #d8dce5">
<EchartsLine class="w100 h100" :key="`chart-${val && val.title || ''}-${item && item.title || ''}-${index}`" :lineData="item && item.dataVal || {}" :dateDataTrans="item && item.dateDataTrans || {}" :dateShowType="item && item.dateShowType || 'datetimerange'" :title="item && item.title || '图表数据'" :chartData="(valData, unit) => chartDataEvent(valData, item.fnEvent,val.title, unit)"></EchartsLine>
</div>
</div>
</el-collapse-item>
</template>
</el-collapse>
</div>
</template>
<script setup>
import EchartsLine from "@/components/echartsList/line.vue";
export default {
name: 'SecondAutoFind',
components: {EchartsLine},
props: {
secondChartList: {
type: Object,
default: () => {}
},
activeNames: {
type: Array,
default: () => []
},
},
watch: {
activeNames: {
handler(val) {
console.log();
// 因加入了fnFilterData方法进行了筛选排序,导致默认打开的不为原指定的元素了,这里就没用了
// this.activeShowList = val;
},
deep: true,
immediate: true
},
secondChartList: {
handler(val) {
this.chartDataLit = this.fnFilterData(val);
// 因加入了fnFilterData方法进行了筛选排序,导致默认打开的不为原指定的元素了,这里就没用了
// this.activeShowList = val;
},
deep: true,
immediate: true
},
},
data() {
return {
activeShowList: [],
chartDataLit: {},
}
},
created() {},
methods: {
// 筛选
fnFilterData(chartList) {
const allKeys = Object.keys(chartList);
const hasKeys = allKeys.filter(key => key.includes('Corporation')); // 含'Corporation'的键
const noKeys = allKeys.filter(key => !key.includes('Corporation')); // 不含'Corporation'的键
const newObj = {};
// 先添加含'Corporation'的键(保持原顺序)
hasKeys.forEach(key => {
newObj[key] = chartList[key];
});
// 再添加不含'Corporation'的键(保持原顺序)
noKeys.forEach(key => {
newObj[key] = chartList[key];
});
// 默认打开第一个元素
if (newObj && Object.keys(newObj).length > 0 && this.activeShowList && this.activeShowList <= 0) {
this.collapseChange([hasKeys[0]] || [Object.keys(newObj)[0]]);
}
return newObj;
},
collapseChange(val) {
this.activeShowList = val;
if (val && val.length > 0) {
this.$emit("collapseChangeData", val);
}
},
chartDataEvent(valData, funcName, tabName, unit) {
this.$emit("chartFnEvent", valData, funcName, tabName, unit);
// // 检查函数是否存在,避免报错
// if (typeof this[funcName] === 'function') {
// // 调用实际函数,并传递参数(如选中的值、当前项)
// // this[funcName]({startTime: valData[0], endTime: valData[1]});
// } else {
// console.warn(`函数 ${funcName} 未定义`);
// }
}
}
}
</script>
<style scoped>
::v-deep .el-collapse-item__header {
background-color: #d4e3fc!important;
/*color: #fff!important;*/
padding-left: 20px;
font-size: 1rem;
}
</style>
@@ -0,0 +1,291 @@
<template>
<div>
<el-form :model="form" ref="form" label-width="130px" class="dynamic-form">
<template v-if="showTactics">
<el-col :span="24">
<el-form-item label="策略名称" prop="policyName">
<el-input v-model="form.policyName" :disabled="readonly" clearable></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="描述" prop="description">
<el-input v-model="form.description" type="textarea" :disabled="readonly" clearable></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="关联资源组" prop="resourceGroupName">
<el-input v-model="form.resourceGroupName" :disabled="readonly" clearable></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="包含设备" prop="includedDevicesName">
<template v-if="readonly">
{{form.includedDevicesName}}
</template>
<template v-else>
<el-input v-model="form.includedDevicesName" :disabled="readonly" clearable></el-input>
</template>
</el-form-item>
</el-col>
</template>
<!-- 动态源文件部分 循环多个源文件地址 -->
<div v-for="(source, index) in form.sources" :key="index" class="source-item">
<!-- 源文件地址格式 -->
<el-col :span="14">
<el-form-item :label="`源文件${index + 1}地址格式`" :prop="`sources.${index}.sourceFilePathType`" :rules="[{ required: true, message: '请选择地址格式', trigger: 'change' }]">
<el-radio-group v-model="source.sourceFilePathType" :disabled="readonly">
<!-- <el-radio label="platform">平台文件地址</el-radio>-->
<el-radio label="1">外网HTTP(S)</el-radio>
</el-radio-group>
<div v-if="!readonly" class="tip">注意当文件大小超过100M时请选择外网HTTP(S)地址格式</div>
<!-- <div class="error-tip" v-if="source.sizeError">您选择的文件已经超过100M请更改文件地址格式选择</div>-->
</el-form-item>
</el-col>
<el-col :span="10" style="vertical-align: top;" v-if="readonly ? false : index === 0 ? true : false">
<el-form-item style="margin-left: -130px;">
<el-button type="primary" @click="addSource" class="add-btn">添加</el-button>
</el-form-item>
</el-col>
<!-- 添加源文件按钮 -->
<el-col :span="10" v-if="readonly ? false : index !== 0 ? true : false">
<el-form-item style="margin-left: -130px;">
<el-button type="danger" @click="removeSource(index)" class="delete-btn">删除</el-button>
</el-form-item>
</el-col>
<!-- 源文件地址 -->
<el-col :span="12">
<el-form-item :label="`源文件${index + 1}地址`" :prop="`sources.${index}.sourceFilePath`" :rules="[{ required: true, message: '请输入外网地址', trigger: 'blur' }]">
<el-input v-model="source.sourceFilePath" :disabled="readonly" placeholder="请输入外网地址" clearable></el-input>
</el-form-item>
</el-col>
</div>
<el-col :span="24">
<!-- 目标目录 -->
<el-form-item label="目标目录" prop="targetDirectory">
<el-input v-model="form.targetDirectory" :disabled="readonly" placeholder="请输入目标目录路径" clearable></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<!-- 命令内容部分 -->
<el-form-item label="命令内容">
<div v-for="(cmd, index) in form.commands" :key="index" class="command-item">
{{index + 1}}. <el-input v-model="cmd.commandContent" :disabled="readonly" class="ml5" placeholder="请输入命令" clearable></el-input>
<el-button type="primary" @click="addCommand" v-if="readonly ? !readonly : index === 0" class="command-btn">添加</el-button>
<el-button type="danger" @click="removeCommand(index)" v-if="readonly ? !readonly : index >= 1" class="command-btn">删除</el-button>
</div>
</el-form-item>
</el-col>
<!-- 执行方式 -->
<el-form-item label="执行方式" prop="executionMethod">
<el-select v-model="form.executionMethod" placeholder="请选择执行方式" :disabled="readonly" clearable>
<el-option v-for="dict in dict.type.policy_method" :key="dict.value" :label="dict.label" :value="dict.value"/>
</el-select>
</el-form-item>
<!-- 定时时间 -->
<el-form-item label="定时时间" v-if="form.executionMethod === '1'" prop="scheduledTime" :rules="[{ required: true, message: '请选择定时时间', trigger: 'change' }]">
<el-date-picker v-model="form.scheduledTime" :disabled="readonly" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss" type="datetime" placeholder="选择日期时间" style="width: 100%;"></el-date-picker>
</el-form-item>
<template v-if="showView">
<el-form-item label="策略状态" prop="policyStatus">
<el-select v-model="form.policyStatus" placeholder="请选择执行方式" :disabled="readonly" clearable>
<el-option v-for="dict in dict.type.policy_status" :key="dict.value" :label="dict.label" :value="dict.value"/>
</el-select>
</el-form-item>
<el-form-item label="下发策略时间" prop="deployTime">
<el-date-picker v-model="form.deployTime" :disabled="readonly" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss" type="datetime" style="width: 100%;"></el-date-picker>
</el-form-item>
<el-form-item label="创建时间" prop="createTime">
<el-date-picker v-model="form.createTime" :disabled="readonly" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss" type="datetime" style="width: 100%;"></el-date-picker>
</el-form-item>
<el-form-item label="修改时间" prop="updateTime">
<el-date-picker v-model="form.updateTime" :disabled="readonly" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss" type="datetime" style="width: 100%;"></el-date-picker>
</el-form-item>
</template>
</el-form>
</div>
</template>
<script>
export default {
name: 'DynamicForm',
dicts: ['policy_method', 'policy_status'],
props: {
formData: {
type: Object,
default: () => ({
sources: [{sourceFilePathType: '1', sourceFilePath: ''}], // 源文件数组,初始为空
commands: [{commandContent: ''}], // 命令内容数组
})
},
// 是否只读
readonly: {
type: Boolean,
default: false
},
// 是否展示第一级的策略信息
showTactics: {
type: Boolean,
default: false
},
// 详情
showView: {
type: Boolean,
default: false
}
},
watch: {
// 监听 props 变化,实时更新内部数据
formData: {
immediate: true, // 初始化时立即执行一次
handler(newVal) {
if (newVal && typeof newVal === 'object' && Object.keys(newVal).length === 0) {
this.form = JSON.parse(JSON.stringify({sources: [{sourceFilePathType: '1', sourceFilePath: ''}], commands: [{commandContent: ''}]}));
} else {
this.form = JSON.parse(JSON.stringify(newVal));
}
},
},
},
data() {
return {
form: {}
};
},
methods: {
// 添加源文件
addSource() {
// sizeError: false
this.form.sources.push({sourceFilePathType: '1', sourceFilePath: ''});
},
// 删除源文件
removeSource(index) {
this.form.sources.splice(index, 1);
},
// 添加命令
addCommand() {
this.form.commands.push({commandContent: ''});
},
// 删除命令
removeCommand(index) {
this.form.commands.splice(index, 1);
},
// 提交表单
submitForm() {
return new Promise((resolve, reject) => {
this.$refs.form.validate((valid) => {
if (valid) {
resolve(this.form);
// // 在这里可以添加自定义验证逻辑,例如检查大文件是否使用了正确的地址格式
// const hasError = this.form.sources.some(source => {
// // 假设这里有判断文件大小的逻辑
// const fileSize = this.getFileSize(source.address); // 假设的方法
// source.sizeError = fileSize > 100 && source.format === 'platform';
// return source.sizeError;
// });
// if (!hasError) {
// this.$message.success('表单提交成功');
// console.log('表单数据:', this.form);
// } else {
// this.$message.error('存在文件大小与地址格式不匹配的问题,请检查');
// }
} else {
this.$message.error('表单验证失败,请检查必填项');
reject(new Error('验证失败')); // 失败时返回错误
return false;
}
});
});
},
// 重置表单
resetForm() {
this.$refs.form.resetFields();
// 重置数组类型的字段
this.form.sources = [
{ format: '', address: '', sizeError: false },
{ format: '', address: '', sizeError: false }
];
this.form.commands = [''];
},
// 模拟获取文件大小的方法
getFileSize(address) {
// 实际应用中这里应该是真实的文件大小获取逻辑
const sizeMap = {
'system-default-1': 50, // 50M
'system-default-2': 150, // 150M
'user-upload-1': 80, // 80M
'user-upload-2': 200 // 200M
};
return sizeMap[address] || 0;
}
},
}
</script>
<style scoped>
/*.dynamic-form {*/
/* max-width: 800px;*/
/* margin: 20px auto;*/
/* padding: 20px;*/
/* background-color: #fff;*/
/* border-radius: 4px;*/
/* box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);*/
/*}*/
.tip {
color: #faad14;
font-size: 12px;
margin-top: 5px;
line-height: 1.5;
}
.error-tip {
color: #f5222d;
font-size: 12px;
margin-top: 5px;
line-height: 1.5;
}
/*.source-item {*/
/* padding-bottom: 15px;*/
/* margin-bottom: 15px;*/
/* border-bottom: 1px dashed #e8e8e8;*/
/*}*/
.source-item:last-child {
border-bottom: none;
}
.delete-btn {
margin-left: 120px;
margin-top: -10px;
}
.add-btn {
margin-left: 120px;
}
.command-item {
display: flex;
align-items: center;
margin-bottom: 10px;
}
.command-item .el-input {
flex: 1;
margin-right: 10px;
}
.command-btn {
white-space: nowrap;
}
</style>
@@ -0,0 +1,227 @@
<template>
<div class="app-container pageTopForm">
<el-form :model="queryParams" ref="queryRef" size="small" v-show="showSearch" label-width="auto">
<el-col :span="8">
<el-form-item label="策略名称" prop="policyName">
<el-input
v-model="queryParams.policyName"
placeholder="请输入策略名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="策略状态" prop="policyStatus">
<el-select
v-model="queryParams.policyStatus"
placeholder="请选择策略状态"
clearable>
<el-option
v-for="dict in dict.type.policy_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item class="lastBtnSty">
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-col>
</el-form>
<TableList :columns="columns" :config="config" :modelIdent="this.$options.name" :queryParams="queryParams" :tableList="tableList" @fnClick="callback" @fnRenderList="getList" @value-change="handleValueChange">
<template #tempMethod="{ row, column }">
<dict-tag :options="dict.type.policy_method" :value="row.executionMethod"/>
</template>
<template #tempResGroup="{ row, column }">
{{resourceGroupIdList[row.resourceGroupId]}}
</template>
<template #tempType="{ row, column }">
<dict-tag :options="dict.type.policy_status" :value="row.policyStatus"/>
</template>
</TableList>
</div>
</template>
<script setup>
import TableList from "@/components/table/index.vue"
import {listPolicy, delPolicy, getResMonitorGroup, getPolicyList} from "@/api/disRevenue/resource"
export default {
name: 'ServerScript',
components: {TableList},
dicts: ['policy_status', 'policy_method'],
data() {
return {
loading: true,
showSearch: true,
tableList: [],
queryParams: {
total: 0,
pageNum: 1,
pageSize: 10,
policyName: '',
policyStatus: ''
},
// 列显隐信息
columns: {
id: { label: `ID`,width: '50'},
policyName: { label: `策略名称`, minWidth: '250', visible: true },
executionMethod: { label: `执行方式`,minWidth: '80', slotName: 'tempMethod', visible: true},
resourceGroupId: { label: `关联资源组`,minWidth: '150', slotName: 'tempResGroup', visible: true },
includedDevicesName: { label: `包含设备`,minWidth: '200', visible: true},
policyStatus: { label: `策略状态`, minWidth: '80', slotName: 'tempType', visible: true },
sourceFilePath: { label: `源文件路径`,minWidth: '150'},
targetDirectory: { label: `目标目录`,minWidth: '200'},
commandContent: { label: `命令内容`,minWidth: '200'},
scheduledTime: { label: `定时时间`,minWidth: '200'},
deployTime: { label: `下发策略时间`,minWidth: '160'},
description: { label: `描述`,minWidth: '200'},
createTime: { label: `创建时间`,minWidth: '160'},
updateTime:{ label: `修改时间`,minWidth: '160'}
},
config: {
searcherForm: [
{label: '模版名称', prop: 'roleName', type: 'selset', options: []}
],
tableButton: {
top: [
{content: '新增', fnCode: 'add', type: 'primary', icon: 'el-icon-plus', hasPermi: 'resource:monitorStategy:add'},
{content: '删除', fnCode: 'delete', type: 'danger', icon: 'el-icon-delete', hasPermi: 'resource:monitorStategy:detele'},
{content: '导出', fnCode: 'export', type: 'warning', icon: 'el-icon-download', hasPermi: 'resource:monitorStategy:export'},
],
line: [
{content: '修改', fnCode: 'edit', type: 'text', icon: 'el-icon-edit', hasPermi: 'resource:monitorStategy:edit'},
{content: '详情', fnCode: 'details', type: 'text', icon: 'el-icon-view', hasPermi: 'resource:monitorStategy:details'},
// {content: '复制', fnCode: 'copy', type: 'text', icon: 'el-icon-document-copy', hasPermi: 'disRevenue:resource:monitorStategy:copy'},
{content: '下发策略', fnCode: 'strategy', type: 'text', showName: 'policyStatus', showVal: '0', icon: 'el-icon-sort-down', hasPermi: 'resource:monitorStategy:strategy'},
{content: '删除', fnCode: 'delete', type: 'text', icon: 'el-icon-delete', hasPermi: 'resource:monitorStategy:detele'},
]
}
},
resourceGroupIdList: {},
}
},
created() {
this.fnResMonitorGroup();
this.getList();
},
activated() {
this.$nextTick(() => {
this.fnResMonitorGroup();
this.getList();
});
},
methods: {
/** 查询列表 */
getList() {
this.loading = true;
listPolicy(this.queryParams).then(response => {
this.tableList = response.rows;
this.queryParams.total = response.total;
this.loading = false;
})
},
// 资源组
fnResMonitorGroup(){
getResMonitorGroup().then(res => {
if (res && res.data) {
res && res.data.forEach(item => {
this.resourceGroupIdList[item.id] = item.groupName;
});
}
});
},
// 处理子组件传递的新值
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/serverScript/details'});
break;
case 'edit':
this.$router.push({
path:'/resource/serverScript/details',
query:{
id: rowData.id
}
});
break;
case 'details':
this.$router.push({
path:'/resource/serverScript/details',
query:{
id: rowData.id,
readonly: true
}
});
break;
case 'delete':
let delList = [];
if (rowData && rowData.id) {
delList.push(rowData.id);
} else {
delList = selectChange;
}
this.$modal.confirm('是否确认删除该数据?').then(function() {
return delPolicy(delList)
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功")
}).catch(() => {});
break;
case 'strategy':
this.$modal.confirm('是否确认下发策略?').then(() => {
this.$modal.loading();
getPolicyList(rowData.id).then(res => {
this.getList();
this.$modal.msgSuccess(res.msg);
this.$modal.closeLoading();
}).catch(error => {
this.$modal.closeLoading();
});
}).catch(() => {});
break;
case 'export':
// let dataList = [];
// Object.keys(this.columns).forEach(item => {
// if (item.visible) {
// dataList.push(item.prop);
// }
// });
// this.download("/system/monitorStategy/export", {properties: dataList,}, `拓扑管理_${new Date().getTime()}.xlsx`);
let paramsList = Object.assign({}, this.queryParams,rowData);
this.download("rocketmq/policy/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>
@@ -0,0 +1,270 @@
<template>
<div class="app-container">
<div v-if="paramsData && paramsData.readonly">
<DynamicForm :formData="ruleFormDataTow" :showTactics="true" :readonly="true" :showView="true"></DynamicForm>
<el-button type="primary" style="float: right;margin-top: 12px;" class="mb10" @click="goBack">返回</el-button>
</div>
<div v-else>
<el-steps :active="active" finish-status="success">
<el-step title="基本信息"></el-step>
<el-step title="脚本策略"></el-step>
<el-step title="策略确认"></el-step>
</el-steps>
<!-- 内容区 -->
<div style="margin-top: 30px;">
<!-- active:0 -->
<div v-if="active === 0">
<Form ref="formRef" style="text-align: center;" :formList="formList" :ruleFormData="ruleFormData" :config="config" @fnClick="callback"></Form>
</div>
<!-- active:2 -->
<div v-if="active === 1">
<DynamicForm ref="dyncForm" :formData="ruleFormDataTow"></DynamicForm>
</div>
<!-- active:3 -->
<div v-if="active === 2">
<DynamicForm :formData="ruleFormDataTow" :showTactics="true" :readonly="true"></DynamicForm>
</div>
</div>
<el-button type="primary" v-show="active > 1" style="float: right;margin-top: 12px;margin-left: 10px;" @click="submit">提交</el-button>
<el-button type="primary" v-show="active < 2" style="float: right;margin-top: 12px;" @click="next('1')">下一步</el-button>
<el-button type="primary" v-show="active > 0" style="float: right;margin-top: 12px;" @click="next('-1')">上一步</el-button>
<el-button type="primary" style="float: right;margin-top: 12px;" @click="goBack">返回</el-button>
</div>
</div>
</template>
<script setup>
import Form from '@/components/form/index.vue';
import TableList from "@/components/table/index.vue"
import DynamicForm from './dynamicForm'
import {getPolicy, addPolicy, updatePolicy, getResMonitorGroup, resNameList, listArrRegisterList} from "@/api/disRevenue/resource"
export default {
name: 'ServerScriptDetails',
components: {Form, TableList, DynamicForm},
data() {
return {
active: 0,
synthesisList: {},
// 第一节点
ruleFormData: {
resourceGroupId: '',
includedDevicesDataList: []
},
config: {
buttonGroup: []
},
formList: [],
// 第二节点 1栏
ruleFormDataTow: {},
groupFormList: {},
includedDevicesList: {},
resourceGroupIdList: {},
}
},
created() {
this.paramsData = this.$route && this.$route.query;
// console.log('paramsData===',this.paramsData);
if (this.paramsData && this.paramsData.id) {
this.getFormDataList(this.paramsData.id);
}
this.formRender();
this.fnResMonitorGroup();
this.getResNameList();
},
methods: {
formRender(){
this.formList = [{
config: {title: '', colSpan: 'disBlock m0Auto'},
controls: {
id: {label: 'ID',hidden: true},
policyName: {label: '策略名称', span: 12, type: 'input', rules: [{required: true, message: '请输入模版名称', trigger: 'blur'}]},
description: {label: '描述', span: 12, type: 'textarea'},
resourceGroupId: {label: '关联资源组', span: 12, eventName: 'change', type: 'select', options:[]},
includedDevicesDataList: {label: '包含设备', span: 12, type: 'select', eventName: 'change', options:[], multiple: true, collapseTags: true}
}
}];
},
// 资源组
fnResMonitorGroup(){
getResMonitorGroup().then(res => {
if (res && res.data) {
this.formList[0].controls['resourceGroupId']['options']= res && res.data.map(item => {
this.resourceGroupIdList[item.id] = item;
return Object.assign({label: item.groupName, value: item.id});
});
}
});
},
getResNameList() {
resNameList().then(val => {
if (val) {
this.formList[0].controls['includedDevicesDataList']['options']= val && val.map(item => {
this.includedDevicesList[item.id] = item;
return Object.assign({label: item.id + '_' + item.resourceName, value: item.id});
});
}
}).catch(() => {
this.$modal.msgError("操作失败")
});
},
// 获取详情
getFormDataList(id) {
getPolicy(id).then(val => {
if (val && val.data) {
let firstForm = {};
Object.keys(this.formList[0].controls).forEach(item => {
firstForm[item] = val.data[item];
});
firstForm.includedDevicesDataList = val.data && val.data.includedDevicesId && val.data.includedDevicesId.split(',').map(id => Number(id));
firstForm['resourceGroupName'] = firstForm && firstForm.resourceGroupId ? this.resourceGroupIdList[val.data.resourceGroupId].groupName : '';
val.data['resourceGroupName'] = firstForm && firstForm.resourceGroupId ? this.resourceGroupIdList[val.data.resourceGroupId].groupName : '';
this.ruleFormData = {...firstForm};
// 第二节点
val.data['sources'] = [];
val.data['commands'] = [];
val.data.executionMethod = val.data.executionMethod.toString();
val.data.commandContent = val.data && val.data.commandContent.split(',');
val.data.sourceFilePath = val.data && val.data.sourceFilePath.split(',');
if (val.data.commandContent && val.data.commandContent.length > 0) {
val.data.commandContent.forEach(item => {
val.data['commands'].push({commandContent: item});
});
}
if (val.data.sourceFilePath && val.data.sourceFilePath.length > 0) {
val.data.sourceFilePath.forEach(item => {
val.data['sources'].push({sourceFilePathType: '1', sourceFilePath: item});
});
}
this.ruleFormDataTow = val.data;
}
}).catch(() => {
// this.$modal.msgError("操作失败")
});
},
async next(num) {
// console.log('num==',num, 'active==',this.active);
if (num === '-1') {
this.active--;
} else {
if (this.active === 0) {
if (!await this.fnFormValid()) {
return;
}
}
if (this.active === 1) {
this.formDataTow();
}
this.active++;
}
},
// form验证
fnFormValid() {
return new Promise((resolve) => {
this.ruleFormData = {};
const formValid = this.$refs.formRef.$refs.ruleForm;
// 3. 操作form(如验证)
formValid.validate((valid) => {
if (valid) {
// 资源组
formValid.model.resourceGroupName = formValid.model && formValid.model.resourceGroupId ? this.resourceGroupIdList[formValid.model.resourceGroupId].groupName: '';
// 包含设备
formValid.model['includedDevicesName'] = [];
if (formValid.model && formValid.model.includedDevicesDataList && formValid.model.includedDevicesDataList.length > 0) {
formValid.model.includedDevicesDataList.forEach(item => {
if (this.includedDevicesList[item]) {
formValid.model['includedDevicesName'].push(this.includedDevicesList[item].resourceName);
}
});
}
formValid.model['includedDevicesId'] = formValid.model['includedDevicesDataList'].join();
formValid.model['includedDevicesName'] = formValid.model['includedDevicesName'].join();
this.ruleFormData = formValid.model;
resolve(true);
} else {
resolve(false);
}
});
});
},
// 第二节点下的form值
formDataTow() {
let newFormVal = {commandContent: [], sourceFilePath: [], sourceFilePathType: []};
this.$refs.dyncForm.submitForm().then(formData => {
this.ruleFormDataTow = Object.assign({}, formData, this.ruleFormData);
if (formData && formData.commands && formData.commands.length > 0) {
formData.commands.forEach(item => {
newFormVal['commandContent'].push(item.commandContent);
});
}
if (formData && formData.sources && formData.sources.length > 0) {
formData.sources.forEach(item => {
newFormVal['sourceFilePath'].push(item.sourceFilePath);
newFormVal['sourceFilePathType'].push(item.sourceFilePathType);
});
}
newFormVal['sourceFilePath'] = newFormVal['sourceFilePath'].join();
newFormVal['sourceFilePathType'] = newFormVal['sourceFilePathType'].join();
newFormVal['commandContent'] = newFormVal['commandContent'].join();
this.groupFormList = Object.assign({},formData, newFormVal);
// console.log('vvvv=====',formData,'newFormVal====',this.groupFormList);
}).catch(error => {
// 处理验证失败的情况
console.error('表单提交失败:', error);
});
},
// 提交
submit() {
let params = Object.assign({}, this.groupFormList, this.ruleFormData);
// console.log('params==',params);
// return;
let fnType = addPolicy;
if (this.paramsData && this.paramsData.id) {
fnType = updatePolicy;
}
this.$modal.loading();
fnType(params).then(response => {
this.$modal.msgSuccess(response.msg);
this.$router.push("/resource/serverScript");
this.$modal.closeLoading();
}).catch(error => {
this.$modal.closeLoading();
});
},
// 返回
goBack() {
this.$router.push({path:'/resource/serverScript'});
},
// 监听事件
callback(result, dataVal, formVal) {
if (result && result.fnCode) {
switch (result.fnCode) {
case 'resourceGroupId':
this.ruleFormData['resourceGroupId'] = dataVal;
this.ruleFormData['includedDevicesDataList'] = [];
listArrRegisterList({id: dataVal}).then(res => {
if (res && res.data) {
res.data.forEach(item => {
this.ruleFormData['includedDevicesDataList'].push(Number(item.id));
});
}
});
break;
case 'includedDevicesDataList':
this.ruleFormData['resourceGroupId'] = null;
this.ruleFormData['includedDevicesDataList'] = dataVal;
break;
default:
}
}
}
}
}
</script>
<style scoped>
::v-deep .el-collapse-item__header {
background-color: #d4e3fc!important;
/*color: #fff!important;*/
padding-left: 20px;
font-size: 1rem;
}
</style>
@@ -0,0 +1,165 @@
<template>
<div class="app-container">
<Form ref="formRef" :formList="formList" :ruleFormData="ruleForm" :config="this.paramsData && this.paramsData.readonly ? {labelWidth: '140px', buttonGroup: []} : {labelWidth: '140px'}" @fnClick="callback"></Form>
<el-button v-if="this.paramsData && this.paramsData.readonly" style="float: right;margin-top: 12px;margin-left: 10px;" @click="callback({fnCode: 'cancel'})">返回</el-button>
</div>
</template>
<script setup>
import Form from '@/components/form/index.vue';
import {getPolicy, addPolicy, updatePolicy} from "@/api/disRevenue/resource"
import {getAllBusScriptName} from "@/api/disRevenue/earnManage"
export default {
name: 'severScriptStratDetails',
components: {Form},
dicts: ['policy_method', 'policy_status'],
props: {
open: {
type: String,
default: () => {}
},
dialogRowData: {
type: Object,
default: (() => {})
}
},
watch: {
open: {
handler(val) {
if (val === 'type_true') {
this.paramsData = {};
this.$set(this.ruleForm, 'deployDevice', this.dialogRowData.clientId);
} else if (val === 'type_false') {
// 清空form
this.$refs['formRef'].$refs.ruleForm.resetFields();
}
},
deep: true,
immediate: true
},
},
data() {
return {
loading: false,
ruleForm: {},
formList: [],
paramsData: {},
scriptList: {},
}
},
created() {
this.paramsData = this.$route && this.$route.query;
if (this.open) {
this.paramsData = {};
this.$set(this.ruleForm, 'deployDevice', this.dialogRowData.clientId);
}
if (this.paramsData && this.paramsData.id) {
this.getFormDataList(this.paramsData.id);
}
this.fnFormList();
this.getBusScriptNames();
},
methods: {
// formList集合
fnFormList(objVal) {
this.formList = [{
config: {title: '',labelWidth: '140px', readonly: this.paramsData && this.paramsData.readonly, colSpan: 'disBlock m0Auto'},
controls: {
id: {label: 'ID',hidden: true},
policyName: {label: '策略名称', span: 18, type: 'input', required: true},
description: {label: '描述', span: 18, type: 'textarea'},
taskName: {label: '关联业务下发任务', span: 18, type: 'input', hidden: !(this.paramsData && this.paramsData.readonly)},
deployDevice: {label: '部署设备', span: 18, type: 'textarea',rows: 15, required: true},
scriptName: {label: '脚本名称', span: 18, type: 'select', eventName: 'change', options: [], required: true},
scriptPath: {label: '脚本文件地址', span: 18, type: 'input', disabled: true, required: true},
defaultParams: {label: '脚本参数', span: 18, type: 'input'},
executionMethod: {label: '执行方式', span: 18, type: 'select', eventName:'change', options: this.dict.type.policy_method},
scheduledTime: {label: '定时时间', span: 18, type: 'datetime', required: true, hidden: true},
policyStatus: {label: '策略状态', span: 18, type: 'select', options: this.dict.type.policy_status, hidden: !(this.paramsData && this.paramsData.readonly)},
deployTime: {label: '下发策略时间', span: 18, type: 'datetime', hidden: !(this.paramsData && this.paramsData.readonly)},
createBy: {label: '创建人', span: 18, type: 'input', hidden: !(this.paramsData && this.paramsData.readonly)},
createTime: {label: '创建时间', span: 18, type: 'datetime', hidden: !(this.paramsData && this.paramsData.readonly)},
updateTime: {label: '修改时间', span: 18, type: 'datetime', hidden: !(this.paramsData && this.paramsData.readonly)},
}
}];
},
// 脚本名称
getBusScriptNames() {
getAllBusScriptName().then(val => {
this.formList[0].controls.scriptName['options'] = val && val.data.map(item => {
this.scriptList[item.scriptName] = item;
return Object.assign({label: item.scriptName, value: item.scriptName});
});
});
},
// 获取详情
getFormDataList(id) {
getPolicy(id).then(val => {
if (val && val.data) {
if (val.data.executionMethod === 1) {
this.formList[0].controls.scheduledTime['hidden'] = false;
}
if (this.paramsData && this.paramsData.readonly) {
val.data.deployDevice = val.data.deployDevice.replace(/\n/g, '<br>');
}
val.data.executionMethod = val && val.data.executionMethod.toString();
// val.data['scriptName'] = Number(val.data['scriptName']);
this.ruleForm = val && val.data;
}
}).catch(() => {
});
},
// 监听事件
callback(result, dataVal, formVal) {
if (result && result.fnCode) {
switch (result.fnCode) {
case 'scriptName':
this.ruleForm = Object.assign({}, this.ruleForm, this.$refs.formRef.$refs.ruleForm.model);
if (dataVal) {
let dataListVal = this.scriptList[dataVal];
this.$set(this.ruleForm, 'scriptPath', dataListVal['scriptPath']);
this.$set(this.ruleForm, 'defaultParams', dataListVal['defaultParams']);
}
break;
case 'executionMethod':
if (dataVal && dataVal === '1') {
this.formList[0].controls.scheduledTime['hidden'] = false;
} else {
this.formList[0].controls.scheduledTime['hidden'] = true;
}
break;
case 'submit':
let fnType = addPolicy;
if (dataVal && dataVal.id) {
fnType = updatePolicy;
}
if(this.loading) return;
this.loading = true;
fnType(dataVal).then(response => {
this.$modal.msgSuccess(response.msg);
if (this.open) {
this.$emit("dialogResult", {open: false});
} else {
this.$router.push("/resource/serverScriptStrat");
}
this.loading = false;
}).catch(() => {
this.$modal.msgError("操作失败")
});
break;
case 'cancel':
if (this.open) {
this.$emit("dialogResult", {open: false});
} else {
this.$router.push("/resource/serverScriptStrat");
}
break;
default:
}
}
}
}
}
</script>
<style>
</style>
@@ -0,0 +1,304 @@
<template>
<div class="app-container pageTopForm">
<el-form :model="queryParams" ref="queryRef" size="small" v-show="showSearch" label-width="auto">
<el-col :span="8">
<el-form-item label="策略名称" prop="policyName">
<el-input
v-model="queryParams.policyName"
placeholder="请输入策略名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="策略状态" prop="policyStatus">
<el-select
v-model="queryParams.policyStatus"
placeholder="请选择策略状态"
clearable>
<el-option
v-for="dict in dict.type.policy_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item class="lastBtnSty">
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-col>
</el-form>
<TableList :columns="columns" :config="config" :modelIdent="this.$options.name" :queryParams="queryParams" :tableList="tableList" @fnClick="callback" @fnRenderList="getList" @value-change="handleValueChange">
<template #tempFirst="{ row, column }">
<div @click="fnDetails(1,row)">
<a href="javascript:;" style="color: #51afff;text-decoration: underline;">{{row.offlineNum}}</a>
</div>
</template>
<template #tempSecond="{ row, column }">
<div @click="fnDetails(2,row)">
<a href="javascript:;" style="color: #51afff;text-decoration: underline;">{{row.sucessNum}}</a>
</div>
</template>
<template #tempThird="{ row, column }">
<div @click="fnDetails(3,row)">
<a href="javascript:;" style="color: #51afff;text-decoration: underline;">{{row.failNum}}</a>
</div>
</template>
<template #tmpExecution="{ row, column }">
<dict-tag :options="dict.type.policy_method" :value="row.executionMethod"/>
</template>
<template #tempStatus="{ row, column }">
<dict-tag :options="dict.type.policy_status" :value="row.policyStatus"/>
</template>
</TableList>
<!-- 弹窗 -->
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
<template v-if="clientList && clientList.length > 0">
<el-radio-group v-model="checkboxGroup" :disabled="dialogData['timeline'] ? false : true" size="mini" @input="handleCheckedCitiesChange">
<el-radio-button style="margin-right: 10px;" v-for="city in clientList" :label="city" :key="city">{{city}}</el-radio-button>
</el-radio-group>
<div v-if="dialogData['timeline']" class="block mt10">
<el-timeline :reverse="true">
<template v-for="(timeline,key,index) of dialogData.timelineList">
<el-timeline-item v-for="item of timeline" :timestamp="item.createTime" placement="top">
<pre>{{item.content}}</pre>
</el-timeline-item>
</template>
</el-timeline>
</div>
</template>
<el-empty v-else :image-size="200"></el-empty>
</el-dialog>
</div>
</template>
<script setup>
import TableList from "@/components/table/index.vue"
import {listPolicy, delPolicy, getScriptResultBySn} from "@/api/disRevenue/resource"
export default {
name: 'serverMonitorStrat',
components: {TableList},
dicts: ['policy_status', 'policy_method'],
data() {
return {
loading: true,
showSearch: true,
tableList: [],
queryParams: {
total: 0,
pageNum: 1,
pageSize: 10,
status: ''
},
// 列显隐信息
columns: {
id: { label: `ID`,width: '50'},
policyName: { label: `策略名称`, minWidth: '200', visible: true },
description: { label: `描述`,minWidth: '200'},
taskName: { label: `关联业务下发`,minWidth: '200',visible: true},
deployDevice: { label: `部署设备`,minWidth: '250'},
scriptName: { label: `脚本名称`,minWidth: '150'},
scriptPath: { label: `脚本地址`,minWidth: '200'},
scriptParams: { label: `脚本参数`,minWidth: '200'},
executionMethod: { label: `执行方式`,minWidth: '200', slotName: 'tmpExecution'},
offlineNum: { label: `不在线数量`,minWidth: '100', slotName: 'tempFirst', visible: true},
sucessNum: { label: `执行成功数量`,minWidth: '120', slotName: 'tempSecond', visible: true},
failNum: { label: `执行失败数量`,minWidth: '120', slotName: 'tempThird', visible: true},
policyStatus: { label: `策略状态`, minWidth: '100', slotName: 'tempStatus', visible: true },
deployTime: { label: `下发策略时间`,minWidth: '160'},
createBy:{ label: `创建人`,minWidth: '100'},
createTime: { label: `创建时间`,minWidth: '160'},
updateTime: { label: `修改时间`,minWidth: '160'},
},
config: {
tableButton: {
top: [
{content: '新增', fnCode: 'add', type: 'primary', icon: 'el-icon-plus', hasPermi: 'resource:serverScriptStrat:add'},
{content: '删除', fnCode: 'delete', type: 'danger', icon: 'el-icon-delete', hasPermi: 'resource:serverScriptStrat:detele'},
{content: '导出', fnCode: 'export', type: 'warning', icon: 'el-icon-download', hasPermi: 'resource:serverScriptStrat:export'},
],
line: [
{content: '修改', fnCode: 'edit', type: 'text', showName: 'policyStatus', showVal: '0', icon: 'el-icon-edit', hasPermi: 'resource:serverScriptStrat:edit'},
{content: '详情', fnCode: 'details', type: 'text', icon: 'el-icon-view', hasPermi: 'resource:serverScriptStrat:details'},
{content: '删除', fnCode: 'delete', type: 'text', showName: 'policyStatus', showVal: '0', icon: 'el-icon-delete', hasPermi: 'resource:serverScriptStrat:detele'},
]
}
},
open: false,
checkboxGroup: '',
title: '',
dialogData: {
timeline: false,
timelineList: {}
},
clientList: [],
changeRowData: {},
}
},
created() {
this.getList();
},
activated() {
this.$nextTick(() => {
this.getList();
});
},
methods: {
/** 查询列表 */
getList() {
// this.$modal.loading();
listPolicy(this.queryParams).then(response => {
this.tableList = response.rows;
this.queryParams.total = response.total;
// this.$modal.closeLoading();
}).catch(err => {
// this.$modal.closeLoading();
})
},
// 处理子组件传递的新值
handleValueChange(newValue) {
// 父组件更新自身数据,实现同步
this.showSearch = newValue;
// console.log('父组件拿到新值:', newValue);
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryRef");
this.handleQuery();
},
fnDetails(num, row){
this.checkboxGroup = '';
this.changeRowData = row;
this.clientList = [];
this.open = true;
if (num === 1) {
this.title = '不在线设备';
this.dialogData['timeline'] = false;
this.clientList = row.offlineClientIds;
} else if (num === 2) {
this.title = '执行成功设备';
this.dialogData['timeline'] = true;
this.clientList = row.sucessClientIds;
if (this.clientList && this.clientList.length > 0) {
this.checkboxGroup = this.clientList[0];
this.handleCheckedCitiesChange(this.clientList[0]);
}
} else {
this.title = '执行失败设备';
this.dialogData['timeline'] = true;
this.clientList = row.failClientIds;
if (this.clientList && this.clientList.length > 0) {
this.checkboxGroup = this.clientList[0];
this.handleCheckedCitiesChange(this.clientList[0]);
}
}
},
// 选中clientId
handleCheckedCitiesChange(valModel) {
if (valModel) {
getScriptResultBySn({clientId: valModel, scriptId: this.changeRowData.id}).then(val => {
if ( val && val.data && val.data.scriptResult && val.data.scriptResult.length > 0) {
this.dialogData['timelineList'] = {};
this.$set(this.dialogData['timelineList'], valModel, val.data.scriptResult);
}
}).catch(error => {
this.dialogData['timelineList'] = {};
});
} else {
this.$delete(this.dialogData['timelineList'], valModel);
}
},
callback(result, rowData, selectChange, selectList) {
if (result && result.fnCode) {
switch (result.fnCode) {
case 'add':
this.$router.push({
path:'/resource/serverScriptStrat/details/index'});
break;
case 'edit':
this.$router.push({
path:'/resource/serverScriptStrat/details/index',
query:{
id: rowData.id
}
});
break;
case 'details':
this.$router.push({
path:'/resource/serverScriptStrat/details/index',
query:{
id: rowData.id,
readonly: true
}
});
break;
case 'delete':
let ids;
if (rowData && rowData.id) {
ids = rowData.id;
} else {
if (selectList && selectList.length <= 0) {
this.$modal.msgWarning("请选择数据!");
return;
}
ids = selectChange;
}
this.$modal.confirm('是否确认删除数据项?').then(function() {
return delPolicy(ids)
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功")
}).catch(() => {});
break;
case 'export':
// let dataList = [];
// Object.keys(this.columns).forEach(item => {
// if (item.visible) {
// dataList.push(item.prop);
// }
// });
// this.download("/system/monitorStategy/export", {properties: dataList,}, `拓扑管理_${new Date().getTime()}.xlsx`);
let paramsList = Object.assign({}, this.queryParams,rowData);
this.download("rocketmq/policy/export", paramsList, `服务器脚本策略_${new Date().getTime()}.xlsx`, null, 'json');
break;
default:
}
}
}
}
}
</script>
<style scoped>
::v-deep .lastBtnSty .el-form-item__content{
margin-left: 10px!important;
}
::v-deep .el-radio-button__inner{
border-radius: 4px!important;
border-left: 1px solid #DCDFE6!important;
}
::v-deep .el-radio-button.is-checked .el-radio-button__inner{
box-shadow: none!important;
}
::v-deep .el-radio-button.is-focus .el-radio-button__inner{
border-color: #1890ff!important;
}
::v-deep .el-timeline .el-timeline-item:last-child .el-timeline-item__tail {
display: block!important;
}
::v-deep .el-dialog{
min-height: 300px;
}
</style>
@@ -0,0 +1,476 @@
<template>
<div class="app-container">
<div style="display: flex; justify-content: center;">
<div class="w100">
<Form ref="formRef" :formList="formList" :config="{labelWidth: '140px',buttonGroup: []}" :ruleFormData="ruleFormData" @fnClick="callback"></Form>
</div>
</div>
<div>
<h3 style="padding: 15px 10px;border-bottom: 1px solid #ddd;">策略内容</h3>
<template v-if="!(paramsData && paramsData.readonly)">
<el-tabs v-model="activeName" class="plr-20">
<el-tab-pane label="监控项" name="first">
<el-collapse v-model="activeFirstName">
<el-collapse-item title="固定监控项" :name="0">
<template slot="title">
<span class="disInlineBlock" style="width: 15%;">固定监控项</span>
<div style="font-size: 13px;margin-left: 10%;">
采集周期<el-select v-model="firstChangeTime" id="selDisabled" clearable placeholder="请选择" @change="handleChangeTime">
<el-option v-for="val in timeOptions" :key="val.value" :label="val.label" :value="val.value"></el-option>
</el-select>
</div>
</template>
<div v-for="item of firstData">
<div class="plr-50">
<div v-for="city of item.checkList" class="w100 mt10 mb10 disInlineBlock fontSize15">
<div class="disInlineBlock w50">
<span style="width: 200px" class="disInlineBlock">{{ city.metricKey }}</span>
<span>{{city.metricName}}</span>
</div>
<div class="disInlineBlock" style="color: #606266">
采集周期<el-select v-model="city['time']" placeholder="请选择" clearable>
<el-option v-for="val in timeOptions" :key="val.value" :label="val.label" :value="val.value"></el-option>
</el-select>
</div>
</div>
</div>
</div>
</el-collapse-item>
</el-collapse>
</el-tab-pane>
<el-tab-pane label="自动发现项" name="second">
<el-collapse v-model="activeTwoName">
<el-collapse-item v-for="(item,key,index) of secondData" :title="item.title" :name="index">
<template slot="title">
<span class="disInlineBlock" style="width: 15%;">{{item.title}}</span>
<div style="font-size: 13px;margin-left: 10%;">
采集周期<el-select v-model="item['time']" id="selDisabled" :disabled="key === 'switchNet' ? true : false" clearable placeholder="请选择">
<el-option v-for="val in timeOptions" :key="val.value" :label="val.label" :value="val.value"></el-option>
</el-select>
</div>
</template>
<div class="plr-50">
<div v-for="city of item.checkList" class="w100 mt10 mb10 disBlock fontSize15">
<span style="width: 300px" class="disInlineBlock">{{city.metricKey}}</span>
<span>{{city.metricName}}</span>
</div>
</div>
</el-collapse-item>
</el-collapse>
</el-tab-pane>
</el-tabs>
</template>
<template v-else>
<el-collapse v-model="activeTwoName">
<template v-for="(item,index) of firstData">
<el-collapse-item v-if="item.checkList && item.checkList.length > 0" :title="'监控项'" :name="index">
<template slot="title">
<span><span v-if="ruleFormData.priority === '1'">华为交换机>></span>监控项</span>
</template>
<div v-for="item of firstData">
<div class="plr-50">
<div v-for="city of item.checkList" class="w100 mt10 mb10 disInlineBlock fontSize15">
<div class="disInlineBlock w50">
<span style="width: 150px;color: #C0C4CC;" class="disInlineBlock">{{ city.metricName }}</span>
<span>{{city.metricKey}}</span>
</div>
<div class="disInlineBlock" style="color: #606266">
采集周期为{{city.timeLabel}}
</div>
</div>
</div>
</div>
</el-collapse-item>
</template>
<template v-for="(item,key,index) of secondData">
<el-collapse-item v-if="item.checkList && item.checkList.length > 0" :title="item.title" :name="index">
<template slot="title">
<span><span v-if="ruleFormData.priority === '1'">华为交换机>></span>自动发现项>>{{item.title}}</span>
</template>
<div class="plr-50">
当前所有子项的采集周期均为{{item.timeLabel}}
<div v-for="city of item.checkList" class="w100 mt10 mb10 disBlock fontSize15">
<span style="width: 300px;color: #C0C4CC;" class="disInlineBlock">{{city.metricName}}</span>
<span>{{city.metricKey}}</span>
</div>
</div>
</el-collapse-item>
</template>
</el-collapse>
</template>
</div>
<el-button v-if="!(paramsData && paramsData.readonly)" style="float: right;margin-top: 12px;margin-left: 10px;" @click="cancel">取消</el-button>
<el-button v-if="!(paramsData && paramsData.readonly)" type="primary" style="float: right;margin-top: 12px;" @click="submit">提交</el-button>
<el-button v-if="paramsData && paramsData.readonly" style="float: right;margin-top: 12px;margin-left: 10px;" @click="cancel">返回</el-button>
<!-- 弹窗 -->
<el-dialog title="旧策略信息" :visible.sync="policyOpen" width="900px" height="300px" append-to-body>
<TableList ref="tabRef" :columns="columns" :config="{colHiddenCheck: true, colTopHiddenIcon: true, currentSel: true}" :queryParams="queryParams" :tableList="tableList" @fnClick="callback"></TableList>
<div style="text-align: right;margin-right: 20px;margin-top: 20px;">
<el-button type="primary" style="margin-left: 10px;" @click="submitPubilc">确定</el-button>
<el-button @click="policyOpen = false">取消</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import Form from '@/components/form/index.vue';
import TableList from "@/components/table/index.vue"
import {addResourcePolicy, updateResourcePolicy,getMonitorTempList, getMonitorPolicy, listAllSwitchName, listMonitorPolicy} from "@/api/disRevenue/resource"
export default {
name: "MonitorStrategy",
components: {Form, TableList},
dicts: ['policy_status', 'collection_cycle', 'switch_type'],
props: {
open: {
type: String,
default: () => {}
}
},
watch: {
open: {
handler(val) {
if (val === 'type_false') {
// 清空form
this.$refs['formRef'].$refs.ruleForm.resetFields();
this.currentDataList = {};
}
},
deep: true,
immediate: true
},
},
data() {
return {
activeName: 'first',
activeFirstName: [0],
firstChangeTime: '',
activeTwoName: [0,1,2,3,4],
timeOptions: [],
ruleFormData: {
deployDevice: []
},
formList: [],
firstData: [
{checkList: []}
],
tempContent: {},
paramsData: {},
secondData: {
switchNet: {title: '网络端口发现', time: '300',
checkList: []
},
switchModule: {title: '光模块发现', time: '',
checkList: []
},
switchMpu: {title: 'MPU发现', time: '',
checkList: []
},
switchPwr: {title: '电源发现', time: '',
checkList: []
},
switchFan: {title: '风扇发现', time: '',
checkList: []
},
},
policyOpen: false,
currentDataList: {},
tableList: [],
queryParams: {
total: 0,
pageNum: 1,
pageSize: 10
},
// 列显隐信息
columns: {
id: { label: `ID`,width: '50'},
policyName: { label: `策略名称`, minWidth: '200', visible: true },
description: { label: `描述`,minWidth: '200',visible: true},
deployDevice: { label: `部署设备`,minWidth: '320',visible: true},
switchType: { label: `交换机类型`,minWidth: '150', slotName: 'tempType'},
priority: { label: `优先级`,minWidth: '150'},
connected: { label: `策略内容`,minWidth: '200'},
status: { label: `策略状态`, minWidth: '100', slotName: 'tempStatus'},
deployTime: { label: `下发策略时间`,minWidth: '160'},
updateTime:{ label: `创建人`,minWidth: '160'},
createTime: { label: `创建时间`,minWidth: '160'},
},
}
},
created() {
this.timeOptions = this.dict.type.collection_cycle;
this.paramsData = this.$route && this.$route.query;
// console.log('paramsData===',this.paramsData);
if (this.paramsData && this.paramsData.id) {
this.getFormDataList(this.paramsData.id);
} else {
this.getDataList();
}
this.fnFormList();
this.switchListName();
},
methods: {
// 接口名称
switchListName() {
listAllSwitchName({}).then(val => {
if(val && val.data) {
// this.switchNameList = val && val.data;
this.formList[0].controls.deployDevice['options'] = val && val.data.map(item => {
return Object.assign({label: item.switchName, value: item.clientId, id: item.clientId});
});
}
});
},
// formList集合
fnFormList(objVal) {
if (this.open) {
this.formList = [{
config: {},
controls: {
id: {label: 'ID',hidden: true},
policyName: {label: '策略名称', span: 18, type: 'input', required: true},
oldPolicy: {label: '引用旧策略', span: 3, type: 'button', style: 'vertical-align: top'},
description: {label: '描述', span: 18, type: 'textarea'},
switchType: {label: '交换机类型', span: 18, type: 'select', required: true, options: this.dict.type.switch_type},
deployDevice: {label: '部署设备', span: 18, type: 'treeSelect', options:[], multiple: true, required: true},
}
}];
} else {
this.formList = [{
config: {readonly: this.paramsData && this.paramsData.readonly, colSpan: this.paramsData && this.paramsData.readonly ? '' : 'disBlock'},
controls: {
id: {label: 'ID',hidden: true},
policyName: {label: '策略名称', span: 12, type: 'input', style: 'display: inline-block;', required: true},
oldPolicy: {label: '引用旧策略', span: 3, type: 'button', style: 'display: inline-block;vertical-align: top', hidden: this.paramsData && this.paramsData.readonly ? true : false},
priority: {label: '优先级', span: 12, type: 'input', hidden: this.paramsData && this.paramsData.readonly ? false : true},
status: {label: '策略状态', span: 12, type: 'select',options: this.dict.type.policy_status, hidden: this.paramsData && this.paramsData.readonly ? false : true},
deployTime: {label: '下发策略时间', span: 12, type: 'date', hidden: this.paramsData && this.paramsData.readonly ? false : true},
createTime: {label: '创建时间', span: 12, type: 'datetime', hidden: this.paramsData && this.paramsData.readonly ? false : true},
switchType: {label: '交换机类型', span: 12, type: 'select', required: true, options: this.dict.type.switch_type},
createBy: {label: '创建人', span: 12, type: 'input',hidden: this.paramsData && this.paramsData.readonly ? false : true},
deployDevice: {label: '部署设备', span: 12, type: 'treeSelect', options:[], multiple: true, required: true},
description: {label: '描述', span: 12, type: 'textarea'},
}
}];
}
},
// 获取详情
getFormDataList(id, btnGain) {
this.tempContent = {};
getMonitorPolicy(id).then(val => {
if (val && val.data) {
if (val.data && val.data.policy) {
val.data.policy['policyName'] = btnGain && btnGain ? val.data.policy['policyName'] + '-引用' : val.data.policy['policyName'];
val.data.policy['deployDevice'] = val.data.policy.deployDevice.split('\n');
// val.data.policy['status'] = Number(val.data.policy.status);
this.ruleFormData = val.data.policy;
}
this.tempContent = val.data['switch'];
}
this.getDataList();
}).catch(() => {
this.getDataList();
// this.$modal.msgError("操作失败")
});
},
getDataList() {
let itemTypeList = ['monitorItem', 'autodiscoverItem'];
itemTypeList.forEach(item => {
let params = {resourceType: 'switch', itemType: item};
this.fnGetMonitorTempList(params);
});
},
// 通过监控模版选项 查询监控策略展示项
fnGetMonitorTempList(params) {
let obj = {};
this.timeOptions.forEach(item => {
obj[item.value] = item.label;
});
getMonitorTempList(params).then(res => {
if (res && res.data) {
if (params.itemType === 'monitorItem') {
let otherData = res.data?.switchOther || [];
if (this.tempContent?.switchOther) {
this.tempContent['switchOther'].forEach(item => {
otherData.some(val => {
if (item.metricKey === val.metricKey) {
val['time'] = item.collectionCycle.toString();
val['timeLabel'] = obj[item.collectionCycle.toString()];
item['timeLabel'] = obj[item.collectionCycle.toString()];
return true;
}
})
});
}
this.firstData[0].checkList = this.paramsData && this.paramsData.readonly ? this.tempContent['switchOther'] : otherData;
}
if (params.itemType === 'autodiscoverItem') {
if (this.tempContent?.switchNet && this.tempContent?.switchNet.length > 0) {
this.secondData['switchNet'].time = this.tempContent.switchNet[0].collectionCycle.toString();
this.secondData['switchNet'].timeLabel = obj[this.tempContent.switchNet[0].collectionCycle.toString()];
this.tempContent['switchNet'].timeLabel = obj[this.tempContent.switchNet[0].collectionCycle.toString()];
}
this.secondData['switchNet'].checkList = this.paramsData && this.paramsData.readonly ? this.tempContent?.switchNet : res.data?.switchNet || [];
if (this.tempContent?.switchModule && this.tempContent?.switchModule.length > 0) {
this.secondData['switchModule'].time = this.tempContent.switchModule[0].collectionCycle.toString();
this.secondData['switchModule'].timeLabel = obj[this.tempContent.switchModule[0].collectionCycle.toString()];
}
this.secondData['switchModule'].checkList = this.paramsData && this.paramsData.readonly ? this.tempContent?.switchModule : res.data?.switchModule || [];
if (this.tempContent?.switchMpu && this.tempContent?.switchMpu.length > 0) {
this.secondData['switchMpu'].time = this.tempContent.switchMpu[0].collectionCycle.toString();
this.secondData['switchMpu'].timeLabel = obj[this.tempContent.switchMpu[0].collectionCycle.toString()];
}
this.secondData['switchMpu'].checkList = this.paramsData && this.paramsData.readonly ? this.tempContent?.switchMpu : res.data?.switchMpu || [];
if (this.tempContent?.switchPwr && this.tempContent?.switchPwr.length > 0) {
this.secondData['switchPwr'].time = this.tempContent.switchPwr[0].collectionCycle.toString();
this.secondData['switchPwr'].timeLabel = obj[this.tempContent.switchPwr[0].collectionCycle.toString()];
}
this.secondData['switchPwr'].checkList = this.paramsData && this.paramsData.readonly ? this.tempContent?.switchPwr : res.data?.switchPwr || [];
if (this.tempContent?.switchFan && this.tempContent?.switchFan.length > 0) {
this.secondData['switchFan'].time = this.tempContent.switchFan[0].collectionCycle.toString();
this.secondData['switchFan'].timeLabel = obj[this.tempContent.switchFan[0].collectionCycle.toString()];
}
this.secondData['switchFan'].checkList = this.paramsData && this.paramsData.readonly ? this.tempContent?.switchFan : res.data?.switchFan || [];
}
}
})
},
// 同步所有city的time为firstChangeTime的值
handleChangeTime() {
// 遍历firstData中的每一项
this.firstData.forEach(item => {
// 遍历当前项的checkList中的每个city
item.checkList.forEach(city => {
// 直接赋值,因为city是响应式对象(假设已初始化time属性)
city.time = this.firstChangeTime;
});
});
},
// form验证
fnFormValid() {
return new Promise((resolve) => {
this.ruleFormData = {};
const formValid = this.$refs.formRef.$refs.ruleForm;
// 3. 操作form(如验证)
formValid.validate((valid) => {
if (valid) {
formValid.model.deployDevice = formValid.model.deployDevice.join('\n');
this.ruleFormData = formValid.model;
resolve(true);
} else {
resolve(false);
}
});
});
},
async submit() {
if (!await this.fnFormValid()) return;
// 监控项
let idsList = [];
this.firstData.forEach(item => {
item && item.checkList.forEach(ids => {
if (ids && ids.time) {
idsList.push({id: ids.id, collectionCycle: ids.time});
}
});
});
// 自动发现项
let autoIds = [];
Object.keys(this.secondData).forEach(key => {
if (this.secondData[key].time) {
this.secondData[key] && this.secondData[key].checkList.forEach(ids => {
autoIds.push({id: ids.id, collectionCycle: this.secondData[key].time});
});
}
});
// console.log('ruleFormData===',this.ruleFormData);
// console.log('idsList===',idsList);
// console.log('autoIds===',autoIds);
let paramsList = idsList.concat(autoIds);
let params = Object.assign(this.ruleFormData, {resourceType: 'switch'},{collectionAndIdList: paramsList});
let fnType = addResourcePolicy;
if (this.paramsData && this.paramsData.id) {
fnType = updateResourcePolicy;
} else {
delete params['id'];
}
this.$modal.loading();
fnType(params).then(response => {
this.$modal.msgSuccess(response.msg);
if (this.open) {
this.$emit("dialogResult", {open: false});
} else {
this.$router.push("/resource/switchMonitorStrat");
}
this.$modal.closeLoading();
}).catch(error => {
this.$modal.closeLoading();
});
},
cancel() {
if (this.open) {
this.$emit("dialogResult", {open: false});
} else {
this.$router.push("/resource/switchMonitorStrat");
}
},
/** 查询列表 */
getList() {
// this.$modal.loading();
listMonitorPolicy(Object.assign({}, this.queryParams, {resourceType: 'switch',priority: 1})).then(response => {
this.tableList = response.rows;
this.queryParams.total = response.total;
if (this.currentDataList && this.currentDataList['id']) {
this.$refs.tabRef.setCurrent(this.currentDataList);
}
}).catch(err => {
// this.$modal.closeLoading();
})
},
submitPubilc() {
this.policyOpen = false;
this.getFormDataList(this.currentDataList.id, 'btnGain');
},
// 监听事件
callback(result, dataVal, formVal) {
if (result && result.fnCode) {
switch (result.fnCode) {
case 'oldPolicy':
this.policyOpen = true;
this.$nextTick(() => {
this.getList();
});
break;
case 'currentData':
this.currentDataList = dataVal;
break;
case 'cancel':
break;
default:
}
}
},
}
}
</script>
<style scoped>
::v-deep #selDisabled{
color: #303133!important;
}
::v-deep .el-collapse-item__header {
background-color: #d4e3fc!important;
/*color: #fff!important;*/
padding-left: 20px;
font-size: 1rem;
}
::v-deep .el-dialog__body {
padding: 10px 20px!important;
}
</style>
@@ -0,0 +1,197 @@
<template>
<div class="app-container pageTopForm">
<el-form :model="queryParams" ref="queryRef" size="small" v-show="showSearch" label-width="auto">
<el-col :span="8">
<el-form-item label="搜索" prop="queryName">
<el-input
v-model="queryParams.queryName"
placeholder="请输入策略名称/交换机名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="策略状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="请选择策略状态"
clearable>
<el-option
v-for="dict in dict.type.policy_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item class="lastBtnSty">
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-col>
</el-form>
<TableList :columns="columns" :config="config" :modelIdent="this.$options.name" :queryParams="queryParams" :tableList="tableList" @fnClick="callback" @fnRenderList="getList" @value-change="handleValueChange">
<template #tempType="{ row, column }">
<dict-tag :options="dict.type.switch_type" :value="row.switchType"/>
</template>
<template #tempStatus="{ row, column }">
<dict-tag :options="dict.type.policy_status" :value="row.status"/>
</template>
</TableList>
</div>
</template>
<script setup>
import TableList from "@/components/table/index.vue"
import {listMonitorPolicy, delMonitorPolicy, getMonitorPolicyList} from "@/api/disRevenue/resource"
export default {
name: 'switchMonitorStrat',
components: {TableList},
dicts: ['switch_type','eps_bandwidth_type', 'policy_status'],
data() {
return {
loading: true,
showSearch: true,
tableList: [],
queryParams: {
total: 0,
pageNum: 1,
pageSize: 10
},
// 列显隐信息
columns: {
id: { label: `ID`,width: '50'},
policyName: { label: `策略名称`, minWidth: '250', visible: true },
description: { label: `描述`,minWidth: '200',visible: true},
deployDevice: { label: `部署设备`,minWidth: '200',visible: true},
switchType: { label: `交换机类型`,minWidth: '150', slotName: 'tempType', visible: true },
priority: { label: `优先级`,minWidth: '150', visible: true },
connected: { label: `策略内容`,minWidth: '200'},
status: { label: `策略状态`, minWidth: '100', slotName: 'tempStatus', visible: true },
deployTime: { label: `下发策略时间`,minWidth: '160'},
updateTime:{ label: `创建人`,minWidth: '160'},
createTime: { label: `创建时间`,minWidth: '160'},
},
config: {
tableButton: {
top: [
{content: '新增', fnCode: 'add', type: 'primary', icon: 'el-icon-plus', hasPermi: 'resource:switchMonitorStrat:add'},
{content: '导出', fnCode: 'export', type: 'warning', icon: 'el-icon-download', hasPermi: 'resource:switchMonitorStrat:export'},
],
line: [
{content: '修改', fnCode: 'edit', type: 'text', showName: 'status', showVal: '0', icon: 'el-icon-edit', hasPermi: 'resource:switchMonitorStrat:edit'},
{content: '详情', fnCode: 'details', type: 'text', icon: 'el-icon-view', hasPermi: 'resource:switchMonitorStrat:details'},
{content: '删除', fnCode: 'delete', type: 'text', showName: 'status', showVal: '0', icon: 'el-icon-delete', hasPermi: 'resource:switchMonitorStrat:detele'},
{}
]
}
}
}
},
created() {
this.getList();
},
activated() {
this.$nextTick(() => {
this.getList();
});
},
methods: {
/** 查询列表 */
getList() {
// this.$modal.loading();
listMonitorPolicy(Object.assign({}, this.queryParams, {resourceType: 'switch'})).then(response => {
this.tableList = response.rows;
this.queryParams.total = response.total;
// this.$modal.closeLoading();
}).catch(err => {
// this.$modal.closeLoading();
})
},
// 处理子组件传递的新值
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, selectList) {
if (result && result.fnCode) {
switch (result.fnCode) {
case 'add':
this.$router.push({
path:'/resource/switchMonitorStrat/details/index'});
break;
case 'edit':
this.$router.push({
path:'/resource/switchMonitorStrat/details/index',
query:{
id: rowData.id
}
});
break;
case 'details':
this.$router.push({
path:'/resource/switchMonitorStrat/details/index',
query:{
id: rowData.id,
readonly: true
}
});
break;
case 'delete':
this.$modal.confirm('是否确认删除数据项?').then(function() {
return delMonitorPolicy(rowData.id)
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功")
}).catch(() => {});
break;
case 'strategy':
this.$modal.confirm('是否确认下发策略?').then(() => {
this.$modal.loading();
getMonitorPolicyList(rowData.id).then(res => {
this.getList();
this.$modal.msgSuccess(res.msg);
this.$modal.closeLoading();
}).catch(error => {
this.$modal.closeLoading();
});
}).catch(() => {});
break;
case 'export':
// let dataList = [];
// Object.keys(this.columns).forEach(item => {
// if (item.visible) {
// dataList.push(item.prop);
// }
// });
// this.download("/system/monitorStategy/export", {properties: dataList,}, `拓扑管理_${new Date().getTime()}.xlsx`);
let paramsList = Object.assign({}, this.queryParams,rowData);
this.download("rocketmq/monitorPolicy/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>
@@ -0,0 +1,40 @@
<template>
<div style="padding: 8px 20px 20px;">
<div class="w100 plr-20" style="font-size: 14px">
<div v-for="(item, key, index) of formData['formFirst']" class="w50 disInlineBlock p10">
<div class="disInlineBlock" style="width: 120px;color: #C0C4CC;">{{item}}</div>
<div class="disInlineBlock" style="width: calc(100% - 120px); vertical-align: top;">{{formData['formValue'] && formData['formValue'][key]}}</div>
</div>
</div>
<div v-for="item of chartList" class="w100 mt10 mb10" style="height: 200px;border-top: 1px solid #d8dce5">
<EchartsLine class="w100 h100" :lineData="item && item.dataVal || {}" :dateDataTrans="item && item.dateDataTrans || {}" :dateShowType="item && item.dateShowType || 'datetimerange'" :title="item && item.title || '图表数据'" :chartData="(valData) => chartDataEvent(valData, item.fnEvent)"></EchartsLine>
</div>
</div>
</template>
<script setup>
import EchartsLine from "@/components/echartsList/line.vue";
export default {
name: 'FirstMonitor',
components: {EchartsLine},
props: {
chartList: {
type: Array,
default: () => []
},
formData: {
type: Object,
default: () => {}
}
},
data() {
return {}
},
created() {},
methods: {
chartDataEvent(valData, funcName) {
this.$emit("chartFnEvent", valData, funcName);
},
}
}
</script>
@@ -0,0 +1,219 @@
<template>
<div class="app-container">
<Form :formList="formList" :config="this.paramsData && this.paramsData.readonly ? {labelWidth: '140px', buttonGroup: []} : {labelWidth: '140px'}" :ruleFormData="ruleForm" @fnClick="callback"></Form>
<div v-if="this.paramsData && this.paramsData.readonly">
<p style="font-size: 1rem;font-weight: 500;border-bottom: 1px solid #ddd;">接口备注信息</p>
<TableList :columns="columns" :config="config" :queryParams="queryParams" :tableList="tableList" @fnClick="callback">
<template #tempChange="{ row, column }">
<div>
<!-- 非编辑状态显示文本 -->
<template v-if="!row.editStatus">
<span>{{ row.interfaceRemark }}</span>
<el-button icon="el-icon-edit" type="text" @click="rowDataChange(row)"></el-button>
</template>
<template v-else>
<!-- 编辑状态显示输入框 -->
<el-col :span="16">
<el-input v-model="row.interfaceRemark" size="mini"></el-input>
</el-col>
<el-col :span="8">
<el-button size="mini" type="primary" @click="submit(row)">确定</el-button>
<el-button size="mini" @click="cancel(row)">取消</el-button>
</el-col>
</template>
</div>
</template>
</TableList>
</div>
<el-button v-if="this.paramsData && this.paramsData.readonly" style="float: right;margin-top: 12px;margin-left: 10px;" @click="callback({fnCode: 'cancel'})">返回</el-button>
</div>
</template>
<script setup>
import Form from '@/components/form/index.vue';
import TableList from '@/components/table/index.vue';
import {addSwitchManage, getSwitchManage, updateSwitchManage,updateSwitchInterface, delSwitchInterface} from "@/api/disRevenue/resource"
export default {
name: 'RegisterHandle',
components: {Form, TableList},
dicts: ['switch_type', 'rm_register_online_state','rm_register_version', 'rm_register_security_level', 'rm_register_permission', 'rm_register_encryption'],
data() {
return {
ruleForm: {
switchType: '1',
snmpVersion: '1',
securityLevel: '2',
readWritePermission: '2',
encryptionMethod: '2',
heartbeatCount: '3次',
heartbeatInterval: '30s',
heartbeatOid: '1.3.6.1.2.1.1.5',
},
formList: [],
paramsData: {},
tableList: [],
// 列显隐信息
columns: {
id: { label: `ID`,width: '80'},
interfaceName: { label: `接口名称`, visible: true, minWidth: '200'},
interfaceRemark: { label: `接口备注`, slotName: 'tempChange', visible: true, minWidth: '250'},
},
queryParams: {
pageNum: 1,
pageSize: 10,
total: 0
},
editStatus: false,
config: {
colTopHiddenIcon: true, colHiddenCheck: true,
tableButton: {
line: [
{content: '删除', fnCode: 'delete', type: 'text', icon: 'el-icon-delete'},
]
}
},
}
},
created() {
this.paramsData = this.$route && this.$route.query;
if (this.paramsData && this.paramsData.id) {
this.getFormDataList(this.paramsData.id);
} else {
this.fnFormList(this.ruleForm);
}
},
methods: {
rowDataChange(row) {
this.$set(row, 'editStatus', true);
},
// getList(){
// listHandle(this.addDateRange(this.queryParams)).then(response => {
// this.tableList = response.rows;
// this.queryParams.total = response.total;
// })
// },
// formList集合
fnFormList(objVal) {
this.formList = [{
config: {title: '基本信息', readonly: this.paramsData && this.paramsData.readonly},
controls: {
id: {label: 'ID',hidden: true},
switchName: {label: '交换机名称', span: 12, type: 'input', required: true},
hardwareSn: {label: '硬件SN', span: 12, type: 'input'},
heartbeatCount: {label: '交换机心跳检测次数', span: 12, type: 'input', disabled: true},
heartbeatInterval: {label: '交换机心跳检测周期', span: 12, type: 'input', disabled: true},
heartbeatOid: {label: '交换机心跳检测OID', span: 12, type: 'input', disabled: true},
switchType: {label: '交换机类型', span: 12, type: 'select', eventName: 'change', required: true, options: this.dict.type.switch_type},
snmpVersion: {label: 'SNMP版本', span: 12, type: 'radio', eventName: 'change', required: true, options: this.dict.type.rm_register_version, hidden: objVal && objVal.switchType === '1' ? false : true},
readWritePermission: {label: '读写权限', span: 12, type: 'radio', options: this.dict.type.rm_register_permission, hidden: objVal && objVal.switchType === '1' ? false : true},
securityLevel: {label: '安全级别', span: 12, type: 'radio', options: this.dict.type.rm_register_security_level, hidden: objVal && objVal.snmpVersion === '1' ? true : false},
encryptionMethod: {label: '加密方式', span: 12, type: 'radio', options: this.dict.type.rm_register_encryption, hidden: objVal && objVal.snmpVersion === '1' ? true : false},
communityName: {label: '团体名称', span: 12, type: 'input',hidden: objVal && objVal.switchType === '1' ? false : true},
snmpAddress: {label: 'SNMP采集地址', span: 12, type: 'input',required: true, hidden: objVal && objVal.switchType === '1' ? false : true},
snmpPort: {label: 'SNMP采集端口', span: 12, type: 'input',required: true, hidden: objVal && objVal.switchType === '1' ? false : true},
switchUser: {label: '用户名', span: 12, type: 'input', hidden: objVal && objVal.snmpVersion === '1' ? true : false},
switchPassword: {label: '密码', span: 12, type: 'input', hidden: objVal && objVal.snmpVersion === '1' ? true : false},
updateTime: {label: '修改时间', span: 12, type: 'datetime', hidden: this.paramsData && this.paramsData.readonly ? false : true},
createTime: {label: '创建时间', span: 12, type: 'datetime', hidden: this.paramsData && this.paramsData.readonly ? false : true},
onlineStatus: {label: '在线状态', span: 12, type: 'select', options: this.dict.type.rm_register_online_state, hidden: this.paramsData && this.paramsData.readonly ? false : true},
upTime: {label: '上机时间', span: 12, type: 'datetime', hidden: this.paramsData && this.paramsData.readonly ? false : true},
}
}];
},
// 获取详情
getFormDataList(id) {
getSwitchManage(id).then(val => {
if (val && val.data) {
// val.data['switchType'] = val.data['switchType'] && val.data['switchType'].toString();
this.ruleForm = val && val.data;
this.fnFormList(this.ruleForm);
if(this.paramsData && this.paramsData.readonly) {
this.tableList = val.data['switchInterfaceInfoList'];
}
}
}).catch(() => {
this.fnFormList(this.ruleForm);
this.$modal.msgError("操作失败")
});
},
// 列表上修改名称
submit(rowData) {
this.$set(rowData, 'editStatus', false);
updateSwitchInterface(rowData).then(response => {
this.$modal.msgSuccess(response.msg);
this.$set(rowData, 'editStatus', false);
this.getFormDataList(this.paramsData.id);
}).catch(() => {
// this.$modal.msgError("操作失败");
});
},
// 取消列表修改
cancel(rowData) {
this.$set(rowData, 'editStatus', false);
},
// 监听事件
callback(result, dataVal, selectChange) {
// console.log('result===',result);
if (result && result.fnCode) {
switch (result.fnCode) {
case 'switchType':
if (dataVal === '1') {
this.formList[0].controls.snmpVersion['hidden'] = false;
this.formList[0].controls.readWritePermission['hidden'] = false;
this.formList[0].controls.communityName['hidden'] = false;
this.formList[0].controls.snmpAddress['hidden'] = false;
this.formList[0].controls.snmpPort['hidden'] = false;
} else {
this.formList[0].controls.snmpVersion['hidden'] = true;
this.formList[0].controls.readWritePermission['hidden'] = true;
this.formList[0].controls.communityName['hidden'] = true;
this.formList[0].controls.snmpAddress['hidden'] = true;
this.formList[0].controls.snmpPort['hidden'] = true;
}
break;
case 'snmpVersion':
if (dataVal === '3') {
this.formList[0].controls.securityLevel['hidden'] = false;
this.formList[0].controls.encryptionMethod['hidden'] = false;
this.formList[0].controls.switchUser['hidden'] = false;
this.formList[0].controls.switchPassword['hidden'] = false;
} else {
this.formList[0].controls.securityLevel['hidden'] = true;
this.formList[0].controls.encryptionMethod['hidden'] = true;
this.formList[0].controls.switchUser['hidden'] = true;
this.formList[0].controls.switchPassword['hidden'] = true;
}
break;
case 'submit':
let fnType = addSwitchManage;
if (dataVal && dataVal.id) {
fnType = updateSwitchManage;
}
fnType(dataVal).then(response => {
this.$modal.msgSuccess(response.msg);
this.$router.push("/resource/switchRegister");
}).catch(() => {
this.$modal.msgError("操作失败")
});
break;
case 'cancel':
this.$router.push("/resource/switchRegister");
break;
case 'delete':
this.$modal.confirm('是否确认删除数据项?').then(function() {
return delSwitchInterface(dataVal.id)
}).then(() => {
this.getFormDataList(this.paramsData.id);
this.$modal.msgSuccess("删除成功")
}).catch(() => {});
break;
default:
}
}
}
}
}
</script>
<style>
</style>
+244
View File
@@ -0,0 +1,244 @@
<template>
<div class="app-container pageTopForm">
<el-form :model="queryParams" ref="queryRef" v-show="showSearch" size="small" label-width="auto">
<el-col :span="6">
<el-form-item label="交换机名称" title="交换机名称" prop="queryName">
<el-input
v-model="queryParams.queryName"
placeholder="请输入交换机名称"
clearable
@keyup.enter.native="handleQuery"/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="交换机在线状态" title="交换机在线状态" prop="onlineStatus">
<el-select
v-model="queryParams.onlineStatus"
placeholder="请选择交换机在线状态"
clearable>
<el-option
v-for="dict in dict.type.rm_register_online_state"
:key="dict.value"
:label="dict.label"
:value="dict.value"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<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_register_resource_type" :value="row.resourceType"/>
</template>
<!-- 端口 -->
<template #tempPort="{ row, column }">
<dict-tag :options="dict.type.rm_register_port" :value="row.resourcePort"/>
</template>
<!-- 协议 -->
<template #tempProtocol="{ row, column }">
<dict-tag :options="dict.type.rm_register_protocol" :value="row.protocol"/>
</template>
<!-- 注册状态 -->
<template #tempStatus="{ row, column }">
<dict-tag :options="dict.type.rm_register_status" :value="row.registrationStatus"/>
</template>
<!-- 在线状态 -->
<template #tempOnlineStatus="{ row, column }">
<dict-tag :options="dict.type.rm_register_online_state" :value="row.onlineStatus"/>
</template>
</TableList>
<!-- 弹窗 -->
<el-dialog title="添加监控策略" :visible.sync="open" width="1000px" append-to-body>
<MonitorStrategy :open="`type_${open}`" @dialogResult="fnDialogResult"></MonitorStrategy>
</el-dialog>
</div>
</template>
<script setup name="Register">
import {listSwitchManage} from '@/api/disRevenue/resource';
import TableList from '@/components/table/index.vue';
// import MonitorStrategy from './monitorStrategy';
import MonitorStrategy from '../switchMonitorStrat/monitorStrategy';
export default {
name: 'SwitchRegister',
components: {TableList, MonitorStrategy},
dicts: ['rm_register_resource_type', 'rm_register_protocol', 'rm_register_status', 'rm_register_port', 'rm_register_online_state'],
data() {
return {
open: false,
roleList: [],
loading: true,
showSearch: true,
ids: [],
single: true,
meltiple: true,
// 列显隐信息
columns: {
id: { label: `ID`,width: '80'},
switchName: { label: `交换机名称`, visible: true, minWidth: '200'},
hardwareSn: { label: `硬件SN`,minWidth: '250'},
resourceType: { label: `交换机类型`, minWidth: '100', slotName: 'tempType'},
snmpAddress: { label: `SNMP采集地址`, visible: true, minWidth: '150'},
snmpPort: { label: `SNMP采集端口`, visible: true, minWidth: '150'},
onlineStatus: { label: `在线状态`, slotName: 'tempOnlineStatus', minWidth: '120', visible: true },
upTime:{ label: `上机时间`,minWidth: '160'},
updateTime:{ label: `修改时间`,minWidth: '160'},
createTime:{ label: `创建时间`,minWidth: '160'},
heartbeatCount: { label: `交换机心跳检测次数`, minWidth: '180'},
heartbeatInterval: { label: `交换机心跳检测周期`, minWidth: '180'},
heartbeatOid: { label: `交换机心跳检测OID`, minWidth: '180'},
protocol: { label: `SNMP版本`, minWidth: '150'},
readWritePermission: { label: `读写权限`, minWidth: '120'},
securityLevel: { label: `安全级别`, minWidth: '120'},
encryptionMethod: { label: `加密方式`, minWidth: '120'},
communityName: { label: `团体名称`, minWidth: '120'},
resourceUserName: { label: `用户名`, minWidth: '100'},
resourcePwd: { label: `密码`, minWidth: '100'}
},
config: {
tableButton: {
top: [
{content: '新增', fnCode: 'add', type: 'primary', icon: 'el-icon-plus', hasPermi: 'resource:switchRegister:add'},
{content: '接口备注', fnCode: 'portRemarks', type: 'success', icon: 'el-icon-plus', hasPermi: 'resource:switchRegister:portRemarks'},
{content: '导出', fnCode: 'export', type: 'warning', icon: 'el-icon-download', hasPermi: 'resource:switchRegister:export'},
],
line: [
{content: '图形监控', fnCode: 'echartView', type: 'text', icon: 'el-icon-data-analysis', hasPermi: 'resource:switchRegister:graphicAnalysis'},
{content: '修改', fnCode: 'edit', type: 'text', icon: 'el-icon-edit', hasPermi: 'resource:switchRegister:edit'},
{content: '详情', fnCode: 'details', type: 'text', icon: 'el-icon-view', hasPermi: 'resource:switchRegister:details'},
{content: '执行监控策略', fnCode: 'monitorStrategy', type: 'text', icon: 'el-icon-document-checked', hasPermi: 'resource:switchRegister:monitorStrategy'},
{},{}
// {content: '注册', fnCode: 'enroll', showName: 'registrationStatus', showVal: '0', type: 'text', icon: 'el-icon-circle-check', hasPermi: 'resource:register:enroll'},
// {content: '取消注册', fnCode: 'unenroll', showName: 'registrationStatus', showVal: '1', type: 'text', icon: 'el-icon-circle-close', hasPermi: 'resource:register:unenroll'},
]
}
},
queryParams: {
pageNum: 1,
pageSize: 10,
total: 0
}
}
},
created() {
this.getList();
},
activated() {
this.$nextTick(() => {
this.getList();
});
},
methods: {
// 处理子组件传递的新值
handleValueChange(newValue) {
// 父组件更新自身数据,实现同步
this.showSearch = newValue;
// console.log('父组件拿到新值:', newValue);
},
/** 查询角色列表 */
getList() {
this.loading = true
listSwitchManage(this.addDateRange(this.queryParams)).then(response => {
this.roleList = response.rows;
this.queryParams.total = response.total;
this.loading = false;
})
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.$refs['queryRef'].resetFields();
this.queryParams = {pageNum: 1, pageSize: 10,total: 0};
// this.resetForm("queryRef");
this.handleQuery();
},
/** 多选框选中数据 */
handleSelectionChange(selection) {
this.ids = selection.map(item => item.roleId);
this.single = selection.length != 1;
this.multiple = !selection.length;
},
fnDialogResult(res){
this.open = false;
},
callback(result, rowData, selectChange) {
// console.log('result==',result);
if (result && result.fnCode) {
switch (result.fnCode) {
case 'add':
this.$router.push("/resource/switchRegister/edit/index");
break;
case 'portRemarks':
// if (selectChange && selectChange.length <= 0) {
// this.$modal.msgWarning("请选择数据!");
// return;
// }
this.$router.push({
path: '/resource/switchRegister/portRemarks',
// query: {ids: selectChange}
});
break;
case 'edit':
this.$router.push({
path:'/resource/switchRegister/edit/index',
query: {id: rowData.id}
});
break;
case 'details':
this.$router.push({
path:'/resource/switchRegister/edit/index',
query: {id: rowData.id, readonly: true}
});
break;
case 'echartView':
this.$router.push({
path:'/resource/switchRegister/monitorChart',
query: {clientId: rowData.clientId}
});
break;
case 'monitorStrategy':
this.open = true;
break;
case 'export':
// let dataList = [];
// Object.keys(this.columns).forEach(item => {
// if (item.visible) {
// dataList.push(item.prop);
// }
// });
// this.download("/system/registration/export", {properties: dataList,}, `资源管理_${new Date().getTime()}.xlsx`);
let paramsList = Object.assign({}, this.queryParams,rowData);
this.download("system/switchManagement/export", paramsList, `交换机管理_${new Date().getTime()}.xlsx`, null, 'json');
break;
default:
}
}
}
}
}
</script>
<style scoped>
::v-deep .lastBtnSty .el-form-item__content{
margin-left: 10px!important;
}
::v-deep .el-dialog__body {
padding: 0px!important;
}
</style>
@@ -0,0 +1,836 @@
<template>
<div class="app-container">
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="自动发现项" name="second">
<template v-if="activeName === 'second'">
<SecondAutoFind v-if="loading" :secondChartList="secondChartList" :activeNames="activeNames" @collapseChangeData="collapseChangeData" @chartFnEvent="chartFnEvent"></SecondAutoFind>
</template>
</el-tab-pane>
<el-tab-pane label="监控项" name="first">
<template v-if="activeName === 'first'">
<FirstMonitor v-if="loading" :formData="formData" :chartList="firstChartList" @chartFnEvent="chartFnEvent"></FirstMonitor>
</template>
</el-tab-pane>
</el-tabs>
<div style="float: right;margin-top: 20px;">
<el-button type="primary" @click="goBack">返回</el-button>
</div>
</div>
</template>
<script>
import FirstMonitor from "./firstMonitor";
import SecondAutoFind from "./secondAutoFind";
import {switchMonitorData, switchCpuData, switchMemData,switchPowerData, postInterFaceName, switchNetDetails,switchNetDiscards,switchNeTotal,
switchNetErrDiscard, switchNetSpeed, moduleAllName, moduleMsg, moduleLowThreshold, modulePower, mpuAllName, mpuMsg, mpuCpuUse, mpuMemUse,
mpuTemperature,pwrAllName, pwrMsg, pwrCurrent, pwrVoltage, fanAllName, fanMsg} from "@/api/disRevenue/resource"
export default {
name: "MonitorChart",
components: {FirstMonitor, SecondAutoFind},
data() {
return {
loading: false,
currTimeList: {},
defaultTimes: [],
firstTabTime: {},
firstTabTimeArr: [],
activeName: 'second',
paramsData: {},
// 第一栏
firstChartTrans: {},
formFirst: {
sysName: '系统名称', sysLocation: '系统位置', sysObjectID: '系统Object ID', hwStackSystemMac: '系统MAC地址',
sysUpTime: '系统运行时间', entPhysicalName: '设备名称', sysContact: '系统联系信息', entPhysicalSoftwareRev: '设备软件版本', sysDescr: '系统描述'
},
formData: {},
firstChartList: [],
resultData: [
{
title: '设备CPU使用率(%)',
dateShowType: 'datetimerange',
dateDataTrans: {transList: true},
dataVal: {
titleVal: {textAlign: 'left', left: '1%'},
yAxisName: ' ',
gridTop: '35%',
legend: {top: '15%', left: '10%'},
lineXData: [],
dataList: [{
name: '设备CPU使用率',
data: [],
}]
}
},{
title: '设备内存使用率(%)',
dateShowType: 'datetimerange',
dateDataTrans: {transList: true},
dataVal: {
titleVal: {textAlign: 'left', left: '1%'},
yAxisName: ' ',
gridTop: '35%',
legend: {top: '15%', left: '10%'},
lineXData: [],
dataList: [{
name: '设备内存使用率',
data: [],
}]
}
},{
title: '功率',
dateShowType: 'datetimerange',
dateDataTrans: {transList: true},
dataVal: {
titleVal: {textAlign: 'left', left: '1%'},
yAxisName: ' ',
gridTop: '35%',
legend: {top: '15%', left: '10%'},
lineXData: [],
dataList: [{
name: '系统平均功率(mW)',
data: [],
},{
name: '系统实时功率(mW)',
data: []
}]
}
}
],
// 第二栏
activeNames: [],
secondChartList: {},
eventDataMap: {},
echartData: {
title: 'GE1/0/1的丢包数',
dateShowType: 'datetimerange',
dateDataTrans: {transList: true},
dataVal: {
titleVal: {textAlign: 'left', left: '1%'},
yAxisName: ' ',
gridTop: '35%',
legend: {top: '15%', left: '10%'},
lineXData: ['2025-9-1', '2025-9-2', '2025-9-3', '2025-9-4', '2025-9-5', '2025-9-6', '2025-9-7'],
dataList: [{
name: '入站丢包',
data: [120, 132, 101, 134, 90, 230, 210],
},{
name: '出站丢包',
data: [220, 182, 191, 234, 290, 330, 310]
}]
}
},
linuxSystem: {
net: {
title: '网络端口GE1/0/1',
type: 'net',
formList: {ifDescr: '端口名称', ifType: '端口类型', ifOperStatus: '端口状态', ifSpeed: '端口适配速率(Mbps)'},
formModel: {},
echartFors: [
{title: '的丢包数', oneName: '入站丢包', twoName: '出站丢包'},
// {title: '的Bites总数', oneName: '端口发送Bites总数', twoName: '端口接收Bites总数'},
{title: '的错误包数量', oneName: '错误的入站数据包数量', twoName: '错误的出战数据包数量'},
{title: '的网络速率', oneName: '端口实时接收速率', twoName: '端口实时发送速率', unitSel: [{label: 'Kb', value: 'Kb'},{label: 'Mb', value: 'Mb'}, {label: 'Gb', value: 'Gb'}]},
],
echartList: []
},
light: {
title: '光模块sabc',
type: 'light',
formList: {name: '光模块端口名称'},
formModel: {name: 'sabc'},
echartFors: [
{title: '的光衰阈值(dBm)', oneName: '光模块发送光衰阈值', twoName: '光模块接收光衰阈值'},
{title: '的功率(dBm)', oneName: '光模块接收功率', twoName: '光模块发送功率'}
],
echartList: []
},
mpu: {
title: 'MPU1',
type: 'mpu',
formList: {name: 'MPU名称', system: 'MPU的操作系统'},
formModel: {name: 'MPU1', system: 'xxxx'},
echartFors: [
{title: '的CPU使用率(%)', oneName: 'CPU利用率'},
{title: '的内存使用率(%)', oneName: '内存利用率'},
{title: '的温度(°C)', oneName: '温度'},
],
echartList: []
},
pw: {
title: '电源PW1',
type: 'pw',
formList: {name: '电源名称', status: '电源状态'},
formModel: {name: 'PW1', status: '正在供电'},
echartFors: [
{title: '电流(mA)', oneName: '电源电流'},
{title: '电压(mV)', oneName: '电源电压'}
],
echartList: []
},
fan: {
title: '风扇FAN1',
type: 'fan',
formList: {name: '风扇名称', status: '风扇状态'},
formModel: {name: 'FAN1', status: 'xxx'},
echartFors: [],
echartList: []
}
},
}
},
created() {
let startData = '';
let endData = '';
let todyTime = '';
const year = new Date().getFullYear();
const month = String(new Date().getMonth() + 1).padStart(2, '0'); // 0=1月,11=12月
const day = String(new Date().getDate()).padStart(2, '0'); // 当前日(如8
const prevDay = String(new Date().getDate() - 1).padStart(2, '0');
startData = `${year}-${month}-${prevDay} 00:00:00`;
endData = `${year}-${month}-${day} 23:59:59`;
todyTime = `${year}-${month}-${day}`;
this.firstTabTime = {startTime: todyTime + ' 00:00:00', endTime: todyTime + ' 23:59:59'};
this.firstTabTimeArr = [todyTime + ' 00:00:00', todyTime + ' 23:59:59'];
this.currTimeList = {startTime: startData, endTime: endData};
this.defaultTimes = [startData, endData];
this.paramsData = this.$route && this.$route.query;
this.handleClick();
},
methods: {
async handleClick(tab, event) {
this.loading = false;
if (this.activeName === 'first') {
await Promise.all([
this.getMonitorData(),
this.getCpuData(this.firstTabTime),
this.getMemData(this.firstTabTime),
this.getPowerData(this.firstTabTime)
]);
this.loading = true;
} else {
this.secondChartList = {};
this.eventDataMap = {};
this.activeNames = [];
await this.fnInterFaceNameList();
this.loading = true;
}
},
getMonitorData() {
this.formData = {formFirst: this.formFirst};
switchMonitorData({clientId: this.paramsData.clientId}).then(res => {
if (res && res.data) {
this.$set(this.formData, 'formValue', res.data);
}
});
},
getCpuData(val) {
let cpuData = JSON.parse(JSON.stringify(this.resultData[0]));
cpuData.dateDataTrans['dateRange'] = this.firstTabTimeArr;
cpuData['fnEvent'] = 'getCpuData';
switchCpuData(Object.assign({},{clientId: this.paramsData.clientId}, val)).then(res => {
if (res && res.data) {
cpuData.dataVal.lineXData = res.data && res.data['xData'] && res.data['xData'].length > 0 ? res.data['xData'] :
this.firstChartTrans && this.firstChartTrans['timeList'] && this.firstChartTrans['timeList'].length > 0 ? this.firstChartTrans['timeList'] : [];
cpuData.dataVal.dataList[0].data = res.data && res.data['yData'] && res.data['yData']['switchCpuUse'] && res.data['yData']['switchCpuUse'].length > 0 ? res.data['yData']['switchCpuUse'] : [];
}
// this.firstChartList[0] = cpuData;
this.$set(this.firstChartList, 0, cpuData);
}).catch(() => {
this.firstChartList[0] = cpuData;
});
},
getMemData(val) {
let memData = JSON.parse(JSON.stringify(this.resultData[1]));
memData.dateDataTrans['dateRange'] = this.firstTabTimeArr;
memData['fnEvent'] = 'getMemData';
switchMemData(Object.assign({},{clientId: this.paramsData.clientId}, val)).then(res => {
if (res && res.data) {
memData.dataVal.lineXData = res.data && res.data['xData'] && res.data['xData'].length > 0 ? res.data['xData'] :
this.firstChartTrans && this.firstChartTrans['timeList'] && this.firstChartTrans['timeList'].length > 0 ? this.firstChartTrans['timeList'] : [];
memData.dataVal.dataList[0].data = res.data && res.data['yData'] && res.data['yData']['switchMemUse'] && res.data['yData']['switchMemUse'].length > 0 ? res.data['yData']['switchMemUse'] : [];
}
// this.firstChartList[1] = memData;
this.$set(this.firstChartList, 1, memData);
}).catch(() => {
this.firstChartList[1] = memData;
});
},
getPowerData(val) {
let powerData = JSON.parse(JSON.stringify(this.resultData[2]));
powerData.dateDataTrans['dateRange'] = this.firstTabTimeArr;
powerData['fnEvent'] = 'getPowerData';
switchPowerData(Object.assign({},{clientId: this.paramsData.clientId}, val)).then(res => {
if (res && res.data) {
powerData.dataVal.lineXData = res.data && res.data['xData'] && res.data['xData'].length > 0 ? res.data['xData'] :
this.firstChartTrans && this.firstChartTrans['timeList'] && this.firstChartTrans['timeList'].length > 0 ? this.firstChartTrans['timeList'] : [];
powerData.dataVal.dataList[0].data = res.data && res.data['yData'] && res.data['yData']['switchAvgPower'] && res.data['yData']['switchAvgPower'].length > 0 ? res.data['yData']['switchAvgPower'] : [];
powerData.dataVal.dataList[1].data = res.data && res.data['yData'] && res.data['yData']['switchcurrentPower'] && res.data['yData']['switchcurrentPower'].length > 0 ? res.data['yData']['switchcurrentPower'] : [];
}
// this.firstChartList[2] = powerData;
this.$set(this.firstChartList, 2, powerData);
}).catch(() => {
this.firstChartList[2] = powerData;
});
},
// two
// 接口名称
fnInterFaceNameList(val) {
this.activeNames = [];
postInterFaceName({clientId: this.paramsData.clientId,resourceType: 2}).then(res => {
let tabNameList = {};
if (res && res.length > 0) {
res && res.forEach(async(item,index) => {
let oneData = JSON.parse(JSON.stringify(this.linuxSystem['net']));
oneData.title = item && item.interfaceName;
tabNameList[item.interfaceName + '_net'] = oneData;
});
this.secondChartList = {...tabNameList};
this.activeNames = [Object.keys(tabNameList)[0]];
this.fnModuleNameList(); // 第二模块名称
setTimeout(() => {
this.fnMpuNameList(); // 第三模块名称
setTimeout(() => {
this.fnPwrNameList(); // 第四模块名称
setTimeout(() => {
this.fnFanNameList(); // 第五模块名称
},500);
},500);
},500);
this.getNetDetailsData(this.currTimeList, tabNameList[Object.keys(tabNameList)[0]].title, Object.keys(tabNameList)[0]);
} else {
this.fnModuleNameList(); // 第二模块名称
setTimeout(() => {
this.fnMpuNameList(); // 第三模块名称
setTimeout(() => {
this.fnPwrNameList(); // 第四模块名称
setTimeout(() => {
this.fnFanNameList(); // 第五模块名称
},500);
},500);
},500);
}
}).catch((error) => {
this.fnModuleNameList(); // 第二模块名称
setTimeout(() => {
this.fnMpuNameList(); // 第三模块名称
setTimeout(() => {
this.fnPwrNameList(); // 第四模块名称
setTimeout(() => {
this.fnFanNameList(); // 第五模块名称
},500);
},500);
},500);
});
},
// 基本信息
getNetDetailsData(times, titleName, keyName) {
this.$modal.loading();
this.eventDataMap[keyName] = true;
switchNetDetails({clientId: this.paramsData.clientId, ifDescr: titleName}).then(async res => {
this.secondChartList[keyName].formModel = res && res.data || [];
if (await this.getNetDiscards(times ,titleName, keyName)) {
// if (await this.getNetTotal(times, titleName, keyName)) {
if (await this.getNetErrDisc(times, titleName, keyName)) {
this.getNetSpeed(times, titleName, keyName);
}
// }
}
}).catch(async error => {
if (await this.getNetDiscards(times ,titleName, keyName)) {
// if (await this.getNetTotal(times, titleName, keyName)) {
if (await this.getNetErrDisc(times, titleName, keyName)) {
this.getNetSpeed(times, titleName, keyName);
}
// }
}
});
},
// 丢包
getNetDiscards(times,titleName, keyName) {
let mountCollect = JSON.parse(JSON.stringify(this.secondChartList[keyName]));
let netEcharts = JSON.parse(JSON.stringify(this.echartData));
let content = JSON.parse(JSON.stringify(this.linuxSystem['net']));
netEcharts.dateDataTrans['dateRange'] = this.defaultTimes;
netEcharts.fnEvent = 'getNetDiscards';
return switchNetDiscards(Object.assign({}, {ifDescr : titleName,clientId: this.paramsData.clientId}, times)).then(res => {
if (res && res.data) {
netEcharts.title = titleName + content.echartFors[0].title;
netEcharts.dataVal.yAxisName = res && res.data && res.data.unit ? '单位' + res.data.unit : ' ';
netEcharts.dataVal.lineXData = res.data && res.data.xData.length > 0 ? res.data.xData : this.firstChartTrans && this.firstChartTrans['timeList'] || [];
// 入
netEcharts.dataVal.dataList[0] = {
name: content.echartFors[0].oneName,
data: res.data && res.data.yData['netInDiscardsData'] || []
};
// 出
netEcharts.dataVal.dataList[1] = {
name: content.echartFors[0].twoName,
data: res.data && res.data.yData['netOutDiscardsData'] || []
};
mountCollect['echartList'][0] = netEcharts;
this.$set(this.secondChartList, keyName, mountCollect);
return true;
}
}).catch(() => {
return true;
});
},
// 总数
getNetTotal(times,titleName, keyName) {
let mountCollect = JSON.parse(JSON.stringify(this.secondChartList[keyName]));
let netEcharts = JSON.parse(JSON.stringify(this.echartData));
let content = JSON.parse(JSON.stringify(this.linuxSystem['net']));
netEcharts.dateDataTrans['dateRange'] = this.defaultTimes;
netEcharts.fnEvent = 'getNetTotal';
return switchNeTotal(Object.assign({}, {ifDescr : titleName, clientId: this.paramsData.clientId}, times)).then(res => {
if (res && res.data) {
netEcharts.title = titleName + content.echartFors[1].title;
netEcharts.dataVal.yAxisName = res && res.data && res.data.unit ? '单位' + res.data.unit : ' ';
netEcharts.dataVal.lineXData = res.data && res.data.xData.length > 0 ? res.data.xData : this.firstChartTrans && this.firstChartTrans['timeList'] || [];
// 入
netEcharts.dataVal.dataList[0] = {
name: content.echartFors[1].oneName,
data: res.data && res.data.yData['netInTotalData'] || []
};
// 出
netEcharts.dataVal.dataList[1] = {
name: content.echartFors[1].twoName,
data: res.data && res.data.yData['netOutTotalData'] || []
};
mountCollect['echartList'][1] = netEcharts;
this.$set(this.secondChartList, keyName, mountCollect);
return true;
}
}).catch(() => {
return true;
});
},
// 错误丢包
getNetErrDisc(times, titleName, keyName) {
let mountCollect = JSON.parse(JSON.stringify(this.secondChartList[keyName]));
let netEcharts = JSON.parse(JSON.stringify(this.echartData));
let content = JSON.parse(JSON.stringify(this.linuxSystem['net']));
netEcharts.dateDataTrans['dateRange'] = this.defaultTimes;
netEcharts.fnEvent = 'getNetErrDisc';
return switchNetErrDiscard(Object.assign({}, {ifDescr : titleName, clientId: this.paramsData.clientId}, times)).then(res => {
if (res && res.data) {
netEcharts.title = titleName + content.echartFors[1].title;
netEcharts.dataVal.yAxisName = res && res.data && res.data.unit ? '单位' + res.data.unit : ' ';
netEcharts.dataVal.lineXData = res.data && res.data.xData.length > 0 ? res.data.xData : this.firstChartTrans && this.firstChartTrans['timeList'] || [];
netEcharts.dataVal.dataList[0] = {
name: content.echartFors[1].oneName,
data: res.data && res.data.yData['netInErrDiscardsData'] || []
};
netEcharts.dataVal.dataList[1] = {
name: content.echartFors[1].twoName,
data: res.data && res.data.yData['netOutErrDiscardsData'] || []
};
mountCollect['echartList'][1] = netEcharts;
this.$set(this.secondChartList, keyName, mountCollect);
return true;
}
}).catch(() => {
return true;
});
},
// 实时流量
getNetSpeed(times, titleName, keyName, unitData) {
let mountCollect = JSON.parse(JSON.stringify(this.secondChartList[keyName]));
let netEcharts = JSON.parse(JSON.stringify(this.echartData));
let content = JSON.parse(JSON.stringify(this.linuxSystem['net']));
netEcharts.dateDataTrans['dateRange'] = this.defaultTimes;
netEcharts.fnEvent = 'getNetSpeed';
return switchNetSpeed(Object.assign(unitData || {}, {ifDescr : titleName, clientId: this.paramsData.clientId}, times)).then(res => {
if (res && res.data) {
netEcharts.title = titleName + content.echartFors[2].title;
netEcharts.dataVal.yAxisName = res && res.data && res.data.unit ? '单位' + res.data.unit : ' ';
netEcharts.dataVal.lineXData = res.data && res.data.xData.length > 0 ? res.data.xData : this.firstChartTrans && this.firstChartTrans['timeList'] || [];
netEcharts.dataVal.dataList[0] = {
name: content.echartFors[2].oneName,
data: res.data && res.data.yData['netInSpeedData'] || []
};
netEcharts.dataVal.dataList[1] = {
name: content.echartFors[2].twoName,
data: res.data && res.data.yData['netOutSpeedData'] || []
};
if (content.echartFors[2].unitSel) {
netEcharts.dataVal['unitModel'] = res && res.data && res.data.unit || '';
netEcharts.dataVal['unitSelList'] = content.echartFors[2].unitSel;
}
mountCollect['echartList'][2] = netEcharts;
this.$set(this.secondChartList, keyName, mountCollect);
// return true;
this.$modal.closeLoading();
}
}).catch(() => {
// return true;
this.$modal.closeLoading();
});
},
// 光模块的所有名称 moduleAllName, moduleMsg, moduleLowThreshold, modulePower
fnModuleNameList(val) {
moduleAllName({clientId: this.paramsData.clientId}).then(res => {
let tabNameList = {};
if (res && res.data && res.data.length > 0) {
res && res.data.forEach(async(item,index) => {
let oneData = JSON.parse(JSON.stringify(this.linuxSystem['light']));
oneData.title = item && item.fiberPortName;
tabNameList[item.fiberPortName + '_module'] = oneData;
this.$set(this.secondChartList, item.fiberPortName + '_module', oneData);
});
if (this.activeNames && this.activeNames.length <= 0) {
this.activeNames = [Object.keys(tabNameList)[0]];
this.getModuleDetailsData(this.currTimeList, tabNameList[Object.keys(tabNameList)[0]].title, Object.keys(tabNameList)[0]);
}
}
});
},
// 基本信息
getModuleDetailsData(times, titleName, keyName) {
this.$modal.loading();
this.eventDataMap[keyName] = true;
moduleMsg({clientId: this.paramsData.clientId, moudleName: titleName}).then(async res => {
this.secondChartList[titleName].formModel = res && res.data || [];
if (await this.getModuleLowThreshold(times ,titleName, keyName)) {
this.getModulePower(times, titleName, keyName);
}
}).catch(async error => {
if (await this.getModuleLowThreshold(times ,titleName, keyName)) {
this.getModulePower(times, titleName, keyName);
}
});
},
// 光衰阈值
getModuleLowThreshold(times,titleName, keyName) {
let mountCollect = JSON.parse(JSON.stringify(this.secondChartList[keyName]));
let netEcharts = JSON.parse(JSON.stringify(this.echartData));
let content = JSON.parse(JSON.stringify(this.linuxSystem['light']));
netEcharts.dateDataTrans['dateRange'] = this.defaultTimes;
netEcharts.fnEvent = 'getModuleLowThreshold';
return moduleLowThreshold(Object.assign({}, {moudleName : titleName,clientId: this.paramsData.clientId}, times)).then(res => {
if (res && res.data) {
netEcharts.title = titleName + content.echartFors[0].title;
netEcharts.dataVal.yAxisName = res && res.data && res.data.unit ? '单位' + res.data.unit : ' ';
netEcharts.dataVal.lineXData = res.data && res.data.xData.length > 0 ? res.data.xData : this.firstChartTrans && this.firstChartTrans['timeList'] || [];
// 入
netEcharts.dataVal.dataList[0] = {
name: content.echartFors[0].oneName,
data: res.data && res.data.yData['TxLowThreshold'] || []
};
// 出
netEcharts.dataVal.dataList[1] = {
name: content.echartFors[0].twoName,
data: res.data && res.data.yData['RxLowThreshold'] || []
};
mountCollect['echartList'][0] = netEcharts;
this.$set(this.secondChartList, keyName, mountCollect);
return true;
}
}).catch(() => {
return true;
});
},
// 功率
getModulePower(times,titleName, keyName) {
let mountCollect = JSON.parse(JSON.stringify(this.secondChartList[keyName]));
let netEcharts = JSON.parse(JSON.stringify(this.echartData));
let content = JSON.parse(JSON.stringify(this.linuxSystem['light']));
netEcharts.dateDataTrans['dateRange'] = this.defaultTimes;
netEcharts.fnEvent = 'getModulePower';
return modulePower(Object.assign({}, {moudleName : titleName, clientId: this.paramsData.clientId}, times)).then(res => {
if (res && res.data) {
netEcharts.title = titleName + content.echartFors[1].title;
netEcharts.dataVal.yAxisName = res && res.data && res.data.unit ? '单位' + res.data.unit : ' ';
netEcharts.dataVal.lineXData = res.data && res.data.xData.length > 0 ? res.data.xData : this.firstChartTrans && this.firstChartTrans['timeList'] || [];
// 入
netEcharts.dataVal.dataList[0] = {
name: content.echartFors[1].oneName,
data: res.data && res.data.yData['RxPower'] || []
};
// 出
netEcharts.dataVal.dataList[1] = {
name: content.echartFors[1].twoName,
data: res.data && res.data.yData['TxPower'] || []
};
mountCollect['echartList'][1] = netEcharts;
this.$set(this.secondChartList, keyName, mountCollect);
this.$modal.closeLoading();
return true;
}
}).catch(() => {
this.$modal.closeLoading();
return true;
});
},
// mpu的所有名称 mpuAllName, mpuMsg, mpuCpuUse, mpuMemUse, mpuTemperature
fnMpuNameList(val) {
mpuAllName({clientId: this.paramsData.clientId}).then(res => {
let tabNameList = {};
if (res && res.data && res.data.length > 0) {
res && res.data.forEach(async(item,index) => {
let oneData = JSON.parse(JSON.stringify(this.linuxSystem['mpu']));
oneData.title = item && item.mpuName;
tabNameList[item.mpuName + '_mpu'] = oneData;
this.$set(this.secondChartList, item.mpuName + '_mpu', oneData);
});
if (this.activeNames && this.activeNames.length <= 0) {
this.activeNames = [Object.keys(tabNameList)[0]];
this.getMpuDetailsData(this.currTimeList, tabNameList[Object.keys(tabNameList)[0]].title, Object.keys(tabNameList)[0]);
}
}
});
},
// 基本信息
getMpuDetailsData(times, titleName, keyName) {
this.$modal.loading();
this.eventDataMap[keyName] = true;
mpuMsg({clientId: this.paramsData.clientId, mpuName: titleName}).then(async res => {
this.secondChartList[titleName].formModel = res && res.data || [];
if (await this.getMpuCpuUse(times ,titleName, keyName)) {
if (await this.getMpuMemUse(times, titleName, keyName)) {
this.getMpuTemperature(times, titleName, keyName);
}
}
}).catch(async error => {
if (await this.getMpuCpuUse(times ,titleName, keyName)) {
if (await this.getMpuMemUse(times, titleName, keyName)) {
this.getMpuTemperature(times, titleName, keyName);
}
}
});
},
//
getMpuCpuUse(times,titleName, keyName) {
let mountCollect = JSON.parse(JSON.stringify(this.secondChartList[keyName]));
let netEcharts = JSON.parse(JSON.stringify(this.echartData));
let content = JSON.parse(JSON.stringify(this.linuxSystem['mpu']));
netEcharts.dateDataTrans['dateRange'] = this.defaultTimes;
netEcharts.fnEvent = 'getMpuCpuUse';
return mpuCpuUse(Object.assign({}, {mpuName : titleName,clientId: this.paramsData.clientId}, times)).then(res => {
if (res && res.data) {
netEcharts.title = titleName + content.echartFors[0].title;
netEcharts.dataVal.yAxisName = res && res.data && res.data.unit ? '单位' + res.data.unit : ' ';
netEcharts.dataVal.lineXData = res.data && res.data.xData.length > 0 ? res.data.xData : this.firstChartTrans && this.firstChartTrans['timeList'] || [];
// 入
netEcharts.dataVal.dataList[0] = {
name: content.echartFors[0].oneName,
data: res.data && res.data.yData['cpuUsage'] || []
};
mountCollect['echartList'][0] = netEcharts;
this.$set(this.secondChartList, keyName, mountCollect);
return true;
}
}).catch(() => {
return true;
});
},
//
getMpuMemUse(times,titleName, keyName) {
let mountCollect = JSON.parse(JSON.stringify(this.secondChartList[keyName]));
let netEcharts = JSON.parse(JSON.stringify(this.echartData));
let content = JSON.parse(JSON.stringify(this.linuxSystem['mpu']));
netEcharts.dateDataTrans['dateRange'] = this.defaultTimes;
netEcharts.fnEvent = 'getMpuMemUse';
return mpuMemUse(Object.assign({}, {mpuName : titleName, clientId: this.paramsData.clientId}, times)).then(res => {
if (res && res.data) {
netEcharts.title = titleName + content.echartFors[1].title;
netEcharts.dataVal.yAxisName = res && res.data && res.data.unit ? '单位' + res.data.unit : ' ';
netEcharts.dataVal.lineXData = res.data && res.data.xData.length > 0 ? res.data.xData : this.firstChartTrans && this.firstChartTrans['timeList'] || [];
// 入
netEcharts.dataVal.dataList[0] = {
name: content.echartFors[1].oneName,
data: res.data && res.data.yData['memUsage'] || []
};
mountCollect['echartList'][1] = netEcharts;
this.$set(this.secondChartList, keyName, mountCollect);
return true;
}
}).catch(() => {
return true;
});
},
//
getMpuTemperature(times,titleName, keyName) {
let mountCollect = JSON.parse(JSON.stringify(this.secondChartList[keyName]));
let netEcharts = JSON.parse(JSON.stringify(this.echartData));
let content = JSON.parse(JSON.stringify(this.linuxSystem['mpu']));
netEcharts.dateDataTrans['dateRange'] = this.defaultTimes;
netEcharts.fnEvent = 'getMpuTemperature';
return mpuTemperature(Object.assign({}, {mpuName : titleName, clientId: this.paramsData.clientId}, times)).then(res => {
if (res && res.data) {
netEcharts.title = titleName + content.echartFors[2].title;
netEcharts.dataVal.yAxisName = res && res.data && res.data.unit ? '单位' + res.data.unit : ' ';
netEcharts.dataVal.lineXData = res.data && res.data.xData.length > 0 ? res.data.xData : this.firstChartTrans && this.firstChartTrans['timeList'] || [];
// 入
netEcharts.dataVal.dataList[0] = {
name: content.echartFors[2].oneName,
data: res.data && res.data.yData['temperature'] || []
};
mountCollect['echartList'][2] = netEcharts;
this.$set(this.secondChartList, keyName, mountCollect);
this.$modal.closeLoading();
return true;
}
}).catch(() => {
this.$modal.closeLoading();
return true;
});
},
// 电源的所有名称 pwrAllName, pwrMsg, pwrCurrent, pwrVoltage
fnPwrNameList(val) {
pwrAllName({clientId: this.paramsData.clientId}).then(res => {
let tabNameList = {};
if (res && res.data && res.data.length > 0) {
res && res.data.forEach(async(item,index) => {
let oneData = JSON.parse(JSON.stringify(this.linuxSystem['pw']));
oneData.title = item && item.pwrName;
tabNameList[item.pwrName + '_pw'] = oneData;
this.$set(this.secondChartList, item.pwrName + '_pw', oneData);
});
if (this.activeNames && this.activeNames.length <= 0) {
this.activeNames = [Object.keys(tabNameList)[0]];
this.getPwrDetailsData(this.currTimeList, tabNameList[Object.keys(tabNameList)[0]].title, Object.keys(tabNameList)[0]);
}
}
});
},
// 基本信息
getPwrDetailsData(times, titleName, keyName) {
this.$modal.loading();
this.eventDataMap[keyName] = true;
pwrMsg({clientId: this.paramsData.clientId, pwrName: titleName}).then(async res => {
this.secondChartList[titleName].formModel = res && res.data || [];
if (await this.getPwrCurrent(times ,titleName, keyName)) {
this.getPwrVoltage(times, titleName, keyName);
}
}).catch(async error => {
if (await this.getPwrCurrent(times ,titleName, keyName)) {
this.getPwrVoltage(times, titleName, keyName);
}
});
},
//
getPwrCurrent(times,titleName, keyName) {
let mountCollect = JSON.parse(JSON.stringify(this.secondChartList[keyName]));
let netEcharts = JSON.parse(JSON.stringify(this.echartData));
let content = JSON.parse(JSON.stringify(this.linuxSystem['pw']));
netEcharts.dateDataTrans['dateRange'] = this.defaultTimes;
netEcharts.fnEvent = 'getPwrCurrent';
return pwrCurrent(Object.assign({}, {pwrName : titleName,clientId: this.paramsData.clientId}, times)).then(res => {
if (res && res.data) {
netEcharts.title = titleName + content.echartFors[0].title;
netEcharts.dataVal.yAxisName = res && res.data && res.data.unit ? '单位' + res.data.unit : ' ';
netEcharts.dataVal.lineXData = res.data && res.data.xData.length > 0 ? res.data.xData : this.firstChartTrans && this.firstChartTrans['timeList'] || [];
// 入
netEcharts.dataVal.dataList[0] = {
name: content.echartFors[0].oneName,
data: res.data && res.data.yData['pwrCurrent'] || []
};
mountCollect['echartList'][0] = netEcharts;
this.$set(this.secondChartList, keyName, mountCollect);
return true;
}
}).catch(() => {
return true;
});
},
//
getPwrVoltage(times,titleName, keyName) {
let mountCollect = JSON.parse(JSON.stringify(this.secondChartList[keyName]));
let netEcharts = JSON.parse(JSON.stringify(this.echartData));
let content = JSON.parse(JSON.stringify(this.linuxSystem['pw']));
netEcharts.dateDataTrans['dateRange'] = this.defaultTimes;
netEcharts.fnEvent = 'getPwrVoltage';
return pwrVoltage(Object.assign({}, {pwrName : titleName, clientId: this.paramsData.clientId}, times)).then(res => {
if (res && res.data) {
netEcharts.title = titleName + content.echartFors[1].title;
netEcharts.dataVal.yAxisName = res && res.data && res.data.unit ? '单位' + res.data.unit : ' ';
netEcharts.dataVal.lineXData = res.data && res.data.xData.length > 0 ? res.data.xData : this.firstChartTrans && this.firstChartTrans['timeList'] || [];
// 入
netEcharts.dataVal.dataList[0] = {
name: content.echartFors[1].oneName,
data: res.data && res.data.yData['pwrVoltage'] || []
};
mountCollect['echartList'][1] = netEcharts;
this.$set(this.secondChartList, keyName, mountCollect);
this.$modal.closeLoading();
return true;
}
}).catch(() => {
this.$modal.closeLoading();
return true;
});
},
// 风扇的所有名称 fanAllName, fanMsg
fnFanNameList(val) {
fanAllName({clientId: this.paramsData.clientId}).then(res => {
let tabNameList = {};
if (res && res.data && res.data.length > 0) {
res && res.data.forEach(async(item,index) => {
let oneData = JSON.parse(JSON.stringify(this.linuxSystem['fan']));
oneData.title = item && item.fanName;
tabNameList[item.fanName + '_fan'] = oneData;
this.$set(this.secondChartList, item.fanName + '_fan', oneData);
});
if (this.activeNames && this.activeNames.length <= 0) {
this.activeNames = [Object.keys(tabNameList)[0]];
this.getFanDetailsData(this.currTimeList, tabNameList[Object.keys(tabNameList)[0]].title, Object.keys(tabNameList)[0]);
}
}
});
},
// 基本信息
getFanDetailsData(times, titleName, keyName) {
this.eventDataMap[keyName] = true;
fanMsg({clientId: this.paramsData.clientId, fanName: titleName}).then(res => {
this.secondChartList[titleName].formModel = res && res.data || [];
this.$modal.closeLoading();
}).catch( error => {
this.$modal.closeLoading();
});
},
collapseChangeData(valList) {
valList && valList.forEach(item => {
if (!this.eventDataMap[item]) {
this.$modal.loading();
if (this.secondChartList[item].type === 'net') {
this.getNetDetailsData(this.currTimeList, this.secondChartList[item].title, item);
} else if (this.secondChartList[item].type === 'light') {
this.getModuleDetailsData(this.currTimeList, this.secondChartList[item].title, item);
} else if (this.secondChartList[item].type === 'mpu') {
this.getMpuDetailsData(this.currTimeList, this.secondChartList[item].title, item);
} else if (this.secondChartList[item].type === 'pw') {
this.getPwrDetailsData(this.currTimeList, this.secondChartList[item].title, item);
} else if (this.secondChartList[item].type === 'fan') {
this.getFanDetailsData(this.currTimeList, this.secondChartList[item].title, item);
}
}
});
},
chartFnEvent(valData, fnName, tabName, key, unit) {
this.firstChartTrans = valData;
// 检查函数是否存在,避免报错
if (typeof this[fnName] === 'function') {
this.defaultTimes = valData.timeArr;
this.firstTabTimeArr = valData.timeArr;
let unitData = unit ? {unit: unit} : {};
// 调用实际函数,并传递参数(如选中的值、当前项)
this[fnName]({startTime: valData.timeArr[0], endTime: valData.timeArr[1]}, tabName, key, unitData);
} else {
console.warn(`函数 ${fnName} 未定义`);
}
},
goBack() {
this.$router.push("/resource/switchRegister");
}
}
}
</script>
<style scoped>
</style>
@@ -0,0 +1,127 @@
<template>
<div class="app-container">
<Form :formList="formList" :ruleFormData="ruleForm" :config="{labelWidth: '140px'}" @fnClick="callback"></Form>
</div>
</template>
<script setup>
import Form from '@/components/form/index.vue';
import {listAllSwitchName, addSwitchInterface, getSwitchInterface, updateSwitchInterface, postInterFaceName} from "@/api/disRevenue/resource"
export default {
name: 'PortRemarks',
components: {Form},
dicts: ['rm_topology_type'],
data() {
return {
loading: false,
ruleForm: {},
formList: [],
paramsData: {},
switchNameList: [],
interfaceNameList: [],
}
},
created() {
this.paramsData = this.$route && this.$route.query;
if (this.paramsData && this.paramsData.id) {
this.getFormDataList(this.paramsData.id);
} else {
this.switchList();
}
this.fnFormList();
},
methods: {
// formList集合
fnFormList(objVal) {
this.formList = [{
config: {title: '基本信息',labelWidth: '140px', colSpan: 'disBlock'},
controls: {
id: {label: 'ID',hidden: true},
switchName: {label: '交换机名称', span: 18, type: 'select', eventName: 'change', options:[], required: true},
interfaceName: {label: '交换机接口名称', span: 18, type: 'select', options:[], required: true},
interfaceRemark: {label: '接口备注', span: 18, type: 'textarea', required: true},
}
}];
},
// 获取交换机下拉
switchList() {
listAllSwitchName({}).then(val => {
if(val && val.data) {
this.switchNameList = val && val.data;
this.formList[0].controls.switchName['options'] = val && val.data.map(item => {
return Object.assign({label: item.switchName, value: item.id});
});
}
});
},
// 接口名称
fnInterFaceNameList(val) {
postInterFaceName(val).then(res => {
this.interfaceNameList = res;
this.formList[0].controls.interfaceName['options'] = res && res.map(item => {
return Object.assign({label: item.interfaceName, value: item.id});
});
});
},
// 获取详情
getFormDataList(id) {
getSwitchInterface(id).then(val => {
this.ruleForm = val && val.data;
this.switchList();
}).catch(() => {
this.$modal.msgError("操作失败")
});
},
// 监听事件
callback(result, dataVal, formVal) {
if (result && result.fnCode) {
switch (result.fnCode) {
case 'switchName':
let switchIp = '';
this.switchNameList.find(item => {
if (item.id === dataVal) {
switchIp = item.snmpAddress;
}
});
this.fnInterFaceNameList({switchIp: switchIp});
break;
case 'submit':
this.switchNameList.find(item => {
if (item.id === dataVal['switchName']) {
dataVal['switchName'] = item.switchName;
dataVal['clientId'] = item.clientId;
dataVal['switchSn'] = item.hardwareSn;
}
});
this.interfaceNameList.find(item => {
if (item.id === dataVal['interfaceName'] || item.interfaceName === dataVal['interfaceName']) {
dataVal['interfaceName'] = item.interfaceName;
}
});
let fnType = addSwitchInterface;
if (dataVal && dataVal.id) {
fnType = updateSwitchInterface;
}
if(this.loading) return;
this.loading = true;
fnType(dataVal).then(response => {
this.$modal.msgSuccess(response.msg);
this.$router.push("/resource/switchRegister")
this.loading = false;
}).catch(() => {
this.$modal.msgError("操作失败")
});
break;
case 'cancel':
this.$router.push("/resource/switchRegister");
break;
default:
}
}
}
}
}
</script>
<style>
</style>
@@ -0,0 +1,76 @@
<template>
<div style="padding: 8px 20px 20px;">
<el-collapse v-model="activeShowList" @change="collapseChange">
<el-collapse-item v-for="(val,key, index) of secondChartList" :title="`【${val && val.title || ''}】`" :name="key || ''">
<div class="mt10 w100">
<div class="w100 plr-20" style="font-size: 14px">
<div v-for="(item,key,index) of val && val.formList || []" :key="`${key}-${index}`" class="w50 disInlineBlock p10">
<div class="disInlineBlock" style="width: 130px;color: #C0C4CC;">{{item}}</div>
<div style="width: calc(100% - 130px);vertical-align: top;" class="disInlineBlock">{{val && val.formModel[key] || '-'}}</div>
</div>
</div>
<div v-for="item of val && val.echartList || []" :key="`div-${val && val.title || ''}-${item && item.title || ''}-${index}`" class="w100 mt20 mb20" style="height: 200px;border-top: 1px solid #d8dce5">
<EchartsLine class="w100 h100" :key="`chart-${val && val.title || ''}-${item && item.title || ''}-${index}`" :lineData="item && item.dataVal || {}" :dateDataTrans="item && item.dateDataTrans || {}" :dateShowType="item && item.dateShowType || 'datetimerange'" :title="item && item.title || '图表数据'" :chartData="(valData, unit) => chartDataEvent(valData, item.fnEvent,val.title, key, unit)"></EchartsLine>
</div>
</div>
</el-collapse-item>
</el-collapse>
</div>
</template>
<script setup>
import EchartsLine from "@/components/echartsList/line.vue";
export default {
name: 'SecondAutoFind',
components: {EchartsLine},
props: {
secondChartList: {
type: Object,
default: () => {}
},
activeNames: {
type: Array,
default: () => []
},
},
watch: {
activeNames: {
handler(val) {
this.activeShowList = val;
},
deep: true,
immediate: true
},
},
data() {
return {
activeShowList: []
}
},
created() {},
methods: {
collapseChange(val) {
this.activeShowList = this.activeNames;
this.$emit("collapseChangeData", val);
},
chartDataEvent(valData, funcName, tabName, key, unit) {
this.$emit("chartFnEvent", valData, funcName, tabName, key, unit);
// // 检查函数是否存在,避免报错
// if (typeof this[funcName] === 'function') {
// // 调用实际函数,并传递参数(如选中的值、当前项)
// // this[funcName]({startTime: valData[0], endTime: valData[1]});
// } else {
// console.warn(`函数 ${funcName} 未定义`);
// }
}
}
}
</script>
<style scoped>
::v-deep .el-collapse-item__header {
background-color: #d4e3fc!important;
/*color: #fff!important;*/
padding-left: 20px;
font-size: 1rem;
}
</style>
+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>