| | |
| | | <template> |
| | | <div class="monitor-page" style="height:100%;display:flex;gap:12px;"> |
| | | <!-- 左侧树形 --> |
| | | <div class="left-tree" style="width:280px;border:1px solid var(--el-border-color);border-radius:6px;"> |
| | | <site-tree @select="handleTreeSelect" /> |
| | | </div> |
| | | <div class="monitor-page"> |
| | | <!-- 左侧树形 --> |
| | | <div class="left-tree"> |
| | | <site-tree @select="handleTreeSelect" /> |
| | | </div> |
| | | |
| | | <!-- 右侧监控区域 --> |
| | | <div class="right-player" style="flex:1;border:1px solid var(--el-border-color);border-radius:6px;padding:12px;overflow:auto;"> |
| | | <el-empty v-if="deviceList.length === 0" description="请左侧选择站点加载监控设备" /> |
| | | <div class="player-grid" v-if="deviceList.length"> |
| | | <div v-for="dev in deviceList" :key="dev.id" class="player-card"> |
| | | <div class="title">{{ dev.iotName }}</div> |
| | | <EzuikitPlayer |
| | | v-if="ysToken" |
| | | :key="'p_' + dev.id + '_' + ysToken" |
| | | :container-id="'player_' + dev.id" |
| | | :access-token="ysToken" |
| | | :url="`ezopen://open.ys7.com/${dev.iotCode}/1.hd.live`" |
| | | /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <!-- 右侧监控区域 --> |
| | | <div class="right-player"> |
| | | <el-empty v-if="deviceList.length === 0" description="请左侧选择站点加载监控设备" /> |
| | | <div v-else class="player-grid" :style="gridStyle"> |
| | | <div v-for="dev in deviceList" :key="dev.id" class="player-card"> |
| | | <!-- <div class="title">{{ dev.iotName }}</div> --> |
| | | <ezuikit-player |
| | | v-if="ysToken" |
| | | :key="'p_' + dev.id + '_' + ysToken" |
| | | :container-id="'player_' + dev.id" |
| | | :access-token="ysToken" |
| | | :url="`ezopen://open.ys7.com/${dev.iotCode}/1.hd.live`" |
| | | :pause-at-first-frame="true" |
| | | /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | |
| | | name: 'monitor-device', |
| | | }); |
| | | |
| | | import { ref, onMounted } from 'vue'; |
| | | import { ref, computed, onMounted } from 'vue'; |
| | | import { useCool } from '/@/cool'; |
| | | import SiteTree from '../components/site-tree.vue'; |
| | | import EzuikitPlayer from '../../ezuikit/components/ezuikit-player.vue'; |
| | |
| | | const { service } = useCool(); |
| | | |
| | | const deviceList = ref<any[]>([]); |
| | | let ysToken = ref(''); |
| | | const ysToken = ref(''); |
| | | |
| | | // ✅ 根据设备数量自动计算网格列数 |
| | | const gridCols = computed(() => { |
| | | const n = deviceList.value.length; |
| | | if (n <= 1) return 1; |
| | | if (n <= 4) return 2; // 2~4 个 → 2 列 |
| | | if (n <= 6) return 3; // 5~6 个 → 3 列 |
| | | if (n <= 8) return 4; // 7~8 个 → 4 列 |
| | | return 4; |
| | | }); |
| | | |
| | | const gridStyle = computed(() => ({ |
| | | gridTemplateColumns: `repeat(${gridCols.value}, 1fr)`, |
| | | })); |
| | | |
| | | async function fetchYsToken() { |
| | | if (ysToken.value) return; |
| | | try { |
| | | //const res = await service.monitor.ys7.getToken(); |
| | | const res = await service.base.sys.param.stringbykey({key:"ys7.accessToken"}); |
| | | ysToken = res; |
| | | const res = await service.base.sys.param.stringbykey({ key: 'ys7.accessToken' }); |
| | | ysToken.value = res as string; // ✅ 修正:赋值给 .value |
| | | } catch (e: any) { |
| | | console.error('萤石 Token 获取失败', e?.response?.data?.message || e.message); |
| | | } |
| | | } |
| | | |
| | | onMounted(fetchYsToken); |
| | | onMounted(fetchYsToken); // ✅ 修正:onMounted |
| | | |
| | | async function handleTreeSelect(businessId: string | number | null) { |
| | | if (!businessId) { |
| | |
| | | if (!ysToken.value) await fetchYsToken(); |
| | | try { |
| | | const res = await service.basicdata.iot.getYsDevices({ businessId }); |
| | | deviceList.value = res || []; |
| | | deviceList.value = (res || []) as any[]; |
| | | } catch { |
| | | deviceList.value = []; |
| | | } |
| | |
| | | |
| | | <style lang="scss" scoped> |
| | | .monitor-page { |
| | | height: 100%; |
| | | height: 100%; |
| | | display: flex; |
| | | gap: 12px; |
| | | } |
| | | .left-tree { |
| | | height: 100%; |
| | | width: 280px; |
| | | height: 100%; |
| | | border: 1px solid var(--el-border-color); |
| | | border-radius: 6px; |
| | | } |
| | | .right-player { |
| | | height: 100%; |
| | | flex: 1; |
| | | height: 100%; |
| | | border: 1px solid var(--el-border-color); |
| | | border-radius: 6px; |
| | | padding: 12px; |
| | | overflow: auto; |
| | | } |
| | | .player-grid { |
| | | display: grid; |
| | | grid-template-columns: repeat(auto-fill, minmax(440px, 1fr)); |
| | | gap: 16px; |
| | | display: grid; |
| | | gap: 16px; |
| | | } |
| | | .player-card { |
| | | .title { |
| | | padding: 6px 0; |
| | | font-weight: 500; |
| | | } |
| | | .title { |
| | | padding: 6px 0; |
| | | font-weight: 500; |
| | | } |
| | | } |
| | | </style> |