feat(断路器): 调整样式、更换插件socket
This commit is contained in:
parent
8567ec8c2e
commit
57d766fab0
Binary file not shown.
|
@ -34,7 +34,7 @@ function createWindow() {
|
|||
// 禁用同源策略,允许跨域请求
|
||||
webSecurity: false,
|
||||
contextIsolation: false,
|
||||
csp: "default-src 'self'; connect-src 'self' http://127.0.0.1:8000 http://192.168.1.17:8000 ws://192.168.1.17:8000 ws://127.0.0.1:8000",
|
||||
csp: "default-src 'self'; connect-src 'self' *",
|
||||
// 禁止build环境使用DevTool
|
||||
// devTools: is.dev ? true : false
|
||||
devTools: true
|
||||
|
|
|
@ -2,11 +2,12 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Electron</title>
|
||||
<title>谷云工具</title>
|
||||
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
||||
<link rel="stylesheet" href="/src/assets/iconfont/iconfont.css">
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="default-src 'self'; connect-src 'self' http://127.0.0.1:8000 http://192.168.1.17:8000 ws://192.168.1.17:8000 ws://127.0.0.1:8000; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"
|
||||
content="default-src 'self'; connect-src 'self' *; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"
|
||||
/>
|
||||
</head>
|
||||
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
<script setup>
|
||||
import { RouterView } from "vue-router"
|
||||
import { RouterView } from 'vue-router'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<RouterView></RouterView>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
<style lang="scss">
|
||||
:root {
|
||||
--el-input-height: 36px;
|
||||
--el-color-primary: #0066cc;
|
||||
--el-fill-color-blank: #e6e6e6;
|
||||
--el-disabled-bg-color: #f7f7f7;
|
||||
}
|
||||
::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
}
|
||||
|
@ -20,4 +26,27 @@ import { RouterView } from "vue-router"
|
|||
::-webkit-scrollbar-track {
|
||||
width: 5px;
|
||||
}
|
||||
/*全局覆盖样式*/
|
||||
.el-collapse-item {
|
||||
color: #333333;
|
||||
.el-collapse-item__header {
|
||||
font-family: Source Han Sans CN;
|
||||
background: #e6e6e6;
|
||||
padding: 0 30px;
|
||||
color: #333333;
|
||||
font-size: 16px;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
font-weight: 500;
|
||||
&.is-active {
|
||||
color: #0066cc;
|
||||
}
|
||||
}
|
||||
.el-collapse-item__wrap {
|
||||
background-color: #f2f2f2 !important;
|
||||
}
|
||||
.el-input__wrapper {
|
||||
background: #e6e6e6;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 4622943 */
|
||||
src: url('iconfont.woff2?t=1721353754291') format('woff2'),
|
||||
url('iconfont.woff?t=1721353754291') format('woff'),
|
||||
url('iconfont.ttf?t=1721353754291') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family: "iconfont" !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-shousuoshangjiantou:before {
|
||||
content: "\e9b6";
|
||||
}
|
||||
|
||||
.icon-up-arrow:before {
|
||||
content: "\e9c1";
|
||||
}
|
||||
|
||||
.icon-unlock:before {
|
||||
content: "\e882";
|
||||
}
|
||||
|
||||
.icon-gexinghuabobao:before {
|
||||
content: "\e66d";
|
||||
}
|
||||
|
||||
.icon-icon_suoding:before {
|
||||
content: "\e76c";
|
||||
}
|
||||
|
||||
.icon-icon_shanchu:before {
|
||||
content: "\e76d";
|
||||
}
|
||||
|
||||
.icon-icon_shanghang:before {
|
||||
content: "\e76e";
|
||||
}
|
||||
|
||||
.icon-icon_xiahang:before {
|
||||
content: "\e76f";
|
||||
}
|
||||
|
||||
.icon-icon_shezhi:before {
|
||||
content: "\e770";
|
||||
}
|
||||
|
||||
.icon-icon_xitong:before {
|
||||
content: "\e771";
|
||||
}
|
||||
|
||||
.icon-icon_jiankong:before {
|
||||
content: "\e772";
|
||||
}
|
||||
|
||||
.icon-icon_caid:before {
|
||||
content: "\e75f";
|
||||
}
|
||||
|
||||
.icon-icon_chajian:before {
|
||||
content: "\e767";
|
||||
}
|
||||
|
||||
.icon-icon_xiaoxi:before {
|
||||
content: "\e768";
|
||||
}
|
||||
|
||||
.icon-icon_gengxin:before {
|
||||
content: "\e769";
|
||||
}
|
||||
|
||||
.icon-icon_fuzhi:before {
|
||||
content: "\e76a";
|
||||
}
|
||||
|
||||
.icon-icon_duanluqi:before {
|
||||
content: "\e76b";
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
Binary file not shown.
After Width: | Height: | Size: 4.4 KiB |
|
@ -0,0 +1,71 @@
|
|||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
|
||||
const settings = defineProps({
|
||||
collapse: Boolean,
|
||||
width: String
|
||||
})
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-aside :width="settings.width">
|
||||
<el-scrollbar>
|
||||
<el-menu
|
||||
default-active="/system/switch"
|
||||
:collapse="settings.collapse"
|
||||
:router="true"
|
||||
>
|
||||
<el-menu-item index="/system/switch"> <span class="iconfont icon-icon_duanluqi"></span> 断路器调试</el-menu-item>
|
||||
<!-- <el-menu-item index="/system/about"><span class="iconfont icon-icon_jiankong"></span> 视频监控</el-menu-item>-->
|
||||
<!-- <el-menu-item index="/test"><el-icon> <Menu /> </el-icon>测试</el-menu-item>-->
|
||||
</el-menu>
|
||||
</el-scrollbar>
|
||||
</el-aside>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
.el-aside {
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
.el-menu{
|
||||
padding: 0 10px;
|
||||
background: #fff;
|
||||
}
|
||||
.el-menu-item{
|
||||
border-radius: 10px;
|
||||
background: #f2f2f2;
|
||||
margin-bottom: 12px;
|
||||
align-items: center;
|
||||
padding: 0;
|
||||
padding-left: 26px !important;
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
.iconfont{
|
||||
margin-right: 10px;
|
||||
color: #999;
|
||||
font-size: 22px;
|
||||
}
|
||||
}
|
||||
.el-menu-item.is-active{
|
||||
background: #4c94db;
|
||||
border-radius: 10px;
|
||||
/*margin: 0 10px;*/
|
||||
color: #fff;
|
||||
.iconfont{
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.el-scrollbar {
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
/*background-color: #1a1c1e;*/
|
||||
}
|
||||
|
||||
.el-menu {
|
||||
border-right: none;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,170 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-header style="display: flex; font-size: 16px">
|
||||
<div class='header-left'>
|
||||
<img :src="logo" alt="">
|
||||
</div>
|
||||
<div class='haeder-menu' :style="{width:menuWidth + 'px'}">
|
||||
<el-menu
|
||||
default-active="/system"
|
||||
mode="horizontal"
|
||||
router="true"
|
||||
>
|
||||
<el-menu-item index="/system">系统模板</el-menu-item>
|
||||
</el-menu>
|
||||
</div>
|
||||
<div class="haeder-right">
|
||||
<div class="block" style="margin-right: 25px">
|
||||
<el-icon size="24" color="#80b3e6"><BellFilled /></el-icon>
|
||||
</div>
|
||||
<div class="user-name" style="margin-right: 10px">
|
||||
admin
|
||||
</div>
|
||||
<el-dropdown trigger="click">
|
||||
<div class="el-dropdown-link avatar-box" style="cursor: pointer">
|
||||
<img :src="avatar" alt="">
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item>admin</el-dropdown-item>
|
||||
<!-- <el-dropdown-item @click="LogOut">退出登录</el-dropdown-item>-->
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</el-header>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue"
|
||||
|
||||
import logo from '@renderer/assets/image/logo.png'
|
||||
import avatar from '@renderer/assets/image/avatar.png'
|
||||
|
||||
const screenWidth = ref(document.documentElement.clientWidth || document.body.clientWidth)
|
||||
|
||||
const timer = ref(false);
|
||||
const domWidth = ref(document.body.clientWidth);
|
||||
const menuWidth = ref(document.body.clientWidth - 363);
|
||||
|
||||
watch(
|
||||
(screenWidth.value = () => {
|
||||
console.log("页面变化",document.body.clientWidth)
|
||||
// 为了避免频繁触发导致页面卡顿,使用定时器
|
||||
if (!timer.value) {
|
||||
if(domWidth.value != document.body.clientWidth){
|
||||
console.log("更新页面")
|
||||
domWidth.value = document.body.clientWidth
|
||||
menuWidth.value = document.body.clientWidth - 363
|
||||
}
|
||||
timer.value = true;
|
||||
setTimeout(function () {
|
||||
timer.value = false
|
||||
}, 200)
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<style scoped lang="scss">
|
||||
.el-header {
|
||||
width: 100%;
|
||||
background-color: #0066cc;
|
||||
color: var(--el-text-color-primary);
|
||||
justify-content: space-between;
|
||||
padding: 0;
|
||||
}
|
||||
.header-left{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 180px;
|
||||
img{
|
||||
width: 154px;
|
||||
height: 37px;
|
||||
}
|
||||
}
|
||||
.haeder-menu{
|
||||
width: calc(100% - 180px - 183px);
|
||||
overflow: hidden;
|
||||
:deep(.el-scrollbar__bar.is-vertical) {
|
||||
display: none;
|
||||
}
|
||||
:deep(a) {
|
||||
width: 100%;
|
||||
}
|
||||
.el-menu.el-menu--horizontal {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
background: #0066cc;
|
||||
border-bottom: none;
|
||||
.el-menu-item{
|
||||
color: #fff !important;
|
||||
width: 124px;
|
||||
font-size: 16px;
|
||||
border: none;
|
||||
text-indent: 10px;
|
||||
|
||||
&.is-active{
|
||||
background: #267dd4;
|
||||
position: relative;
|
||||
&:after{
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 22px;
|
||||
left: 20px;
|
||||
width: 5px;
|
||||
height: 16px;
|
||||
background: #fff;
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
&:not(.is-disabled):hover{
|
||||
background: #4c94db;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.haeder-right{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 165px;
|
||||
margin-right: 18px;
|
||||
.user-name{
|
||||
font-family: Source Han Sans CN;
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
.avatar-box{
|
||||
img{
|
||||
width: 54px;
|
||||
height: 54px;
|
||||
margin-bottom: -2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
right: 20px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.el-dropdown-menu__item {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.icon-color {
|
||||
color: white;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
<template>
|
||||
<el-container direction="vertical" style="min-height: 100vh;min-width: 100vw;overflow: hidden;">
|
||||
<Header></Header>
|
||||
<el-container style="padding: 10px 0">
|
||||
<Aside width="180px"></Aside>
|
||||
<el-main>
|
||||
<router-view v-slot="{ Component }">
|
||||
<keep-alive>
|
||||
<component :is="Component" />
|
||||
</keep-alive>
|
||||
</router-view>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// 组件注册
|
||||
import Header from '@renderer/layout/Header.vue'
|
||||
import Aside from '@renderer/layout/Aside.vue'
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
body{
|
||||
background-color: #eee;
|
||||
max-width: 100vw;
|
||||
}
|
||||
.el-container{
|
||||
/*padding: 10px 0;*/
|
||||
}
|
||||
.el-main {
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
height: 100vh;
|
||||
overflow-x: hidden;
|
||||
background: #fff;
|
||||
padding-right: 10px;
|
||||
}
|
||||
</style>
|
|
@ -1,13 +1,13 @@
|
|||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import HomeView from '@renderer/views/HomeView.vue'
|
||||
import Layout from '@renderer/layout/index.vue'
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
name: 'home',
|
||||
component: HomeView,
|
||||
path: '/system',
|
||||
name: 'system',
|
||||
component: Layout,
|
||||
redirect: {name: 'switch'},
|
||||
children:[
|
||||
{
|
||||
|
@ -37,8 +37,13 @@ const router = createRouter({
|
|||
keepAlive: true,
|
||||
}
|
||||
},
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/', // 这个是根路由,现在我们让它重定向到 /system
|
||||
redirect: '/system',
|
||||
},
|
||||
{ path: '/:pathMatch(.*)', redirect: '/' },
|
||||
]
|
||||
})
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
import { defineStore } from 'pinia'
|
||||
import config from '@renderer/util/config.js'
|
||||
|
||||
// 定义一个名为logWebSocketStore的store,用于管理WebSocket连接的状态和操作
|
||||
export const logWebSocketStore = defineStore('websocket', {
|
||||
state: () => ({
|
||||
websocket: null, // WebSocket实例
|
||||
connectURL: config.wsUrl + '/ws/log', // WebSocket连接的URL
|
||||
socket_open: false, // 标记WebSocket是否连接
|
||||
hearbeat_timer: null, // 心跳检测的定时器
|
||||
hearbeat_interval: 2 * 1000, // 心跳检测的间隔时间
|
||||
is_reonnect: true, // 是否尝试重新连接
|
||||
reconnect_count: 3, // 最大重连次数
|
||||
reconnect_current: 1, // 当前重连次数
|
||||
reconnect_timer: null, // 重连定时器
|
||||
reconnect_interval: 5 * 1000, // 重连间隔时间
|
||||
}),
|
||||
|
||||
actions: {
|
||||
// 初始化WebSocket连接
|
||||
init(overrideReceiveMessage) {
|
||||
let receiveMessage = overrideReceiveMessage || (() => {})
|
||||
// 检查浏览器是否支持WebSocket
|
||||
if (!('WebSocket' in window)) {
|
||||
this.$router.push({ name: 'ErrorPage', params: { error: '浏览器不支持WebSocket' } })
|
||||
return null
|
||||
}
|
||||
// 创建WebSocket实例并设置事件处理函数
|
||||
this.websocket = new WebSocket(this.connectURL)
|
||||
this.websocket.onmessage = (e) => {
|
||||
receiveMessage(e)
|
||||
}
|
||||
this.websocket.onclose = () => {
|
||||
console.log('socket连接关闭----------------------')
|
||||
this.socket_open = false
|
||||
// 尝试重新连接
|
||||
if (this.is_reonnect) {
|
||||
this.reconnect_timer = setTimeout(() => {
|
||||
if (this.reconnect_current > this.reconnect_count) {
|
||||
clearTimeout(this.reconnect_timer)
|
||||
this.is_reonnect = false
|
||||
return
|
||||
}
|
||||
console.log('socket重连次数:' + this.reconnect_current)
|
||||
this.reconnect_current++
|
||||
this.reconnect()
|
||||
}, this.reconnect_interval)
|
||||
}
|
||||
}
|
||||
this.websocket.onopen = () => {
|
||||
this.socket_open = true
|
||||
this.is_reonnect = true
|
||||
// this.heartbeat()
|
||||
}
|
||||
this.websocket.onerror = () => {}
|
||||
},
|
||||
|
||||
// 发送心跳包
|
||||
heartbeat() {
|
||||
this.hearbeat_timer && clearInterval(this.hearbeat_timer)
|
||||
this.hearbeat_timer = setInterval(() => {
|
||||
let data = {}
|
||||
this.send(data)
|
||||
}, this.hearbeat_interval)
|
||||
},
|
||||
|
||||
// 发送数据
|
||||
send(data, callback = null) {
|
||||
// 如果WebSocket连接已建立,则发送数据
|
||||
if (this.websocket.readyState === this.websocket.OPEN) {
|
||||
this.websocket.send(JSON.stringify(data))
|
||||
callback && callback()
|
||||
} else {
|
||||
// 如果WebSocket连接断开,则跳转到错误页面
|
||||
clearInterval(this.hearbeat_timer)
|
||||
this.$router.push({ name: 'ErrorPage', params: { error: 'socket链接已断开' } })
|
||||
}
|
||||
},
|
||||
|
||||
// 关闭WebSocket连接
|
||||
close() {
|
||||
this.is_reonnect = false
|
||||
this.websocket.close()
|
||||
},
|
||||
|
||||
// 重新连接WebSocket
|
||||
reconnect() {
|
||||
// 如果已存在WebSocket实例且不尝试重新连接,则关闭连接
|
||||
if (this.websocket && !this.is_reonnect) {
|
||||
this.close()
|
||||
}
|
||||
// 初始化WebSocket连接
|
||||
this.init()
|
||||
},
|
||||
},
|
||||
})
|
|
@ -1,7 +1,8 @@
|
|||
// // 手动配置的地址
|
||||
// // // 手动配置的地址
|
||||
// window.config = {
|
||||
// url: 'http://192.168.1.17:8000',
|
||||
// wsUrl: 'ws://192.168.1.17:8000',
|
||||
// ws1Url: 'ws://192.168.1.17:8001',
|
||||
// }
|
||||
|
||||
// 手动配置的地址
|
||||
|
@ -10,7 +11,21 @@
|
|||
// wsUrl: 'ws://127.0.0.1:8000',
|
||||
// }
|
||||
|
||||
// export default {
|
||||
// url: 'http://127.0.0.1:8000',
|
||||
// wsUrl: 'ws://127.0.0.1:8000'
|
||||
// }
|
||||
|
||||
export default {
|
||||
url: 'http://127.0.0.1:8000',
|
||||
wsUrl: 'ws://127.0.0.1:8000'
|
||||
wsUrl: 'ws://127.0.0.1:8000',
|
||||
swichWsUrl: 'ws://127.0.0.1:8001',
|
||||
}
|
||||
|
||||
|
||||
// 手动配置的地址
|
||||
// export default {
|
||||
// url: 'http://192.168.1.17:8000',
|
||||
// wsUrl: 'ws://192.168.1.17:8000',
|
||||
// swichWsUrl: 'ws://192.168.1.17:8001',
|
||||
// }
|
||||
|
|
|
@ -5,7 +5,7 @@ let receiveMessage = null
|
|||
import { reactive } from 'vue'
|
||||
const socket = reactive({
|
||||
websocket: null,
|
||||
connectURL: config.wsUrl + '/ws/log',
|
||||
connectURL: config.swichWsUrl + '/ws/log',
|
||||
// 开启标识
|
||||
socket_open: false,
|
||||
// 心跳timer
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div id="switch-box">
|
||||
<div class="switch-main">
|
||||
<div class="switch-main" id="switch-main" :class="isOpenLog?'open-log':''">
|
||||
<el-collapse v-model="activeFold" @change="foldChange">
|
||||
<el-collapse-item name="1" title="Mqtt设置">
|
||||
<el-form
|
||||
|
@ -103,13 +103,12 @@
|
|||
<el-input v-model="attrReadForm.deviceSN" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="10" class="text-center">
|
||||
<el-col :span="10" :offset="1" class="text-center">
|
||||
<el-form-item label="属性">
|
||||
<el-select
|
||||
v-model="attrReadForm.attrName"
|
||||
multiple
|
||||
placeholder="选择属性"
|
||||
style="width: 240px"
|
||||
@change="attrReadChange"
|
||||
>
|
||||
<el-option
|
||||
|
@ -121,7 +120,7 @@
|
|||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4" style="text-align: right">
|
||||
<el-col :span="3" style="text-align: right">
|
||||
<el-button type="primary" @click="addReadAttr">新增属性</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@ -163,13 +162,12 @@
|
|||
<el-input v-model="attrWriteForm.deviceSN" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="10" class="text-center">
|
||||
<el-col :span="10" :offset="1" class="text-center">
|
||||
<el-form-item label="属性">
|
||||
<el-select
|
||||
v-model="attrWriteForm.attrName"
|
||||
multiple
|
||||
placeholder="选择属性"
|
||||
style="width: 240px"
|
||||
@change="attrWriteChange"
|
||||
>
|
||||
<el-option
|
||||
|
@ -181,7 +179,7 @@
|
|||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4" style="text-align: right">
|
||||
<el-col :span="3" style="text-align: right">
|
||||
<el-button type="primary" @click="addWriteAttr">新增属性</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@ -202,7 +200,7 @@
|
|||
<el-input v-model="item.len" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="data">
|
||||
<el-input v-model="item.data" />
|
||||
</el-form-item>
|
||||
|
@ -284,42 +282,66 @@
|
|||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</div>
|
||||
<div class="log-box">
|
||||
<div class="log-box" id="log-box" :class="isOpenLog?'open-log':''">
|
||||
<div class="log-box-header">
|
||||
<div class="log-box-title">日志</div>
|
||||
<div class="log-box-operate">
|
||||
<view class="log-box-operate-item">
|
||||
<div>mqtt状态:</div>
|
||||
<div v-if="connectionState" style="color: #00ff78; display: flex; align-items: center">
|
||||
<div v-if="connectionState" style="color: #00A73C; display: flex; align-items: center">
|
||||
连接
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
style="color: red; display: flex; align-items: center"
|
||||
style="color: #FF3B2B; display: flex; align-items: center"
|
||||
@click="runMqtt(mqttFormRef)"
|
||||
>
|
||||
断连
|
||||
<el-icon>
|
||||
<Refresh />
|
||||
</el-icon>
|
||||
<span class="iconfont icon-icon_gengxin"></span>
|
||||
</div>
|
||||
</view>
|
||||
<view class="log-box-operate-item">
|
||||
<div>日志状态:</div>
|
||||
<div v-if="socketStatus" style="color: #00ff78; display: flex; align-items: center">
|
||||
<div v-if="socketStatus" style="color: #00A73C; display: flex; align-items: center">
|
||||
连接
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
style="color: #ff0000; display: flex; align-items: center"
|
||||
style="color: #FF3B2B; display: flex; align-items: center"
|
||||
@click="initSocket"
|
||||
>
|
||||
断连
|
||||
<el-icon>
|
||||
<Refresh />
|
||||
</el-icon>
|
||||
<span class="iconfont icon-icon_gengxin"></span>
|
||||
</div>
|
||||
</view>
|
||||
<!-- <view class="log-box-operate-item">-->
|
||||
<!-- <div>断路器状态:</div>-->
|
||||
<!-- <div v-if="switchSocketStatus" style="color: #00A73C; display: flex; align-items: center">-->
|
||||
<!-- 连接-->
|
||||
<!-- </div>-->
|
||||
<!-- <div-->
|
||||
<!-- v-else-->
|
||||
<!-- style="color: #FF3B2B; display: flex; align-items: center"-->
|
||||
<!-- @click="initSwitchSocket"-->
|
||||
<!-- >-->
|
||||
<!-- 断连-->
|
||||
<!-- <span class="iconfont icon-icon_gengxin"></span>-->
|
||||
<!-- </div>-->
|
||||
<!-- </view>-->
|
||||
<view class="log-box-operate-item" @click="toggleOpenLog">
|
||||
<el-tooltip
|
||||
v-if="isOpenLog"
|
||||
class="box-item"
|
||||
content="收缩日志"
|
||||
effect="dark"
|
||||
placement="bottom"
|
||||
>
|
||||
<span class="iconfont icon-up-arrow"></span>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-else class="box-item" content="展开日志" effect="dark" placement="bottom">
|
||||
<span class="iconfont icon-shousuoshangjiantou"></span>
|
||||
</el-tooltip>
|
||||
</view>
|
||||
<view class="log-box-operate-item" @click="toggleIsScroll">
|
||||
<el-tooltip
|
||||
v-if="isScroll"
|
||||
|
@ -328,47 +350,27 @@
|
|||
effect="dark"
|
||||
placement="bottom"
|
||||
>
|
||||
<el-icon>
|
||||
<Unlock />
|
||||
</el-icon>
|
||||
<span class="iconfont icon-unlock"></span>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-else class="box-item" content="开启滚动" effect="dark" placement="bottom">
|
||||
<el-icon>
|
||||
<Lock />
|
||||
</el-icon>
|
||||
<span class="iconfont icon-icon_suoding"></span>
|
||||
</el-tooltip>
|
||||
</view>
|
||||
<view class="log-box-operate-item" @click="clearLog">
|
||||
<el-icon>
|
||||
<DeleteFilled />
|
||||
</el-icon>
|
||||
<span class="iconfont icon-icon_shanchu"></span>
|
||||
</view>
|
||||
</div>
|
||||
</div>
|
||||
<div id="log-box-main" class="log-box-main">
|
||||
<div class="log-list">
|
||||
<div v-for="(item, index) in logList" :key="index" class="log-item">
|
||||
<p>{{ item.time }}</p>
|
||||
<el-icon
|
||||
v-if="item.type == 'subscribe'"
|
||||
style="color: #00ff78; font-weight: bold; margin-right: 8px"
|
||||
>
|
||||
<Top />
|
||||
</el-icon>
|
||||
<el-icon
|
||||
v-else-if="item.type == 'publish'"
|
||||
style="color: red; font-weight: bold; margin-right: 8px"
|
||||
>
|
||||
<Bottom />
|
||||
</el-icon>
|
||||
<el-icon v-else-if="item.type == 'system'" style="font-weight: bold; margin-right: 8px">
|
||||
<Message />
|
||||
</el-icon>
|
||||
<p>{{ item.msg }}</p>
|
||||
<span v-if="item.type == 'subscribe'" class="iconfont icon-icon_shanghang"></span>
|
||||
<span v-else-if="item.type == 'publish'" class="iconfont icon-icon_xiahang"></span>
|
||||
<span v-else-if="item.type == 'system'" class="iconfont icon-icon_xitong"></span>
|
||||
<span v-else class="iconfont icon-icon_xiaoxi"></span>
|
||||
{{ item.time }} {{ item.msg }}
|
||||
<el-tooltip class="box-item" content="复制" effect="dark" placement="bottom">
|
||||
<el-icon style="font-weight: bold; cursor: pointer" @click="copyMsg(item.msg)">
|
||||
<DocumentCopy />
|
||||
</el-icon>
|
||||
<span class="iconfont icon-icon_fuzhi" @click="copyMsg(item.msg)"></span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -384,9 +386,11 @@ import config from '@renderer/util/config.js'
|
|||
|
||||
import { reactive, ref, onMounted, computed, watch, onUnmounted } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import socket from '@renderer/util/socket.js'
|
||||
import switchSocket from '@renderer/util/socket.js'
|
||||
import { logWebSocketStore } from '@renderer/stores/logWebSocket.js'
|
||||
const webSocketStore = logWebSocketStore()
|
||||
|
||||
const activeFold = ref(['1'])
|
||||
const activeFold = ref(['1','3','4'])
|
||||
const logList = ref([])
|
||||
//连接状态
|
||||
const connectionState = ref(false)
|
||||
|
@ -399,6 +403,7 @@ const getGuid = () => {
|
|||
})
|
||||
}
|
||||
const isScroll = ref(true)
|
||||
const isOpenLog = ref(false)
|
||||
const mqttFormRef = ref()
|
||||
// const mqttForm = reactive({
|
||||
// clientId: '',
|
||||
|
@ -661,6 +666,7 @@ const testMqtt = (formEl) => {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
//运行
|
||||
const runMqtt = (formEl) => {
|
||||
if (!formEl) return
|
||||
|
@ -676,6 +682,10 @@ const runMqtt = (formEl) => {
|
|||
console.log(response) // 打印响应数据
|
||||
if (response.data.code == 0) {
|
||||
ElMessage.success('连接成功')
|
||||
if(!switchSocketStatus.value){
|
||||
initSwitchSocket()
|
||||
}
|
||||
|
||||
//缓存已成功连接
|
||||
localStorage.setItem('mqttForm', JSON.stringify(mqttForm))
|
||||
connectionState.value = true
|
||||
|
@ -720,6 +730,11 @@ const updateGateway = (formEl) => {
|
|||
//缓存上下行主题
|
||||
localStorage.setItem('gatewayForm', JSON.stringify(gatewayForm))
|
||||
ElMessage.success('更新成功')
|
||||
activeFold.value = activeFold.value.filter((item) => item !== '2')
|
||||
if (!activeFold.value.includes('3')) {
|
||||
// 如果没有,就在头部添加1
|
||||
activeFold.value.unshift('3')
|
||||
}
|
||||
} else {
|
||||
if (response.data.code == 60) {
|
||||
connectionState.value = false
|
||||
|
@ -996,7 +1011,6 @@ const getSocketMeassage = (message) => {
|
|||
if (isScroll.value) {
|
||||
setTimeout(() => {
|
||||
let div = document.querySelector('#log-box-main')
|
||||
console.log('div.scrollHeight', div.scrollHeight)
|
||||
div.scrollTop = div.scrollHeight
|
||||
}, 200)
|
||||
}
|
||||
|
@ -1017,18 +1031,32 @@ const toggleIsScroll = () => {
|
|||
isScroll.value = !isScroll.value
|
||||
}
|
||||
|
||||
const toggleOpenLog = () => {
|
||||
isOpenLog.value = !isOpenLog.value
|
||||
}
|
||||
|
||||
const initSocket = () => {
|
||||
socket.init(getSocketMeassage)
|
||||
webSocketStore.init(getSocketMeassage)
|
||||
}
|
||||
|
||||
const initSwitchSocket = () => {
|
||||
switchSocket.init(getSocketMeassage)
|
||||
}
|
||||
|
||||
// socket连接状态
|
||||
const socketStatus = computed(() => {
|
||||
return socket.socket_open
|
||||
return webSocketStore.socket_open
|
||||
})
|
||||
|
||||
// socket连接状态
|
||||
const switchSocketStatus = computed(() => {
|
||||
return switchSocket.socket_open
|
||||
})
|
||||
|
||||
// 生命周期钩子
|
||||
onMounted(() => {
|
||||
initSocket()
|
||||
|
||||
const storedMqttForm = localStorage.getItem('mqttForm')
|
||||
if (storedMqttForm) {
|
||||
Object.assign(mqttForm, JSON.parse(storedMqttForm))
|
||||
|
@ -1040,7 +1068,8 @@ onMounted(() => {
|
|||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
socket.close()
|
||||
webSocketStore.close()
|
||||
switchSocket.close()
|
||||
})
|
||||
</script>
|
||||
|
||||
|
@ -1049,28 +1078,41 @@ onUnmounted(() => {
|
|||
#switch-box {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
|
||||
padding-bottom: 5px;
|
||||
.switch-main {
|
||||
height: calc(100% - 200px - 60px);
|
||||
height: calc(100% - 188px - 60px);
|
||||
overflow-y: auto;
|
||||
border-radius: 10px;
|
||||
background: #f2f2f2;
|
||||
&.open-log{
|
||||
height: calc(50% - 42px);
|
||||
}
|
||||
}
|
||||
|
||||
.log-box {
|
||||
height: 200px;
|
||||
background: #0066cc;
|
||||
border: 1px solid #2d1ca9;
|
||||
color: #fff;
|
||||
|
||||
border-radius: 10px;
|
||||
height: 160px;
|
||||
margin-top: 10px;
|
||||
//border: 1px solid #2d1ca9;
|
||||
color: #333;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
&.open-log{
|
||||
height: calc(50% - 42px);
|
||||
}
|
||||
.log-box-header {
|
||||
height: 28px;
|
||||
padding: 0 10px;
|
||||
border-bottom: 1px solid #fff;
|
||||
height: 42px;
|
||||
padding: 0 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
line-height: 28px;
|
||||
background: #e6e6e6;
|
||||
font-family: Source Han Sans CN;
|
||||
color: #333333;
|
||||
|
||||
.log-box-operate {
|
||||
display: flex;
|
||||
|
@ -1087,19 +1129,40 @@ onUnmounted(() => {
|
|||
}
|
||||
|
||||
.log-box-main {
|
||||
padding: 10px;
|
||||
height: 169px;
|
||||
padding: 10px 30px;
|
||||
//height: 118px;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
background: #f2f2f2;
|
||||
line-height: 26px;
|
||||
|
||||
.log-item {
|
||||
font-size: 13px;
|
||||
user-select: text;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
//display: flex;
|
||||
//align-items: center;
|
||||
//flex-wrap: wrap;
|
||||
line-height: 26px;
|
||||
|
||||
font-weight: 500;
|
||||
margin-left: 8px;
|
||||
//.log-txt {
|
||||
// font-weight: 500;
|
||||
// margin-left: 8px;
|
||||
// display: inline-block;
|
||||
// word-wrap: break-word;
|
||||
// overflow-wrap: break-word;
|
||||
//}
|
||||
.iconfont{
|
||||
&.icon-icon_fuzhi{
|
||||
line-height: 26px;
|
||||
margin-left: 8px;
|
||||
font-size: 16px;
|
||||
color: #0066cc;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
> p {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1114,18 +1177,22 @@ onUnmounted(() => {
|
|||
}
|
||||
|
||||
:deep(.el-collapse-item__header) {
|
||||
background-color: #0066cc;
|
||||
color: #fff;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
text-indent: 10px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
//height: 42px;
|
||||
//line-height: 42px;
|
||||
}
|
||||
|
||||
:deep(.el-collapse-item__content) {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
:deep(.el-tabs__content) {
|
||||
background: #f2f2f2;
|
||||
}
|
||||
:deep(.el-tabs__item){
|
||||
background: #e6e6e6;
|
||||
&.is-active{
|
||||
background: #f2f2f2;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-box {
|
||||
:deep(.el-form-item__content) {
|
||||
|
|
Loading…
Reference in New Issue