<template>
	<view class="content contentBg">
		<custom-navbar :title="Status.navTitle" :showBack="true" color="#FFFFFF"
			:rightIcon="Status.isRightIconVisible ? '/static/images/common/shape.png' : ''"
			@right-click="gotoShare"></custom-navbar>
		<view :style="{ paddingTop: Status.navBarHeight + 'px' }">
			<view class="eq">
				<view class="leftImg" @click.stop="previewImg(device.devicePic ? device.devicePic : formData.img)">
					<image class="img" :src="device.devicePic ? device.devicePic : formData.img" mode="aspectFit">
					</image>
				</view>
				<view class="rightTxt">
					<view class="row">
						<image class="img" src="/static/images/common/battry.png" mode="aspectFit"></image>
						<view class="txt">
							<view class="bigTxt" :style="{ color: deviceInfo.batteryPercentage < 20 ? '#FF0000' : '' }">
								{{ deviceInfo.batteryPercentage }}%
							</view>
							<view class="smallTxt">电量</view>
						</view>
					</view>
					<view class="row">
						<image class="img" src="/static/images/common/time.png" mode="aspectFit"></image>
						<view class="txt">
							<view class="bigTxt">
								{{ Math.floor((Number(deviceInfo.batteryRemainingTime) || 0) / 60) }}小时
								{{ (Number(deviceInfo.batteryRemainingTime) || 0) % 60 }}分钟
							</view>
							<view class="smallTxt">续航时间</view>
						</view>
					</view>
				</view>
			</view>
			<view class="eqinfo">
				<view class="item">
					<text class="lbl">设备名称</text>
					<text class="value">{{ deviceInfo.deviceName }}</text>
				</view>
				<view class="item">
					<text class="lbl">设备IMEI</text>
					<text class="value">{{ deviceInfo.deviceImei }}</text>
				</view>
				<view class="item">
					<text class="lbl">Mac地址</text>
					<text class="value">{{device.deviceMac}}</text>
				</view>
				<view class="item">
					<text class="lbl">蓝牙名称</text>
					<text class="value valueFont">{{device.bluetoothName}}</text>
				</view>
				<view class="item" @click.stop="bleStatuToggle">
					<text class="lbl">蓝牙状态</text>
					<text class="value"
						:class="(!formData.bleStatu || formData.bleStatu==='err')?'red':'green'">{{getbleStatu}}</text>
				</view>
				<view class="item">
					<text class="lbl">设备状态</text>
					<text class="value"
						:class="deviceInfo.onlineStatus===0?'red':'green'">{{ deviceInfo.onlineStatus === 0 ? '离线': '在线' }}</text>
				</view>
				<view class="info-row">
					<text class="info-label" style="display: flex; align-items: center;">定位信息</text>
					<view class="info-value status-running" @click="gpsPosition(deviceInfo)">
						<view class="info-value status-running">
							{{ deviceInfo && deviceInfo.longitude ? Number(deviceInfo.longitude).toFixed(4) : '' }}
							{{ deviceInfo && deviceInfo.latitude ? Number(deviceInfo.latitude).toFixed(4) : '' }}
						</view>                                                                                                                                                                                                         
						<view class="info-value status-running locationGPS">
							<uni-icons type="location" size="17" color="rgba(255, 255, 255, 0.8)"
								style="vertical-align: bottom;" />
							{{ deviceInfo.address }}
						</view>
					</view>
				</view>
			</view>
			<view class="lampMode">
				<view class="sosContent">
					<view class="btnSos openSos center" :class="{ active: deviceInfo.voiceStrobeAlarm === 1 }"
						@click="sosSetting(1)">
						{{ deviceInfo.voiceStrobeAlarm === 1 ? '报警中' : '强制报警' }}
					</view>
					<view class="btnSos closeSos center" @click="sosSetting(0)">解除</view>
				</view>
			</view>
			<view class="warn">
				<view class="header" @click="setUsrToggle()">
					<text>
						报警模式
					</text>
					<uni-icons color="#ffffffde" size="20" :type="Status.usrToggle ? 'up' : 'down'">
					</uni-icons>
				</view>
				<view class="warnBody">
					<view class="modeSetting">
						<view class="arrow" @click.stop="openVolume(item, index)" v-if="item.show"
							v-for="item, index in dic.sta_VoiceType" :class="{
								'active': formData.sta_VoiceType === item.key,
								'displayNone': !Status.usrToggle && index > 2
							}">
							<view class="outCircle">
								<view class="item">
									<view class="text">{{ item.name }}</view>
								</view>
							</view>
						</view>
					</view>
				</view>
			</view>
			<view class="lamp">
				<view class="title">
					<text>语音播报</text>
				</view>
			</view>
			<view class="lampMode">
				<view class="mode fleft " v-on:click.stop="openVolume(null, '7')"
					:class="{ 'active': formData.sta_VoiceType === '7' }">
					<view class="leftImg">
						<image class="img" :class="{ 'displayNone': formData.sta_VoiceType === '7' }"
							src="/static/images/common/play.png" mode="aspectFit"></image>
						<image class="img" :class="{ 'displayNone': formData.sta_VoiceType !== '7' }"
							src="/static/images/common/pauseActive.png" mode="aspectFit"></image>
					</view>
					<view class="rightTxt">
						<text class="bigTxt">播放语音</text>
					</view>
				</view>
				<view class="mode fleft marginLeft" v-on:click.stop="audioManager(deviceInfo)">
					<view class="leftImg">
						<image class="img" src="/static/images/common/uploadCloud.png" mode="aspectFit"></image>
					</view>
					<view class="rightTxt">
						<text class="bigTxt">语音管理</text>
					</view>
				</view>
				<view class="clear"></view>
			</view>
			<view class="lamp">
				<view class="title">
					<text>警示灯</text>
				</view>
			</view>
			<view class="lampMode">
				<view class="mode fleft " v-for="item, index in dic.sta_LightType" :class="{
					'active': formData.sta_LightType === item.key,
					'marginLeft': index % 2 === 1,
					'displayNone': !item.show
				}" v-on:click.stop="lightTypeSet(item, index)">
					<view class="leftImg">
						<image class="img" :class="{ 'displayNone': formData.sta_LightType === item.key }"
							src="/static/images/100/light.png" mode="aspectFit"></image>
						<image class="img" :class="{ 'displayNone': formData.sta_LightType !== item.key }"
							src="/static/images/100/lightActive.png" mode="aspectFit"></image>
					</view>
					<view class="rightTxt">
						<text class="bigTxt">{{ item.name }}</text>
					</view>
				</view>
				<view class="clear"></view>
			</view>
			<view class="warn" style="padding-bottom: 20rpx;">
				<view class="header">
					<text>调节</text>
				</view>
				<view class="header paddingTop0">
					<text class="sliderTxt">亮度</text>
					<text class="sliderVal">{{ formData.lightBrightness }}%</text>
				</view>
				<view class="slider-container">
					<slider min="10" max="100" step="10" :disabled="false" :value="formData.lightBrightness"
						activeColor="#bbe600" backgroundColor="#686767" block-size="20" block-color="#ffffffde"
						@change="onBrightnessChanging" @changing="onBrightnessChanging" class="custom-slider" />
				</view>
				<view class="line"></view>
				<view class="header paddingTop0">
					<text class="sliderTxt">频率</text>
					<text class="sliderVal">{{ formData.strobeFrequency }}HZ</text>
				</view>
				<view class="slider-container">
					<slider min="1" max="10" step="1" :disabled="false" :value="formData.strobeFrequency"
						activeColor="#bbe600" backgroundColor="#686767" block-size="20" block-color="#ffffffde"
						@change="onFreqChanging" @changing="onFreqChanging" class="custom-slider" />
				</view>
				<view class="line"></view>
				<view class="header paddingTop0">
					<text class="sliderTxt">音量</text>
					<text class="sliderVal">{{ formData.volume }}</text>
				</view>
				<view class="slider-container">
					<slider min="10" max="100" step="1" :disabled="false" :value="formData.volume" activeColor="#bbe600"
						backgroundColor="#686767" block-size="20" block-color="#ffffffde" @change="onVolumeChanging"
						@changing="onVolumeChanging" class="custom-slider" />
				</view>
				<view class="proinfo lamp">
					<text class="title">产品信息</text>
					<view class="itemcontent">
						<view class="item" @click="proParam()">
							<image class="img" src="/static/images/6155/DeviceDetail/param.png" mode="aspectFit">
							</image>
							<text class="txt">产品参数</text>
						</view>
						<view class="item" @click="handRemark()">
							<image class="img" src="/static/images/6155/DeviceDetail/remark.png" mode="aspectFit">
							</image>
							<text class="txt">操作说明</text>
						</view>
						<view class="item" @click="handVideo()">
							<image class="img" src="/static/images/6155/DeviceDetail/video.png" mode="aspectFit">
							</image>
							<text class="txt">操作视频</text>
						</view>
					</view>
				</view>
				<!-- 弹窗通知 -->
				<MessagePopup :visible="Status.Pop.showPop" :type="Status.Pop.popType" :bgColor="Status.Pop.bgColor"
					:borderColor="Status.Pop.borderColor" :textColor="Status.Pop.textColor"
					:buttonBgColor="Status.Pop.buttonBgColor" :buttonTextColor="Status.Pop.buttonTextColor"
					:iconUrl="Status.Pop.iconUrl" :message="Status.Pop.message" :buttonText="Status.Pop.buttonText"
					@buttonClick="HidePop" :visiblePrompt="Status.Pop.visiblePrompt"
					:promptTitle="Status.Pop.promptTitle" v-model="Status.Pop.modelValue"
					:buttonCancelText="Status.Pop.buttonCancelText" :showCancel="Status.Pop.showCancel"
					@cancelPop="closePop" />
			</view>
		</view>
	</view>
</template>

<script>
	import gbk from '@/utils/gbk.js'
	import MqttClient from '@/utils/mqtt.js';
	import {
		showLoading,
		hideLoading,
		updateLoading
	} from '@/utils/loading.js'
	import request, {
		baseURL
	} from '@/utils/request.js';
	import {
		deviceDetail,
		deviceStrobeMode,
		deviceForceAlarmActivation,
		deviceStrobeFrequency,
		deviceLightAdjustment,
		deviceUpdateVolume,
		deviceVoiceBroadcast,
		updateBleStatus,
		getBleStatus,
		parseBleData,
		fetchBlePowerStatus,
		fetchBleLocation
	} from '@/api/100J/HBY100-J.js'
	import BleHelper from '@/utils/BleHelper.js';
	var bleTool = BleHelper.getBleTool();
	import Common from '@/utils/Common.js'
	const pagePath = "/pages/100/HBY100";
	export default {
		data() {
			return {
				mqttClient: null,
				activePermissions: [], // 存储当前设备的权限数组
				Status: {
					isRightIconVisible: false,
					navTitle: '',
					apiType: '',
					navBarHeight: 70 + uni.getSystemInfoSync().statusBarHeight,
					curr: 0,
					total: 0,
					pageHide: false,

					Pop: {
						showPop: false, //是否显示弹窗
						popType: 'custom',
						bgColor: '#383934bd',
						borderColor: '#BBE600',
						textColor: '#ffffffde',
						buttonBgColor: '#BBE600',
						buttonTextColor: '#232323DE',
						iconUrl: '',
						message: '您确定要这样做吗？',
						buttonText: '确定',
						clickEvt: '',
						visiblePrompt: false,
						promptTitle: '设备名称',
						modelValue: '',
						visibleClose: false,
						okCallback: null,
						buttonCancelText: '',
						showCancel: false,
					},
					BottomMenu: {
						show: false,
						showHeader: true,
						menuItems: [{
							text: '强光',
							icon: '/static/images/lightImg/qiang.png'
						}],
						activeIndex: -1,
						bgColor: '#2a2a2a',
						itemBgColor: '#3a3a3a',
						textColor: '#ffffffde',
						textAlign: 'flex-start',
						title: '主灯模式',
						showDivider: false,
						dividerColor: '#00000000',
						dividerThickness: '0rpx',
						dividerMargin: '10rpx',
						itemHeight: '80rpx',
						type: '',
						showBtn: true,
						btnBgColor: "#bbe600",
						btnText: "确定",
						btnTextColor: "#232323de",
						showMask: true,
						maskBgColor: '#00000066',
						showClose: false
					},
					usrToggle: false,
				},
				formData: {
					img: '',
					sta_battery: '',
					xuhang: '',
					blename: '',
					deviceId: '',
					deviceName: '',
					RSSI: '',
					statu: '',
					macAddress: '',
					bleStatu: false,
					sta_address: '',
					sta_VoiceType: '0',
					volume: 10,
					sta_LightType: '',
					strobeFrequency: 0.5,
					lightBrightness: 10,
					sta_system: '',
					warnTime: 0,
				},
				dic: {
					sta_VoiceType: {
						"1": {
							key: "1",
							name: '消防',
							show: true
						},
						"0": {
							key: "0",
							name: '公安',
							show: true
						},
						"3": {
							key: "3",
							name: '交警',
							show: true
						},
						"4": {
							key: "4",
							name: '市政',
							show: true
						},
						"2": {
							key: "2",
							name: '应急',
							show: true
						},
						"6": {
							key: "6",
							name: '医疗',
							show: true
						},
						"5": {
							key: "5",
							name: '铁道',
							show: true
						},
						"7": {
							key: "7",
							name: 'app语音',
							show: false
						},
						"-1": {
							key: "-1",
							name: '关闭',
							show: false
						}
					},

					sta_LightType: [{
							key: "6",
							name: '红蓝交替',
							show: true
						},
						{
							key: "0",
							name: '红闪',
							show: true
						},
						{
							key: "2",
							name: '黄闪',
							show: true
						},
						{
							key: "1",
							name: '蓝闪',
							show: true
						},
						{
							key: "3",
							name: '红色顺时针',
							show: true
						},
						{
							key: "4",
							name: '黄色顺时针',
							show: true
						},
						{
							key: "5",
							name: '红蓝顺时针',
							show: true
						},
						{
							key: "-1",
							name: '关闭',
							show: false
						}
					],


					sta_system: {
						"0": '关机',
						"1": '仅充电',
						"2": '开机未充电',
						"3": '开机且充电',
						"": ""
					}

				},
				device: {
					id: "",
					deviceName: "",
					deviceImei: "",
					deviceMac: "",
					communicationMode: 0,
					devicePic: "",
					typeName: "",
					bluetoothName: null,
					deviceStatus: null,
					bindingTime: "",
					onlineStatus: 0,
					battery: "0",
					latitude: null,
					longitude: null,
					alarmStatus: null,
					detailPageUrl: "/pages/650/HBY650",
					showConfirm: false,
					deviceId: ''
				},
				permissions: [],
				audioData: {
					packetCtn: 0,
					hexs: []
				},
				deviceInfo: {},
			}
		},
		onLoad: function() {
			const eventChannel = this.getOpenerEventChannel();
			var these = this;

			// 低电量：语音上传/蓝牙分包时电量字段易抖动，防抖 + 上传中不弹，避免「发送中频繁低电量」误报
			this._lastBatteryLowToastPct = null;
			this._batteryLowDebounceTimer = null;
			this.$watch("deviceInfo.batteryPercentage", () => {
				if (bleTool.isVoiceUploading && bleTool.isVoiceUploading()) {
					if (this._batteryLowDebounceTimer) {
						clearTimeout(this._batteryLowDebounceTimer);
						this._batteryLowDebounceTimer = null;
					}
					return;
				}
				const n = Math.round(Number(this.deviceInfo.batteryPercentage));
				if (!Number.isFinite(n)) return;
				if (n > 20) {
					this._lastBatteryLowToastPct = null;
					if (this._batteryLowDebounceTimer) {
						clearTimeout(this._batteryLowDebounceTimer);
						this._batteryLowDebounceTimer = null;
					}
					return;
				}
				if (this._batteryLowDebounceTimer) clearTimeout(this._batteryLowDebounceTimer);
				this._batteryLowDebounceTimer = setTimeout(() => {
					this._batteryLowDebounceTimer = null;
					if (bleTool.isVoiceUploading && bleTool.isVoiceUploading()) return;
					const cur = Math.round(Number(this.deviceInfo.batteryPercentage));
					if (!Number.isFinite(cur) || cur > 20) return;
					if (this._lastBatteryLowToastPct === cur) return;
					this._lastBatteryLowToastPct = cur;
					uni.showToast({
						title: '设备电量低',
						icon: 'none',
						duration: 2000
					});
				}, 800);
			});
			eventChannel.on('detailData', function(data) {
				var device = data.data;
				these.device = device;
				these.Status.navTitle = data.data.deviceName;
				these.Status.apiType = data.apiType;
				these.Status.isRightIconVisible = these.Status.apiType === 'listA';

				these.mqttClient = new MqttClient();

				these.mqttClient.connect(() => {
					// 订阅来自设备的状态更新
					const statusTopic = `status/894078/HBY100/${data.data.deviceImei}`;
					these.mqttClient.subscribe(statusTopic, (payload) => {
						try {
							// 解析MQTT返回的payload
							const payloadObj = typeof payload === 'string' ? JSON.parse(
								payload) : payload;
							// console.log(payloadObj, '这是我的数据类型么');
							const data = payloadObj.data ?? {};
							const funcType = payloadObj.funcType ?? ''; // 从顶层获取funcType
							const {
								siren_alarm = {
										enable: 0,
										mode: 0
									},
									led_strobe = {
										enable: 0,
										mode: 0,
										frequency: 0
									},
									volume = 0,
									brightness = {
										red: 0,
										green: 0,
										blue: 0
									},

							} = data;
							// 3. 赋值对应的字段
							// 续航时间相关
							if (funcType == '4') {
								these.deviceInfo.batteryPercentage = data.level //电量
								these.deviceInfo.batteryRemainingTime = data
									.battery_remaining_time //续航时间
								// 设备按键, app同步
							} else if (funcType == '14') {
								// 调节亮度，音量，频率相关字段
								these.formData.strobeFrequency = led_strobe.frequency ||
									0.5; //频率
								these.formData.volume = volume || 10; //音量
								these.formData.lightBrightness = brightness.red ||
									10; //亮度值
								// 警示灯
								const enable1 = led_strobe.enable ?? 0; // 开关：1=开，0=关
								const mode1 = led_strobe.mode ?? 0; // 模式：0/1/2/3/4/5/6
								if (enable1 === 1) {
									// 开启状
									these.formData.sta_LightType = mode1 + '';
								} else {
									// 关闭状态：赋值-1，表示关闭
									these.formData.sta_LightType = '-1';
								}
								//  报警模式，选中，首次上报值，或者切换设备按键上报值
								const enable = siren_alarm.enable ?? 0; // 报警开关：1=开，0=关
								const mode = siren_alarm.mode ?? 0; // 模式：0/1/2/3/4/5/6
								if (String(these.formData.sta_VoiceType) !== '7') {
									if (enable === 1) {
										these.formData.sta_VoiceType = mode + '';
									} else {
										const m = Number(mode);
										these.formData.sta_VoiceType = m === 7 ? '-1' : m + '';
									}
								} else {
									// 播放语音,上报消息
									const voiceStrobeAlarm = data.voice_broadcast ?? 0;
									if (voiceStrobeAlarm === 1) {
										these.formData.sta_VoiceType = '7'
									} else {
										these.formData.sta_VoiceType = '-1'
									}
								}
							}
							// 报警模式相关字段赋值，是语音播放根据这个字段
							if (funcType === '6') {
								console.log('我是谁', data.voice_broadcast);
								// 语音频闪报警：0=关闭，1=开启 ui7是播放的状态
								const voiceStrobeAlarm = data.voice_broadcast ?? 0;
								if (voiceStrobeAlarm === 1) {
									these.formData.sta_VoiceType = '7'
								} else {
									these.formData.sta_VoiceType = '-1'
								}
								// 强制报警按键解除报警状态,app同步
							} else if (funcType === '12') {
								const enable_alarm = data.voice_strobe_alarm ?? 0;
								const mode_alarm = data.mode ?? 0;
								if (enable_alarm === 1) {
									these.deviceInfo.voiceStrobeAlarm = 1;
									these.formData.sta_VoiceType = mode_alarm + '';
								} else {
									these.deviceInfo.voiceStrobeAlarm = -1;
									const m = Number(mode_alarm);
									these.formData.sta_VoiceType = m === 7 ? '-1' : m + '';
								}
							}
							// 警示灯模式选中切换
							if (funcType === '10') {
								const enable = data.enable ?? 0; // 开关：1=开，0=关
								const mode = data.mode ?? 0; // 模式：0/1/2/3/4/5/6
								if (enable === 1) {
									// 开启状
									these.formData.sta_LightType = mode + '';
								} else {
									// 关闭状态：赋值-1，表示关闭
									these.formData.sta_LightType = '-1';
								}
							}
							// 报警模式相关字段
							// console.log('formData赋值完成：', these.formData);
						} catch (e) {
							// 捕获异常并打印，方便排查问题（不要空catch）
							console.log('解析MQTT payload失败：', e);
						}
					})
				})
				console.log(data, 'datatatatat');
				// 分享接口
				if (these.Status.apiType === 'listA') {
					these.fetchDeviceDetail(data.data.id)
				} else {
					these.activePermissions = data.data.permission ? data.data.permission.split(',') : [];
					console.log(these.activePermissions, 'activePermissions');
					these.fetchDeviceDetail(data.data.deviceId)
				}
				// 尝试连接蓝牙：需先扫描获取 BLE deviceId，不能直接用 MAC；延迟 500ms 确保蓝牙适配器就绪
				if (data.data.deviceMac) {
					setTimeout(() => {
						these.tryConnect100JBle(data.data.deviceMac);
					}, 500);
				}
			});
			this.createThrottledFunctions();

			// 系统蓝牙开关：与 BleHelper 状态对齐（测试项「关蓝牙后状态空白」）
			this._hby100jBleAdapterHandler = () => {
				this.$nextTick(() => this.sync100JBleUiFromHelper && this.sync100JBleUiFromHelper());
			};
			if (typeof uni.onBluetoothAdapterStateChange === 'function') {
				uni.onBluetoothAdapterStateChange(this._hby100jBleAdapterHandler);
			}

			// 注册蓝牙相关事件（必须 bind(this)，否则 BleHelper 直接调用回调时 this 丢失，蓝牙状态不更新）
			bleTool.addReceiveCallback(this.bleValueNotify.bind(this), "HBY100J");
			bleTool.addDisposeCallback(this.bleStateBreak.bind(this), "HBY100J");
			bleTool.addRecoveryCallback(this.bleStateRecovry.bind(this), "HBY100J");
			bleTool.addStateBreakCallback(this.bleStateBreak.bind(this), "HBY100J");
			bleTool.addStateRecoveryCallback(this.bleStateRecovry.bind(this), "HBY100J");



		},
		onHide: function() {
			this.Status.pageHide = true;
		},
		onUnload() {
			if (this._batteryLowDebounceTimer) {
				clearTimeout(this._batteryLowDebounceTimer);
				this._batteryLowDebounceTimer = null;
			}
			if (this._hby100jBleAdapterHandler && typeof uni.offBluetoothAdapterStateChange === 'function') {
				uni.offBluetoothAdapterStateChange(this._hby100jBleAdapterHandler);
				this._hby100jBleAdapterHandler = null;
			}
			// 移除蓝牙事件监听
			bleTool.removeReceiveCallback("HBY100J");
			bleTool.removeDisposeCallback("HBY100J");
			bleTool.removeRecoveryCallback("HBY100J");
			bleTool.removeStateBreakCallback("HBY100J");
			bleTool.removeStateRecoveryCallback("HBY100J");
			bleTool.removeDeviceFound("HBY100J_SCAN");
			bleTool.StopSearch();
		},
		onShow() {
			this.Status.pageHide = false;
			// 从系统蓝牙开关/后台返回时，与 BleHelper.LinkedList 对齐，避免「蓝牙状态空白/不刷新」
			this.$nextTick(() => this.sync100JBleUiFromHelper());
		},
		computed: {
			getbleStatu() {
				if (this.formData.bleStatu === true) {
					return '已连接';
				}
				if (this.formData.bleStatu === 'connecting') {
					return '连接中';
				}
				if (this.formData.bleStatu === 'dicconnect') {
					return '正在断开';
				}
				if (this.formData.bleStatu === 'err') {
					return '连接异常';
				}
				return '未连接';
			}
		},

		methods: {
			/** 与 BleHelper 实际连接状态对齐（系统关蓝牙再开、从后台回前台等） */
			sync100JBleUiFromHelper() {
				const mac = (this.device && this.device.deviceMac) || (this.deviceInfo && this.deviceInfo.deviceMac);
				if (!mac || !this.deviceInfo.deviceId) return;
				const macNorm = (m) => (m || '').replace(/:/g, '').toUpperCase();
				const targetMacNorm = macNorm(mac);
				const last6 = targetMacNorm.slice(-6);
				const item = bleTool.data.LinkedList.find((v) => {
					const m = macNorm(v.macAddress || '');
					return m === targetMacNorm || (m.length >= 6 && m.slice(-6) === last6);
				});
				if (!bleTool.data.available) {
					this.formData.bleStatu = false;
					updateBleStatus(false, '', this.deviceInfo.deviceId);
					return;
				}
				if (item && item.Linked) {
					this.formData.bleStatu = true;
					updateBleStatus(true, item.deviceId, this.deviceInfo.deviceId);
					return;
				}
				if (this.formData.bleStatu === true || this.formData.bleStatu === 'connecting') {
					this.formData.bleStatu = false;
					updateBleStatus(false, '', this.deviceInfo.deviceId);
				}
			},
			bleStatuToggle() {
				const mac = (this.device && this.device.deviceMac) || (this.deviceInfo && this.deviceInfo.deviceMac);
				if (!mac) return;
				const macNorm = (m) => (m || '').replace(/:/g, '').toUpperCase();
				const targetMacNorm = macNorm(mac);
				const last6 = targetMacNorm.slice(-6);
				let f = bleTool.data.LinkedList.find((v) => {
					const m = macNorm(v.macAddress || '');
					return m === targetMacNorm || (m.length >= 6 && m.slice(-6) === last6);
				});

				if (!f) {
					this.tryConnect100JBle(mac);
					return;
				}
				if (this.formData.bleStatu === true) {
					this.formData.bleStatu = 'dicconnect';
					bleTool.disconnectDevice(f.deviceId).finally(() => {
						this.formData.bleStatu = false;
						if (this.deviceInfo && this.deviceInfo.deviceId) {
							updateBleStatus(false, '', this.deviceInfo.deviceId);
						}
					});
					return;
				}

				if (this.formData.bleStatu === false || this.formData.bleStatu === 'err') {
					this.formData.bleStatu = 'connecting';
					bleTool.LinkBlue(f.deviceId, f.writeServiceId, f.wirteCharactId, f.notifyCharactId).then(() => {
						this.formData.bleStatu = true;
						this.bleStateRecovry({
							deviceId: f.deviceId
						});
					}).catch(() => {
						this.formData.bleStatu = 'err';
					});
					return;
				}


			},
			createThrottledFunctions() {
				// 创建节流函数
				this.throttledBrightnessChange = this.throttle(this.handleBrightnessChange, 500);
				this.throttledFreqChange = this.throttle(this.handleFreqChange, 500);
				this.throttledVolumeChange = this.throttle(this.handleVolumeChange, 500);
			},
			// 获取设备详情（普通详情）
			fetchDeviceDetail(id) {
				let that = this
				deviceDetail(id).then((res) => {
					if (res.code == 200) {
						const validData = Object.fromEntries(
							Object.entries(res.data).filter(([key, value]) => {
								// 过滤规则：值为 null/undefined/0 的字段都不参与合并
								return value !== null && value !== undefined && value !== 0;
							})
						);
						Object.assign(this.formData, validData);
						that.deviceInfo = res.data;
						that.$nextTick(() => that.sync100JBleUiFromHelper && that.sync100JBleUiFromHelper());
						const strobeEnable = res.data.strobeEnable ?? 0; // 0=关闭，1=开启
						const strobeMode = res.data.strobeMode ?? 0; // 0=红闪、1=蓝闪、3=红色顺时针...
						if (strobeEnable === 1) {
							// 开启状态
							that.formData.sta_LightType = strobeMode + '';
						} else {
							// 关闭状态
							that.formData.sta_LightType = '-1';
						}
						const alarmOnDetail = res.data.voiceStrobeAlarm === 1;
						const amDetail = res.data.alarmMode != null ? Number(res.data.alarmMode) : 0;
						if (alarmOnDetail) {
							this.formData.sta_VoiceType = amDetail + '';
						} else {
							this.formData.sta_VoiceType = amDetail === 7 ? '-1' : amDetail + '';
						}
					}
				})
			},
			// 检查权限的方法
			hasPermission(permissionCode) {
				// 如果还在加载中，直接返回false
				if (this.pageLoading) return false
				// 如果不是分享设备，默认有全部权限
				if (!this.isSharedDevice) return true
				return this.activePermissions.includes(permissionCode)
			},
			handleRightClick(item, s) {
				if (item && item.callback) {
					item.callback(item, s);
				}
			},
			navigatorBack() {
				uni.navigateBack();
			},

			gotoShare(item, s) {
				uni.navigateTo({
					url: '/pages/common/share/index',
					events: {
						ack: function(data) {}
					},
					success: (res) => {
						let json = {
							persissonType: '100J'
						};
						Object.assign(json, this.deviceInfo);
						res.eventChannel.emit('share', {
							data: json
						});
					}
				})
			},
			// 语音管理（传递蓝牙状态，确保子页走蓝牙优先）
			audioManager(item) {
				if (this.Status.apiType !== 'listA') {}
				const ble = getBleStatus();
				uni.navigateTo({
					url: '/pages/100J/audioManager/AudioList',
					events: {},
					success: (res) => {
						res.eventChannel.emit('deviceData', {
							data: item,
							ble
						});
					},
				});
			},
			//频率
			onFreqChanging(e) {
				this.formData.strobeFrequency = e.detail.value;
				this.throttledFreqChange(e.detail.value);
			},
			//音量
			onVolumeChanging(e) {
				this.formData.volume = e.detail.value;
				this.throttledVolumeChange(e.detail.value);
			},

			// 亮度调节
			onBrightnessChanging(e) {
				this.formData.lightBrightness = e.detail.value;
				this.throttledBrightnessChange(e.detail.value);
			},
			// 亮度调节
			handleBrightnessChange(brightnessValue) {
				let data = {
					deviceId: this.deviceInfo.deviceId,
					brightness: brightnessValue
				};
				console.log('发送亮度调节请求:', data);
				deviceLightAdjustment(data).then((res) => {
					if (res.code === 200) {
						console.log('亮度调节成功');
						uni.showToast({
							title: res.msg,
							icon: 'none',
							duration: 1000
						});
					} else {
						uni.showToast({
							title: res.msg || '调节失败',
							icon: 'none',
							duration: 1000
						});
					}
				}).catch((err) => {

				});
			},
			// 频率调节
			handleFreqChange(freqValue) {
				let data = {
					deviceId: this.deviceInfo.deviceId,
					frequency: freqValue
				};

				deviceStrobeFrequency(data).then((res) => {
					if (res.code === 200) {
						uni.showToast({
							title: res.msg,
							icon: 'none',
							duration: 1000
						});
					} else {
						uni.showToast({
							title: res.msg || '调节失败',
							icon: 'none',
							duration: 1000
						});
					}
				}).catch((err) => {});
			},
			// 音量调节处理函数
			handleVolumeChange(volumeValue) {
				let data = {
					deviceId: this.deviceInfo.deviceId,
					volume: volumeValue
				};
				deviceUpdateVolume(data).then((res) => {
					if (res.code === 200) {
						uni.showToast({
							title: res.msg,
							icon: 'none',
							duration: 1000
						});
					} else {
						uni.showToast({
							title: res.msg,
							icon: 'none',
							duration: 1000
						});
					}
				}).catch((err) => {});
			},
			// 节流函数
			throttle(func, delay = 500) {
				let timer = null;
				let lastArgs = null;
				let lastThis = null;
				return function(...args) {
					lastArgs = args;
					lastThis = this;
					if (!timer) {
						timer = setTimeout(() => {
							timer = null;
							func.apply(lastThis, lastArgs);
						}, delay);
					}
				};

			},
			// *******定位******
			gpsPosition(item) {
				// 添加调试日志
				uni.navigateTo({
					url: '/pages/common/map/index',
					events: {
						ack: function(data) {}
					},
					success: (res) => {
						res.eventChannel.emit('Map', {
							data: item
						});
					}
				})
			},
			// 警示灯开关闭
			lightTypeSet(item, index) {
				console.log('走了么');
				let val = item.key;
				// 切换选中/取消选中逻辑
				if (this.formData.sta_LightType === val) {
					val = '-1';
				}
				this.formData.sta_LightType = val;
				let data = {
					deviceId: this.deviceInfo.deviceId,
					// 开启/关闭：选中模式时传1，关闭时传0
					enable: val === '-1' ? 0 : 1,
					// 0 红色爆闪，1 蓝色爆闪，2 黄色爆闪，3，红色顺时针旋转爆闪，4黄色顺时针旋转爆闪，5，红蓝顺时针旋转爆闪，6 红蓝交替爆闪
					mode: item.key
				};
				deviceStrobeMode(data).then((res) => {
					if (res.code == 200) {
						const tipText = data.enable === 1 ? '开启成功' : '关闭成功';
						uni.showToast({
							title: tipText,
							icon: 'none',
							duration: 1000
						});
					} else {
						uni.showToast({
							title: res.msg,
							icon: 'none',
							duration: 1000
						});
					}
				})
			},
			// 报警模式
			setUsrToggle() {
				this.Status.usrToggle = !this.Status.usrToggle;
			},
			// 播放语音
			openVolume(item, index) {
				if (!item) {
					item = this.dic.sta_VoiceType[index];
				}
				let val = item.key;
				const prevVoiceType = this.formData.sta_VoiceType;
				if (this.formData.sta_VoiceType === val) {
					val = '-1';
				}
				this.formData.sta_VoiceType = val;
				console.log(val, 'valllll');
				// 仅「播放语音」7 的开关走播报接口；-1 只有从 7 取消时才视为关播报，避免取消内置音色选中误调播报接口
				const isVoiceOperate = val === '7' || (val === '-1' && prevVoiceType === '7');
				if (this.deviceInfo.voiceStrobeAlarm === 1) {
					// 强制报警已开启：切换下方模式需带报警下发
					const data = {
						deviceIds: [this.deviceInfo.deviceId],
						voiceStrobeAlarm: 1,
						mode: this.formData.sta_VoiceType
					};
					deviceForceAlarmActivation(data).then((res) => {
						if (res.code === 200) {
							uni.showToast({
								title: '强制报警已开启',
								icon: 'none'
							});
						} else {
							uni.showToast({
								title: res.msg,
								icon: 'none'
							});
						}
					});
				} else if (isVoiceOperate) {
					const data = {
						deviceId: this.deviceInfo.deviceId,
						voiceBroadcast: Number(this.formData.sta_VoiceType) === -1 ? 0 : 1,
						mode: this.formData.sta_VoiceType,
						voiceStrobeAlarm: this.deviceInfo.voiceStrobeAlarm
					};
					deviceVoiceBroadcast(data).then((res) => {
						if (res.code == 200) {
							uni.showToast({
								title: res.msg,
								icon: 'none'
							});
						} else {
							uni.showToast({
								title: res.msg,
								icon: 'none'
							});
						}
					}).catch(() => {
						uni.showToast({
							title: '下发失败，请检查蓝牙或网络',
							icon: 'none'
						});
					});
				} else if (prevVoiceType === '7' && val !== '7' && val !== '-1') {
					// 从「播放语音」切到其它内置音色：先关播报；报警未开启时不走 forceAlarm，仅 UI 预选音色
					const data = {
						deviceId: this.deviceInfo.deviceId,
						voiceBroadcast: 0,
						mode: val,
						voiceStrobeAlarm: this.deviceInfo.voiceStrobeAlarm
					};
					deviceVoiceBroadcast(data).then((res) => {
						if (res.code == 200) {
							uni.showToast({
								title: res.msg || '已切换',
								icon: 'none'
							});
						} else {
							uni.showToast({
								title: res.msg || '操作失败',
								icon: 'none'
							});
						}
					}).catch(() => {
						uni.showToast({
							title: '下发失败，请检查蓝牙或网络',
							icon: 'none'
						});
					});
				}
				// 未开启强制报警时，在 0–6 内置音色间切换或取消选中：只改按钮选中，不下发
			},
			// 报警模式
			sosSetting(item) {
				console.log(this.deviceInfo, '44444');
				console.log(item, 'tent');
				const isClose = item === 0;
				// 与「已解除不再重复关报警」对称：已在报警中不再弹窗重复下发「开启」，未报警时不再重复「解除」
				if (!isClose && this.deviceInfo.voiceStrobeAlarm === 1) {
					uni.showToast({ title: '当前已在报警中', icon: 'none' });
					return;
				}
				if (isClose && this.deviceInfo.voiceStrobeAlarm !== 1) {
					uni.showToast({ title: '当前未在报警中', icon: 'none' });
					return;
				}
				if (!this.Status) this.Status = {};
				if (!this.Status.Pop) this.Status.Pop = {
					showPop: false
				};

				// 弹窗配置
				this.Status.Pop = {
					...this.Status.Pop,
					showPop: true,
					message: isClose ? '确定解除声光报警模式?' : '确定开启强制报警?',
					buttonText: isClose ? '解除' : '开启',
					borderColor: "#e034344d",
					buttonBgColor: "#E03434",
					showCancel: true,
					buttonCancelText: '取消',
					okCallback: () => {
						const data = {
							deviceIds: [this.deviceInfo.deviceId],
							voiceStrobeAlarm: isClose ? 0 : 1,
							mode: this.formData.sta_VoiceType
						};
						deviceForceAlarmActivation(data).then((res) => {
							if (res.code === 200) {
								// 与 MQTT / bleValueNotify 一致：报警中=1，解除=-1（勿在请求前乐观改 UI，失败会导致按钮文案错乱）
								this.$set(this.deviceInfo, 'voiceStrobeAlarm', isClose ? -1 : 1);
								uni.showToast({
									title: isClose ? '声光报警已解除' : '强制报警已开启',
									icon: 'none'
								});
								// 解除后「播放语音」行与 mode7 绑定，需退出高亮（兼容 sta_VoiceType 为数字 7）
								if (isClose && String(this.formData.sta_VoiceType) === '7') {
									this.formData.sta_VoiceType = '-1';
								}
							} else {
								uni.showToast({
									title: res.msg,
									icon: 'none'
								});
							}
						}).catch(() => {
							uni.showToast({
								title: '网络或蓝牙异常，请重试',
								icon: 'none'
							});
						});
					}
				};
			},

			deviceRecovry(res) {},
			deviceDispose(res) {},
			// 100J 蓝牙连接：先查缓存/尝试直连，失败则扫描
			// 注意：Android 的 createBLEConnection 需要系统返回的 deviceId，服务端 MAC(11:22:33:44:55:02) 与 deviceId(02:55:44:33:22:11) 字节序相反
			tryConnect100JBle(deviceMac) {
				const that = this;
				const macNorm = (m) => (m || '').replace(/:/g, '').toUpperCase();
				const targetMacNorm = macNorm(deviceMac);
				const last6 = targetMacNorm.slice(-6);
				// Android BLE deviceId 多为 MAC 字节反序，如 11:22:33:44:55:02 -> 02:55:44:33:22:11
				const macToDeviceId = (mac) => {
					const parts = (mac || '').split(':').filter(Boolean);
					return parts.length === 6 ? parts.reverse().join(':') : mac;
				};

				// 1. 查缓存：之前连过且 mac 匹配
				const cached = bleTool.data.LinkedList.find(v => {
					const m = macNorm(v.macAddress);
					return m === targetMacNorm || m.slice(-6) === last6;
				});
				const SVC = '0000AE30-0000-1000-8000-00805F9B34FB';
				const WRITE = '0000AE03-0000-1000-8000-00805F9B34FB';
				const NOTIFY = '0000AE02-0000-1000-8000-00805F9B34FB';
				if (cached && cached.deviceId) {
					console.log('[100J] 使用缓存设备连接', cached.deviceId);
					that.formData.bleStatu = 'connecting';
					bleTool.LinkBlue(cached.deviceId, SVC, WRITE, NOTIFY, 2).then(() => {
						console.log('100J 蓝牙连接成功(缓存)');
						that.formData.bleStatu = true;
						that.bleStateRecovry({
							deviceId: cached.deviceId
						});
					}).catch(err => {
						console.log('100J 蓝牙连接失败(缓存)，尝试扫描', err);
						that.formData.bleStatu = 'err';
						that.connect100JByScan(deviceMac, last6);
					});
					return;
				}

				// 2. 无缓存：先尝试直连。Android 上 deviceId 多为 MAC 反序(11:22:33:44:55:02->02:55:44:33:22:11)
				that.formData.bleStatu = 'connecting';
				const tryDirect = (id) => bleTool.LinkBlue(id, SVC, WRITE, NOTIFY, 2).then(() => {
					console.log('100J 蓝牙连接成功(直连)', id);
					that.formData.bleStatu = true;
					that.bleStateRecovry({
						deviceId: id
					});
				}).catch(ex => {
					that.formData.bleStatu = 'err';
				});
				const deviceIdReversed = macToDeviceId(deviceMac);
				console.log('[100J] 尝试直连', deviceIdReversed, '(MAC反序)');
				tryDirect(deviceIdReversed).catch(() => {
					if (deviceIdReversed !== deviceMac) {
						console.log('[100J] 反序直连失败，尝试原 MAC', deviceMac);
						return tryDirect(deviceMac);
					}
					return Promise.reject();
				}).catch(() => {
					console.log('[100J] 蓝牙直连失败，开始扫描');
					that.connect100JByScan(deviceMac, last6);
				});
			},
			connect100JByScan(deviceMac, last6) {
				const that = this;
				const SVC = '0000AE30-0000-1000-8000-00805F9B34FB';
				const WRITE = '0000AE03-0000-1000-8000-00805F9B34FB';
				const NOTIFY = '0000AE02-0000-1000-8000-00805F9B34FB';
				let resolved = false;
				const timeout = 15000;
				const timer = setTimeout(() => {
					if (resolved) return;
					resolved = true;
					bleTool.StopSearch();
					bleTool.removeDeviceFound('HBY100J_SCAN');
					console.log('100J 蓝牙扫描超时，将使用4G');
					that.formData.bleStatu = false;
					const devId = that.deviceInfo && that.deviceInfo.deviceId;
					if (devId) updateBleStatus(false, '', devId);
				}, timeout);

				bleTool.addDeviceFound((res) => {
					if (resolved) return;
					const devices = res.devices || [];
					const match = devices.find(d => {
						const name = (d.name || '').replace(/\r\n/g, '').trim();
						return name === 'HBY100J' || name.startsWith('LED-') && name.slice(-6) === last6;
					});
					if (match) {
						resolved = true;
						clearTimeout(timer);
						bleTool.StopSearch();
						bleTool.removeDeviceFound('HBY100J_SCAN');
						console.log('[100J] 扫描到目标设备', match.name, match.deviceId);
						that.formData.bleStatu = 'connecting';
						bleTool.LinkBlue(match.deviceId, SVC, WRITE, NOTIFY, 2).then(() => {
							console.log('100J 蓝牙连接成功(扫描)');
							that.formData.bleStatu = true;
							that.bleStateRecovry({
								deviceId: match.deviceId
							});
						}).catch(err => {
							console.log('100J 蓝牙连接失败，将使用4G', err);
							that.formData.bleStatu = 'err';
						});
					}
				}, 'HBY100J_SCAN');

				bleTool.StartSearch().then(() => {
					console.log('[100J] 开始扫描蓝牙，设备名 HBY100J 或 LED-' + last6);
				}).catch(err => {
					if (!resolved) {
						resolved = true;
						clearTimeout(timer);
						bleTool.removeDeviceFound('HBY100J_SCAN');
						console.log('100J 蓝牙扫描启动失败，将使用4G', err);
						that.formData.bleStatu = 'err';
						const devId = that.deviceInfo && that.deviceInfo.deviceId;
						if (devId) updateBleStatus(false, '', devId);
					}
				});
			},
			_match100JBleItemByRes(res) {
				if (!res || !res.deviceId) return true;
				const mac = (this.device && this.device.deviceMac) || (this.deviceInfo && this.deviceInfo.deviceMac);
				if (!mac) return true;
				const macNorm = (m) => (m || '').replace(/:/g, '').toUpperCase();
				const target = macNorm(mac);
				const last6 = target.slice(-6);
				const item = bleTool.data.LinkedList.find((v) => {
					const m = macNorm(v.macAddress || '');
					return v.deviceId === res.deviceId && (m === target || (m.length >= 6 && m.slice(-6) ===
						last6));
				});
				return !!item;
			},
			bleStateBreak(res) {
				// 仅处理本页 100J 的断开，避免其它型号设备断连误改本页状态
				if (res && res.deviceId && !this._match100JBleItemByRes(res)) return;
				this.formData.bleStatu = false;
				updateBleStatus(false, '', this.deviceInfo.deviceId);
			},
			bleStateRecovry(res) {
				// 蓝牙适配器恢复可用（关闭蓝牙后重新开启）：无 deviceId，需主动重连
				if (!res || !res.deviceId) {
					const mac = (this.device && this.device.deviceMac) || (this.deviceInfo && this.deviceInfo.deviceMac);
					if (mac) {
						console.log('[100J] 蓝牙适配器已恢复，尝试重连', mac);
						this.tryConnect100JBle(mac);
					}
					return;
				}
				if (!this._match100JBleItemByRes(res)) return;
				let bleDeviceId = res.deviceId;
				updateBleStatus(true, bleDeviceId, this.deviceInfo.deviceId);
				// 蓝牙连接成功后主动拉取电源状态、定位(优先蓝牙，设备也会每1分钟主动上报)
				// 两指令间隔 150ms，避免 writeBLECharacteristicValue:fail property not support
				fetchBlePowerStatus()
					.then(() => new Promise(r => setTimeout(r, 150)))
					.then(() => fetchBleLocation())
					.catch(() => {});
			},
			previewImg(img) {},
			bleValueNotify: function(receive, device, path, recArr) { //订阅消息
				// 仅处理当前设备的数据（device 为 LinkedList 中匹配 receive.deviceId 的项）
				if (device && device.device && this.deviceInfo.deviceId && device.device.id != this.deviceInfo
					.deviceId) return;
				// 解析蓝牙上报数据 (协议: FC=MAC主动上报, FB=指令响应)
				if (!receive.bytes || receive.bytes.length < 3) return;
				const parsedData = parseBleData(receive.bytes);
				if (!parsedData) return;

				// 5.1 连接后设备主动上报 MAC 地址 (FC + 6字节 + FF)
				if (parsedData.type === 'mac' && parsedData.macAddress) {
					this.formData.macAddress = parsedData.macAddress;
					this.device.deviceMac = parsedData.macAddress;
					this.$set(this.deviceInfo, 'deviceMac', parsedData.macAddress);
					return;
				}

				// 5.4 设备位置 (0x03)：主动查询响应或设备定时上报(1分钟)，优先蓝牙
				// 使用 $set 确保 Vue2 能检测新增属性并触发视图更新
				if (parsedData.longitude !== undefined && parsedData.latitude !== undefined) {
					this.$set(this.deviceInfo, 'longitude', parsedData.longitude);
					this.$set(this.deviceInfo, 'latitude', parsedData.latitude);
				}

				// 5.5 获取设备电源状态 (0x04)
				if (parsedData.batteryPercentage !== undefined) {
					this.$set(this.deviceInfo, 'batteryPercentage', parsedData.batteryPercentage);
				}
				if (parsedData.batteryRemainingTime !== undefined) {
					this.$set(this.deviceInfo, 'batteryRemainingTime', parsedData.batteryRemainingTime);
				}



				// 设备物理按键切换：蓝牙响应同步到 APP 页面（与 4G MQTT 逻辑一致）
				const fc = parsedData.funcCode;
				// 0x0C 强制报警：设备按键切换报警状态
				if (fc === 0x0C && parsedData.alarmEnable !== undefined) {
					if (parsedData.alarmEnable === 1) {
						this.$set(this.deviceInfo, 'voiceStrobeAlarm', 1);
						this.formData.sta_VoiceType = (parsedData.alarmMode ?? 0) + '';
					} else {
						this.$set(this.deviceInfo, 'voiceStrobeAlarm', -1);
						const am = Number(parsedData.alarmMode ?? 0);
						// 报警已关：设备仍可能带 mode7，避免「播放语音」仍显示为开启
						this.formData.sta_VoiceType = am === 7 ? '-1' : am + '';
					}
				}
				// 0x0A 爆闪模式：警示灯开关/模式
				if (fc === 0x0A && parsedData.strobeEnable !== undefined) {
					if (parsedData.strobeEnable === 1) {
						this.formData.sta_LightType = (parsedData.strobeMode ?? 0) + '';
					} else {
						this.formData.sta_LightType = '-1';
					}
				}
				// 0x0E 工作方式：综合状态（设备按键切换后上报）
				if (fc === 0x0E) {
					if (parsedData.strobeEnable !== undefined) {
						if (parsedData.strobeEnable === 1) {
							this.formData.sta_LightType = (parsedData.strobeMode ?? 0) + '';
						} else {
							this.formData.sta_LightType = '-1';
						}
					}
					if (parsedData.alarmEnable !== undefined) {
						if (parsedData.alarmEnable === 1) {
							this.$set(this.deviceInfo, 'voiceStrobeAlarm', 1);
							this.formData.sta_VoiceType = (parsedData.alarmMode ?? 0) + '';
						} else {
							this.$set(this.deviceInfo, 'voiceStrobeAlarm', -1);
							const am = Number(parsedData.alarmMode ?? 0);
							this.formData.sta_VoiceType = am === 7 ? '-1' : am + '';
						}
					}
					if (parsedData.voiceBroadcast !== undefined) {
						if (parsedData.voiceBroadcast === 1) this.formData.sta_VoiceType = '7';
						else if (this.formData.sta_VoiceType === '7') this.formData.sta_VoiceType = '-1';
					}
					if (parsedData.volume !== undefined) this.formData.volume = parsedData.volume;
					if (parsedData.strobeFrequency !== undefined) this.formData.strobeFrequency = parsedData
						.strobeFrequency;
					if (parsedData.redBrightness !== undefined) this.formData.lightBrightness = parsedData
						.redBrightness;
				}
				// 0x09 音量、0x0D 亮度：单独响应时同步
				if (fc === 0x09 && parsedData.volume !== undefined) this.formData.volume = parsedData.volume;
				if (fc === 0x0B && parsedData.strobeFrequency !== undefined) this.formData.strobeFrequency = parsedData
					.strobeFrequency;
				if (fc === 0x0D && parsedData.redBrightness !== undefined) this.formData.lightBrightness = parsedData
					.redBrightness;
			},
			showBleUnConnect() {},

			proParam: function() {
				uni.navigateTo({
					url: '/pages/common/productDes/index?id=' + this.deviceInfo.deviceId,
					success(ev) {}
				});
			},
			handRemark: function() {
				uni.navigateTo({
					url: '/pages/common/operatingInstruct/index?id=' + this.deviceInfo.deviceId,
					success(ev) {

					}
				});
			},
			handVideo: function() {
				uni.navigateTo({
					url: '/pages/common/operationVideo/index?id=' + this.deviceInfo.deviceId,
					success(ev) {

					}
				});
			},

			closePop: function() {
				this.Status.Pop.showPop = false;

				if (this.Status.Pop.cancelCallback) {
					this.Status.Pop.cancelCallback();
				}
			},
			HidePop: function() {
				if (this.Status.Pop.clickEvt == 'SendUsr') {

				}

				this.Status.Pop.showPop = false;
				if (this.Status.Pop.okCallback) {
					this.Status.Pop.okCallback();
				}
			},
			showPop: function(option) {
				hideLoading(this);
				let def = {
					showPop: true, //是否显示弹窗
					popType: 'custom',
					bgColor: '#383934bd',
					borderColor: '#BBE600',
					textColor: '#ffffffde',
					buttonBgColor: '#BBE600',
					buttonTextColor: '#232323DE',
					iconUrl: '',
					message: '',
					buttonText: '确定',
					clickEvt: '',
					visiblePrompt: false,
					promptTitle: '',
					modelValue: '',
					visibleClose: false,
					okCallback: null,
					showSlot: false,
					buttonCancelText: '',
					showCancel: false,
				}

				let keys = Object.keys(def);

				for (let i = 0; i < keys.length; i++) {
					let key = keys[i];
					if (key in option) {
						continue;
					}
					this.Status.Pop[key] = def[key];
				}
				if (option) {
					keys = Object.keys(option);
					for (let i = 0; i < keys.length; i++) {
						let key = keys[i];

						this.Status.Pop[key] = option[key];
					}
				}

				if (!option.borderColor) {
					option.borderColor = '#BBE600';
					option.buttonBgColor = '#BBE600';
				}
				these.Status.Pop.showPop = true;
			},
			btnClick() {

			}
		}
	}
</script>

<style>
	.content {
		padding: 30rpx;
		box-sizing: border-box;
	}

	.eq {
		width: 100%;
		height: 250rpx;
		border-radius: 8px;
		background: rgba(26, 26, 26, 1);
		box-sizing: border-box;
		padding: 24rpx 28rpx;
		display: flex;
		flex-direction: row;
		flex-wrap: nowrap;
		align-content: center;
		justify-content: center;
		align-items: center;
		margin-bottom: 24rpx;
	}

	.eq .leftImg {
		box-sizing: border-box;
		padding: 36rpx;
		border-radius: 16rpx;
		background: rgba(42, 42, 42, 0.5);
	}

	.eq .leftImg,
	.eq .rightTxt {
		width: 50%;
		height: 100%;
	}

	.eq .rightTxt {
		display: flex;
		flex-direction: column;
		flex-wrap: nowrap;
		align-content: flex-start;
		justify-content: space-evenly;
		align-items: flex-start;
	}

	.eq .leftImg .img {
		width: 100%;
		height: 100%;
	}

	.eq .rightTxt .img {
		width: 52rpx;
		height: 52rpx;
	}

	.eq .rightTxt .row {
		width: 100%;
		display: flex;
		flex-direction: row;
		flex-wrap: nowrap;
		align-content: center;
		justify-content: flex-start;
		align-items: center;
		box-sizing: border-box;
		padding-left: 50rpx;
	}

	.eq .rightTxt .row .txt {
		padding-left: 20rpx;
	}

	.eq .bigTxt {
		color: rgba(255, 255, 255, 0.87);
		font-family: PingFang SC;
		font-size: 28rpx;
		font-weight: 400;
	}

	.eq .smallTxt {
		color: rgba(255, 255, 255, 0.6);
		font-family: PingFang SC;
		font-size: 24rpx;
		font-weight: 400;
	}


	.eqinfo {
		border-radius: 16rpx;
		background: rgba(26, 26, 26, 1);
		box-sizing: border-box;
		padding: 15rpx 30rpx;
	}

	.eqinfo .item {
		width: 100%;
		height: 60rpx;
		line-height: 60rpx;
		/* padding: 0rpx 28rpx; */
		box-sizing: border-box;
		display: flex;
		flex-direction: row;
		flex-wrap: nowrap;
		align-content: center;
		justify-content: space-between;
		align-items: center;
	}

	.eqinfo .lbl {
		color: rgba(255, 255, 255, 0.87);
		font-family: PingFang SC;
		font-size: 28rpx;
		font-weight: 400;

		letter-spacing: 0.07px;
		text-align: left;
	}

	.eqinfo .value {
		color: rgba(255, 255, 255, 0.6);
		font-family: PingFang SC;
		font-size: 28rpx;
		font-weight: 400;
		letter-spacing: 0.07px;
		text-align: left;
	}

	.eqinfo .info-value {
		/* margin-top: 30rpx; */
	}

	/* .eqinfo .status-running {
		color: rgba(174, 214, 0, 1);
	} */

	.lamp {
		margin-top: 24rpx;
	}

	.lamp .title {
		width: 100%;
		height: 60rpx;
		line-height: 60rpx;
		padding: 0rpx 28rpx;
		box-sizing: border-box;
		display: flex;
		flex-direction: row;
		flex-wrap: nowrap;
		align-content: center;
		justify-content: space-between;
		align-items: center;
		font-size: 28rpx;
	}

	.lamp.noPadding .title,
	.lamp.noPadding .smlltitle {
		padding: 0rpx 0rpx !important;
	}

	.lamp .smlltitle {
		width: 100%;

		line-height: 15rpx;
		padding: 0rpx 28rpx;
		box-sizing: border-box;
		display: flex;
		flex-direction: row;
		flex-wrap: nowrap;
		align-content: center;
		justify-content: space-between;
		align-items: center;
		font-size: 26rpx;
		color: rgba(255, 255, 255, 0.6);
	}


	.lamp .title .img {
		width: 32rpx;
		height: 32rpx;
		margin-top: 20rpx;
	}

	.lampMode {

		width: 100%;
		box-sizing: border-box;

	}

	.lampMode .mode {
		width: calc(calc(100% - 34rpx) / 2);
		border-radius: 8px;
		margin-top: 20rpx;
		background: rgba(26, 26, 26, 1);
		display: flex;
		flex-direction: row;
		flex-wrap: nowrap;
		align-content: center;
		align-items: center;
		justify-content: flex-start;
		padding: 30rpx;
		box-sizing: border-box;
		border-width: 1px;
		border-style: solid;
		border-color: #00000000;
	}

	.lampMode .mode.active {

		border-color: #aed600 !important;
	}

	.lampMode .mode.active .bigTxt {

		color: #aed600 !important;
	}

	.mode.marginLeft {
		margin-left: 34rpx !important;
	}

	.mode .leftImg {
		width: 70rpx;
		height: 70rpx;
		border-radius: 4px;
		background: rgba(255, 255, 255, 0.06);
		display: flex;
		flex-direction: row;
		flex-wrap: nowrap;
		align-content: center;
		justify-content: center;
		align-items: center;
	}

	.mode.active .leftImg {
		background: rgba(255, 255, 255, 0.06);
	}

	.mode .leftImg .img {
		width: 40rpx;
		height: 40rpx;
	}

	.mode .rightTxt {
		display: flex;
		flex-direction: column;
		flex-wrap: nowrap;
		align-content: flex-start;
		justify-content: center;
		align-items: flex-start;
		padding-left: 20rpx;
	}

	.mode .bigTxt {
		color: rgba(255, 255, 255, 0.87);
		font-family: PingFang SC;
		font-size: 28rpx;
		font-weight: 400;

		letter-spacing: 0.07px;

	}

	.mode .smallTxt {
		color: rgba(255, 255, 255, 0.6);
		font-family: PingFang SC;
		font-size: 24rpx;
		font-weight: 400;

		letter-spacing: 0.07px;

	}

	.usrinfo {
		border-radius: 8px;
		width: 100%;
		box-sizing: border-box;
		padding: 24rpx 28rpx;
		background: rgba(26, 26, 26, 1);
	}

	.usrtitle {
		color: rgba(255, 255, 255, 0.87);
		font-family: PingFang SC;
		font-size: 28rpx;
		font-weight: 400;
		height: 40rpx;
		line-height: 40rpx;
		letter-spacing: 0.07px;

	}

	.usrinfo .btnSend {
		line-height: 65rpx;
		border-radius: 8px;
		width: 120rpx;
		height: 65rpx;
		color: rgba(35, 35, 35, 0.87);
		font-family: PingFang SC;
		font-size: 24rpx;
		font-weight: 400;
		letter-spacing: 0.15rpx;
		text-align: center;
		background-color: #BBE600;
	}

	.usrinfo .item {
		border-radius: 8px;
		width: 100%;
		box-sizing: border-box;
		line-height: 90rpx;
		height: 90rpx;
		background: rgba(42, 42, 42, 1);
		margin-top: 24rpx;
		display: flex;
		flex-direction: row;
		flex-wrap: nowrap;
		align-content: center;
		justify-content: flex-start;
		align-items: center;
	}

	.usrinfo .lbl {
		width: 120rpx;
		height: 100%;
		padding-left: 24rpx;
		box-sizing: border-box;

		text-align: right;

		color: rgba(255, 255, 255, 0.87);
		font-family: PingFang SC;
		font-size: 28rpx;
		font-weight: 400;

		letter-spacing: 0.07px;

	}

	.usrinfo .value {
		width: calc(100% - 120rpx);
		height: 100%;

		font-size: 28rpx;
		font-weight: 400;

		letter-spacing: 0.07px;
		text-align: left;

	}

	.usrinfo .value .uni-input-input {
		color: rgba(255, 255, 255, 0.87);
		font-family: PingFang SC;

	}


	.usrplace {
		color: rgba(255, 255, 255, 0.4);
		font-family: PingFang SC;
		font-size: 28rpx;
		font-weight: 400;
		letter-spacing: 0.07px;
		text-align: left;
	}

	.proinfo .itemcontent {
		display: flex;
		display: flex;
		flex-direction: row;
		flex-wrap: nowrap;
		align-content: center;
		justify-content: space-evenly;
	}

	.proinfo .item {
		width: 180rpx;
		height: 180rpx;
		box-sizing: border-box;
		padding: 40rpx;
		border-radius: 16rpx;
		background: rgba(26, 26, 26, 1);
		display: flex;
		flex-direction: column;
		flex-wrap: nowrap;
		align-content: center;
		justify-content: center;
		align-items: center;
	}

	.proinfo .item .img {
		width: 50rpx;
		height: 50rpx;
	}

	.proinfo .item .txt {
		color: rgba(255, 255, 255, 0.6);
		font-family: PingFang SC;
		font-size: 24rpx;
		font-weight: 400;
		margin-top: 20rpx;
		letter-spacing: 0.07px;
		text-align: left;
	}

	.slider-container {
		padding: 0px;
	}

	.addIco {
		width: 100%;
		height: 360rpx;
		display: flex;
		flex-direction: row;
		flex-wrap: nowrap;
		align-content: center;
		justify-content: center;
		align-items: center;
	}

	.icoContent {
		width: 240rpx;
		height: 240rpx;
		border-radius: 8rpx;


		background: rgba(58, 58, 58, 1);
	}

	.icoContent .img {
		width: 70rpx;
		height: 70rpx;
	}

	.arrowContent {
		border-radius: 16rpx;
		background: rgba(26, 26, 26, 1);
		width: 100%;
		padding: 30rpx 0rpx;
	}

	.modeSetting {
		display: flex;
		flex-direction: row;
		flex-wrap: wrap;
		align-content: center;
		align-items: center;
		justify-content: flex-start;

	}

	.modeSetting .arrow {
		display: flex;
		flex-direction: column;
		flex-wrap: nowrap;
		align-content: center;
		justify-content: center;
		align-items: center;
		width: calc(100% / 3);
		margin-bottom: 25rpx;
	}

	.modeSetting .arrow .text {

		color: rgba(255, 255, 255, 0.6);
		font-family: PingFang SC;
		font-size: 24rpx;
		font-weight: 400;

		letter-spacing: 0.14rpx;

	}

	.modeSetting .arrow.active .text {
		color: rgba(35, 35, 35, 0.87);

	}

	.modeSetting .arrow .outCircle {
		width: 130rpx;
		height: 130rpx;
		box-sizing: border-box;
		display: flex;
		flex-direction: row;
		flex-wrap: nowrap;
		align-content: center;
		justify-content: center;
		align-items: center;
		border: 4rpx solid #00000000;
		border-radius: 50%;
		background: rgba(42, 42, 42, 1);
	}

	.modeSetting .arrow .item {
		width: 100%;
		height: 100%;

		border-radius: 50%;


		box-sizing: border-box;
		display: flex;
		flex-direction: row;
		flex-wrap: nowrap;
		align-content: center;
		justify-content: center;
		align-items: center;
	}

	.modeSetting .arrow.active .outCircle {
		border: 4rpx solid rgba(174, 214, 0, 1);
		padding: 4rpx;
	}

	.modeSetting .item.active .p100 {
		background: rgba(174, 214, 0, 1);
		border-radius: 50%;

	}

	.modeSetting .item .img {
		width: 52rpx;
		height: 56rpx;
	}

	.modeSetting .item .img.translate {
		transform: rotate(180deg);
	}

	.modeSetting .arrow .activity {
		display: none;
	}

	.modeSetting .arrow.active .nomal {
		display: none;
	}

	.modeSetting .arrow.active .item {
		background: rgba(174, 214, 0, 1);
	}

	.modeSetting .arrow.active .activity {
		display: block !important;
	}

	.usrinfo .image {
		width: 30rpx;
		height: 40rpx;
	}

	.usrinfo .img {
		width: 30rpx;
		height: 40rpx;
	}

	.content {

		box-sizing: border-box;
		width: 100%;
		min-height: 100vh;
		height: auto;
	}

	.contentBg {
		background-color: #121212;
		color: #ffffffde;
	}

	.fleft {
		float: left;
	}

	.fright {
		float: right;
	}

	.clear {
		clear: both;
	}

	.displayNone {
		display: none !important;
	}

	.p100 {
		width: 100%;
		height: 100%;
	}

	.center {
		display: flex;
		flex-direction: row;
		flex-wrap: nowrap;
		align-content: center;
		justify-content: center;
		align-items: center;
	}

	.centerLeft {
		display: flex;
		flex-direction: row;
		flex-wrap: nowrap;
		align-content: center;
		justify-content: flex-start;
		align-items: center;
	}

	.warnnig {
		border-radius: 16rpx;
		width: 100%;
		height: 70rpx;
		line-height: 70rpx;
		background: rgba(224, 52, 52, 1);
		box-sizing: border-box;
		padding: 0rpx 30rpx;
		margin-top: 20rpx;
		color: rgba(255, 255, 255, 0.87);
		font-family: 'PingFang SC';
		font-size: 28rpx;
		font-weight: 400;
		display: flex;
		flex-direction: row;
		flex-wrap: nowrap;
		align-content: center;
		justify-content: space-between;
		align-items: center;
	}

	.netContent {
		display: flex;
		flex-direction: row;
		flex-wrap: nowrap;
		align-content: flex-end;
		justify-content: space-around;
		align-items: flex-end;
		width: 50rpx;
	}


	.marginTop10 {
		margin-top: 20rpx;
	}

	.warnnig {
		border-radius: 16rpx;
		width: 100%;
		height: 70rpx;
		line-height: 70rpx;
		background: rgba(224, 52, 52, 1);
		box-sizing: border-box;
		padding: 0rpx 30rpx;
		margin-top: 20rpx;
		color: rgba(255, 255, 255, 0.87);
		font-family: 'PingFang SC';
		font-size: 28rpx;
		font-weight: 400;
		display: flex;
		flex-direction: row;
		flex-wrap: nowrap;
		align-content: center;
		justify-content: space-between;
		align-items: center;
	}

	.sosContent {
		width: 100%;
		height: 110rpx;
		display: flex;
		flex-direction: row;
		flex-wrap: nowrap;
		align-content: center;
		align-items: center;
		justify-content: space-between;
		box-sizing: border-box;
		padding-top: 24rpx;
	}

	.btnSos {
		border-radius: 92rpx;
		height: 100%;
		color: rgba(255, 255, 255, 0.87);
		font-family: PingFang SC;
		font-size: 28rpx;
		font-weight: 400;
		line-height: 110rpx;
		letter-spacing: 0.014rpx;
		text-align: center;

	}

	.openSos {
		width: 62%;
		background: #1a1a1a;
		color: #e03434;
		box-sizing: border-box;
		border: 1rpx solid #e03434;
	}

	.openSos.active {
		background: #e03434 !important;
		color: rgba(255, 255, 255, 0.87) !important;
	}


	.closeSos {
		width: 32%;
		background: #1a1a1a;
	}

	.warn {
		border-radius: 16rpx;
		background: #1a1a1a;
		width: 100%;
		box-sizing: border-box;
		margin-top: 25rpx;
	}

	.warn .header {
		width: 100%;
		box-sizing: border-box;
		padding: 20rpx 25rpx;
		display: flex;
		flex-direction: row;
		flex-wrap: nowrap;
		align-content: center;
		align-items: center;
		justify-content: space-between;

	}

	.paddingTop0 {
		padding: 0rpx 25rpx !important;
	}

	.line {
		width: calc(100% - 50rpx);
		height: 0rpx;
		border-bottom: 1rpx solid rgba(255, 255, 255, 0.06);
		margin: 30rpx 25rpx
	}

	.sliderTxt {
		color: rgba(255, 255, 255, 0.6);

		font-family: PingFang SC;
		font-size: 24rpx;
		font-weight: 400;

		letter-spacing: 0.07px;

	}

	.sliderVal {
		color: rgba(174, 214, 0, 1);

		font-family: PingFang SC;
		font-size: 24rpx;
		font-weight: 400;

		letter-spacing: 0.07px;

	}


	.navbarRight {
		width: 40px;
		height: 100%;

	}

	.navbarRight .imgContent {
		width: 36rpx;
		height: 36rpx;
		position: relative;
	}

	.navbarRight .imgContent:first-child {

		width: 38rpx !important;
		height: 38rpx !important;
		margin-top: -2rpx;
	}

	.navbarRight .imgContent .baber {
		position: absolute;
		z-index: 100;
		width: 30rpx;
		height: 30rpx;
		line-height: 30rpx;
		right: -15rpx;
		top: -15rpx;
		border-radius: 50%;
		background: #f12828;
		color: #ffffff;
		font-family: 'PingFang SC';
		font-style: Regular;
		font-size: 20rpx;
		font-weight: 400;

		text-align: center;
		overflow: hidden;
		white-space: nowrap;

	}

	.navbarRight .imgContent .img {
		width: 100%;
		height: 100%;

		box-sizing: border-box;
		position: relative;
	}

	.navbarRight .imgContent .img:last-child {
		padding: 1rpx;
	}

	.nvbar {
		top: 0px;
	}

	/deep/ .uni-navbar--fixed {
		top: 0px;
	}

	.uninavebartext {
		width: 100%;
		font-size: 32rpx;
	}

	.info-row {
		display: flex;
		justify-content: space-between;
	}

	.info-label {
		font-size: 28rpx;
		color: rgba(255, 255, 255, 0.87);
		white-space: nowrap;
	}

	.info-value {
		font-size: 28rpx;
		color: rgba(255, 255, 255, 0.6);
	}

	.status-running {
		/* color: rgba(255, 255, 255, 0.6); */
		text-align: end;
	}

	.locationGPS {
		width: 88%;
		text-align: end;
		float: right;
		line-height: 45rpx;
		font-size: 28rpx;
	}
</style>