frp管理模块下页面、服务器管理下的生成与显示FRP连接地址页面

This commit is contained in:
康冉冉
2025-12-22 18:39:35 +08:00
parent 5fdb34af89
commit ea9864c8c0
5 changed files with 343 additions and 4 deletions
+29 -2
View File
@@ -30,10 +30,37 @@
:class="toBoolean(formVal.disabled || formItem.config.readonly) ? 'cursorAuto' : ''"
@[formVal.eventName]="(val) => handleChange(key,val,formVal)"></el-input>
<br/><span v-if="!toBoolean(formVal.disabled || formItem.config.readonly)" class="warningCol">{{formVal.warningTitle}}</span>
</template>
</template>
</template>
<template v-if="formVal.type === 'textarea'">
<template v-else-if="formVal.type === 'number'">
<el-input-number
v-model="ruleForm[key]"
:style="{ width: formVal && formVal.controlsList ? `calc(100% / ${formVal.controlsList.length + 1} - 25px)` : '100%' }"
:controls="formVal.controls"
:min="formVal.min || undefined"
:max="formVal.max || undefined"
:disabled="toBoolean(formVal.disabled || formItem.config.readonly)"
:placeholder="toBoolean(formVal.disabled || formItem.config.readonly) ? null : formVal.placeholder || `请输入${formVal.label}`"
:class="toBoolean(formVal.disabled || formItem.config.readonly) ? 'cursorAuto' : ''"
@[formVal.eventName]="(val) => handleChange(key,val,formVal)"></el-input-number>
<template v-for="numItem of formVal.controlsList">
<span style="width: 50px;display: inline-block;text-align: center;">{{numItem.connect}}</span>
<el-input-number
v-model="ruleForm[numItem.value]"
:style="{ width: formVal && formVal.controlsList ? `calc(100% / ${formVal.controlsList.length + 1} - 25px)` : '100%' }"
:controls="formVal.controls"
:min="numItem.min || undefined"
:max="numItem.max || undefined"
:disabled="toBoolean(formVal.disabled || formItem.config.readonly)"
:placeholder="toBoolean(formVal.disabled || formItem.config.readonly) ? null : formVal.placeholder || `请输入${formVal.label}`"
:class="toBoolean(formVal.disabled || formItem.config.readonly) ? 'cursorAuto' : ''"
@[formVal.eventName]="(val) => handleChange(key,val,formVal)"></el-input-number>
</template>
<br/><span v-if="!toBoolean(formVal.disabled || formItem.config.readonly)" class="warningCol">{{formVal.warningTitle}}</span>
</template>
<template v-else-if="formVal.type === 'textarea'">
<div v-if="toBoolean(formVal.disabled || formItem.config.readonly)">
<div style="color: #606266;font-weight: 700;padding-left: 15px;" :style="formVal.style" v-html="ruleForm[key]"></div>
</div>
+15
View File
@@ -431,6 +431,21 @@ export const dynamicRoutes = [
}
]
},
// frp服务器管理
{
path: '/resource/frpServerManage/view',
component: Layout,
hidden: true,
permissions: ['rresource:frpServerManage:edit', 'resource:frpServerManage:details'],
children: [
{
path: ':id?',
component: () => import('@/views/resource/frpServerManage/details'),
name: 'FrpServerManageDetails',
meta: { title: '修改FRP服务端配置', activeMenu: '/resource/frpServerManage' }
}
]
},
// 监控看板
{
path: '/resource/monitorBoard/view',
@@ -0,0 +1,99 @@
<template>
<div class="app-container">
<Form :formList="formList" :ruleFormData="ruleForm" :config="paramsData && paramsData.readonly ? config : {}" @fnClick="callback"></Form>
</div>
</template>
<script setup name="Handle">
import Form from '@/components/form/index.vue';
import {getAlarmLog} from "@/api/disRevenue/resource"
export default {
name: 'frpServerDetails',
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) {
if (this.paramsData && this.paramsData.readonly) {
this.formList = [{
config: {title: '基本信息', readonly: true},
controls: {
id: {label: 'ID',hidden: true},
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'},
connectedDeviceType: { label: `链接生成时间`,span: 12, type: 'input'},
frpcRemotePort: { label: `FRPC_remotePort`,span: 12, type: 'input'},
frpcServerPort: { label: `FRPC_serverPort`,span: 12, type: 'input'},
frpcServerAddr: { label: `FRPC_serverAddr`, span: 12, type: 'input'},
frpcTcp: { label: `FRPC_tcp`,span: 12, type: 'input'},
frpcName: { label: `FRPC_name`,span: 12, type: 'input'},
frpcLocalIp: { label: `FRPC_localIP`,span: 12, type: 'input'},
frpcLocalPort: { label: `FRPC_localPort`,span: 12, type: 'input'},
frpAddtType: { label: `FRP连接地址生成状态`,span: 12, type: 'input'},
createTime: {label: '创建时间', span: 12, type: 'datetime'},
}
}];
} else {
this.formList = [{
config: {title: '基本信息', colSpan: 'disBlock'},
controls: {
id: {label: 'ID',hidden: true},
serverNumMin: {label: '服务器端口范围', span: 12, type: 'number',controls: false, min: '1', max:'65535', placeholder:'请输入数字', controlsList: [{value: 'serverNumMax', connect: '', min: '1', max: '65535'}]},
serverAddr: {label: '服务器地址', span: 12, type: 'input'},
serverPort: {label: '服务器端口', span: 12, type: 'input'},
}
}];
}
},
// 获取详情
getFormDataList(id) {
getAlarmLog(id).then(val => {
if (val && val.data) {
this.ruleForm = val.data;
}
}).catch(() => {
this.$modal.msgError("操作失败")
});
},
// 监听事件
callback(result, dataVal, formVal) {
if (result && result.fnCode) {
switch (result.fnCode) {
case 'submit':
addFrpData(dataVal).then(res => {
this.$modal.msgSuccess(res.msg);
this.$router.push("/resource/frpServerManage");
});
break;
case 'cancel':
this.$router.push("/resource/frpServerManage");
break;
default:
}
}
}
}
}
</script>
<style>
</style>
@@ -0,0 +1,173 @@
<template>
<div class="app-container pageTopForm">
<el-form :model="queryParams" ref="queryRef" size="small" v-show="showSearch" label-width="auto">
<el-col :span="4">
<el-form-item label="ClientID" prop="clientId">
<el-input-number
v-model="queryParams.clientId"
placeholder="请输入ClientID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="~" prop="~">
<el-input-number
v-model="queryParams.clientId"
placeholder="请输入ClientID"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="FRPC服务状态" title="FRPC服务状态" prop="bandwidthType">
<el-select
v-model="queryParams.bandwidthType"
placeholder="请选择FRPC服务状态"
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: 'frpServerManage',
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'},
clientId: { label: `clientID`, minWidth: '250', visible: true },
mgmtPublicIp:{ label: `管理网-公网IP`,minWidth: '120'},
mgmtInterfaceName: { label: `管理网-接口名称`, minWidth: '120'},
mgmtMacAddress: { label: `管理网-mac地址`, minWidth: '150'},
mgmtInterfaceType: { label: `管理网-接口类型`, minWidth: '120'},
mgmtIpv4Address: { label: `管理网-IPv4地址`, minWidth: '120'},
mgmtGateway: { label: `管理网-网关`, minWidth: '120'},
frpcRemotePort: { label: `FRPC_remotePort`,minWidth: '140', visible: true},
connectedDeviceType: { label: `链接生成时间`,minWidth: '130'},
frpcServerAddr: { label: `FRPC_serverAddr`, minWidth: '140', visible: true},
frpcServerPort: { label: `FRPC_serverPort`,minWidth: '140', visible: true},
connected: { label: `FRPC服务状态`,minWidth: '120', visible: true},
frpcName: { label: `FRPC_name`,minWidth: '100'},
frpcTcp: { label: `FRPC_tcp`,minWidth: '90'},
frpcLocalIp: { label: `FRPC_localIP`,minWidth: '110'},
frpcLocalPort: { label: `FRPC_localPort`,minWidth: '120'},
frpAddtType: { label: `FRP连接地址生成状态`,minWidth: '150',visible: true},
},
config: {
tableButton: {
top: [
{content: '修改FRP服务端配置', fnCode: 'edit', type: 'primary', icon: 'el-icon-edit', hasPermi: 'resource:frpServerManage:edit'},
],
line: [
{content: '详情', fnCode: 'details', type: 'text', icon: 'el-icon-view', hasPermi: 'resource:frpServerManage:details'}
]
}
}
}
},
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 'edit':
this.$router.push({
path:'/resource/frpServerManage/view'
});
break;
case 'details':
this.$router.push({
path:'/resource/frpServerManage/view',
query:{
id: rowData.id,
readonly: true
}
});
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>
+27 -2
View File
@@ -184,6 +184,19 @@
<el-button @click="callback({fnCode: 'cancel'})">取消</el-button>
</div>
</el-dialog>
<!-- 显示frp地址 -->
<el-dialog title="FRP连接地址" :visible.sync="frpOpen" width="800px" append-to-body style="padding-bottom: 20px;">
<div v-if="Object.keys(frpDialogContent).length <= 0" class="textAlignCenter" style="font-size: 1rem;">
地址正在生成中......
</div>
<div v-else class="textAlignCenter" style="font-size: 1rem;">
地址FRPC_serverAddr端口FRPC_remotePort
<el-link :underline="false" icon="el-icon-document-copy" title="复制" v-clipboard:copy="frpDialogContent.collect" v-clipboard:success="clipboardSuccess" style="margin-left: 10px;color: #409EFF;"></el-link>
</div>
<div style="text-align: right;margin-right: 20px;margin-bottom: 20px;">
<el-button @click="callback({fnCode: 'cancel'})">取消</el-button>
</div>
</el-dialog>
</div>
</template>
@@ -287,7 +300,7 @@
{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: 'rocketmq:traffic'},
{content: '详情', fnCode: 'details', type: 'text', icon: 'el-icon-view', hasPermi: 'resource:serverRegister:details'},
{title: '更多', hasPermi: ['system:businessDeploy', 'rocketmq:policy', 'rocketmq:monitorPolicy', 'rocketmq:remote', 'resource:serverRegister:tagRemarkEdit', 'resource:serverRegister:mtrChartVew', 'resource:serverRegister:cancelFlash'], more: [
{title: '更多', hasPermi: ['system:businessDeploy', 'rocketmq:policy', 'rocketmq:monitorPolicy', 'rocketmq:remote', 'resource:serverRegister:tagRemarkEdit', 'resource:serverRegister:mtrChartVew', 'resource:serverRegister:cancelFlash', 'resource:serverRegister:createFrpAddr', 'resource:serverRegister:showFrpAddr'], more: [
{content: '下发业务', fnCode: 'issueBusiness', type: 'text', icon: 'el-icon-circle-check', hasPermi: 'system:businessDeploy'},
{content: '下发脚本策略', fnCode: 'issueScript', type: 'text', icon: 'el-icon-circle-check', hasPermi: 'rocketmq:policy'},
{content: '下发监控策略', fnCode: 'issueMonitor', type: 'text', icon: 'el-icon-circle-check', hasPermi: 'rocketmq:monitorPolicy'},
@@ -295,6 +308,8 @@
{content: '修改标签', fnCode: 'tagRemark', type: 'text', icon: 'el-icon-edit', hasPermi: 'resource:serverRegister:tagRemarkEdit'},
{content: 'MTR探测丢包率趋势图', fnCode: 'mtrChartVew', type: 'text', icon: 'el-icon-data-analysis', hasPermi: 'resource:serverRegister:mtrChartVew'},
{content: '取消闪烁', fnCode: 'cancelFlash', type: 'text', showName: 'alarmFlag', showVal: 'true', icon: 'el-icon-magic-stick', hasPermi: 'resource:serverRegister:cancelFlash'},
{content: '生成FRP连接地址', fnCode: 'createFrpAddr', type: 'text', icon: 'el-icon-link', hasPermi: 'resource:serverRegister:createFrpAddr'},
{content: '显示FRP连接地址', fnCode: 'showFrpAddr', type: 'text', icon: 'el-icon-link', hasPermi: 'resource:serverRegister:showFrpAddr'},
]
}
// {content: '注册', fnCode: 'enroll', showName: 'registrationStatus', showVal: '0', type: 'text', icon: 'el-icon-circle-check', hasPermi: 'resource:register:enroll'},
@@ -347,6 +362,8 @@
mtrChartOpen: false,
virNetInterList: {},
alarmFlagHight: false,
frpOpen: false,
frpDialogContent: {},
}
},
created() {
@@ -710,13 +727,21 @@
this.issueOpen = false;
this.pubilcNetOpen = false;
this.tagOpen = false;
this.frpOpen = false;
break;
case 'cancelFlash':
removeAlarmFlag({id: rowData.id}).then(res => {
console.log('res===',res);
this.getHightLight();
});
break;
case 'createFrpAddr':
this.frpOpen = true;
this.frpDialogContent = {};
break;
case 'showFrpAddr':
this.frpOpen = true;
this.frpDialogContent = {frpcServerAddr: '1234', port: '8080', collect: '123:8080'};
break;
case 'export':
// let dataList = [];
// Object.keys(this.columns).forEach(item => {