hldy_app/pages/NursingNew/component/equipment.vue

2315 lines
54 KiB
Vue
Raw Normal View History

<template>
<view class="index-content-other" :style="transition?{opacity: `1`}:{opacity: `0`}">
<view class="zhezhao" v-show="openqingling || openlahzha || openbaoxiu || openhehzha || openchaobiao"
@click="closeall()">
<view class="neuro-box" @click.stop v-if="openqingling">
<view class="button-father">
<view :class="!buttonposition?`buttontarget button`:`button-white` " @click="openqingling=false">
取消</view>
<view :class="buttonposition?`buttontarget button`:`button-white` " @click="qingling()">确定</view>
</view>
<view class="card-font">
确定要清零吗
</view>
</view>
<view class="neuro-box-chaobiao" @click.stop v-if="openchaobiao">
<view class="button-father">
<view :class="!buttonposition?`buttontarget button`:`button-white` " @click="openchaobiao=false">
取消</view>
<view :class="buttonposition?`buttontarget button`:`button-white` " @click="chaobiao()">确定</view>
</view>
<view class="card-font">
确定要抄表吗
</view>
</view>
<view class="neuro-box-lazha" @click.stop v-if="openlahzha">
<view class="button-father">
<view :class="!buttonposition?`buttontarget button`:`button-white` " @click="openlahzha=false">取消
</view>
<view :class="buttonposition?`buttontarget button`:`button-white` " @click="kongzha(`10`)">确定</view>
</view>
<view class="card-font">
确定要{{ typeNow===1?'拉闸' : typeNow===2?'开阀' :"" }}
</view>
</view>
<view class="neuro-box-baoxiu" @click.stop v-if="openbaoxiu">
<view class="button-father">
<view :class="!buttonposition?`buttontarget button`:`button-white` " @click="openbaoxiu=false">取消
</view>
<view :class="buttonposition?`buttontarget button`:`button-white` " @click="baoxiu()">确定</view>
</view>
<view class="card-font">
确定要报修吗
</view>
</view>
<view class="neuro-box-lazha" @click.stop v-if="openhehzha">
<view class="button-father">
<view :class="!buttonposition?`buttontarget button`:`button-white` " @click="openhehzha=false">取消
</view>
<view :class="buttonposition?`buttontarget button`:`button-white` " @click="kongzha(`11`)">确定</view>
</view>
<view class="card-font">
确定要{{ typeNow===1?'合闸' : typeNow===2?'关阀' :"" }}
</view>
</view>
</view>
<view class="right-container-title-nav">
<text style="margin-left: 30rpx;">
NUID{{ uni.getStorageSync('nuId')}}
</text>
<text class="new-weight">
{{ uni.getStorageSync('nuName')}}
</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>
<image class="right-icons-img" :src="`/static/index/undericons/man.png`" />
<view>{{name}}</view>
</view>
</view>
<view class="scroll-vi">
<view class="zhezhao-left"></view>
<view class="zhezhao-right"></view>
<scroll-view scroll-x="true" style="width: 100%;height: 100%;">
<view style="display: flex;align-items: center;">
2025-10-27 17:16:52 +08:00
<view style="width: 100rpx;"></view>
<view v-for="(item,index) in allArray" :key="index"
:class="{zerotarget: movetype===0 && zeroIndex===index}" class="menu"
:style="{backgroundColor: movetype===0 && zeroIndex===index?`#ddf0ff`:``}"
2025-10-27 17:16:52 +08:00
@click="typeNowtarget=index;zeroIndex=index;clean();movetype=0;changeallmessage()">
2025-10-27 17:16:52 +08:00
<donghua :links="item.donghuapian" :playing="typeNowtarget===index" />
<text class="menu-font" :class="{ zoom: typeNowtarget===index }"
:style="typeNowtarget===index?{color:`#008FF5`}:{}">
{{item.lookName}}
</text>
</view>
<view style="width: 100rpx;">
</view>
</view>
</scroll-view>
</view>
2025-10-27 17:16:52 +08:00
<view class="right-right" v-show="!typeNow">
<view class="bottom-view">
<view class="shebei">
设备名称:{{ rightmessage.deviceName }}
<view class="status-button" style="margin-top: 20rpx;margin-bottom: 10rpx;">
{{rightmessage.deviceStatus=='1'?'在线':'离线'}}
</view>
</view>
<view v-for="(item,index) in cameraArray" class="small-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>4 ? index +1 :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="rightjumpopen">
<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="rightjumpopen=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 class="" v-show="!typeNow"> -->
<view class="big-bgc" v-show="!typeNow">
<view
style="width: 100%;height: 100%;z-index: 1;display: flex;justify-content: center;align-items: center;background-color: rgba(226, 227, 231, 0.5);">
<view style="position: relative;">
<image style="width: 600rpx;height: 600rpx;margin-top: -150rpx;" src="/static/nocamera.png" />
<view
style="color: #4D5561;font-size: 32rpx;position: absolute;left: 50%;bottom: 100rpx;transform: translateX(-50%);">
暂无视频内容显示
</view>
</view>
</view>
</view>
<view class="picture" v-show="!typeNow">
<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':''}"
:class="{target: index === bottomTargetIndex}">
<image style="width: 90rpx;height: 90rpx;"
:src="`/static/index/picture/${index}${downtarget===index?1:0}.png`" />
</view>
{{item}}
</view>
</view>
<!-- </view> -->
<view class="index-father" v-show="typeNow===1">
2025-10-27 17:16:52 +08:00
<view class="photo-father">
<view class="juzhong" style="margin-left: -50rpx;">
<donghua :width="`1500rpx`" :height="`1000rpx`" :links="blueArray" :playing="photoplay" :loop="true"
:interval="120" />
</view>
<view class="donghua-number">
{{ randomValue }}
</view>
<view class="weight-time">
{{indexmessage.eleValue?indexmessage.eleValue:'0.00'}}
<view class="big-font-right">
2025-10-27 17:16:52 +08:00
<view class="font-top">
KWH
</view>
<view class="right-kuai">
用电量
</view>
</view>
</view>
<image class="big-img" :src="`/static/index/newindex/wendu/3.png`" />
<view class="bottom-father">
<view class="status-button">
{{indexmessage.relayState=='1'?'合闸':'拉闸'}}
</view>
<view class="status-font">
SN{{indexmessage.address}}
</view>
<view class="status-time">
上次抄表时间{{indexmessage.readTime?indexmessage.readTime:'未抄表'}}
</view>
</view>
</view>
<view class="left-menu">
<view v-for="(item,index) in leftArray" :key="index" class="buttons-father"
@click="clickLeftMenu(index)">
<view class="left-ball" :class="{firsttarget: movetype===1 && zeroIndex===index}"
:style="{backgroundColor: movetype===1 && zeroIndex===index?`#ddf0ff`:``}">
<donghua :width="`50rpx`" :height="`50rpx`" :links="item" style="width: 50rpx;height: 50rpx;"
:playing="movetype===1 && zeroIndex===index" :loop="false" :interval="120" />
</view>
<view class="">
{{ buttonName[index] }}
</view>
</view>
</view>
<view class="right-menu">
<view v-for="(item,index) in rightArray" :key="index" class="buttons-father"
@click="clickRightMenu(index)">
<view class="left-ball" :class="{firsttarget: movetype===2 && zeroIndex===index}"
:style="{backgroundColor: movetype===2 && zeroIndex===index?`#ddf0ff`:``}">
<donghua :width="`50rpx`" :height="`50rpx`" :links="item" style="width: 50rpx;height: 50rpx;"
:playing="movetype===2 && zeroIndex===index" :loop="false" :interval="120" />
</view>
<view style="position: relative;">
{{ index==1 ? buttonName[5] : indexmessage.relayState === '1'? buttonName[3] : buttonName[4]}}
<image v-if="!index" class="biga-img" src="/static/index/newindex/leftmenu/biga.png" />
</view>
</view>
</view>
</view>
<view class="index-father" v-show="typeNow===2">
<view class="photo-father">
<view class="juzhong" style="margin-left: -50rpx;">
<donghua :width="`1500rpx`" :height="`1000rpx`" :links="blueArray" :playing="photoplay" :loop="true"
:interval="120" />
</view>
<view class="water-donghua-number">
{{ randomValue }}
</view>
<view class="weight-time">
{{watermessage.waterValue?watermessage.waterValue:'0.00'}}
<view class="big-font-right">
2025-10-27 17:16:52 +08:00
<view class="font-top">
</view>
<view class="right-kuai">
用水量
</view>
</view>
</view>
<image class="big-img" :src="`/static/index/newindex/wendu/4.png`" />
<view class="bottom-father">
<view class="status-button">
{{watermessage.relayState=='1'?'关阀':'开阀'}}
</view>
<view class="status-font">
SN{{watermessage.address}}
</view>
<view class="status-time">
上次抄表时间{{watermessage.readTime?watermessage.readTime:'未抄表'}}
</view>
</view>
</view>
<view class="left-menu">
<view v-for="(item,index) in leftArray" :key="index" class="buttons-father"
@click="clickLeftMenu(index)">
<view class="left-ball" :class="{firsttarget: movetype===1 && zeroIndex===index}"
:style="{backgroundColor: movetype===1 && zeroIndex===index?`#ddf0ff`:``}">
<donghua :width="`50rpx`" :height="`50rpx`" :links="item" style="width: 50rpx;height: 50rpx;"
:playing="movetype===1 && zeroIndex===index" :loop="false" :interval="120" />
</view>
<view class="">
{{ waterbuttonName[index] }}
</view>
</view>
</view>
<view class="right-menu">
<view v-for="(item,index) in rightArray" :key="index" class="buttons-father"
@click="clickRightMenu(index)">
<view class="left-ball" :class="{firsttarget: movetype===2 && zeroIndex===index}"
:style="{backgroundColor: movetype===2 && zeroIndex===index?`#ddf0ff`:``}">
<donghua :width="`50rpx`" :height="`50rpx`" :links="item" style="width: 50rpx;height: 50rpx;"
:playing="movetype===2 && zeroIndex===index" :loop="false" :interval="120" />
</view>
<view style="position: relative;">
{{ index==1 ? waterbuttonName[5] : watermessage.relayState === '1'? waterbuttonName[3] : waterbuttonName[4]}}
<image v-if="!index" class="biga-img" src="/static/index/newindex/leftmenu/biga.png" />
</view>
</view>
</view>
</view>
2025-10-27 17:16:52 +08:00
<view class="index-father" v-show="typeNow===3">
<view class="photo-father">
<view class="juzhong" style="margin-left: -50rpx;">
<donghua :width="`1500rpx`" :height="`1000rpx`" :links="blueArray" :playing="photoplay" :loop="true"
:interval="120" />
</view>
<view class="wendu-juzhong">
<view class="wendu-top">
<view class="wendu-top-left">
{{ randomValue?splitParts(randomValue).intPart:'-' }}
</view>
<view class="wendu-top-right">
<view class="">
</view>
<view class="">
.{{ randomValue?splitParts(randomValue).fracDigits:'-' }}
</view>
</view>
</view>
<view class="wendu-heng"></view>
<view class="wendu-bottom">
{{tempmessage.humidity?tempmessage.humidity:'-'}} %
</view>
</view>
<view class="weight-time">
{{tempmessage.temperature?tempmessage.temperature:'-'}}
<view class="big-font-right">
<view class="font-top">
</view>
<view class="right-kuai">
温度
</view>
</view>
<view class="zhongjian-shu"></view>
{{tempmessage.humidity?tempmessage.humidity:'-'}}
<view class="big-font-right">
<view class="font-top">
%
</view>
<view class="right-kuai">
湿度
</view>
</view>
</view>
<image class="big-img" :src="`/static/index/newindex/wendu/5.png`" />
<view class="bottom-father">
<view class="status-button">
{{ tempmessage.maintainStatus == 0 ? '正常' : tempmessage.maintainStatus == 1 ? '维修中' : tempmessage.maintainStatus == 2 ? '报废' : '' }}
</view>
<view class="status-font">
SN{{tempmessage.sn}}
</view>
<view class="status-time">
上次抄表时间{{tempmessage.reportingTime?tempmessage.reportingTime:'未抄表'}}
</view>
</view>
</view>
<view class="left-menu">
<view v-for="(item,index) in wenduleftArray" :key="index" class="buttons-father"
@click="clickLeftMenu(index)">
<view class="left-ball" :class="{firsttarget: movetype===1 && zeroIndex===index}"
:style="{backgroundColor: movetype===1 && zeroIndex===index?`#ddf0ff`:``}">
<donghua :width="`50rpx`" :height="`50rpx`" :links="item" style="width: 50rpx;height: 50rpx;"
:playing="movetype===1 && zeroIndex===index" :loop="false" :interval="120" />
</view>
<view class="">
{{ wendubuttonName[index] }}
</view>
</view>
</view>
<view class="right-menu">
<view v-for="(item,index) in wendurightArray" :key="index" class="buttons-father"
@click="clickRightMenu(index)">
<view class="left-ball" :class="{firsttarget: movetype===2 && zeroIndex===index}"
:style="{backgroundColor: movetype===2 && zeroIndex===index?`#ddf0ff`:``}">
<donghua :width="`50rpx`" :height="`50rpx`" :links="item" style="width: 50rpx;height: 50rpx;"
:playing="movetype===2 && zeroIndex===index" :loop="false" :interval="120" />
</view>
<view style="position: relative;">
{{ index==1 ? wendubuttonName[1] : wendubuttonName[2]}}
<image v-if="!index" class="biga-img" src="/static/index/newindex/leftmenu/biga.png" />
</view>
</view>
</view>
</view>
<joysticknew @movecard="movecamera" v-show="!typeNow" />
</view>
</template>
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, computed, nextTick, defineProps, watch, onUnmounted } from 'vue';
import {
electricityMeterlist, electricityMetereleReset, electricityMetereleControl, electricityMeterbaoxiu, electricityMeteleRead,
2025-10-27 17:16:52 +08:00
waterwaterReset, waterwaterControl, waterbaoxiu, waterwaterRead, humidDevicebaoxiu, updateDeviceRealTime
} from "./api.js"
2025-10-27 17:16:52 +08:00
import { movedirection, queryPadPageList } from '@/pages/watch/api/lunpan.js'
import joysticknew from '@/component/public/newgame/joysticknew.vue';
const props = defineProps({
isShow: {
type: Boolean,
required: true,
},
propsmove: {
type: Number
},
isMain: {
type: Boolean
}
});
const movetype = ref(-1);
const buttonposition = ref(false);
const base = genPaths(
'/static/index/newindex/curve',
'curve_',
9,
'png',
1,
false
)
const blueArray = ref([
...base,
...[...base].reverse() // 先拷贝一份再反转,避免修改原 base
])
2025-10-27 17:16:52 +08:00
const downpicture = [
"原图",
"全景拉伸",
"四分屏",
"180°全景",
"360°全景"
]
const bottomTargetIndex = ref(-1);
const downtarget = ref(-1);
const second = ref(0);
const cameraArray = ref([
"截图",
"录制",
"对讲",
"静音",
"预警",
// "返回",
"图片",
"视频",
"清晰度",
"翻转",
])
const cameratarget = ref([]);
const wheelRef = ref(null);
const movecamera = (type : number) => {
handleKey(type)
}
// 对 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)
function doSomething() {
wheelRef.value?.startchange()
if (first.value === 0) {
if (second.value) {
uni.$emit('smallmonitor:toggleVolume');
} else {
uni.$emit('smallmonitor:toggleVolume');
}
}
if (first.value === 1) {
if (second.value) {
uni.$emit('smallmonitor:stopTalk');
} else {
uni.$emit('smallmonitor:openTalk');
}
}
if (first.value === 2) {
uni.$emit('smallmonitor:doSnapshot');
}
if (first.value === 3) {
if (second.value) {
uni.$emit('smallmonitor:stopRecord');
} else {
uni.$emit('smallmonitor: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('smallmonitor:changeQuality'); // 发起截图请求,不关心回调
}
}
if (first.value === 6) {
uni.$emit('smallmonitor:switchDisplay', second.value)
}
if (first.value === 7) {
if (second.value === 3) {
uni.$emit('smallmonitor:flipImage', 6)
} else {
uni.$emit('smallmonitor:flipImage', second.value)
}
}
if (first.value === 8) {
if (second.value) {
uni.$emit('smallmonitor:stopAlarm')
} else {
uni.$emit('smallmonitor:startAlarm')
}
}
}
function useThrottle(fn : () => void, delay = 1000) {
let throttling = false
return () => {
if (throttling) return
fn()
throttling = true
setTimeout(() => {
throttling = false
}, delay)
}
}
const gaoqing = ref(0);
const yuntai = ref(false);
const savefirst = ref(-1);
const first = ref(5);
// 核心逻辑
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
}
}
// 当前活跃的方向0,1,2,3
// -1 表示没有活跃方向
let activeDir = -1
// 定时器 mapkey = 方向
const stopTimers : Record<number, any> = {}
// 管理方向的开始/停止
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) => { })
clearTimeout(stopTimers[type])
stopTimers[type] = null
if (activeDir === type) activeDir = -1
}
// 简单的宽松解析函数
function parseDateFlexible(s) {
if (s instanceof Date) return s
if (typeof s !== 'string') throw new Error('birth must be string or Date')
// 支持 "YYYY-MM-DD" 或 "YYYY年MM月DD日" 或 "YYYY/MM/DD"
const m = s.match(/(\d{4})\D+(\d{1,2})\D+(\d{1,2})/)
if (!m) throw new Error('无法解析的日期格式')
return new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]))
}
const removeIndexOnce = (index : number) => {
const pos = cameratarget.value.indexOf(index)
if (pos !== -1) {
cameratarget.value.splice(pos, 1) // 从 pos 开始删除 1 个元素
}
}
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 jumpopen = ref(false);
const rightjumpopen = ref(false);
const clickcamera = (index : number) => {
switch (index) {
case 0:
// 触发快照事件
uni.$emit('smallmonitor: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('smallmonitor:stopRecord');
removeIndexOnce(index)
} else {
uni.$emit('smallmonitor:startRecord');
cameratarget.value.push(index)
}
break
case 2:
if (cameratarget.value.includes(index)) {
uni.$emit('smallmonitor:stopTalk');
removeIndexOnce(index)
} else {
uni.$emit('smallmonitor:openTalk');
cameratarget.value.push(index)
}
break
case 3:
if (cameratarget.value.includes(index)) {
uni.$emit('smallmonitor:toggleVolume');
removeIndexOnce(index)
} else {
uni.$emit('smallmonitor:toggleVolume');
cameratarget.value.push(index)
}
break
case 4:
if (cameratarget.value.includes(index)) {
uni.$emit('smallmonitor:stopAlarm')
removeIndexOnce(index)
} else {
uni.$emit('smallmonitor:startAlarm')
cameratarget.value.push(index)
}
break
// case 5:
// jumpopen.value = false;
// uni.navigateBack()
// break
case 5:
if (cameratarget.value.includes(index)) {
removeIndexOnce(index)
} else {
cameratarget.value.push(index)
}
break
case 6:
if (cameratarget.value.includes(index)) {
removeIndexOnce(index)
} else {
cameratarget.value.push(index)
}
break
case 7:
if (cameratarget.value.includes(index)) {
uni.$emit('smallmonitor:changeQuality');
removeIndexOnce(index)
} else {
uni.$emit('smallmonitor:changeQuality');
cameratarget.value.push(index)
}
break
case 8:
rightjumpopen.value = true
break
}
}
const clickjump = (index : number) => {
wheretarget.value = index;
if (index === 3) {
uni.$emit('smallmonitor:flipImage', 6)
removeIndexOnce(9)
} else {
uni.$emit('smallmonitor:flipImage', index)
cameratarget.value.push(9)
}
}
const clickDownCard = (index : number) => {
// cleanandopen()
bottomTargetIndex.value = index;
// clickDownCard(0)
downtarget.value = index;
switch (index) {
case 0:
uni.$emit('smallmonitor:switchDisplay', 0)
break
case 1:
uni.$emit('smallmonitor:switchDisplay', 4)
break
case 2:
uni.$emit('smallmonitor:switchDisplay', 1)
break
case 3:
uni.$emit('smallmonitor:switchDisplay', 2)
break
case 4:
uni.$emit('smallmonitor:switchDisplay', 3)
break
}
}
// 监听 isMain 的变化,但只在 isShow 为 true 时响应
watch(
() => props.isMain,
(newVal, oldVal) => {
// 如果不是从一个明确的布尔值变到另一个(例如首次 undefined -> 布尔),可以按需忽略
if (typeof oldVal !== 'boolean') return
if (!props.isShow) return
if (lanjie.value) {
lanjie.value = false
return
}
if (oldVal === true && newVal === false) {
movetype.value = 0;
zeroIndex.value = 0;
2025-10-27 17:16:52 +08:00
typeNowtarget.value = zeroIndex.value;
changeallmessage()
} else if (oldVal === false && newVal === true) {
movetype.value = -1
zeroIndex.value = -1
2025-10-27 17:16:52 +08:00
typeNowtarget.value = 0;
changeallmessage()
}
2025-10-27 17:16:52 +08:00
// console.log("?????",typeNowtarget.value)
}
)
const zeroIndex = ref(-1)
const emit = defineEmits(['back', 'cleanmain', `canback`])
const savetopindex = ref(0)
2025-10-27 17:16:52 +08:00
const removeTimers = new Map<number, ReturnType<typeof setTimeout>>();
onBeforeUnmount(() => {
for (const t of removeTimers.values()) {
clearTimeout(t)
}
removeTimers.clear()
})
watch(
() => props.propsmove,
() => {
if (movetype.value != -1) {
if (openqingling.value || openlahzha.value || openbaoxiu.value || openhehzha.value || openchaobiao.value) {
switch (props.propsmove) {
case 0:
break;
case 1:
buttonposition.value = !buttonposition.value
break;
case 2:
break;
case 3:
buttonposition.value = !buttonposition.value
break;
case 4:
if (buttonposition.value) {
if (openqingling.value) {
qingling()
}
if (openlahzha.value) {
kongzha(`10`)
}
if (openbaoxiu.value) {
baoxiu()
}
if (openhehzha.value) {
kongzha(`11`)
}
if (openchaobiao.value) {
chaobiao()
}
} else {
closeall()
}
break;
case 5:
closeall()
default:
}
return
}
switch (movetype.value) {
case 0:
switch (props.propsmove) {
case 0:
movetype.value = -1
zeroIndex.value = -1
emit("back")
break;
case 1:
2025-10-27 17:16:52 +08:00
if (zeroIndex.value < allArray.value.length - 1) {
zeroIndex.value++
2025-10-27 17:16:52 +08:00
typeNowtarget.value = zeroIndex.value;
changeallmessage()
}
break;
case 2:
2025-10-27 17:16:52 +08:00
if (typeNow.value) {
savetopindex.value = zeroIndex.value;
movetype.value = 1
zeroIndex.value = 0
}
break;
case 3:
if (zeroIndex.value) {
zeroIndex.value--
2025-10-27 17:16:52 +08:00
typeNowtarget.value = zeroIndex.value;
changeallmessage()
} else {
movetype.value = -1
zeroIndex.value = -1
emit("back")
}
break;
case 4:
2025-10-27 17:16:52 +08:00
typeNowtarget.value = zeroIndex.value;
break;
default:
}
break;
case 1:
switch (props.propsmove) {
case 0:
if (zeroIndex.value) {
zeroIndex.value--
} else {
movetype.value = 0
zeroIndex.value = savetopindex.value
2025-10-27 17:16:52 +08:00
typeNowtarget.value = savetopindex.value;
}
break;
case 1:
zeroIndex.value = 0
movetype.value = 2
break;
case 2:
2025-10-27 17:16:52 +08:00
if (typeNow.value != 3) {
if (zeroIndex.value < 2) {
zeroIndex.value++
}
} else {
if (zeroIndex.value < 1) {
zeroIndex.value++
}
}
break;
case 3:
movetype.value = -1
zeroIndex.value = -1
emit("back")
break;
case 4:
2025-10-27 17:16:52 +08:00
if (typeNow.value != 3) {
if (!zeroIndex.value) {
openqingling.value = true;
emit("canback", true)
} else if (zeroIndex.value == 1) {
openchaobiao.value = true
emit("canback", true)
}
} else {
if (!zeroIndex.value) {
openchaobiao.value = true;
emit("canback", true)
} else if (zeroIndex.value == 1) {
// openchaobiao.value = true
// emit("canback", true)
}
}
break;
default:
}
break;
case 2:
switch (props.propsmove) {
case 0:
if (zeroIndex.value) {
zeroIndex.value--
} else {
movetype.value = 0
zeroIndex.value = savetopindex.value
2025-10-27 17:16:52 +08:00
typeNowtarget.value = savetopindex.value;
}
break;
case 1:
break;
case 2:
2025-10-27 17:16:52 +08:00
if (typeNow.value != 3) {
if (zeroIndex.value < 1) {
zeroIndex.value++
}
} else {
}
break;
case 3:
zeroIndex.value = 0
movetype.value = 1
break;
case 4:
2025-10-27 17:16:52 +08:00
if (typeNow.value != 3) {
if (!zeroIndex.value) {
if (indexmessage.value.relayState === '1') {
openlahzha.value = true
emit("canback", true)
} else {
openhehzha.value = true
emit("canback", true)
}
} else {
2025-10-27 17:16:52 +08:00
openbaoxiu.value = true;
emit("canback", true)
}
} else {
openbaoxiu.value = true;
emit("canback", true)
}
break;
default:
}
break;
}
}
}
)
const typeNow = ref(-1);
2025-10-27 17:16:52 +08:00
const typeNowtarget = ref(-1);
const photoplay = ref(false)
const downArray = ref()
const scrollTop = ref(0);
const openqingling = ref(false);
const openlahzha = ref(false);
const openhehzha = ref(false);
const openbaoxiu = ref(false);
const openchaobiao = ref(false);
const qingling = () => {
closeall()
if (typeNow.value == 1) {
electricityMetereleReset(indexmessage.value.cid, indexmessage.value.address).then((res : any) => {
uni.showToast({
title: res.message,
icon: 'none', // 'success' | 'none' (小程序还有 'loading'
duration: 1500,
mask: false
})
setTimeout(() => {
init()
}, 4000)
})
} else if (typeNow.value == 2) {
waterwaterReset(watermessage.value.cid, watermessage.value.address).then((res : any) => {
uni.showToast({
title: res.message,
icon: 'none', // 'success' | 'none' (小程序还有 'loading'
duration: 1500,
mask: false
})
setTimeout(() => {
init()
}, 4000)
})
}
}
const kongzha = (type : string) => {
closeall()
if (typeNow.value == 1) {
electricityMetereleControl(indexmessage.value.cid, indexmessage.value.address, type).then((res : any) => {
uni.showToast({
title: res.message,
icon: 'none', // 'success' | 'none' (小程序还有 'loading'
duration: 1500,
mask: false
})
setTimeout(() => {
init()
}, 4000)
})
} else if (typeNow.value == 2) {
if (type == '10') {
type = '43'
} else {
type = '53'
}
waterwaterControl(watermessage.value.cid, watermessage.value.address, type).then((res : any) => {
uni.showToast({
title: res.message,
icon: 'none', // 'success' | 'none' (小程序还有 'loading'
duration: 1500,
mask: false
})
setTimeout(() => {
init()
}, 4000)
})
}
}
const chaobiao = () => {
closeall()
if (typeNow.value == 1) {
electricityMeteleRead(indexmessage.value.cid, indexmessage.value.address).then((res : any) => {
uni.showToast({
title: res.message,
icon: 'none', // 'success' | 'none' (小程序还有 'loading'
duration: 1500,
mask: false
})
setTimeout(() => {
init()
}, 4000)
})
} else if (typeNow.value == 2) {
waterwaterRead(watermessage.value.cid, watermessage.value.address).then((res : any) => {
uni.showToast({
title: res.message,
icon: 'none', // 'success' | 'none' (小程序还有 'loading'
duration: 1500,
mask: false
})
setTimeout(() => {
init()
}, 4000)
})
2025-10-27 17:16:52 +08:00
} else if (typeNow.value == 3) {
updateDeviceRealTime(tempmessage.value.sn).then((res : any) => {
uni.showToast({
title: res.message,
icon: 'none', // 'success' | 'none' (小程序还有 'loading'
duration: 1500,
mask: false
})
setTimeout(() => {
init()
}, 4000)
})
}
}
const baoxiu = () => {
closeall()
if (typeNow.value == 1) {
electricityMeterbaoxiu(indexmessage.value.id).then((res : any) => {
uni.showToast({
title: res.message,
icon: 'none', // 'success' | 'none' (小程序还有 'loading'
duration: 1500,
mask: false
})
console.log("!1", res)
setTimeout(() => {
init()
}, 4000)
})
} else if (typeNow.value == 2) {
waterbaoxiu(watermessage.value.id).then((res : any) => {
uni.showToast({
title: res.message,
icon: 'none', // 'success' | 'none' (小程序还有 'loading'
duration: 1500,
mask: false
})
console.log("!1", res)
setTimeout(() => {
init()
}, 4000)
2025-10-27 17:16:52 +08:00
})
} else if (typeNow.value == 3) {
humidDevicebaoxiu(tempmessage.value.id).then((res : any) => {
uni.showToast({
title: res.message,
icon: 'none', // 'success' | 'none' (小程序还有 'loading'
duration: 1500,
mask: false
})
// console.log("!1", res)
setTimeout(() => {
init()
}, 4000)
})
}
}
const closeall = () => {
openqingling.value = false;
openlahzha.value = false;
openbaoxiu.value = false;
openhehzha.value = false;
openchaobiao.value = false;
buttonposition.value = false;
emit("canback", false)
}
const clickLeftMenu = (index : number) => {
zeroIndex.value = index;
clean();
movetype.value = 1;
2025-10-27 17:16:52 +08:00
if (typeNow.value != 3) {
if (movetype.value === 1 && !index) {
openqingling.value = true;
emit("canback", true)
} else if (index == 1) {
openchaobiao.value = true;
emit("canback", true)
}
} else {
if (!index) {
openchaobiao.value = true;
emit("canback", true)
}
}
2025-10-27 17:16:52 +08:00
}
const clickRightMenu = (index : number) => {
zeroIndex.value = index;
clean();
movetype.value = 2;
2025-10-27 17:16:52 +08:00
if (typeNow.value != 3) {
if (!index) {
if (indexmessage.value.relayState === '1') {
openlahzha.value = true
emit("canback", true)
} else {
openhehzha.value = true
emit("canback", true)
}
} else {
2025-10-27 17:16:52 +08:00
openbaoxiu.value = true;
emit("canback", true)
}
} else {
openbaoxiu.value = true;
emit("canback", true)
}
}
function onScroll(e) {
scrollTop.value = e.detail.scrollTop
}
// 通用的生成函数
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 leftArray = ref([genPaths(
'/static/index/newindex/leftmenu',
'zero',
11, // 张数
'png',
0, // 起始索引
false // 不补零
),
genPaths(
'/static/index/newindex/leftmenu',
'read',
8, // 张数
'png',
1, // 起始索引
false // 不补零
),
genPaths(
'/static/index/newindex/leftmenu',
'Log',
10, // 张数
'png',
0, // 起始索引
false // 不补零
)],
)
2025-10-27 17:16:52 +08:00
const wenduleftArray = ref([
genPaths(
'/static/index/newindex/leftmenu',
'read',
8, // 张数
'png',
1, // 起始索引
false // 不补零
),
genPaths(
'/static/index/newindex/leftmenu',
'Log',
10, // 张数
'png',
0, // 起始索引
false // 不补零
)],
)
const wendurightArray = ref([
genPaths(
'/static/index/newindex/rightmenu',
'service',
5, // 张数
'png',
0, // 起始索引
false // 不补零
)],
)
const rightArray = ref([])
const waterrightArray = ref([])
const mobanrightArray = ref([genPaths(
'/static/index/newindex/rightmenu',
'closes',
12, // 张数
'png',
0, // 起始索引
false // 不补零
),
genPaths(
'/static/index/newindex/rightmenu',
'switch',
7, // 张数
'png',
0, // 起始索引
false // 不补零
),
genPaths(
'/static/index/newindex/rightmenu',
'service',
5, // 张数
'png',
0, // 起始索引
false // 不补零
)],
)
const buttonName = ref(['清零', "抄表", "日志", "拉闸", "合闸", "报修"])
const waterbuttonName = ref(['清零', "抄表", "日志", "开阀", "关阀", "报修"])
2025-10-27 17:16:52 +08:00
const wendubuttonName = ref(["抄表", "日志", "报修"])
const typeArray = ref([
{
url: genPaths(
'/static/index/newindex/shebei',
'Camera',
9, // 张数
'png',
0, // 起始索引为 1
false // 不补零
), name: '摄像头'
},
{
url: genPaths(
'/static/index/newindex/shebei',
'cable',
10, // 张数
'png',
0, // 起始索引为 1
false // 不补零
), name: '智能电表'
},
{
url: genPaths(
'/static/index/newindex/shebei',
'river',
13, // 张数
'png',
0, // 起始索引为 1
false // 不补零
), name: '智能水表'
},
{
url: genPaths(
'/static/index/newindex/shebei',
'humiture',
9, // 张数
'png',
0, // 起始索引为 1
false // 不补零
), name: '温湿度计'
},
])
// 使用watch监听isShow变化
const transition = ref(false);
2025-10-27 17:16:52 +08:00
//取小数点前后
function splitParts(num) {
const s = String(num);
if (!s.includes('.')) return { intPart: s, fracDigits: '' }; // 没有小数点
const [intPart, fracDigits] = s.split('.');
return { intPart, fracDigits };
}
watch(
() => props.isShow,
(newVal, oldVal) => {
// 当旧值为false新值为true时延迟0.2秒调用方法
if (!oldVal && newVal) {
transition.value = false;
// console.log("????",transition.value)
setTimeout(() => {
transition.value = true;
}, 50)
} else {
transition.value = false;
}
}
)
const name = ref("");
//随机数
const randomValue = ref(0)
let timer = null
// function getRandomNumber() {
// return Number((Math.random() * 100000).toFixed(2))
// }
function rollTo(target) {
let current = 0
2025-10-27 17:16:52 +08:00
const duration = 200 // 滚动总时长1秒
const steps = 60 // 每秒大约 60 帧
const interval = duration / steps
const step = target / steps
clearInterval(timer) // 防止上一个定时器干扰
timer = setInterval(() => {
current += step
if (current >= target) {
current = target
clearInterval(timer)
}
randomValue.value = Number(current.toFixed(2))
}, interval)
}
const indexmessage = ref({
eleValue: "",
address: "",
readTime: "",
relayState: `0`,
cid: 0,
id: 0,
})
const watermessage = ref({
waterValue: "",
address: "",
readTime: "",
relayState: `0`,
cid: 0,
id: 0,
})
2025-10-27 17:16:52 +08:00
const tempmessage = ref({
temperature: "",
humidity: "",
maintainStatus: "",
sn: "",
reportingTime: "",
id: 0,
})
onMounted(() => {
name.value = uni.getStorageSync('realname')
typeNow.value = 0;
photoplay.value = true;
init();
})
const changeallmessage = () => {
2025-10-27 17:16:52 +08:00
uni.$emit('smallmonitor:isshow', false)
typeNow.value=allArray.value[typeNowtarget.value].typeNumber;
if (typeNow.value === 1) {
2025-10-27 17:16:52 +08:00
indexmessage.value = allArray.value[typeNowtarget.value]
const firstTarget = indexmessage.value.eleValue;
rollTo(Number(firstTarget))
} else if (typeNow.value === 2) {
2025-10-27 17:16:52 +08:00
watermessage.value = allArray.value[typeNowtarget.value]
const secondTarget = watermessage.value.waterValue
2025-10-27 17:16:52 +08:00
rollTo(Number(secondTarget))
2025-10-27 17:16:52 +08:00
} else if (typeNow.value === 3) {
tempmessage.value = allArray.value[typeNowtarget.value]
const thirdTarget = tempmessage.value.temperature
rollTo(Number(thirdTarget))
}
else if (!typeNow.value) {
rightmessage.value = allArray.value[typeNowtarget.value]
uni.$emit('smallmonitor:isshow', true)
}
}
2025-10-27 17:16:52 +08:00
const rightmessage = ref({
deviceName: "",
deviceStatus: "1"
});
const allArray = ref([]);
const init = () => {
2025-10-27 17:16:52 +08:00
allArray.value = [];
// console.log("????", uni.getStorageSync('serverUrl'), uni.getStorageSync('nuId'))
electricityMeterlist().then((res : any) => {
2025-10-27 17:16:52 +08:00
console.log("!!!", res.result)
if(res.result.cameraInfoEntityList.length && res.result.cameraInfoEntityList !=null){
res.result.cameraInfoEntityList.forEach((element:any,index:number)=>{
element.typeNumber = 0
element.lookName = "摄像头" + index;
element.donghuapian = typeArray.value[0].url
allArray.value.push(element)
})
}
if(res.result.electricityMeterEntityList.length && res.result.electricityMeterEntityList !=null){
res.result.electricityMeterEntityList.forEach((element:any,index:number)=>{
element.typeNumber = 1
element.lookName = "电表" + index
element.donghuapian = typeArray.value[1].url
allArray.value.push(element)
})
}
if(res.result.waterMeterEntityList.length && res.result.waterMeterEntityList !=null){
res.result.waterMeterEntityList.forEach((element:any,index:number)=>{
element.typeNumber = 2
element.lookName = "水表" + index
element.donghuapian = typeArray.value[2].url
allArray.value.push(element)
})
}
if(res.result.humidDeviceEntityList.length && res.result.humidDeviceEntityList !=null){
res.result.humidDeviceEntityList.forEach((element:any,index:number)=>{
element.typeNumber = 3
element.lookName = "温度计" + index
element.donghuapian = typeArray.value[3].url
allArray.value.push(element)
})
}
console.log("allArray.value",allArray.value)
uni.$emit('smallmonitor:killView');
if (!typeNow.value) {
if (res.result.cameraInfoEntityList[0].deviceName) {
console.log("????")
uni.$emit('smallmonitor:isshow', true);
// 加点延迟吧
setTimeout(() => {
rightmessage.value = res.result.cameraInfoEntityList[0]
uni.$emit('smallmonitor:changeinit', res.result.cameraInfoEntityList[0].deviceIndex);
}, 100)
} else {
uni.$emit('smallmonitor:isshow', false)
}
} else {
uni.$emit('smallmonitor:isshow', false)
}
rightmessage.value = res.result.cameraInfoEntityList
//温度计
tempmessage.value = res.result.humidDeviceEntityList[0];
// 这个是电表
indexmessage.value = res.result.electricityMeterEntityList[0]
if (indexmessage.value.relayState === '1') {
rightArray.value = [mobanrightArray.value[1], mobanrightArray.value[2]]
} else {
rightArray.value = [mobanrightArray.value[0], mobanrightArray.value[2]]
}
// 这个是水表
watermessage.value = res.result.waterMeterEntityList[0]
if (watermessage.value.relayState === '1') {
waterrightArray.value = [mobanrightArray.value[1], mobanrightArray.value[2]]
} else {
waterrightArray.value = [mobanrightArray.value[0], mobanrightArray.value[2]]
}
})
}
const lanjie = ref(false);
const clean = () => {
if (movetype.value == -1) {
lanjie.value = true;
emit("cleanmain")
}
}
onUnmounted(() => {
clearInterval(timer)
})
</script>
<style scoped lang="less">
.index-content-other {
width: calc(100% - 407rpx);
height: 100%;
transition: opacity 1s ease;
position: relative;
.index-father {
width: 100%;
height: 1100rpx;
}
.abs-time {
position: absolute;
right: 20rpx;
top: 150rpx;
.big-time {
font-size: 90rpx;
font-weight: 600;
width: 100%;
justify-content: center;
}
}
}
.right-container-title-nav {
margin-top: 60rpx;
display: flex;
align-items: center;
height: 60rpx;
position: relative;
font-size: 28rpx;
.new-weight {
margin-left: 30rpx;
font-weight: 600;
}
.right-icons {
position: absolute;
right: 30rpx;
top: 0;
display: flex;
align-items: center;
height: 60rpx;
}
.right-icons-img {
width: 60rpx;
height: 60rpx;
margin-left: 20rpx;
margin-right: 20rpx;
}
}
.scroll-vi {
height: 120rpx;
width: 95%;
margin-left: 20rpx;
margin-top: 20rpx;
position: relative;
margin-bottom: 80rpx;
.menu {
margin-top: 15rpx;
flex: 0 0 auto; // 👈 关键点
height: 90rpx;
width: 240rpx;
border-radius: 50rpx;
margin-right: 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;
}
}
}
.date {
display: flex;
justify-content: space-around;
margin-top: 10rpx;
}
.right-container-tem {
display: flex;
.right-container-tem-text {
font-size: 30rpx;
margin-right: 20rpx;
}
.right-container-tem-img {
width: 38rpx;
height: 38rpx;
}
}
.photo-father {
width: 100%;
height: 1100rpx;
display: flex;
flex-direction: column;
align-items: center;
position: relative;
}
.juzhong {
position: absolute;
top: 0%;
left: 50%;
transform: translate(-50%, -10%);
}
.weight-time {
font-weight: 800;
font-size: 100rpx;
margin-bottom: 0rpx;
margin-left: -50rpx;
display: flex;
align-items: center;
.big-font-right {
font-size: 35rpx;
font-weight: 500;
color: black;
margin-left: 30rpx;
display: flex;
flex-direction: column;
2025-10-27 17:16:52 +08:00
align-items: flex-start;
.font-top {
margin-left: 5rpx;
}
.right-kuai {
display: flex;
justify-content: center;
align-items: center;
background-color: #42A5F6;
color: #fff;
width: 110rpx;
height: 50rpx;
border-radius: 15rpx;
font-size: 25rpx;
}
}
}
.big-img {
width: 600rpx;
height: 600rpx;
// margin-top: 100rpx;
margin: 50rpx 0;
}
.left-menu {
position: absolute;
top: 50%;
left: 150rpx;
transform: translateY(-50%);
}
.zoom {
transform: scale(1.2);
transform-origin: bottom left;
transition: transform 1s ease;
}
.left-ball {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
background-color: #fff;
margin-bottom: 15rpx;
}
.right-menu {
position: absolute;
top: 50%;
right: 150rpx;
transform: translateY(-50%);
.right-scroll {
width: 100%;
height: 750rpx;
}
.white-circle {
height: 200rpx;
border-radius: 60rpx;
background-color: #fff;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
text-align: center;
.right-menu-img {
width: 80rpx;
height: 80rpx;
}
.right-menu-name {
width: 80rpx;
}
}
}
.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;
}
.zhezhao-right {
position: absolute;
top: 0rpx;
right: 0%;
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;
}
.zerotarget {
--color: #99C9FD;
--thick: 2px;
--radius: 50rpx;
--outline-offset: 0rpx;
/* 外扩多少 */
/* 内层虚线(你现在用的) */
border-radius: var(--radius);
background-color: white;
/* 内部背景 */
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: 0;
}
.firsttarget {
--color: #99C9FD;
--thick: 2px;
--radius: 50%;
--outline-offset: 0rpx;
/* 外扩多少 */
/* 内层虚线(你现在用的) */
border-radius: var(--radius);
background-color: white;
/* 内部背景 */
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: 0;
}
.buttontarget {
--color: #99C9FD;
--thick: 2px;
--radius: 30rpx;
--outline-offset: 0rpx;
/* 外扩多少 */
/* 内层虚线(你现在用的) */
border-radius: var(--radius);
background-color: white;
/* 内部背景 */
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: 0;
}
@keyframes scalePulse {
0% {
transform: scale(1);
}
25% {
/* 先收缩一点点 */
transform: scale(0.94);
}
65% {
/* 再放大到略超出的感觉 */
transform: scale(1.08);
}
100% {
transform: scale(1);
}
}
.buttons-father {
margin: 30rpx 0;
text-align: center;
position: relative;
}
.biga-img {
position: absolute;
right: -15rpx;
top: 50%;
transform: translateY(-50%);
width: 28rpx;
height: 28rpx;
}
2025-10-27 17:16:52 +08:00
.status-button {
color: #fff;
width: 120rpx;
height: 50rpx;
border-radius: 30rpx;
display: flex;
justify-content: center;
align-items: center;
background-color: #47ADF5;
}
.bottom-father {
width: 100%;
padding-left: 160rpx;
padding-top: 50rpx;
2025-10-27 17:16:52 +08:00
.status-font {
font-weight: 600;
font-size: 38rpx;
margin-top: 20rpx;
}
.status-time {
color: #666666;
margin-top: 20rpx;
}
}
.donghua-number {
position: absolute;
right: 1010rpx;
top: 265rpx;
z-index: 3;
font-size: 35rpx;
font-weight: 600;
}
.water-donghua-number {
position: absolute;
right: 980rpx;
top: 285rpx;
z-index: 3;
font-size: 32rpx;
font-weight: 600;
}
/* 拟态框 固定尺寸 + 阴影样式 + 相对定位于 wrapper */
.neuro-box {
position: absolute;
left: 700rpx;
top: 500rpx;
width: 400rpx;
height: 270rpx;
border-radius: 30rpx;
background-color: #fff;
display: flex;
flex-direction: column;
align-items: center;
z-index: 1;
padding: 0 10%;
z-index: 999;
}
.neuro-box-chaobiao {
position: absolute;
left: 700rpx;
top: 680rpx;
width: 400rpx;
height: 270rpx;
border-radius: 30rpx;
background-color: #fff;
display: flex;
flex-direction: column;
align-items: center;
z-index: 1;
padding: 0 10%;
z-index: 999;
}
.neuro-box-lazha {
position: absolute;
right: 300rpx;
top: 600rpx;
width: 400rpx;
height: 270rpx;
border-radius: 30rpx;
background-color: #fff;
display: flex;
flex-direction: column;
align-items: center;
z-index: 1;
padding: 0 10%;
z-index: 999;
}
.neuro-box-baoxiu {
position: absolute;
right: 300rpx;
top: 770rpx;
width: 400rpx;
height: 270rpx;
border-radius: 30rpx;
background-color: #fff;
display: flex;
flex-direction: column;
align-items: center;
z-index: 1;
padding: 0 10%;
z-index: 999;
}
.button {
width: 40%;
background-color: #ddf0ff;
display: flex;
justify-content: center;
align-items: center;
color: #007CFF;
border: 1rpx solid #007CFF;
font-size: 25rpx;
border-radius: 30rpx;
}
.card-font {
margin-top: 70rpx;
width: 600rpx;
justify-content: center;
display: flex;
}
.button-white {
width: 40%;
border: 2rpx solid #c3cacd;
background: linear-gradient(to bottom, #f3f3f5, #dee4e9);
display: flex;
justify-content: center;
align-items: center;
font-size: 25rpx;
border-radius: 30rpx;
}
.button-father {
position: absolute;
bottom: 60rpx;
left: 50%;
transform: translateX(-50%);
width: 100%;
height: 60rpx;
display: flex;
justify-content: space-around;
padding: 0 50rpx;
}
.zhezhao {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: 5;
}
2025-10-27 17:16:52 +08:00
.zhongjian-shu {
background-color: #E1E4E6;
width: 3rpx;
height: 70%;
margin: auto 70rpx;
}
.wendu-juzhong {
position: absolute;
top: 270rpx;
right: 900rpx;
width: 270rpx;
height: 270rpx;
z-index: 1;
display: flex;
align-items: flex-end;
flex-direction: column;
.wendu-top {
display: flex;
align-items: center;
justify-content: flex-end;
height: 140rpx;
// background-color: red;
width: 100%;
.wendu-top-left {
font-size: 110rpx;
font-weight: 600;
}
.wendu-top-right {
font-size: 45rpx;
font-weight: 600;
// height: 100%;
width: 80rpx;
}
}
.wendu-heng {
width: 80%;
height: 2rpx;
margin: 20rpx auto;
background-color: #333333;
}
.wendu-bottom {
width: 100%;
font-size: 45rpx;
font-weight: 600;
padding-right: 50rpx;
display: flex;
justify-content: flex-end;
}
}
.big-bgc {
margin-left: 40rpx;
margin-top: -40rpx;
width: 1350rpx;
height: 950rpx;
border-radius: 55rpx;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.picture {
display: flex;
margin-top: 50rpx;
margin-left: 30rpx;
.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: rgba(226, 227, 231, 0.5);
border-radius: 30rpx;
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 10rpx;
}
}
}
.right-right {
position: absolute;
right: 0rpx;
top: 80rpx;
height: calc(100% - 250rpx);
width: 570rpx;
}
.bottom-view {
margin-left: 90rpx;
margin-top: 220rpx;
// padding-top: 80rpx;
width: 440rpx;
height: 800rpx;
border-radius: 50rpx;
background-color: rgba(226, 227, 231, 0.5);
position: relative;
display: flex;
flex-wrap: wrap;
overflow: hidden;
align-items: flex-start;
align-content: flex-start;
.small-button-father {
margin-top: 20rpx;
margin-bottom: 0;
margin-left: 28rpx;
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;
}
}
}
.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;
}
.shebei {
width: 100%;
margin-top: 10rpx;
margin-left: 30rpx;
margin-top: 60rpx;
// justify-content: space-around;
}
</style>