feat: 解决冲突
commit
6a477c778b
|
@ -1,5 +1,22 @@
|
||||||
import { cdcmRequestClient } from './request';
|
import { cdcmRequestClient } from './request';
|
||||||
|
|
||||||
|
export async function cdcmCDCMAPI(params, key) {
|
||||||
|
return cdcmRequestClient.post('/cdcm', params, {
|
||||||
|
responseReturn: 'data',
|
||||||
|
headers: {
|
||||||
|
action: key.code,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function cdcmRuleAPI(params, key) {
|
||||||
|
return cdcmRequestClient.post('/rule', params, {
|
||||||
|
responseReturn: 'data',
|
||||||
|
headers: {
|
||||||
|
action: key.code,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
export async function cdcmTemplateAPI(params, key) {
|
export async function cdcmTemplateAPI(params, key) {
|
||||||
return cdcmRequestClient.post('/template', params, {
|
return cdcmRequestClient.post('/template', params, {
|
||||||
headers: {
|
headers: {
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { cdcmRequestClient } from './request';
|
||||||
|
|
||||||
|
export interface action {
|
||||||
|
code: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function cdcmCDCMAPI(params: any, key: action) {
|
||||||
|
return cdcmRequestClient.post('/cdcm', params, {
|
||||||
|
responseReturn: 'data',
|
||||||
|
headers: {
|
||||||
|
action: key.code,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function cdcmRuleAPI(params: any, key: action) {
|
||||||
|
return cdcmRequestClient.post('/rule', params, {
|
||||||
|
responseReturn: 'data',
|
||||||
|
headers: {
|
||||||
|
action: key.code,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function cdcmTemplateAPI(params: any, key: action) {
|
||||||
|
return cdcmRequestClient.post('/template', params, {
|
||||||
|
headers: {
|
||||||
|
action: key.code,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function cdcmDriverAPI(params: any, key: action) {
|
||||||
|
return cdcmRequestClient.post('/driver', params, {
|
||||||
|
headers: {
|
||||||
|
action: key.code,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
|
@ -1,5 +1,57 @@
|
||||||
// 请求码
|
// 请求码
|
||||||
export default {
|
export default {
|
||||||
|
CDCMGetNetworkInfo: {
|
||||||
|
code: 51_002,
|
||||||
|
desc: '获取网络信息',
|
||||||
|
},
|
||||||
|
CDCMGetSystemInfo: {
|
||||||
|
code: 51_001,
|
||||||
|
desc: '获取系统信息',
|
||||||
|
},
|
||||||
|
CDCMSetNetworkInfo: {
|
||||||
|
code: 51_003,
|
||||||
|
desc: '设置网络信息',
|
||||||
|
},
|
||||||
|
CruleAddFlow: {
|
||||||
|
code: 52_608,
|
||||||
|
desc: '添加规则引擎流程',
|
||||||
|
},
|
||||||
|
CruleDeleteFlow: {
|
||||||
|
code: 52_609,
|
||||||
|
desc: '删除规则引擎流程',
|
||||||
|
},
|
||||||
|
CruleGetFlows: {
|
||||||
|
code: 52_610,
|
||||||
|
desc: '获取规则引擎流程',
|
||||||
|
},
|
||||||
|
CruleGetVersion: {
|
||||||
|
code: 52_605,
|
||||||
|
desc: '获取规则引擎版本',
|
||||||
|
},
|
||||||
|
CruleInstall: {
|
||||||
|
code: 52_603,
|
||||||
|
desc: '安装规则引擎',
|
||||||
|
},
|
||||||
|
CruleStart: {
|
||||||
|
code: 52_601,
|
||||||
|
desc: '启动规则引擎',
|
||||||
|
},
|
||||||
|
CruleStartFlow: {
|
||||||
|
code: 52_606,
|
||||||
|
desc: '启动规则引擎流程',
|
||||||
|
},
|
||||||
|
CruleStop: {
|
||||||
|
code: 52_602,
|
||||||
|
desc: '停止规则引擎',
|
||||||
|
},
|
||||||
|
CruleStopFlow: {
|
||||||
|
code: 52_607,
|
||||||
|
desc: '停止规则引擎流程',
|
||||||
|
},
|
||||||
|
CruleUninstall: {
|
||||||
|
code: 52_604,
|
||||||
|
desc: '卸载规则引擎',
|
||||||
|
},
|
||||||
DeviceCreate: {
|
DeviceCreate: {
|
||||||
code: 52_302,
|
code: 52_302,
|
||||||
desc: '创建设备',
|
desc: '创建设备',
|
||||||
|
@ -84,6 +136,14 @@ export default {
|
||||||
code: 52_024,
|
code: 52_024,
|
||||||
desc: '删除模板点位',
|
desc: '删除模板点位',
|
||||||
},
|
},
|
||||||
|
PointExport: {
|
||||||
|
code: 52_025,
|
||||||
|
desc: '导出模板点位',
|
||||||
|
},
|
||||||
|
PointImport: {
|
||||||
|
code: 52_026,
|
||||||
|
desc: '导入模板点位',
|
||||||
|
},
|
||||||
PointQueryAll: {
|
PointQueryAll: {
|
||||||
code: 52_021,
|
code: 52_021,
|
||||||
desc: '查询所有模板点位',
|
desc: '查询所有模板点位',
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
import type { RequestClientOptions } from '@vben/request';
|
||||||
|
|
||||||
|
import { useAppConfig } from '@vben/hooks';
|
||||||
|
import { defaultResponseInterceptor, RequestClient } from '@vben/request';
|
||||||
|
|
||||||
|
import { useTokenStore } from '#/store';
|
||||||
|
|
||||||
|
const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD);
|
||||||
|
function createCDCMRequestClient(
|
||||||
|
baseURL: string,
|
||||||
|
options?: RequestClientOptions,
|
||||||
|
) {
|
||||||
|
const client = new RequestClient({
|
||||||
|
...options,
|
||||||
|
baseURL,
|
||||||
|
});
|
||||||
|
|
||||||
|
client.addResponseInterceptor(
|
||||||
|
defaultResponseInterceptor({
|
||||||
|
codeField: 'code',
|
||||||
|
dataField: 'data',
|
||||||
|
successCode: 0,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// 响应拦截器:自动更新 token
|
||||||
|
client.addResponseInterceptor({
|
||||||
|
fulfilled: (response) => {
|
||||||
|
const token = response.headers?.token;
|
||||||
|
if (token) {
|
||||||
|
// 如果响应头中有新 token,自动更新 store
|
||||||
|
useTokenStore().setToken(token);
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
},
|
||||||
|
rejected: (error) => {
|
||||||
|
// 统一错误处理(如 token 过期)
|
||||||
|
if (error.response?.status === 401) {
|
||||||
|
useTokenStore().deleteToken();
|
||||||
|
// 这里要跳登录页面
|
||||||
|
}
|
||||||
|
return Promise.reject(error);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// 请求拦截器:自动添加 token
|
||||||
|
client.addRequestInterceptor({
|
||||||
|
fulfilled: (config) => {
|
||||||
|
const token = useTokenStore().token;
|
||||||
|
if (token) {
|
||||||
|
// 添加 CDCM 自定义头部
|
||||||
|
config.headers.set('cdcm', token, true);
|
||||||
|
}
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
rejected: (error) => {
|
||||||
|
// 请求错误处理
|
||||||
|
return Promise.reject(error);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const cdcmRequestClient = createCDCMRequestClient(apiURL, {
|
||||||
|
responseReturn: 'data',
|
||||||
|
});
|
|
@ -1,6 +1,32 @@
|
||||||
export default {
|
import type { VxeGridProps } from '#/adapter/vxe-table';
|
||||||
|
|
||||||
|
const base: VxeGridProps['columns'] = [
|
||||||
|
{ field: 'name', title: '名称', width: 200 },
|
||||||
|
{ field: 'point_type', title: '类型', width: 150 },
|
||||||
|
{ field: 'access', title: '权限', width: 80 },
|
||||||
|
{ field: 'calculation', title: '公式', width: 100 },
|
||||||
|
{ field: 'unit', title: '单位', width: 150 },
|
||||||
|
{ field: 'description', title: '描述' },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const point_table = {
|
||||||
modbus: [
|
modbus: [
|
||||||
{ field: 'register_type', title: '寄存器类型' },
|
{ title: '序号', type: 'seq', width: 80 },
|
||||||
{ field: 'register_address', title: '寄存器地址' },
|
{
|
||||||
|
title: '扩展配置',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
field: 'protocol_ext.register_type',
|
||||||
|
title: '寄存器类型',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'protocol_ext.register_address',
|
||||||
|
title: '寄存器地址',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
...base,
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
|
@ -50,7 +50,7 @@ const routes: RouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
badgeType: 'dot',
|
badgeType: 'dot',
|
||||||
icon: 'logos:naiveui',
|
icon: 'logos:naiveui',
|
||||||
link: VBEN_NAIVE_PREVIEW_URL,
|
iframeSrc: VBEN_NAIVE_PREVIEW_URL,
|
||||||
title: $t('demos.vben.naive-ui'),
|
title: $t('demos.vben.naive-ui'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -11,13 +11,13 @@ import { defineStore } from 'pinia';
|
||||||
|
|
||||||
import { getUserInfoApi, loginApi, logoutApi } from '#/api';
|
import { getUserInfoApi, loginApi, logoutApi } from '#/api';
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
import { useStaticConfigStore } from '#/store';
|
// import { useStaticConfigStore } from '#/store';
|
||||||
|
|
||||||
export const useAuthStore = defineStore('auth', () => {
|
export const useAuthStore = defineStore('auth', () => {
|
||||||
const accessStore = useAccessStore();
|
const accessStore = useAccessStore();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
|
||||||
const staticConfigStore = useStaticConfigStore();
|
// const staticConfigStore = useStaticConfigStore();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const loginLoading = ref(false);
|
const loginLoading = ref(false);
|
||||||
|
@ -38,9 +38,9 @@ export const useAuthStore = defineStore('auth', () => {
|
||||||
userInfo.roles = ['admin'];
|
userInfo.roles = ['admin'];
|
||||||
try {
|
try {
|
||||||
loginLoading.value = true;
|
loginLoading.value = true;
|
||||||
const { data } = await loginApi(params);
|
await loginApi(params);
|
||||||
// 保存静态配置
|
// 保存静态配置
|
||||||
staticConfigStore.setConfig(data);
|
// staticConfigStore.setConfig(data);
|
||||||
// console.log('staticConfigStore', staticConfigStore.support_driver_types);
|
// console.log('staticConfigStore', staticConfigStore.support_driver_types);
|
||||||
// const { accessToken } = await loginApi(params);
|
// const { accessToken } = await loginApi(params);
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,299 @@
|
||||||
|
<script setup lang="js">
|
||||||
|
import { onMounted, onUnmounted, ref } from 'vue';
|
||||||
|
|
||||||
|
import {
|
||||||
|
ElCard,
|
||||||
|
ElCol,
|
||||||
|
ElDescriptions,
|
||||||
|
ElDescriptionsItem,
|
||||||
|
ElProgress,
|
||||||
|
ElRow,
|
||||||
|
} from 'element-plus';
|
||||||
|
|
||||||
|
import { cdcmCDCMAPI } from '#/cdcm/api/api.js';
|
||||||
|
import req from '#/cdcm/api/req_code';
|
||||||
|
|
||||||
|
const ret = ref();
|
||||||
|
|
||||||
|
const get_system_info = async () => {
|
||||||
|
const b = await cdcmCDCMAPI(null, req.CDCMGetSystemInfo);
|
||||||
|
ret.value = b;
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
get_system_info();
|
||||||
|
});
|
||||||
|
|
||||||
|
const timer = setInterval(() => {
|
||||||
|
get_system_info();
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
clearInterval(timer);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 数字取整函数
|
||||||
|
const toInt = (value) => {
|
||||||
|
return value ? Math.round(value) : 0;
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<page> 设备详情 </page>
|
<div class="monitor-container">
|
||||||
|
<!-- 上半部分 - 设备信息 -->
|
||||||
|
<ElRow :gutter="20" class="top-row">
|
||||||
|
<ElCol :span="24">
|
||||||
|
<ElCard class="device-card">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="device-title">设备信息</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<ElDescriptions :column="1" border :size="Large">
|
||||||
|
<ElDescriptionsItem label="型号" class="device-info">
|
||||||
|
CDCM2024
|
||||||
|
</ElDescriptionsItem>
|
||||||
|
<ElDescriptionsItem label="开机时间" class="device-info">
|
||||||
|
{{ ret?.running_information?.hostinfo.boottime || '-' }}
|
||||||
|
</ElDescriptionsItem>
|
||||||
|
<ElDescriptionsItem label="运行时长" class="device-info">
|
||||||
|
{{ ret?.running_information?.hostinfo.uptime || '-' }}
|
||||||
|
</ElDescriptionsItem>
|
||||||
|
</ElDescriptions>
|
||||||
|
</ElCard>
|
||||||
|
</ElCol>
|
||||||
|
</ElRow>
|
||||||
|
|
||||||
|
<!-- 下半部分 - 三栏图表 -->
|
||||||
|
<ElRow :gutter="20" class="bottom-row">
|
||||||
|
<!-- 内存信息 -->
|
||||||
|
<ElCol :span="8" class="chart-col">
|
||||||
|
<ElCard class="chart-card">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span>内存使用情况</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div v-if="ret?.running_information?.meminfo" class="chart-content">
|
||||||
|
<ElProgress
|
||||||
|
type="dashboard"
|
||||||
|
:percentage="toInt(ret.running_information.meminfo.used_percent)"
|
||||||
|
:color="
|
||||||
|
ret.running_information.meminfo.used_percent > 80
|
||||||
|
? '#f56c6c'
|
||||||
|
: '#67c23a'
|
||||||
|
"
|
||||||
|
:width="120"
|
||||||
|
/>
|
||||||
|
<div class="memory-stats">
|
||||||
|
<div>
|
||||||
|
总内存:
|
||||||
|
{{ toInt(ret.running_information.meminfo.total) }}
|
||||||
|
MB
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
已用:
|
||||||
|
{{ toInt(ret.running_information.meminfo.used) }}
|
||||||
|
MB
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
可用:
|
||||||
|
{{ toInt(ret.running_information.meminfo.available) }}
|
||||||
|
MB
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
使用率:
|
||||||
|
{{ toInt(ret.running_information.meminfo.used_percent) }}%
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ElCard>
|
||||||
|
</ElCol>
|
||||||
|
|
||||||
|
<!-- 磁盘信息 -->
|
||||||
|
<ElCol :span="8" class="chart-col">
|
||||||
|
<ElCard class="chart-card">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span>磁盘使用情况</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div v-if="ret?.running_information?.diskinfo" class="disk-chart">
|
||||||
|
<div
|
||||||
|
v-for="(disk, index) in ret.running_information.diskinfo"
|
||||||
|
:key="index"
|
||||||
|
class="disk-item"
|
||||||
|
>
|
||||||
|
<div class="disk-name">{{ disk.name }} ({{ disk.path }})</div>
|
||||||
|
<ElProgress
|
||||||
|
:percentage="toInt(disk.used_percent)"
|
||||||
|
:color="disk.used_percent > 80 ? '#f56c6c' : '#67c23a'"
|
||||||
|
:stroke-width="16"
|
||||||
|
/>
|
||||||
|
<div class="disk-stats">
|
||||||
|
<span>总空间: {{ toInt(disk.total) }} MB</span>
|
||||||
|
<span>已用: {{ toInt(disk.used) }} MB</span>
|
||||||
|
<span>剩余: {{ toInt(disk.free) }} MB</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ElCard>
|
||||||
|
</ElCol>
|
||||||
|
|
||||||
|
<!-- 网络信息 -->
|
||||||
|
<ElCol :span="8" class="chart-col">
|
||||||
|
<ElCard class="chart-card">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span>网络流量</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div v-if="ret?.running_information?.netinfo" class="network-chart">
|
||||||
|
<div
|
||||||
|
v-for="(net, index) in ret.running_information.netinfo"
|
||||||
|
:key="index"
|
||||||
|
class="network-item"
|
||||||
|
>
|
||||||
|
<div class="network-name">{{ net.name }}</div>
|
||||||
|
<div class="network-stats">
|
||||||
|
<div>上传: {{ toInt(net.bytesSent / 1024) }} KB</div>
|
||||||
|
<div>下载: {{ toInt(net.bytesRecv / 1024) }} KB</div>
|
||||||
|
<div>上传包: {{ toInt(net.packetsSent) }}</div>
|
||||||
|
<div>下载包: {{ toInt(net.packetsRecv) }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ElCard>
|
||||||
|
</ElCol>
|
||||||
|
</ElRow>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.monitor-container {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-row {
|
||||||
|
height: 50%;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-row {
|
||||||
|
height: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.device-card {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.device-title {
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.device-info {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-col {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-card {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-content {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.memory-stats {
|
||||||
|
margin-top: 20px;
|
||||||
|
font-size: 18px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.memory-stats div {
|
||||||
|
margin: 16px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disk-chart {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0 10px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disk-item {
|
||||||
|
margin-bottom: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disk-name {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disk-stats {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-top: 16px;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.network-chart {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0 10px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.network-item {
|
||||||
|
padding-bottom: 16px;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.network-name {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.network-stats {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 16px;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 调整Element UI组件样式 */
|
||||||
|
:deep(.el-descriptions__header) {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-descriptions__title) {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-card__header) {
|
||||||
|
padding: 15px 20px;
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
|
|
||||||
|
import { ElMessage } from 'element-plus';
|
||||||
|
|
||||||
|
import { useVbenForm } from '#/adapter/form';
|
||||||
|
import { cdcmRuleAPI } from '#/cdcm/api/api';
|
||||||
|
import req from '#/cdcm/api/req_code';
|
||||||
|
|
||||||
|
const [Modal, modalApi] = useVbenModal();
|
||||||
|
|
||||||
|
const [BaseForm] = useVbenForm({
|
||||||
|
commonConfig: {
|
||||||
|
componentProps: {
|
||||||
|
class: 'w-full',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
handleSubmit: onSubmit,
|
||||||
|
layout: 'horizontal',
|
||||||
|
schema: [
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入规则名称',
|
||||||
|
},
|
||||||
|
fieldName: 'label',
|
||||||
|
label: '规则名称',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入规则描述',
|
||||||
|
},
|
||||||
|
fieldName: 'info',
|
||||||
|
label: '规则描述',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
wrapperClass: 'grid-cols-1',
|
||||||
|
});
|
||||||
|
|
||||||
|
async function onSubmit(values: Record<string, any>) {
|
||||||
|
const res = await cdcmRuleAPI(values, req.CruleAddFlow);
|
||||||
|
ElMessage.success(res);
|
||||||
|
modalApi.close();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Modal title="新增规则" :footer="false">
|
||||||
|
<BaseForm />
|
||||||
|
</Modal>
|
||||||
|
</template>
|
|
@ -1,3 +1,186 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { VxeGridProps } from '#/adapter/vxe-table';
|
||||||
|
|
||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
|
|
||||||
|
import { ElButton, ElMessage, ElMessageBox, ElTag } from 'element-plus';
|
||||||
|
|
||||||
|
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
|
import { cdcmRuleAPI } from '#/cdcm/api/api';
|
||||||
|
import req from '#/cdcm/api/req_code';
|
||||||
|
|
||||||
|
import Add from './add.vue';
|
||||||
|
|
||||||
|
const [Modal, modalApi] = useVbenModal({
|
||||||
|
footer: false,
|
||||||
|
fullscreen: true,
|
||||||
|
fullscreenButton: false,
|
||||||
|
closeOnPressEscape: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const [addModal, addApi] = useVbenModal({
|
||||||
|
connectedComponent: Add,
|
||||||
|
onOpenChange: (isOpen: boolean) => {
|
||||||
|
if (!isOpen) {
|
||||||
|
gridApi.reload();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
interface RowType {
|
||||||
|
id: string;
|
||||||
|
label: string;
|
||||||
|
info: string;
|
||||||
|
disabled: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const gridOptions: VxeGridProps<RowType> = {
|
||||||
|
checkboxConfig: {
|
||||||
|
highlight: true,
|
||||||
|
labelField: 'name',
|
||||||
|
},
|
||||||
|
columns: [
|
||||||
|
{ title: '序号', type: 'seq', width: 50 },
|
||||||
|
// { field: 'id', title: 'ID' },
|
||||||
|
{ field: 'label', title: '名称' },
|
||||||
|
{ field: 'info', title: '描述' },
|
||||||
|
{ field: 'disabled', title: '状态', slots: { default: 'disabled' } },
|
||||||
|
{
|
||||||
|
field: 'action',
|
||||||
|
fixed: 'right',
|
||||||
|
slots: { default: 'action' },
|
||||||
|
title: '管理',
|
||||||
|
width: 240,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
exportConfig: {},
|
||||||
|
keepSource: true,
|
||||||
|
proxyConfig: {
|
||||||
|
ajax: {
|
||||||
|
query: async () => {
|
||||||
|
return {
|
||||||
|
items: await cdcmRuleAPI(null, req.CruleGetFlows),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pagerConfig: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const [Grid, gridApi] = useVbenVxeGrid({
|
||||||
|
gridOptions,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 新增
|
||||||
|
const btn_add = () => {
|
||||||
|
addApi.open();
|
||||||
|
};
|
||||||
|
|
||||||
|
const iframeUrl = ref('');
|
||||||
|
const btn_open = (row: RowType) => {
|
||||||
|
modalApi.open();
|
||||||
|
let fullUrl = window.location.host;
|
||||||
|
fullUrl = 'http://10.10.10.123';
|
||||||
|
iframeUrl.value = `${fullUrl}/rule/#flow/${row.id}`;
|
||||||
|
ElMessage.success(`${fullUrl}/rule/#flow/${row.id}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
// const btn_edit = (row: RowType) => {
|
||||||
|
// // console.log('编辑', row);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
const btn_delete = async (row: RowType) => {
|
||||||
|
try {
|
||||||
|
ElMessageBox.confirm('确定要删除这条记录吗?', '删除确认', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
});
|
||||||
|
await cdcmRuleAPI({ id: row.id }, req.CruleDeleteFlow);
|
||||||
|
gridApi.reload();
|
||||||
|
ElMessage.success('删除成功');
|
||||||
|
} catch (error) {
|
||||||
|
if (error === 'cancel') {
|
||||||
|
ElMessage.info('已取消删除');
|
||||||
|
} else {
|
||||||
|
ElMessage.error('删除失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const btn_start = async (row: RowType) => {
|
||||||
|
try {
|
||||||
|
await cdcmRuleAPI({ id: row.id }, req.CruleStartFlow);
|
||||||
|
gridApi.reload();
|
||||||
|
ElMessage.success('启用成功');
|
||||||
|
} catch {
|
||||||
|
ElMessage.error('启用失败');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const btn_stop = async (row: RowType) => {
|
||||||
|
try {
|
||||||
|
await cdcmRuleAPI({ id: row.id }, req.CruleStopFlow);
|
||||||
|
gridApi.reload();
|
||||||
|
ElMessage.success('停用成功');
|
||||||
|
} catch {
|
||||||
|
ElMessage.error('停用失败');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<page> 逻辑编程 </page>
|
<div class="vp-raw w-full">
|
||||||
|
<Grid>
|
||||||
|
<template #toolbar-tools>
|
||||||
|
<ElButton class="mr-2" type="success" @click="btn_add"> 新增 </ElButton>
|
||||||
|
</template>
|
||||||
|
<template #disabled="{ row }">
|
||||||
|
<ElTag :type="row.disabled ? 'info' : 'success'">
|
||||||
|
{{ row.disabled ? '停用' : '运行' }}
|
||||||
|
</ElTag>
|
||||||
|
</template>
|
||||||
|
<template #action="{ row }">
|
||||||
|
<!-- <ElButton size="small" type="primary" round @click="btn_edit(row)">
|
||||||
|
编辑
|
||||||
|
</ElButton> -->
|
||||||
|
<ElButton size="small" type="primary" round @click="btn_open(row)">
|
||||||
|
打开
|
||||||
|
</ElButton>
|
||||||
|
<ElButton
|
||||||
|
size="small"
|
||||||
|
type="success"
|
||||||
|
round
|
||||||
|
@click="btn_start(row)"
|
||||||
|
v-show="row.disabled ? true : false"
|
||||||
|
>
|
||||||
|
启用
|
||||||
|
</ElButton>
|
||||||
|
<ElButton
|
||||||
|
size="small"
|
||||||
|
type="info"
|
||||||
|
round
|
||||||
|
@click="btn_stop(row)"
|
||||||
|
v-show="row.disabled ? false : true"
|
||||||
|
>
|
||||||
|
停用
|
||||||
|
</ElButton>
|
||||||
|
<ElButton size="small" type="danger" round @click="btn_delete(row)">
|
||||||
|
删除
|
||||||
|
</ElButton>
|
||||||
|
</template>
|
||||||
|
</Grid>
|
||||||
|
<Modal title="逻辑编程">
|
||||||
|
<iframe
|
||||||
|
:src="iframeUrl"
|
||||||
|
style="width: 100%; height: 100%; border: none"
|
||||||
|
></iframe>
|
||||||
|
</Modal>
|
||||||
|
<addModal />
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,3 +1,195 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, onUnmounted, ref } from 'vue';
|
||||||
|
|
||||||
|
import { ElButton, ElCard, ElCol, ElMessage, ElRow } from 'element-plus';
|
||||||
|
|
||||||
|
import { useVbenForm } from '#/adapter/form';
|
||||||
|
import { cdcmCDCMAPI } from '#/cdcm/api/api';
|
||||||
|
import req from '#/cdcm/api/req_code';
|
||||||
|
|
||||||
|
const ret = ref();
|
||||||
|
|
||||||
|
const get_system_info = async () => {
|
||||||
|
const b = await cdcmCDCMAPI(null, req.CDCMGetNetworkInfo);
|
||||||
|
ret.value = b;
|
||||||
|
netAAPI.setValues(ret.value.ip[0]);
|
||||||
|
netBAPI.setValues(ret.value.ip[1]);
|
||||||
|
dnsAPI.setValues(ret.value.dns);
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
get_system_info();
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {});
|
||||||
|
|
||||||
|
const netConfig = {
|
||||||
|
commonConfig: {
|
||||||
|
componentProps: {
|
||||||
|
class: 'w-full',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
showDefaultActions: false,
|
||||||
|
schema: [
|
||||||
|
{
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
allowClear: true,
|
||||||
|
filterOption: true,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: '静态IP',
|
||||||
|
value: 'STATIC',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '动态IP',
|
||||||
|
value: 'DHCP',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '动态IP及DNS',
|
||||||
|
value: 'DHCP_DNS',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
placeholder: '请选择',
|
||||||
|
showSearch: true,
|
||||||
|
defaultValue: 'STATIC',
|
||||||
|
},
|
||||||
|
fieldName: 'mode',
|
||||||
|
label: 'IP模式',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
fieldName: 'ip',
|
||||||
|
label: 'IP地址',
|
||||||
|
defaultValue: 'aa',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
fieldName: 'mk',
|
||||||
|
label: '子网掩码',
|
||||||
|
defaultValue: 'aa',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
fieldName: 'gw',
|
||||||
|
label: '网关地址',
|
||||||
|
defaultValue: 'aa',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
wrapperClass: 'grid-cols-1',
|
||||||
|
};
|
||||||
|
const dnsConfig = {
|
||||||
|
commonConfig: {
|
||||||
|
componentProps: {
|
||||||
|
class: 'w-full',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
showDefaultActions: false,
|
||||||
|
schema: [
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
fieldName: 'dns1',
|
||||||
|
label: '首选地址',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
fieldName: 'dns2',
|
||||||
|
label: '备用地址',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
wrapperClass: 'grid-cols-1',
|
||||||
|
};
|
||||||
|
const [netA, netAAPI] = useVbenForm(netConfig);
|
||||||
|
const [netB, netBAPI] = useVbenForm(netConfig);
|
||||||
|
const [dns, dnsAPI] = useVbenForm(dnsConfig);
|
||||||
|
const set_network_info = async () => {
|
||||||
|
// 获取所有表单数据
|
||||||
|
const values = await netAAPI.getValues();
|
||||||
|
const values2 = await netBAPI.getValues();
|
||||||
|
const values3 = await dnsAPI.getValues();
|
||||||
|
ElMessage.success(JSON.stringify(values));
|
||||||
|
ElMessage.success(JSON.stringify(values2));
|
||||||
|
ElMessage.success(JSON.stringify(values3));
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<page> 网络配置 </page>
|
<page>
|
||||||
|
<ElRow :gutter="20" class="equal-height-row">
|
||||||
|
<ElCol :span="8">
|
||||||
|
<ElCard class="equal-height-card">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span>网卡A</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<netA />
|
||||||
|
</ElCard>
|
||||||
|
</ElCol>
|
||||||
|
<ElCol :span="8">
|
||||||
|
<ElCard class="equal-height-card">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span>网卡B</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<netB />
|
||||||
|
</ElCard>
|
||||||
|
</ElCol>
|
||||||
|
<ElCol :span="8">
|
||||||
|
<ElCard class="equal-height-card">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span>DNS</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<dns />
|
||||||
|
</ElCard>
|
||||||
|
</ElCol>
|
||||||
|
<ElCol :span="24" class="mt-4 text-center">
|
||||||
|
<ElButton @click="set_network_info" type="primary" class="large-button">
|
||||||
|
设定
|
||||||
|
</ElButton>
|
||||||
|
</ElCol>
|
||||||
|
</ElRow>
|
||||||
|
</page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.card-header {
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.equal-height-row {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.equal-height-card {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.equal-height-card :deep(.el-card__body) {
|
||||||
|
flex: 1;
|
||||||
|
padding: 20px;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.equal-height-card :deep(.el-form-item__label) {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.equal-height-card :deep(.el-input__inner),
|
||||||
|
.equal-height-card :deep(.el-select__input) {
|
||||||
|
height: 40px;
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.large-button {
|
||||||
|
padding: 12px 24px;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -40,7 +40,7 @@ const gridOptions: VxeGridProps<TemplateType> = {
|
||||||
labelField: 'name',
|
labelField: 'name',
|
||||||
},
|
},
|
||||||
columns: [
|
columns: [
|
||||||
{ title: '序号', type: 'seq', width: 100 },
|
{ title: '序号', type: 'seq', width: 80 },
|
||||||
{ field: 'name', title: '模板名称', width: 300 },
|
{ field: 'name', title: '模板名称', width: 300 },
|
||||||
{ field: 'type', title: '模板类型', width: 200 },
|
{ field: 'type', title: '模板类型', width: 200 },
|
||||||
{ field: 'description', title: '模板描述' },
|
{ field: 'description', title: '模板描述' },
|
||||||
|
|
|
@ -90,7 +90,6 @@ const [Drawer, drawerApi] = useVbenDrawer({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const [addPointModal, addApi] = useVbenModal({
|
const [addPointModal, addApi] = useVbenModal({
|
||||||
connectedComponent: AddPoint,
|
connectedComponent: AddPoint,
|
||||||
});
|
});
|
||||||
|
|
|
@ -18,7 +18,7 @@ export default defineConfig(async () => {
|
||||||
rewrite: (path) => path.replace(/^\/api/, ''),
|
rewrite: (path) => path.replace(/^\/api/, ''),
|
||||||
// mock代理目标地址
|
// mock代理目标地址
|
||||||
// target: 'http://10.10.10.41:5566/api',
|
// target: 'http://10.10.10.41:5566/api',
|
||||||
target: 'http://api.shikicc.com:8900/api',
|
target: 'http://10.10.10.123/api',
|
||||||
ws: true,
|
ws: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -4,13 +4,17 @@
|
||||||
"language": "en,en-US",
|
"language": "en,en-US",
|
||||||
"allowCompoundWords": true,
|
"allowCompoundWords": true,
|
||||||
"words": [
|
"words": [
|
||||||
|
"AAPI",
|
||||||
"acmr",
|
"acmr",
|
||||||
"antd",
|
"antd",
|
||||||
"antdv",
|
"antdv",
|
||||||
"astro",
|
"astro",
|
||||||
|
"BAPI",
|
||||||
"brotli",
|
"brotli",
|
||||||
"CDCM",
|
"CDCM",
|
||||||
|
"CDCMAPI",
|
||||||
"clsx",
|
"clsx",
|
||||||
|
"Crule",
|
||||||
"defu",
|
"defu",
|
||||||
"demi",
|
"demi",
|
||||||
"echarts",
|
"echarts",
|
||||||
|
|
Loading…
Reference in New Issue