feat: 系统模块

master
JINGYJ 3 weeks ago
parent e385062a81
commit 6ac136d878

@ -0,0 +1,424 @@
<template>
<!-- 通信管理弹框 -->
<el-dialog
title="通信管理"
v-model="dialogVisible"
width="800px"
:before-close="handleClose"
class="custom-dialog"
>
<!-- 内容容器左侧菜单 + 右侧表单 -->
<div class="dialog-container">
<!-- 左侧导航菜单 -->
<div class="left-menu">
<div
class="menu-item"
:class="{ active: activeMenu === 'device' }"
@click="activeMenu = 'device'"
>
<i class="el-icon-setting"></i> 设备管理
</div>
<div
class="menu-item"
:class="{ active: activeMenu === 'receive' }"
@click="activeMenu = 'receive'"
>
<i class="el-icon-s-data"></i> 接收事件
</div>
<div
class="menu-item"
:class="{ active: activeMenu === 'send' }"
@click="activeMenu = 'send'"
>
<i class="el-icon-s-opportunity"></i> 发送事件
</div>
<div
class="menu-item"
:class="{ active: activeMenu === 'heartbeat' }"
@click="activeMenu = 'heartbeat'"
>
<i class="el-icon-heart-rate"></i> 心跳管理
</div>
<div
class="menu-item"
:class="{ active: activeMenu === 'response' }"
@click="activeMenu = 'response'"
>
<i class="el-icon-switch-button"></i> 响应配置
</div>
</div>
<!-- 右侧内容区域 -->
<div class="right-content">
<!-- 设备列表 + 协议配置 -->
<div class="device-section" v-if="activeMenu === 'device'">
<!-- 设备列表 -->
<div class="device-list">
<div class="device-title">设备列表</div>
<el-button icon="el-icon-plus" size="mini" @click="addDevice"></el-button>
<div class="device-item" v-for="(item, index) in deviceList" :key="index">
<span>{{ item.name }}</span>
<el-switch
v-model="item.enabled"
active-text="开启"
inactive-text="关闭"
@change="handleSwitch(index)"
/>
</div>
</div>
<!-- 通信协议配置 -->
<div class="protocol-config">
<div class="config-title">通信协议</div>
<el-form label-width="80px">
<el-form-item label="协议类型">
<el-select v-model="form.protocolType" placeholder="选择协议">
<el-option label="TCP客户端" value="tcp"></el-option>
<el-option label="UDP客户端" value="udp"></el-option>
</el-select>
</el-form-item>
<el-form-item label="设备名称">
<el-input v-model="form.deviceName"></el-input>
</el-form-item>
<el-form-item label="目标IP">
<el-input v-model="form.targetIp"></el-input>
</el-form-item>
<el-form-item label="目标端口">
<el-input v-model="form.targetPort"></el-input>
</el-form-item>
<el-form-item label="数据上传">
<el-switch v-model="form.dataUpload"></el-switch>
</el-form-item>
<el-form-item label="自动重连">
<el-switch v-model="form.autoReconnect"></el-switch>
</el-form-item>
<el-form-item label="接受结束符">
<el-switch v-model="form.acceptTerminator"></el-switch>
</el-form-item>
</el-form>
</div>
</div>
<!-- 接收事件 -->
<div class="event-section" v-else-if="activeMenu === 'receive'">
<div class="config-title">接收事件</div>
<el-input
type="textarea"
v-model="receiveData"
placeholder="接收事件内容"
rows="6"
class="event-textarea"
></el-input>
<div class="event-actions">
<el-checkbox v-model="hexDisplay">16</el-checkbox>
<el-button type="primary" size="mini" @click="clearReceive"></el-button>
<el-button type="primary" size="mini" @click="fetchReceive"></el-button>
</div>
</div>
<!-- 发送事件 -->
<div class="event-section" v-else-if="activeMenu === 'send'">
<div class="config-title">发送事件</div>
<el-input
type="textarea"
v-model="sendData"
placeholder="发送事件内容"
rows="6"
class="event-textarea"
></el-input>
<div class="event-actions">
<el-button type="primary" size="mini" @click="sendDataAction"></el-button>
</div>
</div>
<!-- 心跳管理 -->
<div class="heartbeat-section" v-else-if="activeMenu === 'heartbeat'">
<div class="config-title">心跳管理</div>
<el-form label-width="100px">
<el-form-item label="心跳间隔">
<el-input v-model="heartbeatInterval" placeholder="单位:秒"></el-input>
</el-form-item>
<el-form-item label="心跳内容">
<el-input v-model="heartbeatContent"></el-input>
</el-form-item>
</el-form>
</div>
<!-- 响应配置 -->
<div class="response-section" v-else-if="activeMenu === 'response'">
<div class="config-title">响应配置</div>
<el-form label-width="100px">
<el-form-item label="响应超时">
<el-input v-model="responseTimeout" placeholder="单位:秒"></el-input>
</el-form-item>
<el-form-item label="重试次数">
<el-input v-model="retryCount"></el-input>
</el-form-item>
</el-form>
</div>
<!-- 底部操作按钮 -->
<div class="bottom-actions">
<el-button type="danger" @click="deleteDevice"></el-button>
</div>
</div>
</div>
</el-dialog>
<!-- 触发弹框按钮用于测试 -->
<el-button type="primary" @click="dialogVisible = true" style="margin: 20px"
>打开通信管理</el-button
>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
//
const dialogVisible = ref(false)
//
const activeMenu = ref('device') // device/receive/send/heartbeat/response
//
const deviceList = reactive([
{ name: '1.TCP客户端', enabled: true },
{ name: '2.UDP客户端', enabled: false }
])
//
const form = reactive({
protocolType: 'tcp', // tcp/udp
deviceName: 'TCP客户端',
targetIp: '',
targetPort: '',
dataUpload: false,
autoReconnect: false,
acceptTerminator: true
})
//
const receiveData = ref('')
//
const sendData = ref('')
// 16
const hexDisplay = ref(true)
//
const heartbeatInterval = ref('')
const heartbeatContent = ref('')
//
const responseTimeout = ref('')
const retryCount = ref('')
//
const addDevice = () => {
deviceList.push({ name: `新设备${deviceList.length + 1}`, enabled: false })
}
//
const handleSwitch = (index: number) => {
console.log(`设备 ${deviceList[index].name} 状态:`, deviceList[index].enabled)
}
//
const clearReceive = () => {
receiveData.value = ''
}
//
const fetchReceive = () => {
receiveData.value = '模拟接收数据0A 0B 0C 0D' //
}
//
const sendDataAction = () => {
console.log('发送数据:', sendData.value)
//
}
//
const deleteDevice = () => {
if (deviceList.length > 0) {
deviceList.pop()
}
}
//
const handleClose = (done: () => void) => {
//
form.protocolType = 'tcp'
form.deviceName = 'TCP客户端'
form.targetIp = ''
form.targetPort = ''
form.dataUpload = false
form.autoReconnect = false
form.acceptTerminator = true
//
receiveData.value = ''
sendData.value = ''
done()
}
</script>
<style scoped lang="scss">
/* 弹框整体样式 */
.custom-dialog {
.el-dialog__header {
border-bottom: 1px solid #444;
}
.el-dialog__body {
padding: 0;
background: #2c2c2c;
color: #fff;
}
}
/* 内容容器:左侧菜单 + 右侧表单 */
.dialog-container {
display: flex;
height: 500px;
padding: 20px;
}
/* 左侧菜单 */
.left-menu {
width: 180px;
background: #373737;
border-radius: 4px;
padding: 20px 0;
margin-right: 20px;
.menu-item {
color: #fff;
padding: 12px 20px;
cursor: pointer;
transition: background 0.3s;
display: flex;
align-items: center;
gap: 8px;
&:hover {
background: #4d4d4d;
}
&.active {
background: #4d4d4d;
font-weight: bold;
}
}
}
/* 右侧内容区域 */
.right-content {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
}
/* 设备管理区域 */
.device-section {
display: flex;
gap: 20px;
.device-list {
width: 220px;
background: #373737;
border-radius: 4px;
padding: 16px;
.device-title {
font-size: 14px;
font-weight: bold;
margin-bottom: 12px;
}
.device-item {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
}
.protocol-config {
flex: 1;
background: #373737;
border-radius: 4px;
padding: 16px;
.config-title {
font-size: 14px;
font-weight: bold;
margin-bottom: 12px;
}
}
}
/* 事件区域(接收/发送) */
.event-section {
background: #373737;
border-radius: 4px;
padding: 16px;
.config-title {
font-size: 14px;
font-weight: bold;
margin-bottom: 12px;
}
.event-textarea {
width: 100%;
background: #2c2c2c;
color: #fff;
border: 1px solid #444;
border-radius: 4px;
padding: 8px;
resize: none;
}
.event-actions {
display: flex;
align-items: center;
gap: 16px;
margin-top: 8px;
}
}
/* 心跳管理区域 */
.heartbeat-section {
background: #373737;
border-radius: 4px;
padding: 16px;
.config-title {
font-size: 14px;
font-weight: bold;
margin-bottom: 12px;
}
}
/* 响应配置区域 */
.response-section {
background: #373737;
border-radius: 4px;
padding: 16px;
.config-title {
font-size: 14px;
font-weight: bold;
margin-bottom: 12px;
}
}
/* 底部操作按钮 */
.bottom-actions {
display: flex;
justify-content: flex-end;
margin-top: 20px;
}
</style>

@ -35,10 +35,14 @@
<span class="el-dropdown-link">系统</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>日志</el-dropdown-item>
<el-dropdown-item>通信管理</el-dropdown-item>
<el-dropdown-item>控制器管理</el-dropdown-item>
<el-dropdown-item>相机管理</el-dropdown-item>
<el-dropdown-item @click="handleMenuClick('log')"></el-dropdown-item>
<el-dropdown-item @click="handleMenuClick('communication')"
>通信管理</el-dropdown-item
>
<el-dropdown-item @click="handleMenuClick('controller')"
>控制器管理</el-dropdown-item
>
<el-dropdown-item @click="handleMenuClick('camera')"></el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
@ -65,6 +69,25 @@ const emit = defineEmits<Emits>()
const dragging = ref(false)
const mouseX = ref(0)
const mouseY = ref(0)
const handleMenuClick = (command) => {
console.log('点击的菜单项:', command)
// command
switch (command) {
case 'log':
//
break
case 'communication':
//
break
case 'controller':
//
break
case 'camera':
//
break
}
}
const mousedown = (event) => {
dragging.value = true
mouseX.value = event.x

Loading…
Cancel
Save