From b9bd29a1a81f6f7de479e3cc3fdfe3d85fc660bf Mon Sep 17 00:00:00 2001
From: he wei <858544502@qq.com>
Date: 星期三, 23 四月 2025 13:35:06 +0800
Subject: [PATCH] UA 整理提交

---
 src/views/device/realtime/index.vue |  582 +++++++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 451 insertions(+), 131 deletions(-)

diff --git a/src/views/device/realtime/index.vue b/src/views/device/realtime/index.vue
index 83fdcbd..0f806db 100644
--- a/src/views/device/realtime/index.vue
+++ b/src/views/device/realtime/index.vue
@@ -1,111 +1,300 @@
 <script setup name="Realtime">
-	import { ref, onMounted, reactive, computed, watchEffect } from "vue";
-	import lockRecord from "./lockRecord.vue";
-	import useWebSocket from "@/hooks/useWebsocket.js";
+import { ref, onMounted, reactive, watch, computed, watchEffect, onActivated } from "vue";
+import lockRecord from "./lockRecord.vue";
+import useWebSocket from "@/hooks/useWebsocket.js";
+import stationList from '@/components/stationList.vue';
+import useElement from "@/hooks/useElement.js";
+import { useRouter, useRoute } from "vue-router";
+const router = useRouter();
+const route = useRoute();
 
-	import useElement from "@/hooks/useElement.js";
+import settings from './settings.vue';
 
-	const { $loading, $message, $confirm } = useElement();
-	const { sendData, message: listMessage } = useWebSocket("real");
+import { storeToRefs } from "pinia";
+import { getStationBaojiInfo } from "@/api/station.js";
 
-	const currentAreaId = ref();
-	const tableData = ref([]);
-	const pageNum = ref(1);
-	const pageSize = ref(10);
-	const total = ref(0);
-	const offline_num = ref(0);
-	const online_num = ref(0);
-	const sum = ref(0);
-	const open_num = ref(0);
-	const close_num = ref(0);
-	const unLoad_num = ref(0);
-	const recordVisible = ref(false);
-	const recordTitle = ref('寮�鍚叧闂褰�');
-	const currLockId = ref();
+import { useUserStore } from '@/store/user.js';
+const userStore = useUserStore();
+const { urole, permits } = storeToRefs(userStore);
 
-	function itemClickHandler(item) {
-		// console.log(item, '====item', item.data);
-		// areaId lockName lockState lockType pageNum pageSize
-		currentAreaId.value = item.data.id;
-		sendMessage();
+import isHasPermit from '@/utils/isHasPermit';
+import {
+	lockOpen,
+	openLockBl,
+	closeLockBl,
+} from '@/api/lockManager.js';
+import svgStation from '@/components/svg/svgStation.vue';
+
+// 鏄惁鏈夋帶鍒舵潈闄�
+let isCanControl = isHasPermit("control_permit", permits.value);
+
+const { $loading, $message, $confirm, $confirmPwdDo } = useElement();
+const { sendData, message: listMessage } = useWebSocket("real");
+
+const baojiId = ref();
+const stationId = ref();
+const tableData = ref([]);
+const pageNum = ref(1);
+const pageSize = ref(10);
+const total = ref(0);
+const offline_num = ref(0);
+const online_num = ref(0);
+const sum = ref(0);
+const open_num = ref(0);
+const close_num = ref(0);
+const unLoad_num = ref(0);
+const recordVisible = ref(false);
+const recordTitle = ref('寮�鍚叧闂褰�');
+const currLockId = ref();
+const queryFlag = ref(0);
+const activeName = ref('topology');
+const settingsVisible = ref(false);
+
+function itemClickHandler(item) {
+	console.log(item, '====item', item);
+	const [_baojiId, _stationId] = item.id.split('-');
+	// TODO
+	// areaId lockName lockState lockType pageNum pageSize
+	baojiId.value = _baojiId;
+	stationId.value = _stationId;
+	getStationInfo();
+	sendMessage();
+}
+
+const stationName = ref('');
+const locationInfo = ref();
+
+watchEffect(() => {
+	let _total = 0;
+	if (listMessage.value) {
+		let {
+			pageInfo,
+			offLineNum,
+			unLoadNum,
+			sumLinf,
+			openNum,
+			onlineNum,
+			closeNum
+		} = JSON.parse(listMessage.value)?.data2;
+
+    let control = JSON.parse(listMessage.value)?.data3 || [];
+    let all = JSON.parse(listMessage.value)?.data4 || [];
+
+    locationInfo.value = {
+      control,
+      all
+    };
+
+		offline_num.value = offLineNum;
+		online_num.value = onlineNum;
+		sum.value = sumLinf;
+		open_num.value = openNum;
+		close_num.value = closeNum;
+		unLoad_num.value = unLoadNum;
+
+		_total = pageInfo.total;
+		tableData.value = pageInfo.list.map(v => ({
+			...v,
+			onlineState: ['绂荤嚎', '鍦ㄧ嚎'][v.lockOnline],
+			state: { 0: '宸查棴閿�', 1: '宸插紑閿�' }[v.lockState],
+			onlineState: { 0: '绂荤嚎', 1: '鍦ㄧ嚎' }[v.lockOnline],
+			modelStr: v.model == 1 ? '鍦ㄧ嚎妯″紡' : '绂荤嚎妯″紡',
+			blStateStr: v.blState == 0 ? '钃濈墮鍏抽棴' : '钃濈墮寮�鍚�',
+			openTime: v.lockState == 1 ? v.lastUpdateTime : '--',
+			closeTime: v.lockState == 0 ? v.lastUpdateTime : '--',
+		}));
 	}
 
-	watchEffect(() => {
-    let _total = 0;
-		if (listMessage.value) {
-			let {
-				pageInfo,
-				offLineNum,
-				unLoadNum,
-				sumLinf,
-				openNum,
-				onlineNum,
-				closeNum
-			} = JSON.parse(listMessage.value)?.data2;
+	total.value = _total;
+});
 
-			offline_num.value = offLineNum;
-			online_num.value = onlineNum;
-			sum.value = sumLinf;
-			open_num.value = openNum;
-			close_num.value = closeNum;
-			unLoad_num.value = unLoadNum;
-
-      _total = pageInfo.total;
-			tableData.value = pageInfo.list.map(v => ({
-				...v,
-				onlineState: ['绂荤嚎', '鍦ㄧ嚎'][v.lockOnline],
-				state: { '-1': '鏈畨瑁�', 0: '宸查棴閿�', 1: '宸插紑閿�' }[v.lockState],
-				openTime: v.lockState == 1 ? v.lastUpdateTime : '--',
-				closeTime: v.lockState == 0 ? v.lastUpdateTime : '--',
-			}));
+function getStationInfo() {
+	getStationBaojiInfo({
+		baojiId: baojiId.value,
+		stationId: stationId.value
+	}).then((res) => {
+		let { code, data, data2, data3 } = res;
+		if (code && data) {
+			console.log(data);
+			stationName.value = data2.stationName + ' ' + data3.baojiName;
 		}
+	})
+		.catch((err) => {
+			console.log(err);
+		});
 
-    total.value = _total;
+}
+
+function open(scope) {
+	console.log('scope', scope, '=============');
+	let {
+		row
+	} = scope;
+
+	$confirmPwdDo(() => {
+		let loading = $loading();
+		lockOpen(scope.row.lockId).then((res) => {
+			let { code, data } = res;
+			loading.close();
+			if (code && data) {
+				$message.success("鎿嶄綔鎴愬姛");
+				sendMessage();
+			} else {
+				$message.error("鎿嶄綔澶辫触");
+			}
+		})
+			.catch((err) => {
+				console.log(err);
+				loading.close();
+			});
+
+	});
+}
+
+function viewRecord(data) {
+	console.log(data, '999999999999-------');
+	let { row } = data;
+	// recordTitle.value = `寮�鍚叧闂褰� - ${row.areaPath} ${row.lockName}`;
+	// currLockId.value = row.lockId;
+	// recordVisible.value = true;
+	router.push({
+		path: '/device/history',
+		query: {
+			stationId: stationId.value,
+			baojiId: baojiId.value,
+			lockId: row.lockId,
+			flag: Math.random()
+		}
 	});
 
-	function test() {
+}
 
-	}
+function sendMessage() {
+	let params = {
+		stationId: stationId.value,
+		baojiId: baojiId.value,
+		pageNum: pageNum.value,
+		pageSize: pageSize.value,
+	};
+	sendData(JSON.stringify(params));
+}
+function handleSizeChange(val) {
+	pageSize.value = val;
+	sendMessage();
+}
 
-	function viewRecord(data) {
-		console.log(data);
-		let { row } = data;
-		recordTitle.value = `寮�鍚叧闂褰� - ${row.areaPath} ${row.lockName}`;
-		currLockId.value = row.lockId;
-		recordVisible.value = true;
-	}
+function handleCurrentChange(val) {
+	pageNum.value = val;
+	sendMessage();
+}
 
-	function sendMessage() {
-		let params = {
-			areaId: currentAreaId.value,
-			pageNum: pageNum.value,
-			pageSize: pageSize.value,
-		};
-		sendData(JSON.stringify(params));
-	}
-	function handleSizeChange(val) {
-		pageSize.value = val;
-		sendMessage();
-	}
+function openBl(scope) {
+  $confirmPwdDo(() => {
+    let loading = $loading();
+    openLockBl(
+      scope.row.lockId
+    ).then((res) => {
+      let { code, data } = res;
+      loading.close();
+      if (code && data) {
+        console.log(data);
+        $message.success("鎿嶄綔鎴愬姛");
+        sendMessage();
+      } else {
+        $message.error("鎿嶄綔澶辫触");
+      }
+    })
+      .catch((err) => {
+        loading.close();
+        console.log(err);
+      });
+  });
+}
 
-	function handleCurrentChange(val) {
-		pageNum.value = val;
-		sendMessage();
+function closeBl(scope) {
+  $confirmPwdDo(() => {
+    let loading = $loading();
+    closeLockBl(
+      scope.row.lockId
+    ).then((res) => {
+      let { code, data } = res;
+      loading.close();
+      if (code && data) {
+        console.log(data);
+        $message.success("鎿嶄綔鎴愬姛");
+        sendMessage();
+      } else {
+        $message.error("鎿嶄綔澶辫触");
+      }
+    })
+      .catch((err) => {
+        loading.close();
+        console.log(err);
+      });
+  });
+}
+
+function goHistory() {
+	router.push({
+		path: '/device/history',
+		query: {
+			stationId: stationId.value,
+			baojiId: baojiId.value,
+			flag: Math.random()
+		}
+	})
+}
+
+const tree = ref(null);
+
+function settingsOk() {
+  settingsVisible.value = false;
+  sendMessage();
+}
+
+onActivated(() => {
+	if (queryFlag.value == route.query.flag) {
+		return;
 	}
+	queryFlag.value = route.query.flag || 0;
+	if (route.query.stationId && route.query.baojiId) {
+		baojiId.value = route.query.baojiId;
+		stationId.value = route.query.stationId;
+
+		tree.value.setCurrent(baojiId.value + '-' + stationId.value);
+	}
+	console.log('baojiId, stationId', baojiId.value, stationId.value, '=============real');
+
+})
 </script>
 
 <template>
   <div class="page-wrapper">
     <div class="page-header">
       <div class="hdw-card-container">
-        <hdw-card title="鍖哄煙鍒楄〃" is-full>
-          <hdw-tree @item-click="itemClickHandler"></hdw-tree>
-        </hdw-card>
+        <yc-card title="鍖哄煙鍒楄〃" is-full>
+          <hdw-tree ref="tree" @item-click="itemClickHandler"></hdw-tree>
+        </yc-card>
       </div>
     </div>
     <div class="page-content">
-      <hdw-card is-full>
+      <yc-card is-full>
         <div class="page-content-wrapper">
+          <div class="p-title">
+            {{ stationName }}
+            <div class="btn-grp">
+              <el-tooltip
+                class="item"
+                effect="dark"
+                content="鍘嗗彶鏁版嵁"
+                placement="bottom"
+              >
+                <div class="btn" @click="goHistory">
+                  <svg-icon icon-class="history"></svg-icon>
+                </div>
+              </el-tooltip>
+            </div>
+          </div>
           <div class="page-content-tools">
             <div class="item">
               <div class="label">璁惧鎬绘暟閲�</div>
@@ -119,10 +308,10 @@
               <div class="label">绂荤嚎鏁伴噺</div>
               <div class="value">{{ offline_num }}</div>
             </div>
-            <div class="item">
+            <!-- <div class="item">
               <div class="label">鏈畨瑁呮暟閲�</div>
               <div class="value">{{ unLoad_num }}</div>
-            </div>
+            </div> -->
             <div class="item">
               <div class="label">宸插紑閿�</div>
               <div class="value">{{ open_num }}</div>
@@ -132,56 +321,121 @@
               <div class="value">{{ close_num }}</div>
             </div>
           </div>
-          <div class="page-content-table">
-            <div class="pos-rel">
-              <div class="pos-abs">
-                <el-table stripe :data="tableData" border style="width: 100%; height: 100%">
-                  <el-table-column type="index" width="50" />
-                  <el-table-column prop="lockId" label="閿佸叿ID" width="180" />
-                  <el-table-column prop="lockName" label="閿佸叿鍚嶇О" width="180" />
-                  <el-table-column prop="areaPath" label="鍏宠仈鍖哄煙" />
-                  <el-table-column prop="onlineState" label="鍦ㄧ嚎鐘舵��" width="180" />
-                  <el-table-column prop="state" label="鐘舵��" width="180" />
-                  <el-table-column prop="openTime" label="寮�鍚椂闂�" width="180" />
-                  <el-table-column prop="closeTime" label="鍏抽棴鏃堕棿" width="180" />
-                  <el-table-column align="center" fixed="right" label="鎿嶄綔" width="200">
-                    <template #default="scope">
-                      <el-button type="primary" size="small" :disabled="scope.row.lockState == -1"
-                        @click="viewRecord(scope)">鍘嗗彶寮�鍚叧闂褰�</el-button>
-                    </template>
-                  </el-table-column>
-                </el-table>
+          <el-tabs type="border-card" v-model="activeName" class="tabs">
+            <el-tab-pane name="topology" label="鎷撴墤鍥�">
+              <div class="btn-settings" title="閰嶇疆" @click="settingsVisible = true"></div>
+              <svg-station :rtData="tableData" :locationInfo="locationInfo" class="svg-station"></svg-station>
+            </el-tab-pane>
+            <el-tab-pane name="list" label="鍒楄〃">
+              <div class="page-content-table">
+                <div class="pos-rel">
+                  <div class="pos-abs">
+                    <el-table
+                      stripe
+                      :data="tableData"
+                      border
+                      style="width: 100%; height: 100%"
+                    >
+                      <el-table-column type="index" fixed="left" width="50" />
+                      <el-table-column prop="lockId" label="閿佸叿ID" width="180" />
+                      <el-table-column
+                        prop="lockName"
+                        label="閿佸叿鍚嶇О"
+                        width="180"
+                      />
+                      <el-table-column
+                        prop="onlineState"
+                        label="鍦ㄧ嚎鐘舵��"
+                        width="180"
+                      />
+                      <el-table-column
+                        prop="blStateStr"
+                        label="钃濈墮鐘舵��"
+                        width="180"
+                      />
+                      <el-table-column prop="state" label="鐘舵��" width="180" />
+                      <el-table-column
+                        prop="openTime"
+                        label="寮�鍚椂闂�"
+                        width="180"
+                      />
+                      <el-table-column
+                        prop="closeTime"
+                        label="鍏抽棴鏃堕棿"
+                        width="180"
+                      />
+                      <el-table-column
+                        align="center"
+                        fixed="right"
+                        label="鎿嶄綔"
+                        width="320"
+                      >
+                        <template #default="scope">
+                          <el-button
+                            type="danger"
+                            size="small"
+                            v-if="isCanControl && scope.row.lockOnline == 1 && scope.row.lockState == 0"
+                            @click="open(scope)"
+                            >杩滅▼寮�閿�</el-button
+                          >
+                          <el-button
+                            type="primary"
+                            v-if="isCanControl && scope.row.lockOnline == 1 && scope.row.blState == 0"
+                            size="small"
+                            @click="openBl(scope)"
+                            >寮�鍚摑鐗�</el-button
+                          >
+                          <el-button
+                            type="primary"
+                            v-if="isCanControl &&  scope.row.lockOnline == 1 && scope.row.blState == 1"
+                            size="small"
+                            @click="closeBl(scope)"
+                            >鍏抽棴钃濈墮</el-button
+                          >
+                          <el-button
+                            type="primary"
+                            size="small"
+                            :disabled="scope.row.lockState == -1"
+                            @click="viewRecord(scope)"
+                            >鍘嗗彶寮�鍚叧闂褰�</el-button
+                          >
+                        </template>
+                      </el-table-column>
+                    </el-table>
+                  </div>
+                </div>
               </div>
-            </div>
-          </div>
-          <div class="page-content-page">
-            <div class="page-tool"></div>
-            <div class="el-page-container">
-              <el-pagination v-model:current-page="pageNum" v-model:page-size="pageSize"
-                :page-sizes="[10,20, 40, 60, 80, 100, 200, 300, 400]" size="small"
-                layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handleSizeChange"
-                @current-change="handleCurrentChange" />
-            </div>
-            <div class="page-tool"></div>
-          </div>
+              <div class="page-content-page">
+                <div class="page-tool"></div>
+                <div class="el-page-container">
+                  <el-pagination
+                    v-model:current-page="pageNum"
+                    v-model:page-size="pageSize"
+                    :page-sizes="[10,20, 40, 60, 80, 100, 200, 300, 400]"
+                    size="small"
+                    layout="total, sizes, prev, pager, next, jumper"
+                    :total="total"
+                    @size-change="handleSizeChange"
+                    @current-change="handleCurrentChange"
+                  />
+                </div>
+                <div class="page-tool"></div>
+              </div>
+            </el-tab-pane>
+          </el-tabs>
         </div>
-      </hdw-card>
+      </yc-card>
     </div>
     <div class="page-footer"></div>
-    <!-- 缂栬緫 鏂板缓 -->
-    <el-dialog v-model="addEditVisible" :title="addEditTitle" width="500" align-center :close-on-click-modal="false">
-      <add-edit v-if="addEditVisible" :isBatch="isBatch" :info="editLock" :isAdd="isAdd" @close="addEditVisible = false"
-        @ok="okHandle"></add-edit>
-    </el-dialog>
-    <!-- 寮�闂攣璁板綍 -->
-    <el-dialog class="dialog-record" v-model="recordVisible" :close-on-click-modal="false"
-      style="display: flex; flex-direction: column; padding: 16px 0 0; height: 500px; width: 1100px;">
-      <template #header>
-        <div class="dialog-title">
-          {{ recordTitle }}
-        </div>
-      </template>
-      <lock-record v-if="recordVisible" :lockId="currLockId"></lock-record>
+    <!-- 閰嶇疆鏈烘煖 -->
+    <el-dialog
+      v-model="settingsVisible"
+      title="閰嶇疆"
+      width="780"
+      align-center
+      :close-on-click-modal="false"
+    >
+      <settings v-if="settingsVisible" :locationInfo="locationInfo" @cancel="settingsVisible = false" @success="settingsOk"></settings>
     </el-dialog>
   </div>
 </template>
@@ -198,10 +452,41 @@
   }
 }
 
+.p-title {
+  background: #0ff;
+  color: #000;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  height: 36px;
+  border-radius: 6px;
+  margin-bottom: 8px;
+  font-weight: 700;
+  position: relative;
+
+  .btn-grp {
+    position: absolute;
+    right: 10px;
+
+    .btn {
+      cursor: pointer;
+    }
+  }
+}
+
 .page-content-wrapper {
   display: flex;
   flex-direction: column;
   height: 100%;
+  .tabs {
+    flex: 1;
+    :deep(.el-tab-pane) {
+      display: flex;
+      flex-direction: column;
+      height: 100%;
+      position: relative;
+    }
+  }
 
   .page-content-tools {
     padding-bottom: 8px;
@@ -231,7 +516,7 @@
 }
 
 .hdw-card-container {
-  width: 240px;
+  width: 320px;
   padding-right: 8px;
   height: 100%;
 }
@@ -305,4 +590,39 @@
 :deep(.el-dialog__body) {
   flex: 1;
 }
-</style>
\ No newline at end of file
+:deep(.el-tabs--border-card>.el-tabs__content) {
+  padding: 0;
+  position: relative;
+}
+.svg-station {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+}
+
+.btn-settings {
+  position: absolute;
+  z-index: 1;
+  right: 200px;
+  top: 20px;
+  cursor: pointer;
+  width: 36px;
+  height: 36px;
+  background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 1024 1024' %3e%3cpath d='M950.857143 402.285714h-51.748572a403.2 403.2 0 0 0-36.571428-86.308571l36.571428-36.571429a73.142857 73.142857 0 0 0 0-103.314285l-51.017142-51.931429a73.142857 73.142857 0 0 0-103.314286 0l-36.571429 36.571429A393.691429 393.691429 0 0 0 621.714286 125.074286V73.142857a73.142857 73.142857 0 0 0-73.142857-73.142857h-73.142858a73.142857 73.142857 0 0 0-73.142857 73.142857v51.931429a393.691429 393.691429 0 0 0-86.308571 35.657143l-36.571429-36.571429a73.142857 73.142857 0 0 0-103.314285 0L124.16 175.908571a73.142857 73.142857 0 0 0 0 103.314286l36.571429 36.571429a403.2 403.2 0 0 0-36.571429 86.308571H73.142857a73.142857 73.142857 0 0 0-73.142857 73.142857v73.142857a73.142857 73.142857 0 0 0 73.142857 73.142858h51.748572a403.2 403.2 0 0 0 36.571428 86.308571l-36.571428 36.571429a73.142857 73.142857 0 0 0 0 103.314285l51.748571 51.748572a73.142857 73.142857 0 0 0 103.314286 0l36.571428-36.571429A393.691429 393.691429 0 0 0 402.285714 898.925714V950.857143a73.142857 73.142857 0 0 0 73.142857 73.142857h73.142858a73.142857 73.142857 0 0 0 73.142857-73.142857v-51.931429a393.691429 393.691429 0 0 0 86.308571-35.657143l36.571429 36.571429a73.142857 73.142857 0 0 0 103.314285 0l51.748572-51.748571a73.142857 73.142857 0 0 0 0-103.314286l-36.571429-36.571429a403.2 403.2 0 0 0 36.571429-86.308571H950.857143a73.142857 73.142857 0 0 0 73.142857-73.142857V475.428571a73.142857 73.142857 0 0 0-73.142857-73.142857zM617.142857 613.668571a146.285714 146.285714 0 1 1-3.474286-206.811428 146.285714 146.285714 0 0 1 3.474286 206.811428z' fill='%230ff' %3e%3c/path%3e%3c/svg%3e") center center / contain no-repeat;
+  transform-origin: 50% 50%;
+  &:hover {
+    animation: rotate 12s linear infinite;
+  }
+}
+
+@keyframes rotate {
+  from {
+    transform: rotate(0deg);
+  }
+  to {
+    transform: rotate(360deg);
+  }
+}
+</style>

--
Gitblit v1.9.1