on-site-robots-screen/src/views/home/index.vue

281 lines
7.0 KiB
Vue
Raw Normal View History

2025-06-17 16:01:11 +08:00
<template>
<!-- 非全屏状态 -->
<div ref="appRef" class="app-container">
<!-- 机器人首页 -->
<!-- 使用grid布局 -->
<!-- 非全屏模式 -->
2025-06-24 18:12:02 +08:00
<div class="robot-container">
2025-06-17 16:01:11 +08:00
<!-- 左一 -->
2025-06-24 18:12:02 +08:00
<div
:style="{
gridColumn: fullScreenVisible ? '1 / 9' : '1 / 4',
gridRow: fullScreenVisible ? '1 / 13' : '1 / 7',
}"
>
2025-06-17 16:01:11 +08:00
<LeftOne
2025-06-24 18:12:02 +08:00
:videoId="'video-1'"
:cameraNode="cameraNode_1"
:fullScreenVisible="fullScreenVisible"
@onHandleChangeView="onHandleChangeView"
2025-06-17 16:01:11 +08:00
@onHandleOperationPanel="onHandleOperationPanel"
2025-06-24 18:12:02 +08:00
@onHandleFullScreenToggle="onHandleFullScreenToggleL"
2025-06-17 16:01:11 +08:00
/>
</div>
<!-- 左二 -->
2025-06-24 18:12:02 +08:00
<div class="robot-2" v-if="!fullScreenVisible">
2025-06-17 16:01:11 +08:00
<LeftTwo />
</div>
<!-- 中一 -->
2025-06-24 18:12:02 +08:00
<div
:style="{
gridColumn: fullScreenVisible ? '9 / 13' : '4 / 10',
gridRow: fullScreenVisible ? '1 / 6' : '1 / 8',
}"
>
<CenterOne
:videoId="'video-2'"
:cameraNode_2="cameraNode_2"
:fullScreenVisible="fullScreenVisible"
/>
2025-06-17 16:01:11 +08:00
</div>
<!-- 中二 -->
2025-06-24 18:12:02 +08:00
<div class="robot-4" v-if="!fullScreenVisible">
2025-06-17 16:01:11 +08:00
<CenterTwo />
</div>
<!-- 右一 -->
2025-06-24 18:12:02 +08:00
<div class="robot-5" v-if="!fullScreenVisible">
2025-06-17 16:01:11 +08:00
<RightOne />
</div>
<!-- 右二 -->
2025-06-24 18:12:02 +08:00
<div class="robot-6" v-if="!fullScreenVisible">
2025-06-17 16:01:11 +08:00
<RightTwo />
</div>
2025-06-24 18:12:02 +08:00
<div class="robot-7" v-if="fullScreenVisible">
2025-06-17 16:01:11 +08:00
<ControlDeck />
</div>
</div>
</div>
<!-- 操作面板 -->
2025-06-18 18:08:48 +08:00
<n-drawer resizable placement="right" :default-width="502" v-model:show="operationPanelVisible">
<div class="operation-panel-container">
<div class="operation-panel-content">
<ControlDeck />
</div>
</div>
2025-06-17 16:01:11 +08:00
</n-drawer>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
2025-06-24 18:12:02 +08:00
import { initLoginApi, getDeviceUrlApi } from '@/utils/initLogin'
2025-06-17 16:01:11 +08:00
import { useScale } from '@/hooks/useScale' // 引入自定义 Hook
import LeftOne from './components/left-one.vue'
import LeftTwo from './components/left-two.vue'
import CenterOne from './components/center-one.vue'
import CenterTwo from './components/center-two.vue'
import RightOne from './components/right-one.vue'
2025-06-18 18:08:48 +08:00
import RightTwo from './components/right-two/index.vue'
2025-06-17 16:01:11 +08:00
import ControlDeck from './components/control-deck.vue'
const appRef = ref(null) // 获取 DOM 引用
2025-06-18 18:08:48 +08:00
const fullScreenVisible = ref(false) // 全屏状态
2025-06-17 16:01:11 +08:00
// 使用 useScale Hook直接调用无需在 setup() 里)
const { baseWidth, baseHeight, scale } = useScale(appRef)
2025-06-24 18:12:02 +08:00
const cameraNode_1 = ref({
puid: '201115200268437643',
idx: 0,
stream: 0,
name: '',
operateType: 1,
steamCode: '',
steamURL: '',
})
const cameraNode_2 = ref({
puid: '201115200268437643',
idx: 1,
stream: 0,
name: '',
operateType: 1,
steamCode: '',
steamURL: '',
})
2025-06-17 16:01:11 +08:00
const operationPanelVisible = ref(false) // 操作面板是否显示
// 打开操作面板
const onHandleOperationPanel = (visible) => {
operationPanelVisible.value = visible
}
// 全屏控制
2025-06-24 18:12:02 +08:00
const onHandleFullScreenToggleL = (visible) => {
2025-06-17 16:01:11 +08:00
fullScreenVisible.value = visible
}
2025-06-24 18:12:02 +08:00
// 视角切换
const onHandleChangeView = () => {
const tempIdx = cameraNode_1.value.idx
cameraNode_1.value.idx = cameraNode_2.value.idx
cameraNode_2.value.idx = tempIdx
const temp = cameraNode_1.value.steamURL
cameraNode_1.value.steamURL = cameraNode_2.value.steamURL
cameraNode_2.value.steamURL = temp
}
const loginParams = ref({
// - 登录平台IP
address: '60.168.132.97',
port: '49988',
// - 登录平台用户名
user: 'admin',
// - 登录平台密码
password: 'Aa123456',
// - 登录平台企业ID
epid: 'YDJFXK',
// - 登录平台是否通过网闸模式
bfix: 0,
})
// 初始化登录
const initLoginData = async () => {
initLoginApi(loginParams.value).then((res) => {
localStorage.setItem('token', res?.data?.token)
getDeviceData()
})
}
// 获取视频地址
const getDeviceData = async () => {
const { data: res } = await getDeviceUrlApi({
token: localStorage.getItem('token'),
puid: '201115200268437643',
idx: 0,
stream: 0,
type: 'HTTP-FLV',
})
const { data: res2 } = await getDeviceUrlApi({
token: localStorage.getItem('token'),
puid: '201115200268437643',
idx: 1,
stream: 0,
type: 'HTTP-FLV',
})
cameraNode_1.value.steamURL = res?.streamUrl
cameraNode_2.value.steamURL = res2?.streamUrl
}
initLoginData()
2025-06-17 16:01:11 +08:00
</script>
<style lang="scss">
.app-container {
.robot-container,
.full-screen-container {
width: 100%;
height: 100%;
display: grid;
grid-template-rows: repeat(12, 1fr);
grid-template-columns: repeat(12, 1fr);
// gap: 10px;
}
// 左侧
.robot-1 {
grid-column: 1 / 4;
grid-row: 1 / 7;
}
.robot-2 {
grid-column: 1 / 4;
grid-row: 7 / 13;
}
// 中间
.robot-3 {
grid-column: 4 / 10;
grid-row: 1 / 8;
}
.robot-4 {
grid-column: 4 / 10;
grid-row: 8 / 13;
}
// 右侧
.robot-5 {
grid-column: 10 / 13;
grid-row: 1 / 8;
}
.robot-6 {
grid-column: 10 / 13;
grid-row: 8 / 13;
}
2025-06-24 18:12:02 +08:00
.robot-7 {
grid-column: 9 / 13;
grid-row: 6 / 13;
}
2025-06-17 16:01:11 +08:00
.full-screen-left1 {
grid-column: 1 / 9;
grid-row: 1 / 13;
}
.full-screen-right1 {
grid-column: 9 / 13;
2025-06-18 18:08:48 +08:00
grid-row: 1 / 6;
2025-06-17 16:01:11 +08:00
}
.full-screen-right2 {
grid-column: 9 / 13;
2025-06-18 18:08:48 +08:00
grid-row: 6 / 13;
2025-06-17 16:01:11 +08:00
}
}
.pagination-container {
display: flex;
justify-content: flex-end;
margin-top: 10px;
padding-right: 10px;
}
.child-container {
width: 100%;
height: 100%;
padding: 10px;
display: flex;
flex-direction: column;
box-sizing: border-box;
}
.more-btn {
width: 58px;
height: 24px;
border-radius: 12px;
color: #d6fdff;
background: linear-gradient(to bottom, rgba(15, 47, 78, 0.5) 0%, rgba(0, 222, 255, 0.5) 100%);
text-align: center;
line-height: 24px;
cursor: pointer;
}
2025-06-18 18:08:48 +08:00
.n-drawer {
background-color: rgba(0, 0, 0, 0.8);
}
.operation-panel-container {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.operation-panel-content {
width: 90%;
background-color: rgba(0, 112, 190, 0.3);
color: #fff;
border: 1px solid #0070be;
}
}
2025-06-17 16:01:11 +08:00
</style>