|
|
@ -0,0 +1,361 @@
|
|
|
|
|
|
|
|
<template>
|
|
|
|
|
|
|
|
<!-- 通信管理弹框 -->
|
|
|
|
|
|
|
|
<DSDialog title="通信管理" v-model="show" width="1200" class="commManagement-dialog ds-dialog">
|
|
|
|
|
|
|
|
<div class="commManagement-container">
|
|
|
|
|
|
|
|
<div class="commManagement-siderBar">
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
|
|
|
class="commManagement-sidebar-item"
|
|
|
|
|
|
|
|
:class="{ active: activeTab === v.value }"
|
|
|
|
|
|
|
|
@click="setActiveTab(v)"
|
|
|
|
|
|
|
|
v-for="(v, k) in commBars"
|
|
|
|
|
|
|
|
:key="k"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<!-- // TODO 替换icon -->
|
|
|
|
|
|
|
|
<img :src="activeTab === v.value ? v.iconSelected : v.icon" alt="" class="w-[32px]" />
|
|
|
|
|
|
|
|
<span>{{ v.label }}</span>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="commManagement-line-first" />
|
|
|
|
|
|
|
|
<div class="commManagement-infoList">
|
|
|
|
|
|
|
|
<div class="commManagement-infoList-title">
|
|
|
|
|
|
|
|
<span>{{ currentTabLabel }}</span>
|
|
|
|
|
|
|
|
<div class="infoList-title-btn" @click="addDevice">+</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="commManagement-infoList-content">
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
|
|
|
class="commManagement-infoList-item"
|
|
|
|
|
|
|
|
:class="{ active: deviceTab === item.name }"
|
|
|
|
|
|
|
|
v-for="(item, index) in deviceList"
|
|
|
|
|
|
|
|
:key="index"
|
|
|
|
|
|
|
|
@click="selectDevice(item)"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<span>{{ item.name }}</span>
|
|
|
|
|
|
|
|
<el-switch v-model="item.enabled" size="small" />
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<el-empty
|
|
|
|
|
|
|
|
:image-size="54"
|
|
|
|
|
|
|
|
:image="NoDataIcon"
|
|
|
|
|
|
|
|
style="margin-top: 130px"
|
|
|
|
|
|
|
|
v-if="deviceList.length === 0"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="commManagement-line-second" />
|
|
|
|
|
|
|
|
<div class="commManagement-content">
|
|
|
|
|
|
|
|
<el-form label-width="auto" size="default" :model="formInfoDevice" style="max-width: 752px">
|
|
|
|
|
|
|
|
<div>通信协议</div>
|
|
|
|
|
|
|
|
<el-row :gutter="24">
|
|
|
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
|
|
|
<el-form-item label="协议类型" label-position="top">
|
|
|
|
|
|
|
|
<el-input v-model="formDeviceInfo.protocol" />
|
|
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
</el-col>
|
|
|
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
|
|
|
<el-form-item label="设备名称" label-position="top">
|
|
|
|
|
|
|
|
<el-input v-model="formDeviceInfo.deviceName" />
|
|
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
</el-col>
|
|
|
|
|
|
|
|
</el-row>
|
|
|
|
|
|
|
|
<div>通信参数</div>
|
|
|
|
|
|
|
|
<el-row :gutter="24">
|
|
|
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
|
|
|
<el-form-item label="目标IP" label-position="top">
|
|
|
|
|
|
|
|
<el-input v-model="formDeviceInfo.IP" />
|
|
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
</el-col>
|
|
|
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
|
|
|
<el-form-item label="目标端口" label-position="top">
|
|
|
|
|
|
|
|
<el-input v-model="formDeviceInfo.targetPort" />
|
|
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
</el-col>
|
|
|
|
|
|
|
|
</el-row>
|
|
|
|
|
|
|
|
<el-form-item label="数据上传" label-position="left">
|
|
|
|
|
|
|
|
<el-switch v-model="formDeviceInfo.dataUpload" />
|
|
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
<el-form-item label="自动重连" label-position="left">
|
|
|
|
|
|
|
|
<el-switch v-model="formDeviceInfo.reconnect" />
|
|
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
<el-form-item label="接受结束符" label-position="left">
|
|
|
|
|
|
|
|
<el-switch v-model="formDeviceInfo.acceptEnd" />
|
|
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
<el-form-item v-if="formDeviceInfo.acceptEnd">
|
|
|
|
|
|
|
|
<el-tabs v-model="dataTab" class="data-tabs" @tab-click="handleClick">
|
|
|
|
|
|
|
|
<el-tab-pane label="接收数据" name="receive">
|
|
|
|
|
|
|
|
<el-input
|
|
|
|
|
|
|
|
v-model="formDeviceInfo.endInfo"
|
|
|
|
|
|
|
|
type="textarea"
|
|
|
|
|
|
|
|
resize="none"
|
|
|
|
|
|
|
|
class="fixed-height-textarea"
|
|
|
|
|
|
|
|
:rows="4"
|
|
|
|
|
|
|
|
maxlength="350"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</el-tab-pane>
|
|
|
|
|
|
|
|
<el-tab-pane label="发送数据" name="send">
|
|
|
|
|
|
|
|
<el-input
|
|
|
|
|
|
|
|
v-model="formDeviceInfo.endInfo"
|
|
|
|
|
|
|
|
type="textarea"
|
|
|
|
|
|
|
|
resize="none"
|
|
|
|
|
|
|
|
class="fixed-height-textarea"
|
|
|
|
|
|
|
|
:rows="4"
|
|
|
|
|
|
|
|
maxlength="350"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</el-tab-pane>
|
|
|
|
|
|
|
|
</el-tabs>
|
|
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
<el-row :gutter="20">
|
|
|
|
|
|
|
|
<el-col :span="6">
|
|
|
|
|
|
|
|
<el-checkbox value="16radix" name="type"> 16进制 </el-checkbox>
|
|
|
|
|
|
|
|
</el-col>
|
|
|
|
|
|
|
|
<el-col :span="6" :offset="12">
|
|
|
|
|
|
|
|
<DSButton type="danger" class="mr-2 form-device-btn">清空内容</DSButton>
|
|
|
|
|
|
|
|
<DSButton type="danger" class="form-device-btn"> 接收数据</DSButton>
|
|
|
|
|
|
|
|
</el-col>
|
|
|
|
|
|
|
|
</el-row>
|
|
|
|
|
|
|
|
</el-form>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</DSDialog>
|
|
|
|
|
|
|
|
<DeviceDialog v-model:value="isDeviceDialog" />
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
|
|
|
defineOptions({
|
|
|
|
|
|
|
|
name: 'CommManagement'
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
import { DSButton } from '@/components/Button'
|
|
|
|
|
|
|
|
import { DSDialog } from '@/components/Dialog'
|
|
|
|
|
|
|
|
import DeviceDialog from './deviceDialog.vue'
|
|
|
|
|
|
|
|
import DeviceIcon from '@/assets/images/common/device.png'
|
|
|
|
|
|
|
|
import DeviceSelectedIcon from '@/assets/images/common/device_selected.png'
|
|
|
|
|
|
|
|
import SendIcon from '@/assets/images/common/send.png'
|
|
|
|
|
|
|
|
import SendSelectedIcon from '@/assets/images/common/send_selected.png'
|
|
|
|
|
|
|
|
import ReceiveIcon from '@/assets/images/common/receive.png'
|
|
|
|
|
|
|
|
import ReceiveSelectedIcon from '@/assets/images/common/receive_selected.png'
|
|
|
|
|
|
|
|
import HeartbeatIcon from '@/assets/images/common/heartbeat.png'
|
|
|
|
|
|
|
|
import HeartbeatSelectedIcon from '@/assets/images/common/heartbeat_selected.png'
|
|
|
|
|
|
|
|
import ResponseIcon from '@/assets/images/common/response.png'
|
|
|
|
|
|
|
|
import ResponseSelectedIcon from '@/assets/images/common/response_selected.png'
|
|
|
|
|
|
|
|
import NoDataIcon from '@/assets/images/common/no_data.png'
|
|
|
|
|
|
|
|
interface Props {
|
|
|
|
|
|
|
|
/** import DeviceDialog from './deviceDialog.vue';
|
|
|
|
|
|
|
|
弹窗显隐 */
|
|
|
|
|
|
|
|
value: boolean
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
interface Emits {
|
|
|
|
|
|
|
|
(e: 'update:value', val: boolean): void
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
|
|
|
|
|
|
value: false
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
const emit = defineEmits<Emits>()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const show = computed({
|
|
|
|
|
|
|
|
get() {
|
|
|
|
|
|
|
|
return props.value
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
set(val: boolean) {
|
|
|
|
|
|
|
|
emit('update:value', val)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
const isDeviceDialog = ref(false)
|
|
|
|
|
|
|
|
// 左侧菜单激活状态
|
|
|
|
|
|
|
|
const activeTab = ref('device') // device/receive/send/heartbeat/response
|
|
|
|
|
|
|
|
const deviceTab = ref('') // device/receive/send/heartbeat/response
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 根据 activeTab 匹配对应的中文 label
|
|
|
|
|
|
|
|
const currentTabLabel = computed(() => {
|
|
|
|
|
|
|
|
// 在 commBars 中找到 value 与 activeTab 匹配的项,返回其 label
|
|
|
|
|
|
|
|
const matched = commBars.find((item) => item.value === activeTab.value)
|
|
|
|
|
|
|
|
// 如果找不到匹配项,默认显示空或提示文字
|
|
|
|
|
|
|
|
return matched ? matched.label : ''
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 设备列表
|
|
|
|
|
|
|
|
const deviceList = reactive([
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
name: '1.TCP客户端',
|
|
|
|
|
|
|
|
enabled: false,
|
|
|
|
|
|
|
|
info: {
|
|
|
|
|
|
|
|
protocol: '1',
|
|
|
|
|
|
|
|
deviceName: '1',
|
|
|
|
|
|
|
|
IP: '1',
|
|
|
|
|
|
|
|
targetPort: '1',
|
|
|
|
|
|
|
|
dataUpload: false,
|
|
|
|
|
|
|
|
reconnect: false,
|
|
|
|
|
|
|
|
acceptEnd: false,
|
|
|
|
|
|
|
|
endInfo: '1'
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{ name: '2.UDP客户端', enabled: false }
|
|
|
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const dataTab = ref('receive')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const formDeviceInfo = reactive({
|
|
|
|
|
|
|
|
protocol: '',
|
|
|
|
|
|
|
|
deviceName: '',
|
|
|
|
|
|
|
|
IP: '',
|
|
|
|
|
|
|
|
targetPort: '',
|
|
|
|
|
|
|
|
dataUpload: false,
|
|
|
|
|
|
|
|
reconnect: false,
|
|
|
|
|
|
|
|
acceptEnd: false,
|
|
|
|
|
|
|
|
endInfo: ''
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
interface CommBar {
|
|
|
|
|
|
|
|
label: string
|
|
|
|
|
|
|
|
value: 'device' | 'receive' | 'send' | 'heartbeat' | 'response'
|
|
|
|
|
|
|
|
icon: string
|
|
|
|
|
|
|
|
iconSelected: string
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const commBars: CommBar[] = [
|
|
|
|
|
|
|
|
{ label: '设备列表', value: 'device', icon: DeviceIcon, iconSelected: DeviceSelectedIcon },
|
|
|
|
|
|
|
|
{ label: '接收事件', value: 'receive', icon: ReceiveIcon, iconSelected: ReceiveSelectedIcon },
|
|
|
|
|
|
|
|
{ label: '发送事件', value: 'send', icon: SendIcon, iconSelected: SendSelectedIcon },
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
label: '心跳管理',
|
|
|
|
|
|
|
|
value: 'heartbeat',
|
|
|
|
|
|
|
|
icon: HeartbeatIcon,
|
|
|
|
|
|
|
|
iconSelected: HeartbeatSelectedIcon
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{ label: '响应配置', value: 'response', icon: ResponseIcon, iconSelected: ResponseSelectedIcon }
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
const setActiveTab = (tab: SettingItem) => {
|
|
|
|
|
|
|
|
activeTab.value = tab.value
|
|
|
|
|
|
|
|
console.log(activeTab.value)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const selectDevice = (device: Device) => {
|
|
|
|
|
|
|
|
deviceTab.value = device.name
|
|
|
|
|
|
|
|
Object.assign(formDeviceInfo, device.info)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 添加设备
|
|
|
|
|
|
|
|
const addDevice = () => {
|
|
|
|
|
|
|
|
if (isDeviceDialog.value) {
|
|
|
|
|
|
|
|
isDeviceDialog.value = false
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// 弹窗显隐
|
|
|
|
|
|
|
|
isDeviceDialog.value = true
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log(isDeviceDialog.value, 'isDeviceDialog.value')
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 接收事件内容
|
|
|
|
|
|
|
|
const receiveData = ref('')
|
|
|
|
|
|
|
|
// 发送事件内容
|
|
|
|
|
|
|
|
const sendData = ref('')
|
|
|
|
|
|
|
|
// 16进制显示
|
|
|
|
|
|
|
|
const hexDisplay = ref(true)
|
|
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
|
|
|
|
/* 弹框整体样式 */
|
|
|
|
|
|
|
|
.commManagement-container {
|
|
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
|
|
height: 766px;
|
|
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
.commManagement-siderBar {
|
|
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
|
|
width: 120px;
|
|
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
|
|
padding: 24px;
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
.commManagement-sidebar-item {
|
|
|
|
|
|
|
|
margin-bottom: 16px;
|
|
|
|
|
|
|
|
height: 62px;
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
.commManagement-infoList {
|
|
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
|
|
width: 252px;
|
|
|
|
|
|
|
|
.commManagement-infoList-title {
|
|
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
|
|
height: 50px;
|
|
|
|
|
|
|
|
padding: 0 16px;
|
|
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
|
|
.infoList-title-btn {
|
|
|
|
|
|
|
|
width: 24px;
|
|
|
|
|
|
|
|
height: 24px;
|
|
|
|
|
|
|
|
background: #154ddd;
|
|
|
|
|
|
|
|
border: none;
|
|
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
|
|
font-size: 24px;
|
|
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
|
|
line-height: 20px;
|
|
|
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
.commManagement-infoList-content {
|
|
|
|
|
|
|
|
.commManagement-infoList-item {
|
|
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
|
|
height: 32px;
|
|
|
|
|
|
|
|
padding: 0 16px;
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
.commManagement-infoList-item.active {
|
|
|
|
|
|
|
|
background: #f2f2f7;
|
|
|
|
|
|
|
|
span {
|
|
|
|
|
|
|
|
color: #154ddd;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
.commManagement-content {
|
|
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
|
|
padding: 16px 24px 24px;
|
|
|
|
|
|
|
|
.data-tabs {
|
|
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
|
|
:deep(.el-tabs__item) {
|
|
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
:deep(.fixed-height-textarea) {
|
|
|
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
|
|
|
height: 110px !important;
|
|
|
|
|
|
|
|
min-height: 110px !important;
|
|
|
|
|
|
|
|
max-height: 110px !important;
|
|
|
|
|
|
|
|
.el-textarea__inner {
|
|
|
|
|
|
|
|
height: 110px !important;
|
|
|
|
|
|
|
|
background: #303136;
|
|
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
.form-device-btn {
|
|
|
|
|
|
|
|
width: 80px;
|
|
|
|
|
|
|
|
padding: 0 12px;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
.commManagement-line-first,
|
|
|
|
|
|
|
|
.commManagement-line-second {
|
|
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
|
|
left: 120px;
|
|
|
|
|
|
|
|
width: 1px;
|
|
|
|
|
|
|
|
height: 100vh;
|
|
|
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
|
|
|
opacity: 0.3;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
.commManagement-line-second {
|
|
|
|
|
|
|
|
left: 372px;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
</style>
|