2025-05-22 16:37:43 +08:00
|
|
|
|
<template>
|
|
|
|
|
<view class="device-detail">
|
|
|
|
|
<!-- 设备信息 -->
|
2025-07-09 17:11:02 +08:00
|
|
|
|
<view class="device-info" v-if="tabbarIndex === 0 && deviceForm.deviceType !== 3">
|
2025-05-22 16:37:43 +08:00
|
|
|
|
<view class="top-wrap">
|
|
|
|
|
<view class="nav-bar">
|
|
|
|
|
<navbar color="#ffffff">{{ navTitle }}</navbar>
|
|
|
|
|
</view>
|
2025-07-09 17:11:02 +08:00
|
|
|
|
<view class="sub-wrap" :style="{width: '85%'}">
|
2025-05-22 16:37:43 +08:00
|
|
|
|
<u-subsection :list="baseTabList" :current="baseTabIndex" bgColor=" rgba(255,255,255,0.2)"
|
|
|
|
|
activeColor="#3378FE" inactiveColor="#FFFFFF" @change="handleBaseTabsClick"></u-subsection>
|
|
|
|
|
</view>
|
2025-07-09 17:11:02 +08:00
|
|
|
|
|
2025-05-22 16:37:43 +08:00
|
|
|
|
</view>
|
|
|
|
|
<view class="content-wrap">
|
|
|
|
|
<!-- 设备 -->
|
|
|
|
|
<view class="device-content">
|
2025-07-09 17:11:02 +08:00
|
|
|
|
<view>
|
2025-05-22 16:37:43 +08:00
|
|
|
|
<!-- 设备运行状态 -->
|
2025-07-09 17:11:02 +08:00
|
|
|
|
<running-status v-if="deviceForm.deviceId" v-show="baseTabIndex === 0" ref="runningStatus"
|
2025-05-22 16:37:43 +08:00
|
|
|
|
:device="deviceForm"></running-status>
|
|
|
|
|
<!-- 设备实时监测 -->
|
2025-07-10 17:09:36 +08:00
|
|
|
|
<!-- <device-monitor v-show="baseTabIndex == 1" ref="deviceMonitor" :show="baseTabIndex == 1"
|
2025-05-22 16:37:43 +08:00
|
|
|
|
:device="deviceForm">
|
2025-07-10 17:09:36 +08:00
|
|
|
|
</device-monitor> -->
|
2025-05-22 16:37:43 +08:00
|
|
|
|
<!-- 视频监控 -->
|
2025-07-10 17:09:36 +08:00
|
|
|
|
<!-- <video-monitor v-show="baseTabIndex == 2" ref="videoMonitor"
|
|
|
|
|
:device="deviceForm"></video-monitor> -->
|
2025-05-22 16:37:43 +08:00
|
|
|
|
<!-- 告警记录 -->
|
|
|
|
|
<device-alertLog v-show="baseTabIndex == 3" ref="deviceAlertLog"
|
|
|
|
|
:device="deviceForm"></device-alertLog>
|
|
|
|
|
</view>
|
|
|
|
|
|
2025-07-09 17:11:02 +08:00
|
|
|
|
|
|
|
|
|
<!-- 设备删除提示 -->
|
|
|
|
|
<u-modal :show="show" :title="modalTitle" :content="content" showCancelButton @confirm="confirm"
|
|
|
|
|
@cancel="cancel"></u-modal>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="device-info-video" v-if="tabbarIndex === 0 && deviceForm.deviceType === 3">
|
|
|
|
|
<view class="top-wrap">
|
|
|
|
|
<view class="nav-bar">
|
|
|
|
|
<navbar color="#ffffff">{{ navTitle }}</navbar>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="sub-wrap" :style="{width: '85%'}" v-if="deviceForm.deviceType !== 3">
|
|
|
|
|
<u-subsection :list="baseTabList" :current="baseTabIndex" bgColor=" rgba(255,255,255,0.2)"
|
|
|
|
|
activeColor="#3378FE" inactiveColor="#FFFFFF" @change="handleBaseTabsClick"></u-subsection>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="sub-wrap" :style="{width: '44%'}" v-else>
|
|
|
|
|
<u-subsection :list="videoTabList" :current="videotabIndex" bgColor=" rgba(255,255,255,0.2)"
|
|
|
|
|
activeColor="#3378FE" inactiveColor="#FFFFFF" @change="handleVideoTabsClick"></u-subsection>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="content-wrap">
|
|
|
|
|
<!-- 设备 -->
|
|
|
|
|
<view class="device-content">
|
2025-05-22 16:37:43 +08:00
|
|
|
|
<!-- 视频监控设备 -->
|
2025-07-09 17:11:02 +08:00
|
|
|
|
<view>
|
2025-05-22 16:37:43 +08:00
|
|
|
|
<!-- 设备通道 -->
|
|
|
|
|
<view class="channel_wrap" v-show="videotabIndex == 0">
|
|
|
|
|
<view class="item_body" v-for="(item, i) in channelList" :key="i"
|
|
|
|
|
@click="gotoDevicePlayer(item.deviceSipId, item.channelSipId, item.status)">
|
|
|
|
|
<view class="img">
|
|
|
|
|
<u-icon name="play-circle" color="#2979ff" size="28"></u-icon>
|
|
|
|
|
</view>
|
|
|
|
|
<view>
|
|
|
|
|
<u--text lines="2" lineHeight="24" size="16" :text="item.channelName"></u--text>
|
|
|
|
|
<view style="display:flex;margin-top:6px;">
|
|
|
|
|
<view style="margin-right:20px;">
|
|
|
|
|
<u--text prefixIcon="info-circle"
|
|
|
|
|
iconStyle="color:#606266;font-size:14px;margin-right:3px;" size="12"
|
|
|
|
|
color="#606266" mode="name" :text="item.model"></u--text>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="status">
|
|
|
|
|
<u-tag v-if="item.statusInfo" :type="item.statusInfo.type" :plain="true"
|
|
|
|
|
size="mini" :text="item.statusInfo.name"></u-tag>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<u-empty mode="list" :show="channelTotal === 0" marginTop="30"></u-empty>
|
|
|
|
|
<u-loadmore :status="channelLoadStatus" v-if="channelTotal > channelQueryParams.pageSize"
|
|
|
|
|
marginTop="20" />
|
|
|
|
|
</view>
|
|
|
|
|
<view class="base-info" v-show="videotabIndex === 1">
|
|
|
|
|
<u--form labelPosition="left" :model="deviceForm" :rules="deviceRules" ref="deviceForm"
|
|
|
|
|
labelWidth="90" labelAlign="left">
|
|
|
|
|
<view class="card-wrap">
|
|
|
|
|
<view class="title-wrap">
|
|
|
|
|
<u--text :text="$tt('deviceDetail.basicMsg')" bold color="#606266"></u--text>
|
|
|
|
|
</view>
|
|
|
|
|
<u-form-item :label="$tt('deviceDetail.deviceName')" prop="deviceName" borderBottom>
|
|
|
|
|
<view class="item-right" slot="right">
|
|
|
|
|
<u--input v-model="deviceForm.deviceName" clearable border="none"
|
|
|
|
|
inputAlign="right"></u--input>
|
|
|
|
|
</view>
|
|
|
|
|
</u-form-item>
|
|
|
|
|
<u-form-item :label="$tt('deviceDetail.longitude')"
|
|
|
|
|
v-if="deviceForm.locationWay === 3" borderBottom>
|
|
|
|
|
<view class="item-right" slot="right">
|
|
|
|
|
<u--input v-model="deviceForm.longitude" type="digit"
|
|
|
|
|
:placeholder="$tt('deviceDetail.inputLongitude')" border="none"
|
|
|
|
|
inputAlign="right"></u--input>
|
|
|
|
|
</view>
|
|
|
|
|
</u-form-item>
|
|
|
|
|
<u-form-item :label="$tt('deviceDetail.latitude')"
|
|
|
|
|
v-if="deviceForm.locationWay === 3" borderBottom>
|
|
|
|
|
<view class="item-right" slot="right">
|
|
|
|
|
<u--input v-model="deviceForm.latitude" type="digit"
|
|
|
|
|
:placeholder="$tt('deviceDetail.inputLatitude')" border="none"
|
|
|
|
|
inputAlign="right"></u--input>
|
|
|
|
|
</view>
|
|
|
|
|
</u-form-item>
|
|
|
|
|
<u-form-item :label="$tt('deviceDetail.address')"
|
|
|
|
|
v-if="deviceForm.locationWay === 3" borderBottom>
|
|
|
|
|
<view class="item-right" slot="right">
|
|
|
|
|
<u--input v-model="deviceForm.networkAddress" border="none"
|
|
|
|
|
inputAlign="right"></u--input>
|
|
|
|
|
</view>
|
|
|
|
|
</u-form-item>
|
|
|
|
|
<u-form-item :label="$tt('deviceDetail.remark')"></u-form-item>
|
|
|
|
|
|
|
|
|
|
<u-textarea v-model="deviceForm.remark" height="40" fontSize="14"
|
|
|
|
|
:placeholder="$tt('deviceDetail.inputMsg')" style="background-color: #F7F7F7;"
|
|
|
|
|
confirmType="done"></u-textarea>
|
|
|
|
|
|
|
|
|
|
<view style="margin-top: 20px; display: flex; gap: 10px;">
|
2025-07-09 17:11:02 +08:00
|
|
|
|
<u-button v-if="!profile.deptId" @tap="gotoShare" size="small" :plain="true"
|
|
|
|
|
type="primary"
|
2025-05-22 16:37:43 +08:00
|
|
|
|
:customStyle="{fontSize: '30rpx',height: '88rpx',borderRadius: '10rpx'}">{{$tt('deviceDetail.share')}}</u-button>
|
|
|
|
|
<u-button type="primary" @tap="submitForm" size="small"
|
|
|
|
|
:customStyle="{fontSize: '30rpx',height: '88rpx',borderRadius: '10rpx'}">{{$tt('deviceDetail.preserve')}}</u-button>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<!-- 设备状态 -->
|
|
|
|
|
<view class="card-wrap">
|
|
|
|
|
<u-form-item borderBottom>
|
|
|
|
|
<view style="display: flex;">
|
|
|
|
|
<u-row>
|
|
|
|
|
<u-col :span="7.5">
|
|
|
|
|
<u--text :text="$tt('deviceDetail.deviceStatus')" bold
|
|
|
|
|
color="#000000"></u--text>
|
|
|
|
|
</u-col>
|
|
|
|
|
<u-col :span="2">
|
|
|
|
|
<u-button :text="$tt('home.notActive')" type="warning" size="mini"
|
|
|
|
|
plain v-if="deviceForm.status == 1"
|
|
|
|
|
customStyle="width:50px;margin-left:12rpx;"></u-button>
|
|
|
|
|
<u-button :text="$tt('home.disabled')" type="error" size="mini"
|
|
|
|
|
plain v-if="deviceForm.status == 2"
|
|
|
|
|
customStyle="width:50px;margin-left:12rpx;"></u-button>
|
|
|
|
|
<u-button :text="$tt('home.onLine')" type="success" size="mini"
|
|
|
|
|
plain v-if="deviceForm.status == 3"
|
|
|
|
|
customStyle="width:50px;margin-left:12rpx;"></u-button>
|
|
|
|
|
<u-button :text="$tt('home.offline')" type="info" size="mini" plain
|
|
|
|
|
v-if="deviceForm.status == 4"
|
|
|
|
|
customStyle="width:50px;margin-left:12rpx;"></u-button>
|
|
|
|
|
</u-col>
|
|
|
|
|
</u-row>
|
|
|
|
|
</view>
|
|
|
|
|
<view slot="right" @click="handleDeleteDevice">
|
|
|
|
|
<u-icon name="trash" color="#f85959" size="23"></u-icon>
|
|
|
|
|
</view>
|
|
|
|
|
</u-form-item>
|
|
|
|
|
<u-form-item :label="$tt('deviceDetail.serialNumber')" borderBottom>
|
|
|
|
|
<view class="item-right" slot="right"><u--text
|
|
|
|
|
:text="deviceForm.serialNumber"></u--text></view>
|
|
|
|
|
</u-form-item>
|
|
|
|
|
<u-form-item :label="$tt('deviceDetail.belongingProducts')" borderBottom>
|
|
|
|
|
<view class="item-right" slot="right"><u--text
|
|
|
|
|
:text="deviceForm.productName"></u--text>
|
|
|
|
|
</view>
|
|
|
|
|
</u-form-item>
|
|
|
|
|
<u-form-item :label="$tt('deviceDetail.firmwareVersion')" borderBottom>
|
|
|
|
|
<view class="item-right" slot="right"><u--text
|
|
|
|
|
:text="formatVersion(deviceForm.firmwareVersion)"></u--text></view>
|
|
|
|
|
</u-form-item>
|
|
|
|
|
<u-form-item :label="$tt('deviceDetail.positionMethod')" borderBottom
|
|
|
|
|
v-if="deviceForm.deviceType === 3">
|
|
|
|
|
<view class="item-right" slot="right"><u--text
|
|
|
|
|
:text="deviceForm.locationWayInfo.name"></u--text></view>
|
|
|
|
|
</u-form-item>
|
|
|
|
|
<u-form-item :label="$tt('deviceDetail.longitude')" borderBottom
|
|
|
|
|
v-if="deviceForm.longitude && deviceForm.locationWay !== 3">
|
|
|
|
|
<view class="item-right" slot="right"><u--text
|
|
|
|
|
:text="deviceForm.longitude"></u--text>
|
|
|
|
|
</view>
|
|
|
|
|
</u-form-item>
|
|
|
|
|
<u-form-item :label="$tt('deviceDetail.latitude')" borderBottom
|
|
|
|
|
v-if="deviceForm.latitude && deviceForm.locationWay !== 3">
|
|
|
|
|
<view class="item-right" slot="right"><u--text
|
|
|
|
|
:text="deviceForm.latitude"></u--text>
|
|
|
|
|
</view>
|
|
|
|
|
</u-form-item>
|
|
|
|
|
<u-form-item :label="$tt('deviceDetail.equipmentSignal')" borderBottom>
|
|
|
|
|
<view class="item-right" slot="right"><u--text
|
|
|
|
|
:text="$tt('deviceDetail.veryGood')" type="success"
|
|
|
|
|
v-if="deviceForm.rssi >= '-55'"></u--text>
|
|
|
|
|
<u--text :text="$tt('deviceDetail.excellent')" type="success"
|
|
|
|
|
v-else-if="deviceForm.rssi >= '-70' && deviceForm.rssi < '-55'"></u--text>
|
|
|
|
|
<u--text :text="$tt('deviceDetail.good')" type="success"
|
|
|
|
|
v-else-if="deviceForm.rssi >= '-85' && deviceForm.rssi < '-70'"></u--text>
|
|
|
|
|
<u--text :text="$tt('deviceDetail.average')" type="warning"
|
|
|
|
|
v-else-if="deviceForm.rssi >= '-100' && deviceForm.rssi < '-85'"></u--text>
|
|
|
|
|
<u--text :text="$tt('deviceDetail.poor')" type="error" v-else></u--text>
|
|
|
|
|
</view>
|
|
|
|
|
</u-form-item>
|
|
|
|
|
<u-form-item :label="$tt('deviceDetail.address')"
|
|
|
|
|
v-if="deviceForm.networkAddress && deviceForm.locationWay !== 3" borderBottom>
|
|
|
|
|
<view class="item-right" slot="right"><u--text
|
|
|
|
|
:text="deviceForm.networkAddress"></u--text>
|
|
|
|
|
</view>
|
|
|
|
|
</u-form-item>
|
|
|
|
|
<u-form-item :label="$tt('deviceDetail.networkAddress')" borderBottom>
|
|
|
|
|
<view class="item-right" slot="right"><u--text
|
|
|
|
|
:text="deviceForm.networkIp"></u--text>
|
|
|
|
|
</view>
|
|
|
|
|
</u-form-item>
|
|
|
|
|
<u-form-item :label="$tt('deviceDetail.activationTime')">
|
|
|
|
|
<view class="item-right" slot="right"><u--text
|
|
|
|
|
:text="deviceForm.activeTime"></u--text>
|
|
|
|
|
</view>
|
|
|
|
|
</u-form-item>
|
|
|
|
|
<u--image :src="imageUrl" radius="10" mode="aspectFill" width="100%" height="200">
|
|
|
|
|
<view slot="error" style="font-size: 18rpx;">{{$tt('deviceDetail.loadingFail')}}
|
|
|
|
|
</view>
|
|
|
|
|
<template v-slot:loading>
|
|
|
|
|
<u-loading-icon></u-loading-icon>
|
|
|
|
|
</template>
|
|
|
|
|
</u--image>
|
|
|
|
|
</view>
|
|
|
|
|
</u--form>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<!-- 设备删除提示 -->
|
|
|
|
|
<u-modal :show="show" :title="modalTitle" :content="content" showCancelButton @confirm="confirm"
|
|
|
|
|
@cancel="cancel"></u-modal>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<!-- 设备定时 -->
|
2025-07-10 17:09:36 +08:00
|
|
|
|
<!-- <device-timing v-if="tabbarIndex === 1" ref="deviceTiming" :device="deviceForm"></device-timing> -->
|
2025-05-22 16:37:43 +08:00
|
|
|
|
<!-- 设备日志 -->
|
|
|
|
|
<device-log v-if="tabbarIndex === 2" ref="deviceLog" :device="deviceForm"></device-log>
|
|
|
|
|
<!-- 设备统计 -->
|
|
|
|
|
<!-- <device-statistic v-show="tabbarIndex === 3" :device="deviceForm" :type="tabbarIndex"
|
|
|
|
|
ref="deviceStatistic"></device-statistic> -->
|
|
|
|
|
<device-history v-if="tabbarIndex === 3" ref="deviceHistory" :device="deviceForm"></device-history>
|
|
|
|
|
<!-- 设备组态 -->
|
2025-07-10 17:09:36 +08:00
|
|
|
|
<!-- <device-scada v-show="tabbarIndex === 4" :show="tabbarIndex === 4" :device="deviceForm"
|
|
|
|
|
ref="deviceScada"></device-scada> -->
|
|
|
|
|
|
2025-05-22 16:37:43 +08:00
|
|
|
|
<u-tabbar :value="tabbarIndex" @change="tabbarChange" :fixed="true" :placeholder="true"
|
|
|
|
|
:safeAreaInsetBottom="true" :border="false" activeColor="#3378FE" v-if="deviceForm.deviceType !==3">
|
|
|
|
|
<u-tabbar-item :text="$tt('deviceDetail.device')" @click="tabbarClick(0)">
|
|
|
|
|
<image style="width:18px;height:18px;" slot="active-icon" src="/static/home/tabBar/device_blue.png">
|
|
|
|
|
</image>
|
|
|
|
|
<image style="width:18px;height:18px;" slot="inactive-icon" src="/static/home/tabBar/device_black.png">
|
|
|
|
|
</image>
|
|
|
|
|
</u-tabbar-item>
|
2025-07-10 17:09:36 +08:00
|
|
|
|
<!-- <u-tabbar-item :text="$tt('deviceDetail.timing')" @click="tabbarClick(1)">
|
2025-05-22 16:37:43 +08:00
|
|
|
|
<image style="width:18px;height:18px;" slot="active-icon" src="/static/home/tabBar/time_blue.png">
|
|
|
|
|
</image>
|
|
|
|
|
<image style="width:18px;height:18px;" slot="inactive-icon" src="/static/home/tabBar/time_black.png">
|
|
|
|
|
</image>
|
2025-07-10 17:09:36 +08:00
|
|
|
|
</u-tabbar-item> -->
|
2025-05-22 16:37:43 +08:00
|
|
|
|
<u-tabbar-item :text="$tt('deviceDetail.journal')" @click="tabbarClick(2)">
|
|
|
|
|
<image style="width:18px;height:18px;" slot="active-icon" src="/static/home/tabBar/log_blue.png">
|
|
|
|
|
</image>
|
|
|
|
|
<image style="width:18px;height:18px;" slot="inactive-icon" src="/static/home/tabBar/log_black.png">
|
|
|
|
|
</image>
|
|
|
|
|
</u-tabbar-item>
|
|
|
|
|
<u-tabbar-item :text="$tt('deviceDetail.static')" @click="tabbarClick(3)">
|
|
|
|
|
<image style="width:18px;height:18px;" slot="active-icon" src="/static/home/tabBar/statistic_blue.png">
|
|
|
|
|
</image>
|
|
|
|
|
<image style="width:18px;height:18px;" slot="inactive-icon"
|
|
|
|
|
src="/static/home/tabBar/statistic_black.png">
|
|
|
|
|
</image>
|
|
|
|
|
</u-tabbar-item>
|
2025-07-10 17:09:36 +08:00
|
|
|
|
<!-- <u-tabbar-item :text="$tt('deviceDetail.scada')" @click="tabbarClick(4)">
|
2025-05-22 16:37:43 +08:00
|
|
|
|
<image style="width:18px;height:18px;" slot="active-icon" src="/static/home/tabBar/scada_blue.png">
|
|
|
|
|
</image>
|
|
|
|
|
<image style="width:18px;height:18px;" slot="inactive-icon" src="/static/home/tabBar/scada_black.png">
|
|
|
|
|
</image>
|
2025-07-10 17:09:36 +08:00
|
|
|
|
</u-tabbar-item> -->
|
2025-05-22 16:37:43 +08:00
|
|
|
|
</u-tabbar>
|
2025-07-10 17:09:36 +08:00
|
|
|
|
<!-- <u-modal :show="showScada" content="暂无组态,请先去网页端配置模板组态" @confirm="() => showScada = false"
|
|
|
|
|
@cancel="() => showScada = false" showCancelButton></u-modal> -->
|
2025-07-09 17:11:02 +08:00
|
|
|
|
<!-- 选择直播还是回放 -->
|
|
|
|
|
<u-popup :show="isSelect" :round="5" mode="bottom" :closeOnClickOverlay="true" @close="isSelect = false">
|
|
|
|
|
<view class="trigger-popup-wrap">
|
|
|
|
|
<view class="cell-group-wrap">
|
|
|
|
|
<u-cell-group :border="false">
|
|
|
|
|
<view class="cell-wrap">
|
|
|
|
|
<u-cell title="实时视频" icon="/static/home/video/play.png"
|
|
|
|
|
:iconStyle="{ marginRight: '10rpx' }" :border="false" isLink
|
|
|
|
|
@click="gotoPlayer"></u-cell>
|
|
|
|
|
</view>
|
|
|
|
|
<view class="cell-wrap">
|
|
|
|
|
<u-cell title="录像回放" icon="/static/home/video/record.png"
|
|
|
|
|
:iconStyle="{ marginRight: '10rpx' }" :border="false" isLink
|
|
|
|
|
@click="gotoDeviceVideo"></u-cell>
|
|
|
|
|
</view>
|
|
|
|
|
</u-cell-group>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</u-popup>
|
|
|
|
|
<!-- 选择录像时间 -->
|
|
|
|
|
<u-calendar :show="showcalendar" :minDate="minDate" :maxDate="maxDate" month-num="7" :defaultDate="defaultDate"
|
|
|
|
|
@confirm="confirmCalendar" @close="closeCalendar"></u-calendar>
|
2025-05-22 16:37:43 +08:00
|
|
|
|
</view>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import projectConfig from '@/env.config.js';
|
|
|
|
|
import navbar from '@/components/navBar/index.vue';
|
2025-07-10 17:09:36 +08:00
|
|
|
|
// import videoMonitor from './video/index.vue';
|
2025-05-22 16:37:43 +08:00
|
|
|
|
import deviceAlertLog from './log/alertLog.vue';
|
|
|
|
|
import runningStatus from './status/index.vue';
|
|
|
|
|
import deviceLog from './log/index.vue';
|
|
|
|
|
import deviceHistory from './statistic/history.vue';
|
2025-07-10 17:09:36 +08:00
|
|
|
|
// import deviceMonitor from './monitor/index.vue';
|
|
|
|
|
// import deviceTiming from './timing/index.vue';
|
|
|
|
|
// import deviceScada from './scada.vue';
|
2025-07-09 17:11:02 +08:00
|
|
|
|
import {
|
|
|
|
|
listChannel
|
|
|
|
|
} from '@/apis/modules/sip';
|
2025-05-22 16:37:43 +08:00
|
|
|
|
import {
|
|
|
|
|
getDevice,
|
|
|
|
|
getRunningStatus,
|
|
|
|
|
cacheJsonThingsModel,
|
|
|
|
|
deviceSynchronization,
|
|
|
|
|
updateDevice,
|
|
|
|
|
delDevice
|
|
|
|
|
} from '@/apis/modules/device';
|
2025-07-09 17:11:02 +08:00
|
|
|
|
import {
|
|
|
|
|
getSipStatusInfo,
|
|
|
|
|
getLocationWayInfo
|
|
|
|
|
} from '@/helpers/common.js'
|
2025-05-22 16:37:43 +08:00
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
components: {
|
|
|
|
|
navbar,
|
|
|
|
|
runningStatus,
|
|
|
|
|
deviceLog,
|
2025-07-10 17:09:36 +08:00
|
|
|
|
// deviceMonitor,
|
|
|
|
|
// deviceTiming,
|
|
|
|
|
// videoMonitor,
|
2025-05-22 16:37:43 +08:00
|
|
|
|
deviceAlertLog,
|
|
|
|
|
deviceHistory,
|
2025-07-10 17:09:36 +08:00
|
|
|
|
// deviceScada
|
2025-05-22 16:37:43 +08:00
|
|
|
|
},
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
navTitle: this.$tt('navBar.deviceDetails'),
|
|
|
|
|
deviceId: 0,
|
|
|
|
|
baseTabIndex: 0, // 基础设备tab index
|
|
|
|
|
videotabIndex: 0,
|
|
|
|
|
tabbarIndex: 0,
|
|
|
|
|
baseTabList: [{
|
|
|
|
|
name: this.$tt('deviceDetail.overview')
|
2025-07-09 17:11:02 +08:00
|
|
|
|
}, {
|
2025-05-22 16:37:43 +08:00
|
|
|
|
name: this.$tt('deviceDetail.alert')
|
|
|
|
|
}],
|
|
|
|
|
videoTabList: [{
|
|
|
|
|
name: this.$tt('deviceDetail.channel')
|
|
|
|
|
}, {
|
|
|
|
|
name: this.$tt('deviceDetail.deviceDetail')
|
|
|
|
|
}],
|
|
|
|
|
show: false, // 删除设备模态框
|
|
|
|
|
modalTitle: '删除警告', // 对话框标题
|
|
|
|
|
content: '', // 对话框内容
|
|
|
|
|
deviceForm: {
|
|
|
|
|
isShadow: 0, // 避免u-switch报错,初始化
|
|
|
|
|
deviceName: '',
|
|
|
|
|
locationWay: 1,
|
|
|
|
|
protocolCode: '',
|
|
|
|
|
}, // 设备详情
|
|
|
|
|
deviceDisable: 0, // 设备状态(1=禁用,0=不禁用)
|
|
|
|
|
isSubDev: false, // 是否有子设备
|
|
|
|
|
imageUrl: '', // 图片地址
|
2025-07-09 17:11:02 +08:00
|
|
|
|
deviceSipId: '',
|
|
|
|
|
channelSipId: '',
|
2025-05-22 16:37:43 +08:00
|
|
|
|
deviceRules: { // 表单校验
|
|
|
|
|
deviceName: [{
|
|
|
|
|
required: true,
|
|
|
|
|
message: this.$tt('deviceDetail.deviceCheck'),
|
|
|
|
|
trigger: ['blur', 'change']
|
|
|
|
|
}]
|
|
|
|
|
},
|
2025-07-09 17:11:02 +08:00
|
|
|
|
isSelect: false,
|
2025-05-22 16:37:43 +08:00
|
|
|
|
// 设备通道
|
|
|
|
|
channelLoadStatus: 'nomore',
|
|
|
|
|
channelQueryParams: {
|
|
|
|
|
pageNum: 1,
|
|
|
|
|
pageSize: 10,
|
|
|
|
|
deviceSipId: '',
|
|
|
|
|
},
|
|
|
|
|
channelTotal: 0,
|
|
|
|
|
channelList: [],
|
2025-07-10 17:09:36 +08:00
|
|
|
|
// showScada: false,
|
2025-07-09 17:11:02 +08:00
|
|
|
|
showcalendar: false, //录像时间选择弹出框
|
|
|
|
|
minDate: "",
|
|
|
|
|
maxDate: "",
|
|
|
|
|
defaultDate: "",
|
2025-05-22 16:37:43 +08:00
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
onLoad: function(option) {
|
|
|
|
|
this.deviceId = Number(option.deviceId);
|
|
|
|
|
this.deviceForm.protocolCode = option.protocolCode;
|
|
|
|
|
this.connectMqtt(); // 连接mqtt
|
|
|
|
|
},
|
2025-07-09 17:11:02 +08:00
|
|
|
|
onHide() {
|
|
|
|
|
this.isSelect = false;
|
|
|
|
|
},
|
2025-05-22 16:37:43 +08:00
|
|
|
|
onUnload() {
|
|
|
|
|
this.mqttUnSubscribe(this.deviceForm); // 取消订阅主题
|
|
|
|
|
},
|
|
|
|
|
onShow() {
|
2025-07-10 17:09:36 +08:00
|
|
|
|
// uni.$off('re-device-timing-list');
|
|
|
|
|
// uni.$once('re-device-timing-list', (dat) => {
|
|
|
|
|
// if (dat) {
|
|
|
|
|
// this.$refs.deviceTiming.dataList = [];
|
|
|
|
|
// this.$refs.deviceTiming.queryParams.pageNum = 1;
|
|
|
|
|
// this.$refs.deviceTiming.getList();
|
|
|
|
|
// }
|
|
|
|
|
// });
|
2025-05-22 16:37:43 +08:00
|
|
|
|
},
|
2025-07-09 17:11:02 +08:00
|
|
|
|
mounted() {
|
|
|
|
|
this.initCalendar();
|
2025-05-22 16:37:43 +08:00
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
// 基础tab点击事件
|
|
|
|
|
handleBaseTabsClick(index) {
|
|
|
|
|
this.baseTabIndex = index;
|
|
|
|
|
},
|
|
|
|
|
// 视频tab点击事件
|
|
|
|
|
handleVideoTabsClick(index) {
|
|
|
|
|
this.videotabIndex = index;
|
|
|
|
|
},
|
|
|
|
|
/* 连接Mqtt消息服务器 */
|
|
|
|
|
async connectMqtt() {
|
|
|
|
|
if (this.$mqttTool.client === null) {
|
|
|
|
|
await this.$mqttTool.connect(this.vuex_token);
|
|
|
|
|
}
|
|
|
|
|
this.mqttCallback();
|
|
|
|
|
// 获取设备信息并订阅主题
|
|
|
|
|
this.getDevice();
|
|
|
|
|
},
|
|
|
|
|
/* Mqtt回调处理 */
|
|
|
|
|
mqttCallback() {
|
|
|
|
|
this.$mqttTool.client.on('message', (topic, message, buffer) => {
|
|
|
|
|
let topics = topic.split('/');
|
|
|
|
|
let productId = topics[1];
|
|
|
|
|
let deviceNum = topics[2];
|
|
|
|
|
message = JSON.parse(message.toString());
|
|
|
|
|
if (!message) {
|
|
|
|
|
return;
|
|
|
|
|
};
|
|
|
|
|
if (topics[3] == 'status' || topics[2] == 'status') {
|
|
|
|
|
console.log('接收到【设备状态-详情】主题:', topic);
|
|
|
|
|
console.log('接收到【设备状态-详情】内容:', message);
|
|
|
|
|
// 更新列表中设备的状态
|
|
|
|
|
if (this.deviceForm.serialNumber == deviceNum) {
|
|
|
|
|
this.deviceForm.status = message.status;
|
|
|
|
|
this.deviceForm.isShadow = message.isShadow;
|
|
|
|
|
this.deviceForm.rssid = message.rssid;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
//不是modbus不转发到子页面,其他设备的页面有回调方法
|
|
|
|
|
if (this.isSubDev) {
|
|
|
|
|
/*发送设备上报到子模块*/
|
|
|
|
|
if (topic.endsWith('ws/service')) {
|
|
|
|
|
console.log('接收到【设备数据上报】主题:', topic)
|
|
|
|
|
console.log('接收到【设备数据上报】主题:', message)
|
|
|
|
|
this.$bus.$emit("updateDeviceStatus", {
|
|
|
|
|
serialNumber: topics[2],
|
|
|
|
|
productId: this.deviceForm.productId,
|
|
|
|
|
data: message.message,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
/** Mqtt订阅主题 */
|
|
|
|
|
mqttSubscribe(device) {
|
|
|
|
|
// 订阅当前设备状态和实时监测
|
|
|
|
|
let topicStatus = '/' + device.productId + '/' + device.serialNumber + '/status/post';
|
|
|
|
|
let topicMonitor = '/' + device.productId + '/' + device.serialNumber + '/monitor/post';
|
|
|
|
|
let topicReply = '/' + device.productId + '/' + device.serialNumber + '/service/reply';
|
|
|
|
|
let topicService = '/' + device.productId + '/' + device.serialNumber + '/ws/service';
|
|
|
|
|
let topics = [];
|
|
|
|
|
topics.push(topicStatus);
|
|
|
|
|
topics.push(topicMonitor);
|
|
|
|
|
topics.push(topicReply);
|
|
|
|
|
topics.push(topicService);
|
|
|
|
|
this.$mqttTool.subscribe(topics);
|
|
|
|
|
},
|
|
|
|
|
/** Mqtt取消订阅主题 */
|
|
|
|
|
mqttUnSubscribe(device) {
|
|
|
|
|
// 订阅当前设备状态和实时监测
|
|
|
|
|
let topicStatus = '/' + device.productId + '/' + device.serialNumber + '/status/post';
|
|
|
|
|
let topicMonitor = '/' + device.productId + '/' + device.serialNumber + '/monitor/post';
|
|
|
|
|
let topicReply = '/' + device.productId + '/' + device.serialNumber + '/service/reply';
|
|
|
|
|
let topicService = '/' + device.productId + '/' + device.serialNumber + '/ws/service';
|
|
|
|
|
let topics = [];
|
|
|
|
|
topics.push(topicStatus);
|
|
|
|
|
topics.push(topicMonitor);
|
|
|
|
|
topics.push(topicReply);
|
|
|
|
|
topics.push(topicService);
|
|
|
|
|
this.$mqttTool.unsubscribe(topics);
|
|
|
|
|
console.log('取消订阅', topics);
|
|
|
|
|
},
|
|
|
|
|
// 导航栏改变
|
|
|
|
|
tabbarChange() {},
|
|
|
|
|
// 导航栏单击
|
|
|
|
|
tabbarClick(index) {
|
|
|
|
|
this.tabbarIndex = index;
|
|
|
|
|
},
|
|
|
|
|
// 格式化版本显示
|
|
|
|
|
formatVersion(version) {
|
|
|
|
|
return `Version ${version}`;
|
|
|
|
|
},
|
|
|
|
|
// 刷新设备
|
|
|
|
|
onPullDownRefresh() {
|
|
|
|
|
if (this.tabbarIndex == 0) {
|
|
|
|
|
if (this.baseTabIndex == 0) {
|
|
|
|
|
// 设备运行状态
|
|
|
|
|
this.getDevice();
|
|
|
|
|
this.$refs.runningStatus.baseStatusRefresh();
|
2025-07-10 17:09:36 +08:00
|
|
|
|
} else if (this.baseTabIndex == 1) {
|
|
|
|
|
// 告警记录
|
2025-05-22 16:37:43 +08:00
|
|
|
|
this.getDevice();
|
|
|
|
|
} else {
|
|
|
|
|
uni.stopPullDownRefresh();
|
|
|
|
|
}
|
|
|
|
|
} else if (this.tabbarIndex == 1) {
|
|
|
|
|
// 设备定时
|
2025-07-10 17:09:36 +08:00
|
|
|
|
// this.$refs.deviceTiming.deviceTimerRefresh();
|
2025-05-22 16:37:43 +08:00
|
|
|
|
uni.stopPullDownRefresh();
|
|
|
|
|
} else if (this.tabbarIndex == 3) {
|
|
|
|
|
// 设备统计
|
2025-07-10 17:09:36 +08:00
|
|
|
|
// this.$refs.deviceStatistic.getCacheThingsModdel();
|
|
|
|
|
uni.stopPullDownRefresh();
|
2025-05-22 16:37:43 +08:00
|
|
|
|
} else {
|
|
|
|
|
uni.stopPullDownRefresh();
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
/**获取设备详情*/
|
|
|
|
|
getDevice() {
|
|
|
|
|
getDevice(this.deviceId).then(async response => {
|
2025-07-09 17:11:02 +08:00
|
|
|
|
|
2025-05-22 16:37:43 +08:00
|
|
|
|
try {
|
|
|
|
|
let data = response.data;
|
|
|
|
|
if (data.deviceType !== 3) {
|
|
|
|
|
// 获取缓存物模型
|
|
|
|
|
data.cacheThingsModel = await this.getCacheThingsModdel(data.productId);
|
|
|
|
|
// 获取设备运行状态
|
|
|
|
|
data.thingsModels = await this.getRunningStatusInfo(this.deviceId, data.slaveId);
|
|
|
|
|
// 格式化物模型,拆分出监测值,数组添加前缀
|
|
|
|
|
this.formatThingsModel(data);
|
|
|
|
|
} else {
|
|
|
|
|
// 获取通道列表
|
|
|
|
|
this.channelList = await this.getChannelList(data.serialNumber);
|
|
|
|
|
}
|
|
|
|
|
this.navTitle = data.deviceName;
|
|
|
|
|
// this.isSubDev = data.subDeviceList.length > 0;
|
|
|
|
|
this.imageUrl = data.imgUrl;
|
|
|
|
|
if (this.imageUrl != null && this.imageUrl != '') {
|
2025-07-09 17:11:02 +08:00
|
|
|
|
this.imageUrl = projectConfig.BASE_URL + this.imageUrl;
|
2025-05-22 16:37:43 +08:00
|
|
|
|
} else {
|
|
|
|
|
this.imageUrl = '/static/common/device.png';
|
|
|
|
|
}
|
|
|
|
|
// 禁用状态
|
|
|
|
|
if (data.status == 2) {
|
|
|
|
|
this.deviceDisable = 1;
|
|
|
|
|
}
|
|
|
|
|
// 获取定位方式
|
|
|
|
|
data.locationWayInfo = getLocationWayInfo(data.locationWay);
|
|
|
|
|
//Mqtt订阅
|
|
|
|
|
uni.stopPullDownRefresh();
|
|
|
|
|
this.mqttSubscribe(data);
|
|
|
|
|
//增加协议字段为后面数据采集做判断
|
|
|
|
|
data.protocolCode = this.deviceForm.protocolCode;
|
|
|
|
|
this.deviceForm = data;
|
2025-07-09 17:11:02 +08:00
|
|
|
|
|
|
|
|
|
|
2025-05-22 16:37:43 +08:00
|
|
|
|
} catch (e) {
|
|
|
|
|
console.log(e);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
2025-07-09 17:11:02 +08:00
|
|
|
|
// 重组数据
|
|
|
|
|
setdeviceValue(data) {
|
|
|
|
|
let restart = true;
|
|
|
|
|
while (restart) {
|
|
|
|
|
restart = false; // 默认不重启循环
|
|
|
|
|
let model = {
|
|
|
|
|
id: '',
|
|
|
|
|
name: '',
|
|
|
|
|
isMonitor: 0,
|
|
|
|
|
isHistory: 0,
|
|
|
|
|
isChart: 0,
|
|
|
|
|
isReadonly: 0,
|
|
|
|
|
isApp: 0,
|
|
|
|
|
order: 8,
|
|
|
|
|
type: 1,
|
|
|
|
|
datatype: {
|
|
|
|
|
type: '',
|
|
|
|
|
falseText: '',
|
|
|
|
|
trueText: '',
|
|
|
|
|
min: 0,
|
|
|
|
|
max: 100,
|
|
|
|
|
step: 1,
|
|
|
|
|
unit: '',
|
|
|
|
|
arrayType: '',
|
|
|
|
|
arrayCount: 0,
|
|
|
|
|
showWay: null,
|
|
|
|
|
maxLength: 1024,
|
|
|
|
|
enumList: null,
|
|
|
|
|
params: [],
|
|
|
|
|
arrayParams: [],
|
|
|
|
|
arrayModel: []
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 检查是否存在需要分组的元素
|
|
|
|
|
const hasElementsToProcess = data.thingsModels.some((item) => item.id.includes('array_'));
|
|
|
|
|
if (!hasElementsToProcess) {
|
|
|
|
|
// console.log('所有分组已处理,结束循环');
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
// 组合数据
|
|
|
|
|
for (let i = 0; i < data.thingsModels.length; i++) {
|
|
|
|
|
if (!data.thingsModels[i].id.includes('array_')) continue;
|
|
|
|
|
//整体判断所有的data.thingsModels,里面的id是否含有下划线
|
|
|
|
|
if (data.thingsModels[i].id.includes('array_')) {
|
|
|
|
|
// console.log('存在下划线', data.thingsModels[i].id);
|
|
|
|
|
//判断存在下划线的个数为1
|
|
|
|
|
const thingsModelId = data.thingsModels[i].id.split('_');
|
2025-07-10 17:09:36 +08:00
|
|
|
|
const thingsModelName = data.thingsModels[i].name?.includes('array_') ? data.thingsModels[i]
|
|
|
|
|
.name
|
2025-07-09 17:11:02 +08:00
|
|
|
|
?.split('_') : [data.thingsModels[i].name];
|
|
|
|
|
if (thingsModelId.length >= 2 && thingsModelId[0] !== 'array' && thingsModelName.length >= 2) {
|
|
|
|
|
//找到一个对象
|
|
|
|
|
if (model.id === '') {
|
|
|
|
|
model.id = thingsModelId[0];
|
|
|
|
|
model.name = thingsModelName[0];
|
|
|
|
|
model.datatype.type = 'object';
|
|
|
|
|
}
|
|
|
|
|
if (model.id === thingsModelId[0]) {
|
|
|
|
|
model.isReadonly = data.thingsModels[i].isReadonly;
|
|
|
|
|
const name = thingsModelName.slice(1);
|
|
|
|
|
data.thingsModels[i].name = name.length > 1 ? name.join('_') : thingsModelName[1];
|
|
|
|
|
if (data.thingsModels[i].name === '' || data.thingsModels[i].name === null) {
|
|
|
|
|
//此时没有名字
|
|
|
|
|
data.thingsModels[i].name = model.name;
|
|
|
|
|
}
|
|
|
|
|
model.datatype.params.push(data.thingsModels[i]);
|
|
|
|
|
data.thingsModels.splice(i, 1);
|
|
|
|
|
i--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (thingsModelId.length === 3 && thingsModelId[0] === 'array') {
|
|
|
|
|
//找到一个数组
|
|
|
|
|
|
|
|
|
|
if (model.id === '') {
|
|
|
|
|
model.id = thingsModelId[2];
|
|
|
|
|
|
|
|
|
|
model.datatype.type = 'array';
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
if (model.id === thingsModelId[2]) {
|
|
|
|
|
model.value = model.value ? model.value + ',' + data.thingsModels[i].value : data
|
|
|
|
|
.thingsModels[i].value;
|
|
|
|
|
model.shadow = model.shadow ? model.shadow + ',' + data.thingsModels[i].shadow : data
|
|
|
|
|
.thingsModels[i].shadow;
|
|
|
|
|
model.isReadonly = data.thingsModels[i].isReadonly;
|
|
|
|
|
model.datatype.arrayType = data.thingsModels[i].datatype.type;
|
|
|
|
|
const name = data.thingsModels[i].name.match(/(.*)\d$/);
|
|
|
|
|
if (model.name === '') {
|
|
|
|
|
model.name = name[1];
|
|
|
|
|
}
|
|
|
|
|
model.datatype.arrayModel.push({
|
|
|
|
|
id: data.thingsModels[i].id,
|
|
|
|
|
name: data.thingsModels[i].name
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
data.thingsModels.splice(i, 1);
|
|
|
|
|
i--;
|
|
|
|
|
model.datatype.arrayCount++;
|
|
|
|
|
}
|
|
|
|
|
//console.log('model', model);
|
|
|
|
|
}
|
|
|
|
|
if (thingsModelId.length >= 4 && thingsModelId[0] === 'array') {
|
|
|
|
|
//找到一个数组对象
|
|
|
|
|
if (model.id === '') {
|
|
|
|
|
//model.id = id.join('_');
|
|
|
|
|
model.id = thingsModelId[2];
|
|
|
|
|
model.datatype.type = 'array';
|
|
|
|
|
}
|
|
|
|
|
// 对象
|
|
|
|
|
if (model.id === thingsModelId[2]) {
|
|
|
|
|
model.isReadonly = data.thingsModels[i].isReadonly;
|
|
|
|
|
model.datatype.arrayType = 'object';
|
|
|
|
|
|
|
|
|
|
const matchedIndex = thingsModelName.findIndex((item) => item.match(/(.*)\d$/));
|
|
|
|
|
const matchedName = matchedIndex !== -1 ? thingsModelName.slice(0, matchedIndex + 1) :
|
|
|
|
|
undefined;
|
|
|
|
|
const modelName = matchedIndex !== -1 ? thingsModelName.slice(matchedIndex + 1) :
|
|
|
|
|
undefined;
|
|
|
|
|
const name = matchedName.length > 1 ? matchedName.join('_') : matchedName[0];
|
|
|
|
|
|
|
|
|
|
if (model.name === '') {
|
|
|
|
|
model.name = name ? name : '';
|
|
|
|
|
//console.log(model.name);
|
|
|
|
|
}
|
|
|
|
|
data.thingsModels[i].name = modelName.length > 1 ? modelName.join('_') : modelName[0];
|
|
|
|
|
//data.thingsModels[i].id = id.join('_');
|
|
|
|
|
if (data.thingsModels[i].name === '' || data.thingsModels[i].name === null) {
|
|
|
|
|
//此时没有名字
|
|
|
|
|
data.thingsModels[i].name = model.name;
|
|
|
|
|
}
|
|
|
|
|
if (model.datatype.arrayParams.length === 0) {
|
|
|
|
|
//尚未赋值
|
|
|
|
|
//console.log('内部未赋值');
|
|
|
|
|
this.$set(model.datatype.arrayParams, 0, [data.thingsModels[i]]);
|
|
|
|
|
} else {
|
|
|
|
|
//已经赋值
|
|
|
|
|
let hasMatched = false; // 标记是否找到匹配的子数组
|
|
|
|
|
// 遍历所有子数组
|
|
|
|
|
model.datatype.arrayParams.some((subArray) => {
|
|
|
|
|
// 检查当前子数组是否包含匹配的 param
|
|
|
|
|
const isMatch = subArray.some((param) => {
|
|
|
|
|
const obj = param.id.split('_');
|
|
|
|
|
//console.log('obj', thingsModelId[1]);
|
|
|
|
|
return obj[1] === thingsModelId[1];
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (isMatch) {
|
|
|
|
|
// 向匹配的子数组末尾添加元素
|
|
|
|
|
this.$set(subArray, subArray.length, data.thingsModels[i]);
|
|
|
|
|
hasMatched = true;
|
|
|
|
|
return true; // 终止遍历
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
});
|
|
|
|
|
// 若未找到匹配的子数组,创建新子数组
|
|
|
|
|
if (!hasMatched) {
|
|
|
|
|
const newIndex = model.datatype.arrayParams.length;
|
|
|
|
|
this.$set(model.datatype.arrayParams, newIndex, [data.thingsModels[i]]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
data.thingsModels.splice(i, 1);
|
|
|
|
|
i--;
|
|
|
|
|
model.datatype.arrayCount++;
|
|
|
|
|
}
|
|
|
|
|
//console.log('model', model);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 将组合后的 model 加入列表
|
|
|
|
|
if (model.id !== '') {
|
|
|
|
|
data.thingsModels.push(model);
|
|
|
|
|
restart = true; // 强制重新检查是否有更多分组
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
console.log("重组后", data)
|
|
|
|
|
return data
|
|
|
|
|
},
|
2025-05-22 16:37:43 +08:00
|
|
|
|
// 设置设备的状态(1-未激活,2-禁用,3-在线,4-离线)
|
|
|
|
|
setDeviceStatus() {
|
|
|
|
|
if (this.deviceDisable == 1) {
|
|
|
|
|
this.deviceForm.status = 2;
|
|
|
|
|
} else {
|
|
|
|
|
// 禁用状态,启用后状态是离线
|
|
|
|
|
if (this.deviceForm.status == 2) {
|
|
|
|
|
this.deviceForm.status = 4;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
// 设备数据同步
|
|
|
|
|
deviceSynchronization() {
|
|
|
|
|
deviceSynchronization(this.deviceForm.serialNumber).then(async response => {
|
|
|
|
|
try {
|
|
|
|
|
let data = response.data;
|
|
|
|
|
if (data.deviceType !== 3) {
|
|
|
|
|
// 获取缓存物模型
|
|
|
|
|
data.cacheThingsModel = await this.getCacheThingsModdel(data.productId);
|
|
|
|
|
// 获取设备运行状态
|
|
|
|
|
data.thingsModels = await this.getRunningStatusInfo(this.deviceId, data.slaveId);
|
|
|
|
|
// 格式化物模型,拆分出监测值,数组添加前缀
|
|
|
|
|
this.formatThingsModel(data);
|
|
|
|
|
}
|
|
|
|
|
this.navTitle = data.deviceName;
|
|
|
|
|
this.imageUrl = data.imgUrl;
|
|
|
|
|
if (this.imageUrl != null && this.imageUrl != '') {
|
2025-07-09 17:11:02 +08:00
|
|
|
|
this.imageUrl = projectConfig.BASE_URL + this.imageUrl;
|
2025-05-22 16:37:43 +08:00
|
|
|
|
} else {
|
|
|
|
|
this.imageUrl = '/static/common/device.png';
|
|
|
|
|
}
|
|
|
|
|
// 禁用状态
|
|
|
|
|
if (data.status == 2) {
|
|
|
|
|
this.deviceDisable = 1;
|
|
|
|
|
}
|
|
|
|
|
this.deviceForm = response.data;
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.log(e);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
/** 删除设备按钮操作 */
|
|
|
|
|
handleDeleteDevice() {
|
|
|
|
|
this.content = '是否确认删除 ' + this.deviceForm.deviceName + ' ?';
|
|
|
|
|
this.show = true;
|
|
|
|
|
},
|
|
|
|
|
// 确认删除设备
|
|
|
|
|
confirm() {
|
|
|
|
|
this.show = false;
|
|
|
|
|
delDevice(this.deviceForm.deviceId).then(res => {
|
|
|
|
|
if (res.code == 200) {
|
|
|
|
|
// 跳转主页,通过globalData传递参数
|
|
|
|
|
getApp().globalData.operate = 'operate';
|
|
|
|
|
uni.switchTab({
|
|
|
|
|
url: '/pages/tabBar/home/index'
|
|
|
|
|
});
|
|
|
|
|
} else if (res.code == 500) {
|
|
|
|
|
uni.showToast({
|
|
|
|
|
icon: 'none',
|
|
|
|
|
title: res.msg
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
// 取消
|
|
|
|
|
cancel() {
|
|
|
|
|
this.show = false;
|
|
|
|
|
},
|
|
|
|
|
/** 提交按钮 */
|
|
|
|
|
submitForm() {
|
|
|
|
|
if (!this.deviceForm.locationWay) {
|
|
|
|
|
uni.showToast({
|
|
|
|
|
icon: 'none',
|
|
|
|
|
title: this.$tt('deviceDetail.positionCheck')
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
this.$refs.deviceForm.validate().then(e => {
|
|
|
|
|
if (this.deviceForm.deviceId !== 0) {
|
|
|
|
|
this.setDeviceStatus(); // 设置设备状态
|
|
|
|
|
let device = {
|
|
|
|
|
deviceId: this.deviceForm.deviceId,
|
|
|
|
|
deviceName: this.deviceForm.deviceName,
|
|
|
|
|
isShadow: this.deviceForm.isShadow,
|
|
|
|
|
status: this.deviceForm.status,
|
|
|
|
|
remark: this.deviceForm.remark,
|
|
|
|
|
locationWay: this.deviceForm.locationWay,
|
|
|
|
|
longitude: this.deviceForm.longitude,
|
|
|
|
|
latitude: this.deviceForm.latitude,
|
|
|
|
|
networkAddress: this.deviceForm.networkAddress
|
|
|
|
|
};
|
|
|
|
|
updateDevice(device).then(res => {
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
uni.showToast({
|
|
|
|
|
icon: 'success',
|
|
|
|
|
title: this.$tt('deviceDetail.updateSuccess')
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
2025-07-09 17:11:02 +08:00
|
|
|
|
//分享监控设备
|
2025-05-22 16:37:43 +08:00
|
|
|
|
gotoShare() {
|
|
|
|
|
uni.$u.route('/pagesA/device/share/list', {
|
|
|
|
|
deviceId: this.deviceForm.deviceId,
|
|
|
|
|
productId: this.deviceForm.productId,
|
|
|
|
|
deviceName: this.deviceForm.deviceName
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
/** 获取缓存物模型*/
|
|
|
|
|
getCacheThingsModdel(productId) {
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
cacheJsonThingsModel(productId).then(res => {
|
|
|
|
|
resolve(JSON.parse(res.data));
|
|
|
|
|
}).catch(err => {
|
|
|
|
|
reject(err);
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
// 获取设备运行状态
|
|
|
|
|
getRunningStatusInfo(deviceId, slaveId) {
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
getRunningStatus(deviceId, slaveId).then(res => {
|
|
|
|
|
resolve(res.data.thingsModels);
|
|
|
|
|
}).catch(err => {
|
|
|
|
|
reject(err);
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
// 物模型格式化
|
|
|
|
|
formatThingsModel(data) {
|
|
|
|
|
if (data && data.length !== 0) {
|
|
|
|
|
data.chartList = [];
|
|
|
|
|
data.monitorList = [];
|
|
|
|
|
data.statisticList = [];
|
2025-07-09 17:11:02 +08:00
|
|
|
|
data = this.setdeviceValue(data);
|
2025-05-22 16:37:43 +08:00
|
|
|
|
for (let i = 0; i < data.thingsModels.length; i++) {
|
|
|
|
|
if (data.thingsModels[i].datatype.type === "array") {
|
|
|
|
|
if (data.thingsModels[i].datatype.arrayType === "object") {
|
|
|
|
|
for (let k = 0; k < data.thingsModels[i].datatype.arrayParams.length; k++) {
|
|
|
|
|
for (let j = 0; j < data.thingsModels[i].datatype.arrayParams[k].length; j++) {
|
|
|
|
|
// 数组元素中参数ID添加前缀,例如:array_00_
|
2025-07-09 17:11:02 +08:00
|
|
|
|
// let index = k > 9 ? String(k) : '0' + k;
|
|
|
|
|
// let prefix = 'array_' + index + '_';
|
|
|
|
|
// data.thingsModels[i].datatype.arrayParams[k][j].id = prefix + data.thingsModels[i]
|
|
|
|
|
// .datatype.arrayParams[k][j].id;
|
2025-05-22 16:37:43 +08:00
|
|
|
|
// 图表、实时监测、监测统计分类放置
|
|
|
|
|
if (data.thingsModels[i].datatype.arrayParams[k][j].isChart === 1) {
|
|
|
|
|
data.thingsModels[i].datatype.arrayParams[k][j].name = "[" + data.thingsModels[
|
|
|
|
|
i].name + (k + 1) + "] " + data.thingsModels[i].datatype.arrayParams[k]
|
|
|
|
|
[j].name;
|
|
|
|
|
data.thingsModels[i].datatype.arrayParams[k][j].datatype.arrayType = "object";
|
|
|
|
|
data.chartList.push(data.thingsModels[i].datatype.arrayParams[k][j]);
|
|
|
|
|
// 监测统计
|
|
|
|
|
if (data.thingsModels[i].datatype.arrayParams[k][j].isHistory == 1) {
|
|
|
|
|
data.statisticList.push(data.thingsModels[i].datatype.arrayParams[k][j]);
|
|
|
|
|
}
|
|
|
|
|
// 实时监测
|
|
|
|
|
if (data.thingsModels[i].datatype.arrayParams[k][j].isMonitor == 1) {
|
|
|
|
|
data.monitorList.push(data.thingsModels[i].datatype.arrayParams[k][j]);
|
|
|
|
|
}
|
|
|
|
|
data.thingsModels[i].datatype.arrayParams[k].splice(j--, 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 字符串拆分为物模型数组 model=id/name/type/isReadonly/value/shadow
|
|
|
|
|
let values = data.thingsModels[i].value && data.thingsModels[i].value != "" ? data
|
|
|
|
|
.thingsModels[i].value.split(',') : [];
|
|
|
|
|
let shadows = data.thingsModels[i].shadow && data.thingsModels[i].shadow != "" ? data
|
|
|
|
|
.thingsModels[i].shadow.split(',') : [];
|
|
|
|
|
for (let j = 0; j < data.thingsModels[i].datatype.arrayCount; j++) {
|
|
|
|
|
if (!data.thingsModels[i].datatype.arrayModel) {
|
|
|
|
|
data.thingsModels[i].datatype.arrayModel = [];
|
|
|
|
|
}
|
|
|
|
|
// 数组里面的ID需要添加前缀和索引,例如:array_00_temperature
|
|
|
|
|
let index = j > 9 ? String(j) : '0' + j;
|
|
|
|
|
let prefix = 'array_' + index + '_';
|
|
|
|
|
data.thingsModels[i].datatype.arrayModel[j] = {
|
2025-07-09 17:11:02 +08:00
|
|
|
|
...data.thingsModels[i].datatype.arrayModel[j],
|
|
|
|
|
//id: prefix + data.thingsModels[i].id,
|
|
|
|
|
//name: data.thingsModels[i].name,
|
2025-05-22 16:37:43 +08:00
|
|
|
|
type: data.thingsModels[i].type,
|
|
|
|
|
isReadonly: data.thingsModels[i].isReadonly,
|
|
|
|
|
value: values[j] ? values[j] : "",
|
|
|
|
|
shadow: shadows[j] ? shadows[j] : ""
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (data.thingsModels[i].datatype.type === "object") {
|
|
|
|
|
for (let j = 0; j < data.thingsModels[i].datatype.params.length; j++) {
|
|
|
|
|
// 图表、实时监测、监测统计分类放置
|
|
|
|
|
if (data.thingsModels[i].datatype.params[j].isChart === 1) {
|
|
|
|
|
// 图表
|
|
|
|
|
data.thingsModels[i].datatype.params[j].name = "[" + data.thingsModels[i].name + "] " +
|
|
|
|
|
data.thingsModels[i].datatype.params[j].name;
|
|
|
|
|
data.chartList.push(data.thingsModels[i].datatype.params[j]);
|
|
|
|
|
// 监测统计
|
|
|
|
|
if (data.thingsModels[i].datatype.params[j].isHistory == 1) {
|
|
|
|
|
data.statisticList.push(data.thingsModels[i].datatype.params[j]);
|
|
|
|
|
}
|
|
|
|
|
// 实时监测
|
|
|
|
|
if (data.thingsModels[i].datatype.params[j].isMonitor == 1) {
|
|
|
|
|
data.monitorList.push(data.thingsModels[i].datatype.params[j]);
|
|
|
|
|
}
|
|
|
|
|
data.thingsModels[i].datatype.params.splice(j--, 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (data.thingsModels[i].isChart === 1) {
|
|
|
|
|
// 图表、实时监测、监测统计分类放置
|
|
|
|
|
data.chartList.push(data.thingsModels[i]);
|
|
|
|
|
// 监测统计
|
|
|
|
|
if (data.thingsModels[i].isHistory == 1) {
|
|
|
|
|
data.statisticList.push(data.thingsModels[i]);
|
|
|
|
|
}
|
|
|
|
|
// 实时监测
|
|
|
|
|
if (data.thingsModels[i].isMonitor == 1) {
|
|
|
|
|
data.monitorList.push(data.thingsModels[i]);
|
|
|
|
|
}
|
|
|
|
|
// 使用i--解决索引变更问题
|
|
|
|
|
data.thingsModels.splice(i--, 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-07-09 17:11:02 +08:00
|
|
|
|
|
|
|
|
|
// 整理数据
|
|
|
|
|
for (let i = 0; i < data.thingsModels.length; i++) {
|
|
|
|
|
// 物模型分类放置
|
|
|
|
|
if (data.thingsModels[i].datatype.type == 'array') {
|
|
|
|
|
if (data.thingsModels[i].datatype.arrayType == 'object' && data.thingsModels[i].datatype
|
|
|
|
|
.arrayParams.length > 0) {
|
|
|
|
|
// 此时遍历删除
|
|
|
|
|
data.thingsModels[i].datatype.arrayParams = data.thingsModels[i].datatype.arrayParams
|
|
|
|
|
.filter((item) => item.length > 0);
|
|
|
|
|
if (data.thingsModels[i].datatype.arrayParams.length === 0) {
|
|
|
|
|
data.thingsModels.splice(i--, 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (data.thingsModels[i].datatype.type == 'object') {
|
|
|
|
|
if (data.thingsModels[i].datatype.params.length === 0) {
|
|
|
|
|
data.thingsModels.splice(i--, 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-05-22 16:37:43 +08:00
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
// 设备通道
|
|
|
|
|
getChannelList(serialNumber) {
|
|
|
|
|
this.channelQueryParams.deviceSipId = serialNumber;
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
listChannel(this.channelQueryParams).then(response => {
|
|
|
|
|
this.channelTotal = response.total;
|
|
|
|
|
response.rows.map(item => {
|
|
|
|
|
item.statusInfo = getSipStatusInfo(item.status);
|
|
|
|
|
return item;
|
|
|
|
|
})
|
|
|
|
|
resolve(response.rows);
|
|
|
|
|
}).catch(error => {
|
|
|
|
|
reject(error);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
gotoDevicePlayer(deviceSipId, channelSipId, status) {
|
2025-07-09 17:11:02 +08:00
|
|
|
|
this.deviceSipId = deviceSipId;
|
|
|
|
|
this.channelSipId = channelSipId;
|
2025-05-22 16:37:43 +08:00
|
|
|
|
let statusInfo = getSipStatusInfo(status)
|
|
|
|
|
if (status !== 3) {
|
|
|
|
|
uni.showToast({
|
|
|
|
|
icon: 'none',
|
|
|
|
|
title: `无法查看${getSipStatusInfo(status).name}数据`
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// #ifdef H5
|
|
|
|
|
uni.$u.route('/pages_player/list/devicePlayer', {
|
|
|
|
|
deviceId: deviceSipId,
|
|
|
|
|
channelSipId: channelSipId,
|
|
|
|
|
});
|
|
|
|
|
//#endif
|
2025-07-09 17:11:02 +08:00
|
|
|
|
// #ifdef APP-PLUS
|
|
|
|
|
uni.$u.route('/pages_player/list/devicePlayerWebView', {
|
2025-05-22 16:37:43 +08:00
|
|
|
|
deviceId: deviceSipId,
|
|
|
|
|
channelSipId: channelSipId,
|
|
|
|
|
});
|
|
|
|
|
//#endif
|
2025-07-09 17:11:02 +08:00
|
|
|
|
// #ifdef MP-WEIXIN
|
|
|
|
|
this.isSelect = true;
|
2025-05-22 16:37:43 +08:00
|
|
|
|
//#endif
|
|
|
|
|
},
|
2025-07-09 17:11:02 +08:00
|
|
|
|
gotoPlayer() {
|
|
|
|
|
uni.$u.route('/pages_player/list/devicePlayerMpWeixin', {
|
|
|
|
|
deviceId: this.deviceSipId,
|
|
|
|
|
channelSipId: this.channelSipId,
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
//选择时间
|
|
|
|
|
gotoDeviceVideo() {
|
|
|
|
|
this.showcalendar = true;
|
|
|
|
|
},
|
|
|
|
|
//录像控制
|
|
|
|
|
initCalendar() {
|
|
|
|
|
this.defaultDate = new Date();
|
|
|
|
|
let minstamp = new Date().getTime() - 1000 * 3600 * 24 * 28 * 6;
|
|
|
|
|
let maxstamp = new Date().getTime();
|
|
|
|
|
var mindate = new Date(minstamp);
|
|
|
|
|
let minmonth = mindate.getMonth() + 1;
|
|
|
|
|
let minday = mindate.getDate();
|
|
|
|
|
if (minmonth <= 9) {
|
|
|
|
|
minmonth = '0' + minmonth;
|
|
|
|
|
}
|
|
|
|
|
if (minday <= 9) {
|
|
|
|
|
minday = '0' + minday;
|
|
|
|
|
}
|
|
|
|
|
var maxdate = new Date(maxstamp);
|
|
|
|
|
let maxmonth = maxdate.getMonth() + 1;
|
|
|
|
|
let maxday = maxdate.getDate();
|
|
|
|
|
if (maxmonth <= 9) {
|
|
|
|
|
maxmonth = '0' + maxmonth;
|
|
|
|
|
}
|
|
|
|
|
if (maxday <= 9) {
|
|
|
|
|
maxday = '0' + maxday;
|
2025-05-22 16:37:43 +08:00
|
|
|
|
}
|
2025-07-09 17:11:02 +08:00
|
|
|
|
this.minDate = mindate.getFullYear() + '-' + minmonth + '-' + minday;
|
|
|
|
|
this.maxDate = maxdate.getFullYear() + '-' + maxmonth + '-' + maxday;
|
2025-05-22 16:37:43 +08:00
|
|
|
|
},
|
|
|
|
|
// 返回监听
|
|
|
|
|
onBackPress(options) {
|
|
|
|
|
if (options.from === 'navigateBack') {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
uni.switchTab({
|
|
|
|
|
url: '/pages/tabBar/home/index'
|
|
|
|
|
});
|
|
|
|
|
return true;
|
|
|
|
|
},
|
2025-07-09 17:11:02 +08:00
|
|
|
|
confirmCalendar(n) {
|
|
|
|
|
this.playbackDate = n[0];
|
|
|
|
|
this.showcalendar = false;
|
|
|
|
|
this.queryDate = n;
|
|
|
|
|
// this.loadDevRecord();
|
|
|
|
|
uni.$u.route('/pages_player/list/devicePlayerMpWeixin', {
|
|
|
|
|
deviceId: this.deviceSipId,
|
|
|
|
|
channelSipId: this.channelSipId,
|
|
|
|
|
videoVod: true,
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
closeCalendar(n) {
|
|
|
|
|
this.showcalendar = false;
|
|
|
|
|
},
|
|
|
|
|
|
2025-05-22 16:37:43 +08:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss">
|
|
|
|
|
page {
|
|
|
|
|
background: $uni-bg-color-grey;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
.device-detail {
|
|
|
|
|
height: 100vh;
|
|
|
|
|
width: 100%;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
|
|
|
|
.device-info {
|
|
|
|
|
// #ifdef MP-WEIXIN
|
|
|
|
|
height: calc(100vh - 168rpx);
|
|
|
|
|
// #endif
|
|
|
|
|
// #ifndef MP-WEIXIN
|
|
|
|
|
height: calc(100vh - 100rpx);
|
|
|
|
|
// #endif
|
2025-07-09 17:11:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.device-info-video {
|
|
|
|
|
height: 100vh;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.device-info-video,
|
|
|
|
|
.device-info {
|
2025-05-22 16:37:43 +08:00
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
overflow-y: hidden;
|
|
|
|
|
|
|
|
|
|
.top-wrap {
|
|
|
|
|
position: relative;
|
|
|
|
|
background-size: cover;
|
|
|
|
|
background-image: url('@/static/common/bg.png');
|
|
|
|
|
// #ifdef MP-WEIXIN
|
|
|
|
|
min-height: 480rpx;
|
|
|
|
|
// #endif
|
|
|
|
|
// #ifdef H5
|
|
|
|
|
min-height: 480rpx;
|
|
|
|
|
// #endif
|
|
|
|
|
// #ifdef APP-PLUS
|
|
|
|
|
min-height: 550rpx;
|
|
|
|
|
// #endif
|
|
|
|
|
z-index: 0;
|
|
|
|
|
|
|
|
|
|
.sub-wrap {
|
2025-07-09 17:11:02 +08:00
|
|
|
|
//width: 80%;
|
|
|
|
|
padding: 32rpx 34rpx;
|
2025-05-22 16:37:43 +08:00
|
|
|
|
|
|
|
|
|
::v-deep .u-subsection--button {
|
|
|
|
|
height: 68rpx;
|
|
|
|
|
padding: 8rpx;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.content-wrap {
|
|
|
|
|
flex: 1 1 auto;
|
2025-07-09 17:11:02 +08:00
|
|
|
|
background: $uni-bg-color-grey;
|
|
|
|
|
z-index: 1;
|
2025-05-22 16:37:43 +08:00
|
|
|
|
border-top-left-radius: 40rpx;
|
|
|
|
|
border-top-right-radius: 40rpx;
|
2025-07-09 17:11:02 +08:00
|
|
|
|
//padding: 0 30rpx;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
margin-top: -256rpx;
|
2025-05-22 16:37:43 +08:00
|
|
|
|
// #ifndef H5 || APP-PLUS || MP-ALIPAY
|
2025-07-09 17:11:02 +08:00
|
|
|
|
margin-top: -178rpx;
|
2025-05-22 16:37:43 +08:00
|
|
|
|
// #endif
|
|
|
|
|
z-index: 1;
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
|
|
|
|
|
.device-content {
|
|
|
|
|
padding: 28rpx;
|
|
|
|
|
|
|
|
|
|
.channel_wrap {
|
|
|
|
|
|
|
|
|
|
.item_body {
|
|
|
|
|
position: relative;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
2025-07-09 17:11:02 +08:00
|
|
|
|
margin-bottom: 15px;
|
2025-05-22 16:37:43 +08:00
|
|
|
|
background: #fff;
|
|
|
|
|
border-radius: 20rpx;
|
|
|
|
|
|
|
|
|
|
.img {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
border-radius: 5px;
|
|
|
|
|
width: 90px;
|
|
|
|
|
height: 60px;
|
|
|
|
|
background: #e5e5e5;
|
|
|
|
|
margin: 10px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.status {
|
|
|
|
|
position: absolute;
|
|
|
|
|
right: 13px;
|
|
|
|
|
top: 13px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.base-info {
|
|
|
|
|
.card-wrap {
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
padding: 29rpx 32rpx;
|
|
|
|
|
border-radius: 20rpx;
|
|
|
|
|
margin-bottom: 24rpx;
|
|
|
|
|
|
|
|
|
|
.item-right {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
::v-deep .u-form-item__body {
|
|
|
|
|
height: 80rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.title-wrap {
|
|
|
|
|
display: flex;
|
|
|
|
|
padding: 20rpx 0;
|
|
|
|
|
border-bottom: 1px solid #efefef;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-07-09 17:11:02 +08:00
|
|
|
|
|
|
|
|
|
.trigger-popup-wrap {
|
|
|
|
|
padding: 30rpx;
|
|
|
|
|
|
|
|
|
|
.title {
|
|
|
|
|
font-size: 32rpx;
|
|
|
|
|
text-align: center;
|
|
|
|
|
margin-bottom: 30rpx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.cell-group-wrap {
|
|
|
|
|
.cell-wrap {
|
|
|
|
|
padding: 6rpx 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-05-22 16:37:43 +08:00
|
|
|
|
}
|
|
|
|
|
</style>
|