소스 검색

fix: 兼容通道编辑数据不全的报错,优化服务检测页面显示

yanglzh 1 년 전
부모
커밋
e6f336d946

+ 6 - 0
README rule.md

@@ -7,5 +7,11 @@
 5. 表格高度
 6. 文件上传,图片上传 增加 source 字段
 7. 地图ak和地图中心电从参数中获取
+8. 多选反选
+9. 弹窗页面有table的用小table
+10. build 方式
+11. 本地启动说明 .local
+12. 部署说
+13. 图形显示
 多余log
 大页面分组件

+ 1 - 1
src/views/iot/iotmanager/dashboard.vue

@@ -46,7 +46,7 @@
 						<el-button size="small" text type="primary" @click="toMore()">更多信息</el-button>
 					</div>
 					<el-table :data="tableData.data" style="width: 100%" v-loading="loading">
-						<el-table-column label="ID" align="center" prop="id" width="60" v-col="'ID'" />
+						<el-table-column label="ID" align="center" prop="id" width="80" v-col="'ID'" />
 						<el-table-column label="告警类型" prop="type" :show-overflow-tooltip="true" v-col="'type'">
 							<template #default="scope">
 								<span v-if="scope.row.type == 1">规则告警</span>

+ 62 - 75
src/views/iot/network/tunnel/component/list.vue

@@ -1,53 +1,42 @@
 <template>
     <div>
         <el-table v-loading="loading" :data="data" style="width: 100%">
-            <el-table-column align="center" prop="id" v-col="'id'" label="ID" width="80"/>
-            <el-table-column align="center" prop="name" v-col="'name'" label="名称"/>
-            <el-table-column align="center" prop="types" v-col="'type'" label="类型" :formatter="(a:any) => typesFormat(a.types)"/>
-            <el-table-column align="center" prop="addr" v-col="'address'" label="地址"/>
-            <el-table-column show-overflow-tooltip align="center" v-col="'createTime'" prop="createdAt" label="创建时间" width="170"/>
+            <el-table-column align="center" prop="id" v-col="'id'" label="ID" width="80" />
+            <el-table-column align="center" prop="name" v-col="'name'" label="名称" />
+            <el-table-column align="center" prop="types" v-col="'type'" label="类型" :formatter="(a: any) => typesFormat(a.types)" />
+            <el-table-column align="center" prop="addr" v-col="'address'" min-width="120" label="地址" />
+            <el-table-column show-overflow-tooltip align="center" v-col="'createTime'" prop="createdAt" label="创建时间" width="170" />
             <el-table-column align="center" prop="types" v-col="'status'" label="状态">
                 <template #default="scope">
                     <el-tag size="medium" v-if="!scope.row.status" class="ml-2" type="info">未启动</el-tag>
                     <el-tag size="medium" v-else class="ml-2" type="success">启动</el-tag>
                 </template>
             </el-table-column>
-            <el-table-column align="center" label="操作" v-col="'auth'" width="200">
+            <el-table-column align="center" label="操作" v-col="'auth'" width="160">
                 <template #default="scope">
                     <el-button @click="toDetail(scope.row.id)" size="small" v-auth="'detail'" type="text">详情</el-button>
                     <el-button size="small" link key="info" type="info" v-auth="'edit'" @click="toEdit(scope.row.id)">编辑</el-button>
                     <el-popover placement="bottom" :width="160" trigger="click">
                         <template #reference>
-                            <el-button  size="small" type="text" v-auth="'more'" class="more-btn" @click="isShowMore = !isShowMore">更多
-                                <i style="margin-left: 2px;" :class="isShowMore ? 'fa fa-angle-down':'fa fa-angle-up'"></i>
+                            <el-button size="small" type="text" v-auth="'more'" class="more-btn" @click="isShowMore = !isShowMore">更多
+                                <i style="margin-left: 2px;" :class="isShowMore ? 'fa fa-angle-down' : 'fa fa-angle-up'"></i>
                             </el-button>
                         </template>
-                    <div class="more-opearte-wrap">
-                        <el-button @click="onChangeStatus(scope.row.id, 1)" :disabled="scope.row.status" v-auth="'on'" link size="small"  key="success" type="success">启 用</el-button>
-                        <el-divider direction="vertical" />
-                        <el-button @click="onChangeStatus(scope.row.id, 0)" :disabled="!scope.row.status" v-auth="'off'" link size="small" key="warning" type="warning">禁 用</el-button>
-                        <el-divider direction="vertical" />
-                        <el-button @click="onRowDel(scope.row)" link size="small" key="danger" v-auth="'off'" type="danger">删 除</el-button>
-                    </div>
+                        <div class="more-opearte-wrap">
+                            <el-button @click="onChangeStatus(scope.row.id, 1)" :disabled="scope.row.status" v-auth="'on'" link size="small" key="success" type="success">启 用</el-button>
+                            <el-divider direction="vertical" />
+                            <el-button @click="onChangeStatus(scope.row.id, 0)" :disabled="!scope.row.status" v-auth="'off'" link size="small" key="warning" type="warning">禁 用</el-button>
+                            <el-divider direction="vertical" />
+                            <el-button @click="onRowDel(scope.row)" link size="small" key="danger" v-auth="'off'" type="danger">删 除</el-button>
+                        </div>
                     </el-popover>
                 </template>
             </el-table-column>
         </el-table>
-        <el-pagination
-            @size-change="onHandleSizeChange"
-            @current-change="onHandleCurrentChange"
-            class="mt15"
-            :pager-count="5"
-            :page-sizes="[10, 20, 30, 50, 100, 200, 300, 500]"
-            v-model:current-page="param.page"
-            background
-            v-model:page-size="param.pageSize"
-            layout="total, sizes, prev, pager, next, jumper"
-            :total="total"
-        >
+        <el-pagination @size-change="onHandleSizeChange" @current-change="onHandleCurrentChange" class="mt15" :pager-count="5" :page-sizes="[10, 20, 30, 50, 100, 200, 300, 500]" v-model:current-page="param.page" background v-model:page-size="param.pageSize"
+            layout="total, sizes, prev, pager, next, jumper" :total="total">
         </el-pagination>
     </div>
-    
 </template>
 
 <script lang="ts">
@@ -59,13 +48,13 @@ import api from '/@/api/network';
 
 // 定义接口来定义对象的类型
 interface TableDataForm {
-	id: number;
+    id: number;
     server: string;
-	name: string;
-	
+    name: string;
+
 }
 interface TableData {
-	data:  Array<TableDataForm>;
+    data: Array<TableDataForm>;
     total: number;
     loading: boolean;
     param: {
@@ -77,12 +66,12 @@ interface TableData {
 
 export default defineComponent({
     name: 'tunnel',
-	props: {
-		// 输入框前置内容
-		keyWord: {
-			type: String,
-			default: '',
-		},
+    props: {
+        // 输入框前置内容
+        keyWord: {
+            type: String,
+            default: '',
+        },
     },
     setup(props, { emit }) {
 
@@ -96,7 +85,7 @@ export default defineComponent({
 
         const router = useRouter();
         const state = reactive<TableData>({
-			data: [],
+            data: [],
             total: 0,
             loading: false,
             param: {
@@ -104,28 +93,28 @@ export default defineComponent({
                 pageSize: 10,
             },
             isShowMore: true
-		});
+        });
         // 改变状态
         const onChangeStatus = (id: number, status: number) => {
-            api.tunnel.changeTunnelStatus({id: id, status: status}).then((res:any) => {
-		        ElMessage.success(status?'已开启':'已关闭');
+            api.tunnel.changeTunnelStatus({ id: id, status: status }).then((res: any) => {
+                ElMessage.success(status ? '已开启' : '已关闭');
                 fetchList();
             })
         };
         // 分页改变
-		const onHandleSizeChange = (val: number) => {
-			state.param.pageSize = val;
+        const onHandleSizeChange = (val: number) => {
+            state.param.pageSize = val;
             fetchList()
-		};
-		// 分页改变
-		const onHandleCurrentChange = (val: number) => {
-			state.param.page = val;
+        };
+        // 分页改变
+        const onHandleCurrentChange = (val: number) => {
+            state.param.page = val;
             fetchList()
-		};
+        };
         // 初始化表格数据
-		const initTableData = () => {
+        const initTableData = () => {
             fetchList()
-		};
+        };
         // 获取数据
         const fetchList = () => {
             state.loading = true
@@ -140,25 +129,25 @@ export default defineComponent({
                 state.total = total
                 state.param.page = page
                 state.loading = false
-			});
+            });
 
 
-		};
+        };
         // 删除
-		const onRowDel = (row: TableDataForm) => {
-			ElMessageBox.confirm(`此操作将永久删除“${row.name}”,是否继续?`, '提示', {
-				confirmButtonText: '确认',
-				cancelButtonText: '取消',
-				type: 'warning',
-			})
-				.then(() => {
-					api.tunnel.deleteItem({ids: [row.id]}).then((res: any) => {
-						fetchList()
-						ElMessage.success('删除成功');
-					});
-				})
-				.catch(() => {});
-		};
+        const onRowDel = (row: TableDataForm) => {
+            ElMessageBox.confirm(`此操作将永久删除“${row.name}”,是否继续?`, '提示', {
+                confirmButtonText: '确认',
+                cancelButtonText: '取消',
+                type: 'warning',
+            })
+                .then(() => {
+                    api.tunnel.deleteItem({ ids: [row.id] }).then((res: any) => {
+                        fetchList()
+                        ElMessage.success('删除成功');
+                    });
+                })
+                .catch(() => { });
+        };
         const toDetail = (id: number) => {
             router.push(`/iotmanager/network/tunnel/detail/${id}`)
         };
@@ -166,9 +155,9 @@ export default defineComponent({
             router.push(`/iotmanager/network/tunnel/edit/${id}`)
         };
         // 页面加载时
-		onMounted(() => {
-			initTableData();
-		});
+        onMounted(() => {
+            initTableData();
+        });
         return {
             fetchList,
             toDetail,
@@ -188,11 +177,9 @@ export default defineComponent({
 ::v-deep div.more-opearte-wrap {
     flex-direction: row;
     background-color: pink;
+
     // padding: 4px!important;
-    div {
-       
-    }
-    
+    div {}
+
 }
-    
 </style>

+ 8 - 6
src/views/iot/network/tunnel/edit.vue

@@ -208,14 +208,16 @@ export default defineComponent({
                 state.form['types'] = types
                 state.form['addr'] = addr
                 state.form['status'] = status
-                state.form['serial'] = JSON.parse(serial)
-                state.form['retry'] = JSON.parse(retry)
-                state.form['heartbeat'] = JSON.parse(heartbeat)
+                state.form['serial'] = JSON.parse(serial || '{}')
+                state.form['retry'] = JSON.parse(retry || '{}')
+                state.form['heartbeat'] = JSON.parse(heartbeat || '{}')
                 state.form['protoccol'] = protoccol ? JSON.parse(protoccol) : { name: "Modbus RTU", options: {} }
                 state.form['id'] = id
-                let jsonData = JSON.stringify(JSON.parse(protoccol).options);
-                state.resourceModalPro.content = JSON.stringify(JSON.parse(jsonData), null, 4);
-                mirrorRef.value.setValue(state.resourceModalPro.content);
+                if (protoccol) {
+                    let jsonData = JSON.stringify(JSON.parse(protoccol).options)
+                    state.resourceModalPro.content = JSON.stringify(JSON.parse(jsonData), null, 4);
+                    mirrorRef.value.setValue(state.resourceModalPro.content);
+                }
             })
         };
         onMounted(() => {

+ 145 - 34
src/views/system/monitor/server/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="system-user-container">
+  <div class="system-user-container" v-loading="loading">
     <div class="flex-row gap-3">
       <el-col :xs="24" :sm="12" :md="8" class="marg-b-15">
         <el-card class="box-card-meter">
@@ -225,7 +225,7 @@
 </template>
 
 <script lang="ts">
-import { toRefs, reactive, onMounted, getCurrentInstance, defineComponent } from 'vue';
+import { ref, toRefs, reactive, onMounted, getCurrentInstance, defineComponent } from 'vue';
 import * as echarts from 'echarts';
 import 'echarts-wordcloud';
 import dayjs from 'dayjs';
@@ -237,10 +237,11 @@ export default defineComponent({
   setup() {
     const { proxy } = getCurrentInstance() as any;
     const state: any = reactive({
-      myCharts: [],
       sysInfo: {},
     });
 
+    const loading = ref(true)
+
     let myChart1: any;
     let myChart2: any;
     let myChart3: any;
@@ -272,11 +273,13 @@ export default defineComponent({
     function goInfo(event: { data: any; }) {
       const data = JSON.parse(event.data);
       Object.assign(goInfoData, data);
+      loading.value = false
     }
 
     function hostInfo(event: { data: any; }) {
       const data = JSON.parse(event.data);
       Object.assign(hostData, data);
+      loading.value = false
     }
 
     const myChart4Data: any = {
@@ -297,14 +300,15 @@ export default defineComponent({
         trigger: 'axis',
       },
       grid: {
-        top: 10,
-        bottom: 20,
-        left: 10,
-        right: 10,
+        top: 5,
+        bottom: 5,
+        left: 5,
+        right: 30,
         containLabel: true
       },
       xAxis: {
         type: 'category',
+        boundaryGap: false,
         splitLine: {
           show: false
         }
@@ -312,6 +316,9 @@ export default defineComponent({
       yAxis: {
         type: 'value',
         boundaryGap: [0, '100%'],
+        axisLabel: {
+          formatter: '{value}%'
+        },
         splitLine: {
           show: false
         }
@@ -321,7 +328,12 @@ export default defineComponent({
           name: '使用率',
           type: 'line',
           showSymbol: false,
-          data: []
+          data: [],
+          smooth: true,
+          lineStyle: {
+            width: 0
+          },
+          areaStyle: {}
         }
       ]
     };
@@ -371,6 +383,10 @@ export default defineComponent({
     function setOptChart(myChart: any, myChartData: any, value: number) {
       myChartData.name.push(dayjs().format('HH:mm:ss'));
       myChartData.value.push(value);
+      if (myChartData.name.length > 20) {
+        myChartData.name.shift()
+        myChartData.value.shift()
+      }
       myChart.setOption({
         xAxis: {
           data: myChartData.name
@@ -402,8 +418,9 @@ export default defineComponent({
               offsetCenter: [-2, '30%'], //设置表盘title(今日预计用电量)位置
             },
             axisLine: {
-              show: true,
               lineStyle: {
+                show: true,
+                with: 25,
                 // 属性lineStyle控制线条样式
                 color: [
                   [0.3, '#4dabf7'],
@@ -413,6 +430,27 @@ export default defineComponent({
                 ],
               },
             },
+            axisTick: {
+              distance: 0,
+              length: 4,
+              lineStyle: {
+                color: 'auto',
+                width: 1
+              }
+            },
+            axisLabel: {
+              distance: 12,
+              color: '#000',
+              fontSize: 12
+            },
+            splitLine: { // 分割线
+              length: 5,
+              distance: 2,
+              lineStyle: {
+                width: 1,
+                color: 'auto'
+              }
+            },
             splitNumber: 5, //分割线之间的刻度
 
             detail: {
@@ -434,7 +472,6 @@ export default defineComponent({
         ],
       };
       myChart1.setOption(option);
-      state.myCharts.push(myChart1);
     };
     //内存
     const initChartRAM = () => {
@@ -455,8 +492,9 @@ export default defineComponent({
               offsetCenter: [-2, '30%'], //设置表盘title(今日预计用电量)位置
             },
             axisLine: {
-              show: true,
               lineStyle: {
+                show: true,
+                with: 25,
                 // 属性lineStyle控制线条样式
                 color: [
                   [0.3, '#4dabf7'],
@@ -466,6 +504,27 @@ export default defineComponent({
                 ],
               },
             },
+            axisTick: {
+              distance: 0,
+              length: 4,
+              lineStyle: {
+                color: 'auto',
+                width: 1
+              }
+            },
+            axisLabel: {
+              distance: 12,
+              color: '#000',
+              fontSize: 12
+            },
+            splitLine: { // 分割线
+              length: 5,
+              distance: 2,
+              lineStyle: {
+                width: 1,
+                color: 'auto'
+              }
+            },
             splitNumber: 5, //分割线之间的刻度
 
             detail: {
@@ -487,7 +546,6 @@ export default defineComponent({
         ],
       };
       myChart2.setOption(option);
-      state.myCharts.push(myChart2);
     };
     //磁盘
     const initChartDISK = () => {
@@ -508,8 +566,9 @@ export default defineComponent({
               offsetCenter: [-2, '30%'], //设置表盘title(今日预计用电量)位置
             },
             axisLine: {
-              show: true,
               lineStyle: {
+                show: true,
+                with: 25,
                 // 属性lineStyle控制线条样式
                 color: [
                   [0.3, '#4dabf7'],
@@ -519,6 +578,27 @@ export default defineComponent({
                 ],
               },
             },
+            axisTick: {
+              distance: 0,
+              length: 4,
+              lineStyle: {
+                color: 'auto',
+                width: 1
+              }
+            },
+            axisLabel: {
+              distance: 12,
+              color: '#000',
+              fontSize: 12
+            },
+            splitLine: { // 分割线
+              length: 5,
+              distance: 2,
+              lineStyle: {
+                width: 1,
+                color: 'auto'
+              }
+            },
             splitNumber: 5, //分割线之间的刻度
 
             detail: {
@@ -540,28 +620,63 @@ export default defineComponent({
         ],
       };
       myChart3.setOption(option);
-      state.myCharts.push(myChart3);
     };
 
     //cpu运行状态
     const initChartCPURun = () => {
       myChart4 = echarts.init(proxy.$refs.chartsWarningRef4);
-      myChart4.setOption({ ...moveOption });
-      state.myCharts.push(myChart4);
+      moveOption.series[0].areaStyle = {
+        opacity: 0.8,
+        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+          {
+            offset: 0,
+            color: 'rgb(128, 255, 165)'
+          },
+          {
+            offset: 1,
+            color: 'rgb(1, 191, 236)'
+          }
+        ])
+      }
+      myChart4.setOption(moveOption);
     };
 
     //内存运行状态
     const initChartRAMRun = () => {
       myChart5 = echarts.init(proxy.$refs.chartsWarningRef5);
-      myChart5.setOption({ ...moveOption });
-      state.myCharts.push(myChart5);
+      moveOption.series[0].areaStyle = {
+        opacity: 0.8,
+        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+          {
+            offset: 0,
+            color: 'rgb(0, 221, 255)'
+          },
+          {
+            offset: 1,
+            color: 'rgb(77, 119, 255)'
+          }
+        ])
+      }
+      myChart5.setOption(moveOption);
     };
 
     //磁盘运行状态
     const initChartDISKRun = () => {
       myChart6 = echarts.init(proxy.$refs.chartsWarningRef6);
-      myChart6.setOption({ ...moveOption });
-      state.myCharts.push(myChart6);
+      moveOption.series[0].areaStyle = {
+        opacity: 0.8,
+        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+          {
+            offset: 0,
+            color: 'rgb(55, 162, 255)'
+          },
+          {
+            offset: 1,
+            color: 'rgb(116, 21, 219)'
+          }
+        ])
+      }
+      myChart6.setOption(moveOption);
     };
 
     // 页面加载时
@@ -575,17 +690,6 @@ export default defineComponent({
     });
 
     function startWs() {
-      // ws = null;
-      // ws = new WebSocket(import.meta.env.VITE_WS_URL + '/monitorServer/ws');
-      // ws.onopen = () => {};
-      // ws.onmessage = ({ data: dataStr }) => {
-      // 	const data = JSON.parse(dataStr);
-      // 	state.sysInfo = data;
-      // 	setOptChart1(data.cpuUsed);
-      // 	setOptChart2(data.memUsage);
-      //   setOptChart3(data.diskUsedPercent);
-      // };
-
       const es = new EventSource(getOrigin(import.meta.env.VITE_SERVER_URL + "/subscribe/sysenv"));
 
       es.addEventListener("host", displayHost);
@@ -606,6 +710,7 @@ export default defineComponent({
       state.sysInfo.sysComputerName = data.hostname
       state.sysInfo.goStartTime = data.bootTime
       state.sysInfo.goRunTime = data.uptime
+      loading.value = false
     }
 
     function displayMem(event: { data: any; }) {
@@ -617,23 +722,27 @@ export default defineComponent({
       state.sysInfo.goUsed = data.goUsed
       state.sysInfo.memUsage = data.usedPercent.toFixed(2)
       setOptChart(myChart5, myChart5Data, state.sysInfo.memUsage);
-
+      loading.value = false
     }
 
     function displayCpu(event: { data: any; }) {
       const data = JSON.parse(event.data);
+      // console.log(dayjs().format('HH:mm:ss'))
+      // console.log(data)
+
       state.sysInfo.cpuNum = data.Number
       state.sysInfo.cpuCores = data.Cores
       state.sysInfo.cpuUsed = data.UsedPercent[0].toFixed(2)
       setOptChart1(data.UsedPercent[0].toFixed(2));
       setOptChart(myChart4, myChart4Data, state.sysInfo.cpuUsed);
+      loading.value = false
     }
 
     function displaySysLoad(event: { data: any; }) {
       const data = JSON.parse(event.data)
       state.sysInfo.cpuAvg5 = data.load5.toFixed(2)
       state.sysInfo.cpuAvg15 = data.load15.toFixed(2)
-
+      loading.value = false
     }
 
     function displayDisk(event: { data: any; }) {
@@ -643,7 +752,7 @@ export default defineComponent({
       state.sysInfo.diskUsedPercent = data.usedPercent.toFixed(2)
       setOptChart3(data.usedPercent.toFixed(2));
       setOptChart(myChart6, myChart6Data, state.sysInfo.diskUsedPercent);
-
+      loading.value = false
     }
 
 
@@ -661,6 +770,7 @@ export default defineComponent({
       ...toRefs(state),
       goInfoData,
       hostData,
+      loading,
       setOptChart1,
       setOptChart2,
       setOptChart3,
@@ -690,6 +800,7 @@ export default defineComponent({
   },
   methods: {
     memorySizeFormat(size: any) {
+      if (size === null || size === undefined) return ''
       size = parseFloat(size);
       let rank = 0;
       let rankchar = 'Bytes';