hldy_app/pages/watch/index.vue

1848 lines
42 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="view">
<view class="view-left">
<view class="title-father">
<image class="title-img" src="/static/index/watch/uni.png" />
<view class="title-font">
护理单元
</view>
</view>
<view class="zhezhao-top"></view>
<view class="zhezhao-bottom"></view>
<scroll-view class="menus-father" scroll-y :scroll-top="topnum">
<view v-for="(item,index) in filteredMenu" :key="index" class="menu"
:class="{warning: item.warning,target: index === leftTargetIndex}" :style="[
index === menuIndex ? { backgroundColor: '#fff' } : {},
leftTargetIndex === index ? { backgroundColor: '#ddf0ff' } : {}
]" @click="menuIndex=index;">
<view class="menu-img">
<donghua :width="`65rpx`" :height="`65rpx`" :links="item.url" :playing="menuIndex===index" />
</view>
<!-- <image class="menu-img" :src="item.url" /> -->
<view style="margin-left: 10rpx;">
<view
style="font-size: 31rpx;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;width: 200rpx;"
:style="index === menuIndex?{color:`#017DE9 `}:{} ">
{{item.name}}
</view>
<!-- <view style="font-size: 20rpx;color: #A1A1A1;">
NUID {{item.NUID}}
</view> -->
</view>
</view>
<view style="height: 45rpx;">
</view>
</scroll-view>
</view>
<view class="view-right">
<!-- <view class="right-container-title-nav">
<view class="right-icons">
<view class="right-container-tem">
<image class="right-container-tem-img" src="/static/index/newindex/wendu/0.png" />
<text class="right-container-tem-text">23°C</text>
<image class="right-container-tem-img" src="/static/index/newindex/wendu/1.png" />
<text class="right-container-tem-text">39%</text>
</view>
</view>
</view> -->
<view class="scroll-vi">
<view class="zhezhao-left"></view>
<view class="zhezhao-right"></view>
<scroll-view scroll-x="true" style="width: 66%;height: 100%;">
<view style="display: flex;align-items: center;margin-top: 5rpx;">
<view v-for="(item,index) in typeArray" :key="index" class="menu"
:style="topTargetIndex === index ? { backgroundColor: '#ddf0ff' } : {}"
:class="{target: index === topTargetIndex}" @click="typeNow=index;">
<!-- <image class="menu-img" :src="item.url" v-if="item.url" /> -->
<donghua :links="item.url" :playing="typeNow===index" v-if="item.url" />
<text class="menu-font" :class="{ zoom: typeNow===index }"
:style="typeNow===index?{color:`#008FF5`}:{}" v-if="item.url">
{{item.name}}
</text>
<view v-if="!item.url">
<image style="width: 50rpx;height: 50rpx;" src="/static/index/watch/more.png" />
</view>
</view>
</view>
</scroll-view>
<view class="right-father">
<view style="font-weight: 600;font-size: 90rpx;margin-right: 15rpx;">
10:18
</view>
<view class="" style="font-weight: 600;margin-right: 50rpx;">
<view class="">7-25</view>
<view class="">星期三</view>
</view>
<!-- <view class="">
返回
</view> -->
<view :class="{ targetbutton: shezhi }" style="display: flex;align-items: center;">
<image style="width: 65rpx;height: 65rpx;" src="/static/index/newindex/curve/shezhi.png"
@click="goback" />
<view style="font-size: 32rpx;margin-left: 10rpx;" @click="goback">
设置
</view>
</view>
</view>
</view>
<view class="big-bgc">
<view
style="width: 100%;position: absolute;top: 0;left: 0;z-index: 1;display: flex;align-items: center;">
<text style="margin-top: 40rpx;font-size: 32rpx;margin-left: 50rpx;">
NUID2508000001
</text>
<text class="new-weight">
护理单元01
</text>
<view class="right-icons">
<view class="right-container-tem">
<image class="right-container-tem-img" src="/static/index/newindex/wendu/0.png" />
<text class="right-container-tem-text">23°C</text>
<image class="right-container-tem-img" src="/static/index/newindex/wendu/1.png" />
<text class="right-container-tem-text">39%</text>
</view>
</view>
</view>
<!-- <image style="width: 100%;height: 100%;" src="/static/index/watch/bgc.png" /> -->
<!-- <image style="width: 100rpx;height: 100rpx;position: absolute;top: 50%;left: 50%;transform: translate(-50%,-50%);" src="/static/index/watch/play.png" @click="jumpToCeshi" /> -->
</view>
<view class="picture">
<view class="picture-card" v-for="(item,index) in downpicture" :key="index"
:style="{color:downtarget===index?'#1486EB':''}" @click="clickDownCard(index)">
<view class="bgc-card" :style="{background:downtarget===index?'#E2EDFC':''}">
<image style="width: 90rpx;height: 90rpx;"
:src="`/static/index/picture/${index}${downtarget===index?1:0}.png`" />
</view>
{{item}}
</view>
</view>
<!-- <view style="display: flex;margin-top: 20rpx;">
<view class="card-father">
<view class="up-title">
<view class="">
监控截屏
</view>
<image style="width: 50rpx;height: 50rpx;margin-right: 20rpx;"
src="/static/index/watch/more.png" />
</view>
<view style="display: flex;">
<view class="small-bgc" style="margin-right: 20rpx;">
<image style="width: 100%;height: 100%;position: absolute;top: 0;left: 0;"
src="/static/index/watch/bgc.png" />
</view>
<view class="small-bgc">
<image style="width: 100%;height: 100%;position: absolute;top: 0;left: 0;"
src="/static/index/watch/bgc.png" />
</view>
</view>
</view>
<view class="card-father">
<view class="up-title">
<view class="">
视频回放
</view>
<image style="width: 50rpx;height: 50rpx;margin-right: 20rpx;"
src="/static/index/watch/more.png" />
</view>
<view style="display: flex;">
<view class="small-bgc" style="margin-right: 20rpx;">
<image style="width: 100%;height: 100%;position: absolute;top: 0;left: 0;"
src="/static/index/watch/bgc.png" />
<image style="width: 50rpx;height: 50rpx;" src="/static/index/watch/play.png" />
</view>
<view class="small-bgc">
<image style="width: 100%;height: 100%;position: absolute;top: 0;left: 0;"
src="/static/index/watch/bgc.png" />
<image style="width: 50rpx;height: 50rpx;" src="/static/index/watch/play.png" />
</view>
</view>
</view>
</view> -->
<view class="right-right">
<view class="red-kuang" v-if="typeNow===0">
<image style="width: 75rpx;height: 90rpx;margin-left: 40rpx;margin-top: -10rpx;"
src="/static/index/watch/laotai.png" />
<view class="">
<view style="margin-left: 20rpx;display: flex;align-items: center;margin-bottom: 5rpx;">
<view class="font-weight">
王金凤
</view>
<view class="font-small" style="margin-left: 30rpx;">
女 80岁
</view>
<view class="blue-bgc">
当日指令
</view>
</view>
<view class="font-small" style="margin-left: 20rpx;margin-top: 0rpx;">
入住时间2025.01.01
</view>
</view>
</view>
<view class="red-kuang" v-if="typeNow===1">
<image style="width: 110rpx;height: 140rpx;margin-left: 40rpx;margin-top: -10rpx;"
src="/static/index/watch/laotou.png" />
<view class="">
<view
style="margin-left: 20rpx;display: flex;align-items: center;margin-bottom: 5rpx;margin-top: 25rpx;height: 60rpx;">
<view class="font-weight">
李树奎
</view>
<view class="font-small" style="margin-left: 10rpx;">
男 50岁
</view>
</view>
<view class="font-small" style="margin-left: 20rpx;margin-top: 25rpx;">
入职时间2025.01.15
</view>
</view>
</view>
<view class="states-father" v-if="typeNow===0">
<view class="states" :class="item.error?`warning`:``" v-for="(item,index) in iconArray"
:key="index">
<image style="width: 40rpx;height: 40rpx;" :src="item.url" />
<view style="color: #555555;margin-left: 5rpx;font-size: 25rpx;">
{{ item.name }}
</view>
</view>
</view>
<view class="states-father" v-if="typeNow===1">
<view class="phone-number">
<image class="bgc-image" src="/static/index/watch/phonebgc.png" />
<image style="width: 20rpx;height: 35rpx;margin-left: 40rpx;"
src="/static/index/watch/phone.png" />
<view class="font-phone">15533556676</view>
<image class="phone-ball" src="/static/index/watch/phoneball.png" />
</view>
</view>
<view class="big-view">
<view class="font-weight">
10:00 - 10:10
</view>
<view class="pao">
<image style="width: 100%;height: 100%;position: absolute;top: 0;left: 0;"
src="/static/index/watch/pao.png" />
<view style="font-size: 20rpx;z-index: 1;">
待进行
</view>
</view>
<view class="juzhong" style="top: -120rpx;">
<donghua :width="`600rpx`" :height="`500rpx`" :links="blueArray" :playing="photoplay"
:loop="true" :interval="120" />
</view>
<view class="juzhong" style="z-index: 2;margin-top: 50rpx;">
<donghua :width="`300rpx`" :height="`200rpx`" :links="bluesmallArray" :playing="photoplay"
:loop="true" :interval="120" />
</view>
<image style="width: 300rpx;height: 200rpx;" src="/static/index/newindex/wendu/2.png" />
<view style="font-size: 25rpx;">
一级压疮防护
</view>
</view>
<view class="bottom-view">
<view v-for="(item,index) in cameraArray" class="button-father" @click="clickcamera(index)">
<view class="bottom-button"
:style="{backgroundColor:cameratarget.includes(index)?`#DDE9F0`:`` }">
<image style="width: 70%;height: 70%"
:src="`/static/index/camera/${index}${cameratarget.includes(index)?1:0}.png`" />
</view>
<view style="font-size: 25rpx;" :style="{color:cameratarget.includes(index)?`#0E86EA`:`` }">
{{item}}
</view>
</view>
<view class="jump-white" v-show="jumpopen">
<view style="display: flex;justify-content: space-around;height: 100rpx;width: 100%;align-items: center;">
<view class="">
清晰度
</view>
<image style="width: 40rpx;height: 40rpx" src="/static/index/camera/back.png" @click="jumpopen=false" />
</view>
<view class="jump-item" v-for="(item,index) in where" :key="index" @click="clickjump(index)" :style="{backgroundColor:wheretarget===index?'#E5E8EE':''}" >
<image style="width: 50rpx;height: 50rpx;margin-right: 10rpx;margin-left:-10rpx" :src="wheretarget===index?item.target:item.url" />
<view :style="{color:wheretarget===index?'#0E86EA':''}">
{{item.name}}
</view>
</view>
</view>
</view>
</view>
</view>
<!-- <specialDrawerVue ref="gobackdrawer" :circletarget="openright" @open="cleanandopen">
<bigroll ref="wheelRef" :opensecondmenu="opensecondmenu" @firstIndex="firstIndex"
@secondIndex="secondIndex" />
</specialDrawerVue> -->
<arrowkeys @movecard="movecard" :getblue="getblue" :moveleft="5" />
<joysticknew @movecard="movecamera" v-show="!cameratarget.includes(5)" />
<!-- 自动更新组件 -->
<!-- <zy-update ref="zyupgrade" :noticeflag="true" theme="blue" :h5preview="false" oldversion="1.0.0"
:appstoreflag="true" :autocheckupdate="true"></zy-update> -->
</view>
</template>
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, computed } from 'vue';
// import ZyUpdate from '@/component/zy-upgrade/zy-upgrade.vue'
import { onShow, onLoad } from "@dcloudio/uni-app"
import specialDrawerVue from '../../component/public/specialDrawer.vue';
import bigroll from './drawer/index.vue';
import { movedirection } from './api/lunpan.js'
import joysticknew from '@/component/public/newgame/joysticknew.vue';
const cameraArray = ref([])
onLoad(() => {
cameraArray.value = cameraSmall
})
const zyupgrade = ref(null);
const menuIndex = ref(-1);
const typeNow = ref(-1);
const photoplay = ref(false);
const getblue = ref(false);
const gobackdrawer = ref(null);
const wheelRef = ref(null);
const topnum = ref(0); // scroll-top (px)
const itemHeight = 100; // 每项高度 (px)
const containerHeight = 400; // scroll-view 高度 (px)
const wheretarget = ref(3);
const where = [
{
name:"左右翻转",
url:"/static/index/camera/800.png",
target:"/static/index/camera/801.png",
},
{
name:"上下翻转",
url:"/static/index/camera/810.png",
target:"/static/index/camera/811.png",
},
{
name:"中心翻转",
url:"/static/index/camera/820.png",
target:"/static/index/camera/821.png",
},
{
name:"不翻转",
url:"/static/index/camera/830.png",
target:"/static/index/camera/831.png",
},
]
const downpicture = [
"原图",
"全景拉伸",
"四分屏",
"180°全景",
"360°全景"
]
const cameratarget = ref([]);
const cameraBig = [
"截图",
"录制",
"对讲",
"静音",
"预警",
"更多",
"图片",
"视频",
"清晰度",
"翻转",
]
const cameraSmall = [
"截图",
"录制",
"对讲",
"静音",
"预警",
"更多",
]
const downtarget = ref(0)
const jumpToCeshi = () => {
uni.navigateTo({
url: '/pages/denglu'
})
}
const clickDownCard = (index : number) => {
downtarget.value = index;
switch (index) {
case 0:
uni.$emit('monitor:switchDisplay', 0)
break
case 1:
uni.$emit('monitor:switchDisplay', 4)
break
case 2:
uni.$emit('monitor:switchDisplay', 1)
break
case 3:
uni.$emit('monitor:switchDisplay', 2)
break
case 4:
uni.$emit('monitor:switchDisplay', 3)
break
}
}
const first = ref(5);
const second = ref(0);
const firstIndex = (index : number) => {
first.value = index;
yuntai.value = false;
}
const secondIndex = (index : number) => {
second.value = index;
yuntai.value = false;
}
// const change
const opendrawer = () => {
gobackdrawer.value.openDrawer();
}
function clamp(v, a, b) { return Math.max(a, Math.min(b, v)); }
// 确保 idx 可见:若在上方/下方不可见则调整 topnum
function ensureVisible(idx) {
// 逐步算数(清晰、稳妥)
const targetTop = idx * itemHeight; // idx乘以每项高度
const viewTop = topnum.value; // 视图当前顶部位置
const viewBottom = viewTop + containerHeight; // 视图底部位置
if (targetTop < viewTop) {
// 目标在上方:把顶部滚到目标的 top
topnum.value = clamp(targetTop, 0, filteredMenu.value.length * itemHeight - containerHeight);
} else if (targetTop + itemHeight > viewBottom) {
// 目标在下方:滚动使目标完全显示在视图底部
const needTop = targetTop + itemHeight - containerHeight;
topnum.value = clamp(needTop, 0, filteredMenu.value.length * itemHeight - containerHeight);
}
// console.log("????",topnum.value,targetTop,viewBottom)
// 否则已可见,无动作
}
// 通用的生成函数
function genPaths(base, prefix, count, ext = 'png', startIndex = 0, pad = false) {
return Array.from({ length: count }, (_, i) => {
const idx = pad
? String(i + startIndex).padStart(2, '0')
: i + startIndex
return `${base}/${prefix}${idx}.${ext}`
})
}
const base = genPaths(
'/static/index/newindex/curve',
'curve_',
9,
'png',
1,
false
)
const blueArray = ref([
...base,
...[...base].reverse() // 先拷贝一份再反转,避免修改原 base
])
const basesmall = genPaths(
'/static/index/newindex/curve',
'breathe_',
9,
'png',
1,
false
)
const bluesmallArray = ref([
...basesmall,
...[...basesmall].reverse() // 先拷贝一份再反转,避免修改原 base
])
const peopleArray = ref([
{
name: "王金福",
url: "/static/index/watch/people0.png"
},
{
name: "李宝田",
url: "/static/index/watch/people1.png"
},
])
const iconArray = ref([
{
name: "省医保",
url: "/static/index/watch/00.png",
error: false
},
{
name: "重度失能",
url: "/static/index/watch/01.png",
error: false
},
{
name: "欠费",
url: "/static/index/watch/03.png",
error: true
},
])
const typeArray = ref(
[
// {
// name: '全部',
// url: genPaths(
// '/static/index/watch',
// 'all_',
// 8, // 张数
// 'png',
// 1, // 起始索引为 1
// false // 不补零
// )
// },
{
name: '护理单元',
url: genPaths(
'/static/index/watch',
'nurs_',
10, // 张数
'png',
1, // 起始索引为 1
false // 不补零
)
},
{
name: '仓库',
url: genPaths(
'/static/index/watch',
'warehouse_',
6, // 张数
'png',
1, // 起始索引为 1
false // 不补零
)
},
{
name: '配务室',
url: genPaths(
'/static/index/watch',
'delivery_',
5, // 张数
'png',
1, // 起始索引为 1
false // 不补零
)
},
{
name: '服务大厅',
url: genPaths(
'/static/index/watch',
'service_',
5, // 张数
'png',
1, // 起始索引为 1
false // 不补零
)
},
{
name: '',
url: ""
},
// {
// name: '全部',
// url: "/static/index/newindex/curve/home_1.png"
// },
// {
// name: '全部',
// url: "/static/index/newindex/curve/home_1.png"
// },
// {
// name: '全部',
// url: "/static/index/newindex/curve/home_1.png"
// },
// {
// name: '全部',
// url: "/static/index/newindex/curve/home_1.png"
// },
]
)
const leftMenuArray = ref([
{
name: '护理单元01',
NUID: "2508000001",
url: genPaths(
'/static/index/watch',
'nurs_',
10, // 张数
'png',
1, // 起始索引为 1
false // 不补零
),
warning: false, type: 0
},
{
name: '护理单元02',
NUID: "2508000002",
url: genPaths(
'/static/index/watch',
'nurs_',
10, // 张数
'png',
1, // 起始索引为 1
false // 不补零
),
warning: false, type: 0
},
{
name: '护理单元03',
NUID: "2508000003",
url: genPaths(
'/static/index/watch',
'nurs_',
10, // 张数
'png',
1, // 起始索引为 1
false // 不补零
),
warning: true, type: 0
},
{
name: '仓库01',
NUID: "2508000001",
url: genPaths(
'/static/index/watch',
'warehouse_',
6, // 张数
'png',
1, // 起始索引为 1
false // 不补零
),
warning: false, type: 1
},
{
name: '配务室',
NUID: "2508000001",
url: genPaths(
'/static/index/watch',
'delivery_',
5, // 张数
'png',
1, // 起始索引为 1
false // 不补零
),
warning: false, type: 2
},
{
name: '服务大厅',
NUID: "2508000001",
url: genPaths(
'/static/index/watch',
'service_',
5, // 张数
'png',
1, // 起始索引为 1
false // 不补零
),
warning: false, type: 3
},
])
onMounted(() => {
menuIndex.value = 0;
typeNow.value = 0;
photoplay.value = true;
getblue.value = true;
})
const leftTargetIndex = ref(0);
const topTargetIndex = ref(-1);
const shezhi = ref(false)
const openright = ref(false);
const openfirstmenu = ref(false);
const opensecondmenu = ref(false);
// const circletarget = ref(false)
const cleanandopen = () => {
leftTargetIndex.value = -1;
topTargetIndex.value = -1;
shezhi.value = false;
openright.value = false;
openright.value = false;
openfirstmenu.value = true;
opensecondmenu.value = false
}
const movecamera = (type : number) => {
handleKey(type)
}
const movecard = (type : number) => {
if (leftTargetIndex.value !== -1) {
switch (type) {
case 0:
if (menuIndex.value > 0) {
menuIndex.value--
typeNow.value = 0
leftTargetIndex.value = menuIndex.value
ensureVisible(menuIndex.value)
} else {
topTargetIndex.value = typeNow.value
leftTargetIndex.value = -1
}
break
case 1:
// if (typeNow.value < typeArray.value.length - 1) {
// typeNow.value = 0
// ensureVisible(menuIndex.value)
// }
// typeNow.value = 0;
topTargetIndex.value = typeNow.value
leftTargetIndex.value = -1
break
case 2:
if (menuIndex.value < filteredMenu.value.length - 1) {
menuIndex.value++
typeNow.value = 0
leftTargetIndex.value = menuIndex.value
ensureVisible(menuIndex.value)
}
break
case 3:
// if (typeNow.value > 0) {
// typeNow.value--
// ensureVisible(menuIndex.value)
// }
break
case 4:
if (!typeNow.value) {
uni.navigateTo({
url: '/pages/NursingNew/index'
})
} else if (typeNow.value === 1) {
uni.navigateTo({
url: '/pages/Warehousing/index'
})
}
break
}
} else if (topTargetIndex.value !== -1) {
switch (type) {
case 0:
break
case 1:
if (typeNow.value < typeArray.value.length - 2) {
// console.log("???", typeArray.value.length)
typeNow.value++
topTargetIndex.value = typeNow.value
} else {
shezhi.value = true
topTargetIndex.value = -1
}
break
case 2:
topTargetIndex.value = -1
menuIndex.value = 0
leftTargetIndex.value = menuIndex.value
ensureVisible(menuIndex.value)
break
case 3:
if (typeNow.value) {
typeNow.value--
topTargetIndex.value = typeNow.value
} else {
topTargetIndex.value = -1
menuIndex.value = 0
typeNow.value = 0
leftTargetIndex.value = menuIndex.value
ensureVisible(menuIndex.value)
}
break
case 5:
topTargetIndex.value = -1
menuIndex.value = 0
leftTargetIndex.value = menuIndex.value
ensureVisible(menuIndex.value)
break
}
} else if (shezhi.value) {
switch (type) {
case 0:
break
case 1:
break
case 2:
shezhi.value = false;
openright.value = true
break
case 3:
typeNow.value = 3
topTargetIndex.value = typeNow.value
shezhi.value = false;
break
case 4:
goback()
break
case 5:
topTargetIndex.value = -1
menuIndex.value = 0
leftTargetIndex.value = menuIndex.value
ensureVisible(menuIndex.value)
shezhi.value = false;
break
}
} else if (openright.value) {
switch (type) {
case 0:
shezhi.value = true;
openright.value = false
break
case 1:
opendrawer()
openfirstmenu.value = true;
openright.value = false
break
case 2:
break
case 3:
topTargetIndex.value = -1
menuIndex.value = 0
leftTargetIndex.value = menuIndex.value
ensureVisible(menuIndex.value)
openright.value = false;
break
case 4:
opendrawer()
openfirstmenu.value = true;
openright.value = false
break
case 5:
topTargetIndex.value = -1
menuIndex.value = 0
leftTargetIndex.value = menuIndex.value
ensureVisible(menuIndex.value)
openright.value = false;
break
}
} else if (openfirstmenu.value) {
switch (type) {
case 0:
// wheelRef.value.moveFirstDown()
moveDownDebounced() // 使用防抖
break
case 1:
break
case 2:
// wheelRef.value.moveFirstUp()
moveUpDebounced() // 使用防抖
break
case 3:
openfirstmenu.value = false;
opensecondmenu.value = true;
break
case 4:
openfirstmenu.value = false;
opensecondmenu.value = true;
break
case 5:
gobackdrawer.value.closeDrawer();
openfirstmenu.value = false;
openright.value = true
break
}
} else if (yuntai.value) {
handleKey(type)
} else if (opensecondmenu.value) {
switch (type) {
case 0:
// wheelRef.value.moveFirstDown()
// moveDownDebounced() // 使用防抖
moveDownsecond()
break
case 1:
opensecondmenu.value = false;
openfirstmenu.value = true;
break
case 2:
moveUpsecond()
// wheelRef.value.moveFirstUp()
// moveUpDebounced() // 使用防抖
break
case 3:
break
case 4:
clickDownsecond()
break
case 5:
// gobackdrawer.value.closeDrawer();
opensecondmenu.value = false;
openfirstmenu.value = true;
// openright.value = true
break
}
}
}
const removeTimers = new Map<number, ReturnType<typeof setTimeout>>();
onBeforeUnmount(() => {
for (const t of removeTimers.values()) {
clearTimeout(t)
}
removeTimers.clear()
})
const removeIndexOnce = (index : number) => {
const pos = cameratarget.value.indexOf(index)
if (pos !== -1) {
cameratarget.value.splice(pos, 1) // 从 pos 开始删除 1 个元素
}
}
const jumpopen = ref(false);
const clickcamera = (index : number) => {
switch (index) {
case 0:
// 触发快照事件
uni.$emit('monitor:doSnapshot')
// 如果数组里不存在就 push避免重复
if (!cameratarget.value.includes(index)) {
cameratarget.value.push(index)
}
// 如果之前有定时器,先清掉(实现“重新计时”)
if (removeTimers.has(index)) {
clearTimeout(removeTimers.get(index)!)
}
// 新建一个 1s 后移除的定时器
const timerId = setTimeout(() => {
const pos = cameratarget.value.indexOf(index)
if (pos !== -1) {
cameratarget.value.splice(pos, 1)
}
removeTimers.delete(index)
}, 500)
removeTimers.set(index, timerId)
break
case 1:
if (cameratarget.value.includes(index)) {
uni.$emit('monitor:stopRecord');
removeIndexOnce(index)
} else {
uni.$emit('monitor:startRecord');
cameratarget.value.push(index)
}
break
case 2:
if (cameratarget.value.includes(index)) {
uni.$emit('monitor:stopTalk');
removeIndexOnce(index)
} else {
uni.$emit('monitor:openTalk');
cameratarget.value.push(index)
}
break
case 3:
if (cameratarget.value.includes(index)) {
uni.$emit('monitor:toggleVolume');
removeIndexOnce(index)
} else {
uni.$emit('monitor:toggleVolume');
cameratarget.value.push(index)
}
break
case 4:
if (cameratarget.value.includes(index)) {
uni.$emit('monitor:stopAlarm')
removeIndexOnce(index)
} else {
uni.$emit('monitor:startAlarm')
cameratarget.value.push(index)
}
break
case 5:
if (cameratarget.value.includes(index)) {
cameraArray.value = cameraSmall
removeIndexOnce(index)
} else {
cameraArray.value = cameraBig
cameratarget.value.push(index)
}
jumpopen.value = false;
break
case 6:
if (cameratarget.value.includes(index)) {
removeIndexOnce(index)
} else {
cameratarget.value.push(index)
}
break
case 7:
if (cameratarget.value.includes(index)) {
removeIndexOnce(index)
} else {
cameratarget.value.push(index)
}
break
case 8:
if (cameratarget.value.includes(index)) {
uni.$emit('monitor:changeQuality');
removeIndexOnce(index)
} else {
uni.$emit('monitor:changeQuality');
cameratarget.value.push(index)
}
break
case 9:
jumpopen.value = true
// if (cameratarget.value.includes(index)) {
// removeIndexOnce(index)
// } else {
// cameratarget.value.push(index)
// }
break
}
}
const clickjump = (index:number) => {
wheretarget.value = index;
if(index===3){
uni.$emit('monitor:flipImage', 6)
removeIndexOnce(9)
}else{
uni.$emit('monitor:flipImage', index)
cameratarget.value.push(9)
}
}
// 对 moveFirstUp / moveFirstDown 包装防抖
const moveUpDebounced = useThrottle(() => wheelRef.value?.moveFirstUp(), 400)
const moveDownDebounced = useThrottle(() => wheelRef.value?.moveFirstDown(), 400)
const moveUpsecond = useThrottle(() => wheelRef.value?.moveSecondUp(), 400)
const moveDownsecond = useThrottle(() => wheelRef.value?.moveSecondDown(), 400)
const clickDownsecond = useThrottle(() => doSomething(), 700)
const gaoqing = ref(0);
const yuntai = ref(false);
const savefirst = ref(-1);
function doSomething() {
wheelRef.value?.startchange()
// console.log("???",first.value)
if (first.value === 0) {
if (second.value) {
uni.$emit('monitor:toggleVolume');
} else {
uni.$emit('monitor:toggleVolume');
}
}
if (first.value === 1) {
if (second.value) {
uni.$emit('monitor:stopTalk');
} else {
uni.$emit('monitor:openTalk');
}
}
if (first.value === 2) {
uni.$emit('monitor:doSnapshot');
}
if (first.value === 3) {
if (second.value) {
uni.$emit('monitor:stopRecord');
} else {
uni.$emit('monitor:startRecord');
}
}
if (first.value === 4) {
if (!second.value) {
savefirst.value = first.value
first.value = -1;
yuntai.value = true;
} else {
}
}
if (first.value === 5) {
if (gaoqing.value !== second.value) {
gaoqing.value = second.value
uni.$emit('monitor:changeQuality'); // 发起截图请求,不关心回调
}
}
if (first.value === 6) {
uni.$emit('monitor:switchDisplay', second.value)
}
if (first.value === 7) {
if (second.value === 3) {
uni.$emit('monitor:flipImage', 6)
} else {
uni.$emit('monitor:flipImage', second.value)
}
}
if (first.value === 8) {
if (second.value) {
uni.$emit('monitor:stopAlarm')
} else {
uni.$emit('monitor:startAlarm')
}
}
// if()
}
function useThrottle(fn : () => void, delay = 1000) {
let throttling = false
return () => {
if (throttling) return
fn()
throttling = true
setTimeout(() => {
throttling = false
}, delay)
}
}
const filteredMenu = computed(() => {
menuIndex.value = -1
setTimeout(() => menuIndex.value = 0, 50)
return leftMenuArray.value.filter(item => item.type === typeNow.value);
});
const goback = () => {
// uni.navigateBack()
uni.navigateTo({
url: '/pages/watch/settings/settings'
})
}
const goToCeshi = () => {
uni.navigateTo({
url: '/pages/ceshi'
})
}
// 生命周期钩子
onShow(() => {
// zyupgrade.value?.check_update();
});
// 当前活跃的方向0,1,2,3
// -1 表示没有活跃方向
let activeDir = -1
// 定时器 mapkey = 方向
const stopTimers : Record<number, any> = {}
// 核心逻辑
function handleKey(type : number) {
switch (type) {
case 0: runDirection(1, 0); break // 上
case 1: runDirection(5, 1); break // 右
case 2: runDirection(7, 2); break // 下
case 3: runDirection(3, 3); break // 左
case 4: // 确定
first.value = savefirst.value
yuntai.value = false
savefirst.value = -1
moveUpsecond()
clickDownsecond()
break
case 5: // 取消
first.value = savefirst.value
yuntai.value = false
savefirst.value = -1
moveUpsecond()
clickDownsecond()
break
}
}
// 管理方向的开始/停止
function runDirection(dirCode : number, type : number) {
// 如果换方向,先停掉旧的
if (activeDir !== -1 && activeDir !== type) {
stopDirection(activeDir)
}
activeDir = type
// 执行开始
movedirection(dirCode, 1)
// 重置 stop 计时器
if (stopTimers[type]) clearTimeout(stopTimers[type])
stopTimers[type] = setTimeout(() => {
stopDirection(type)
}, 550) // 如果 550ms 内没有新指令 → 自动停止
}
// 停止动作
function stopDirection(type : number) {
if (type === -1) return
let dirCode = 0
switch (type) {
case 0: dirCode = 1; break
case 1: dirCode = 5; break
case 2: dirCode = 7; break
case 3: dirCode = 3; break
}
movedirection(dirCode, 0).then((res : any) => {
// console.log("stop", dirCode, res)
})
clearTimeout(stopTimers[type])
stopTimers[type] = null
if (activeDir === type) activeDir = -1
}
</script>
<style lang="less" scoped>
.view {
background-color: #eff0f4;
width: 100%;
height: 100vh;
display: flex;
.view-left {
height: 100%;
width: 23%;
// background-color: red;
.title-father {
// padding: 100rpx 0rpx;
padding-top: 120rpx;
padding-bottom: 50rpx;
padding-left: 60rpx;
display: flex;
.title-img {
width: 55rpx;
height: 55rpx;
margin-right: 20rpx;
}
.title-font {
font-size: 40rpx;
font-weight: 800;
}
}
.menus-father {
// margin-top: 20rpx;
width: 100%;
height: 800rpx;
.menu {
margin: 45rpx 0;
margin-left: 30rpx;
height: 110rpx;
width: 300rpx;
border-radius: 60rpx;
overflow: hidden;
display: flex;
// justify-content: center;
align-items: center;
.menu-img {
width: 65rpx;
height: 65rpx;
margin-left: 25rpx;
display: flex;
justify-content: center;
align-items: center;
// background-color: #eff0f4;
border-radius: 50%;
// padding: 5rpx;
// margin-right: 15rpx;
}
}
}
}
.view-right {
height: 100%;
width: 90%;
position: relative;
.right-container-title-nav {
margin-top: 60rpx;
display: flex;
align-items: center;
height: 60rpx;
position: relative;
font-size: 28rpx;
.right-icons-img {
width: 60rpx;
height: 60rpx;
margin-left: 20rpx;
margin-right: 20rpx;
}
}
.scroll-vi {
height: 100rpx;
width: 100%;
margin-left: 0rpx;
margin-top: 100rpx;
position: relative;
display: flex;
// background-color: red;
// margin-bottom: 50rpx;
.menu {
flex: 0 0 auto; // 👈 关键点
height: 90rpx;
width: 240rpx;
border-radius: 50rpx;
// margin: 45rpx auto;
margin-left: 20rpx;
background-color: #fff;
display: flex;
justify-content: center;
align-items: center;
padding-top: 9rpx;
.menu-img {
width: 55rpx;
height: 55rpx;
margin-right: 15rpx;
}
.menu-font {
margin-top: 18rpx;
font-size: 25rpx;
}
}
}
}
}
.right-container-tem {
display: flex;
.right-container-tem-text {
font-size: 32rpx;
margin-right: 20rpx;
}
.right-container-tem-img {
width: 38rpx;
height: 38rpx;
}
}
.new-weight {
margin: 0 30rpx;
margin-top: 40rpx;
// font-weight: 600;
font-size: 32rpx;
}
.big-bgc {
// margin-top: -50rpx;
margin-top: 20rpx;
width: 1250rpx;
height: 913rpx;
border-radius: 50rpx;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
position: relative;
// animation: glowFlash 1.2s infinite ease-in-out;
}
.small-bgc {
// margin: 0 20rpx;
width: 298rpx;
height: 220rpx;
border-radius: 25rpx;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.card-father {
margin-right: 20rpx;
.up-title {
display: flex;
justify-content: space-between;
align-items: center;
margin: 10rpx 0;
margin-left: 20rpx;
font-size: 30rpx;
}
}
@keyframes glowFlash {
0%,
100% {
box-shadow:
0 0 4rpx #f1d7da,
0 0 8rpx #f1d7da,
0 0 12rpx #f1d7da;
}
50% {
box-shadow:
0 0 10rpx #f1d7da,
0 0 20rpx #f1d7da,
0 0 30rpx #f1d7da;
}
}
.right-right {
position: absolute;
right: -20rpx;
top: 230rpx;
height: calc(100% - 250rpx);
width: 650rpx;
.red-kuang {
margin-top: 0rpx;
margin-left: 90rpx;
width: 510rpx;
height: 120rpx;
border-radius: 50rpx;
position: relative;
display: flex;
align-items: center;
background-color: rgba(226, 227, 231, 0.5);
.blue-bgc {
width: 120rpx;
height: 50rpx;
display: flex;
justify-content: center;
align-items: center;
z-index: 1;
font-size: 23rpx;
background-color: rgba(248, 249, 250, 0.5);
color: #017DE9;
border-radius: 20rpx;
margin-left: 30rpx;
}
.font-weight {
font-size: 30rpx;
font-weight: 600;
}
.font-small {
font-size: 25rpx;
}
}
}
.states-father {
display: flex;
margin-top: 20rpx;
margin-left: 90rpx;
width: 100%;
.states {
width: 157rpx;
margin-right: 15rpx;
height: 60rpx;
border-radius: 60rpx;
background-color: rgba(226, 227, 231, 0.5);
display: flex;
justify-content: center;
align-items: center;
}
.phone-number {
width: 100%;
height: 80rpx;
display: flex;
align-items: center;
position: relative;
}
}
.bottom-view {
margin-left: 90rpx;
margin-top: 20rpx;
width: 510rpx;
height: 690rpx;
border-radius: 50rpx;
background-color: rgba(226, 227, 231, 0.5);
position: relative;
display: flex;
flex-wrap: wrap;
overflow: hidden;
align-items: flex-start;
/* 关键:禁用 stretch子项按自己的高度 */
align-content: flex-start;
/* 多行时顶端对齐(可选) */
.button-father {
margin-top: 20rpx;
margin-bottom: 0;
margin-left: 45rpx;
// height: 150rpx;
// margin-right: 34rpx;
// background-color: red;
text-align: center;
.bottom-button {
background-color: #F2F2F4;
display: flex;
justify-content: center;
align-items: center;
width: 110rpx;
height: 110rpx;
border: 1rpx solid #CDD3DD;
border-radius: 35rpx;
margin-bottom: 5rpx;
}
}
}
.big-view {
margin-left: 90rpx;
margin-top: 20rpx;
width: 510rpx;
height: 340rpx;
border-radius: 50rpx;
background-color: rgba(226, 227, 231, 0.5);
position: relative;
display: flex;
flex-direction: column;
align-items: center;
overflow: hidden;
.font-weight {
font-size: 40rpx;
margin-top: 30rpx;
font-weight: 600;
}
.pao {
position: absolute;
right: 40rpx;
top: 20rpx;
width: 85rpx;
height: 40rpx;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
// background-color: red;
}
}
.small-button {
// width: 70%;
margin-top: 10rpx;
height: 70rpx;
display: flex;
// justify-content: space-between;
.gray-ball {
display: flex;
justify-content: center;
align-items: center;
background-color: #F8F9FA;
width: 60rpx;
height: 60rpx;
border-radius: 50%;
margin: 0 10rpx;
.laba-img {
width: 35rpx;
height: 35rpx;
}
}
}
.right-bottom {
margin-left: 50rpx;
margin-top: 30rpx;
width: 550rpx;
height: 240rpx;
border-radius: 50rpx;
background-color: rgba(226, 227, 231, 0.5);
position: relative;
.bottom-img {
width: 60rpx;
height: 60rpx;
margin-bottom: 30rpx;
}
.people-card {
width: 245rpx;
height: 100rpx;
border-radius: 25rpx;
background-color: rgba(248, 249, 250, 0.5);
margin-left: 20rpx;
display: flex;
justify-content: center;
align-items: center;
}
}
.right-father {
width: 650rpx;
position: absolute;
right: 0rpx;
top: 0;
// height: 100rpx;
// background-color: red;
display: flex;
justify-content: center;
align-items: center;
}
.right-icons {
position: absolute;
right: 30rpx;
top: 30rpx;
// transform: translateY(-50%);
display: flex;
align-items: center;
height: 60rpx;
}
.warning {
animation: glowFlash 1.2s infinite ease-in-out;
border: 1rpx solid #ff5757;
background-color: rgba(239, 240, 244, 0.5);
}
.zoom {
transform: scale(1.2);
transform-origin: bottom left;
transition: transform 1s ease;
}
.juzhong {
position: absolute;
top: 0%;
left: 50%;
transform: translateX(-50%);
}
.zhezhao-left {
position: absolute;
top: 0rpx;
left: 0%;
height: 100%;
width: 120rpx;
background: linear-gradient(to right,
rgba(239, 240, 244, 1) 0%,
/* #eff0f4 全不透明 */
rgba(239, 240, 244, 0) 100%
/* #eff0f4 完全透明 */
);
z-index: 4;
pointer-events: none;
}
.zhezhao-right {
position: absolute;
top: 0rpx;
right: 34%;
height: 100%;
width: 120rpx;
background: linear-gradient(to left,
rgba(239, 240, 244, 1) 0%,
/* #eff0f4 全不透明 */
rgba(239, 240, 244, 0) 100%
/* #eff0f4 完全透明 */
);
z-index: 4;
pointer-events: none;
}
.zhezhao-top {
position: absolute;
top: 220rpx;
left: 0%;
width: 350rpx;
height: 120rpx;
background: linear-gradient(to bottom,
rgba(239, 240, 244, 1) 0%,
/* #eff0f4 全不透明 */
rgba(239, 240, 244, 0) 100%
/* #eff0f4 完全透明 */
);
z-index: 4;
pointer-events: none;
}
.zhezhao-bottom {
position: absolute;
bottom: 450rpx;
left: 0%;
width: 350rpx;
height: 120rpx;
// background-color: red;
background: linear-gradient(to top,
rgba(239, 240, 244, 1) 0%,
/* #eff0f4 全不透明 */
rgba(239, 240, 244, 0) 100%
/* #eff0f4 完全透明 */
);
z-index: 4;
pointer-events: none;
}
.bgc-image {
width: 500rpx;
height: 200rpx;
position: absolute;
top: -50rpx;
left: 0;
}
.font-phone {
font-size: 35rpx;
font-weight: 600;
margin-left: 30rpx;
}
.phone-ball {
width: 50rpx;
height: 50rpx;
position: absolute;
top: 50%;
transform: translateY(-50%);
right: 130rpx;
}
.target {
--color: #99C9FD;
--thick: 2px;
--radius: 60rpx;
--outline-offset: 0rpx;
/* 外扩多少 */
/* 内层虚线(你现在用的) */
border-radius: var(--radius);
background-color: #ddf0ff;
/* 内部背景 */
animation: scalePulse 360ms cubic-bezier(.2, .8, .2, 1);
/* 外层虚线:放在 outline不会影响元素尺寸 */
outline: var(--thick) dashed var(--color);
outline-offset: var(--outline-offset);
/* 保证文本 / 子元素在最上层 */
position: relative;
z-index: 1;
}
.targetbutton {
--color: #99C9FD;
--thick: 2px;
--radius: 60rpx;
--outline-offset: 10rpx;
/* 外扩多少 */
/* 内层虚线(你现在用的) */
border-radius: var(--radius);
// background-color: #ddf0ff;
/* 内部背景 */
animation: scalePulse 360ms cubic-bezier(.2, .8, .2, 1);
/* 外层虚线:放在 outline不会影响元素尺寸 */
outline: var(--thick) dashed var(--color);
outline-offset: var(--outline-offset);
/* 保证文本 / 子元素在最上层 */
position: relative;
z-index: 1;
}
.picture {
display: flex;
margin-top: 150rpx;
.picture-card {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin-left: 20rpx;
margin-right: 10rpx;
width: 200rpx;
.bgc-card {
width: 100%;
height: 130rpx;
background-color: #EAEAEC;
border-radius: 30rpx;
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 10rpx;
}
}
}
.jump-white {
position: absolute;
bottom: 20rpx;
left: 50rpx;
width: 300rpx;
height: 400rpx;
background-color: #fff;
border-radius: 30rpx;
box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.1)
}
.jump-item{
margin: 10rpx 10rpx;
height: 60rpx;
justify-content: center;
width: 93%;
display: flex;
border-radius: 20rpx;
align-items: center;
}
</style>