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