diff --git a/pages/6155/deviceDetail.vue b/pages/6155/deviceDetail.vue index 6c8b781..952b0be 100644 --- a/pages/6155/deviceDetail.vue +++ b/pages/6155/deviceDetail.vue @@ -77,7 +77,7 @@ 泛光模式 - + + @@ -446,6 +446,35 @@ } }, methods: { + calcTotalPackets(frames) { + if (!Array.isArray(frames) || frames.length === 0) { + return 0; + } + return frames.reduce((frameSum, frame) => { + if (!Array.isArray(frame)) { + return frameSum; + } + const packSum = frame.reduce((packAcc, pack) => { + if (!Array.isArray(pack)) { + return packAcc; + } + return packAcc + pack.length; + }, 0); + return frameSum + packSum; + }, 0); + }, + toByteValue(value) { + if (typeof value === 'number') { + return value; + } + if (typeof value === 'string') { + if (value.startsWith('0x') || value.startsWith('0X')) { + return parseInt(value, 16); + } + return parseInt(`0x${value}`, 16); + } + return 0; + }, deviceRecovry(res) { if (this.Status.pageHide) { return; @@ -545,12 +574,21 @@ if (!json) { return; } + console.log("收到设备数据:", json); let keys = Object.keys(json); keys.forEach((key) => { if (key in these.formData) { - these.formData[key] = json[key]; + // 确保响应式更新 + console.log(`更新字段 ${key}: ${these.formData[key]} -> ${json[key]}`); + these.$set(these.formData, key, json[key]); + } else { + console.log(`字段 ${key} 不在 formData 中,跳过更新`); } }); + + // 强制触发视图更新,确保电量显示同步 + these.$forceUpdate(); + console.log("更新后的电量:", these.formData.battary); if (this.formData.battary <= 20) { this.showPop({ @@ -900,7 +938,9 @@ if (res.statusCode === 200) { if (res.data.code == 200) { console.log("上传完成,耗时:" + m + "分" + s + "秒"); - updateLoading(these,{text:"上传完成,耗时:" + m + "分" + s + "秒,正在切片。"}) + updateLoading(these, { + text: "上传完成,耗时:" + m + "分" + s + "秒,正在切片。" + }) resolve(res.data); return; @@ -921,37 +961,42 @@ } //视频切片 - let videoCutPacket = (array) => { + let videoCutPacket = (data) => { return new Promise((resolve, reject) => { try { - let imgSize = 25600; - let packetSize = 3200; - let tdSize = 500; + const imgSize = 25600; + const packetSize = 3200; + const chunkSize = 500; + const maxPacketCount = 30; + let source = Array.isArray(data) ? data.slice() : []; let results = []; - for (let i = 0; i < 30; i++) { //先切出30张,每张25600字节 - let packet = array.slice(0, imgSize); - array.splice(0, imgSize) + for (let i = 0; i < maxPacketCount && source.length >= imgSize; i++) { + let frameBytes = source.splice(0, imgSize); + let framePackets = []; - let secondLevel = []; - for (let j = 0; j < 8; j++) { //每张切8大包,每包3200字节 - let childPacket = packet.slice(0, packetSize); + for (let j = 0; j < 8 && frameBytes.length > 0; j++) { + let majorPacket = frameBytes.splice(0, packetSize); + let childPackets = []; - packet.splice(0, packetSize); - - let thirdLevel = []; - for (let k = 0; k < 7; k++) { //每1个大包切出7个小包,前6包500字节,第7包200字节,共计56小包 - - let arr = childPacket.slice(0, tdSize); - - childPacket.splice(0, tdSize) - thirdLevel.push(arr); + while (majorPacket.length > 0) { + let chunk = majorPacket.splice(0, chunkSize); + if (chunk.length) { + childPackets.push(chunk); + } + } + if (childPackets.length) { + framePackets.push(childPackets); } - secondLevel.push(thirdLevel); } - results.push(secondLevel); + + if (framePackets.length) { + results.push(framePackets); + } } - updateLoading(these,{text:'切片完成,正在发送'}); + updateLoading(these, { + text: '切片完成,正在发送' + }); resolve(results); } catch (error) { updateLoading(these, { @@ -960,31 +1005,25 @@ reject(error); } }); - - - - } - + //发送视频到设备 let shotVideoClick = (array, type, ReSendNo) => { var sendImagePackets = () => { return new Promise((resolve, reject) => { - - - this.currentPacket = 0; - - // 总数据包数 - var totalPackets = 1680; + let totalPackets = these.calcTotalPackets(array); this.totalPackets = totalPackets; + if (totalPackets === 0) { + reject('没有可发送的数据'); + return; + } let currentPacket = 1; let imgIndex = 0; let imgPackIndex = 0; let childPacketIndex = 0; if (ReSendNo) { - this.currentPacket = ReSendNo - 1; currentPacket = ReSendNo; totalPackets = ReSendNo; @@ -992,96 +1031,91 @@ } // 发送单个数据包 const sendNextPacket = () => { - // console.log("111111") - if (currentPacket > totalPackets) { + if (imgIndex >= array.length) { resolve(); - return; } - // console.log("111111") - // 计算当前包的数据 - let packetSize = 500; - - if ((currentPacket - 1) % 56 === 0) { - - packetSize = 508; + if (!array[imgIndex]) { + console.error("没有找到对应的帧数据", imgIndex); + reject(`帧数据缺失,索引 ${imgIndex}`); + return; } - if (childPacketIndex === 6) { - packetSize = 200; + let childPacketsGroup = array[imgIndex][imgPackIndex]; + if (!childPacketsGroup || !childPacketsGroup.length) { + console.error("帧数据结构异常", imgIndex, imgPackIndex); + reject(`帧数据结构异常,帧 ${imgIndex}`); + return; } - if ((currentPacket - 1) % 56 === 55) { - packetSize = 201; + let packetData = childPacketsGroup[childPacketIndex]; + let packetSize = packetData.length; + + const isFirstChild = childPacketIndex === 0; + const isLastChild = childPacketIndex === (childPacketsGroup + .length - 1); + + if (isFirstChild) { + packetSize = packetData.length + 8; } - console.log("imgIndex=" + imgIndex + ",imgPackIndex=" + - imgPackIndex + - ",childPacketIndex=" + childPacketIndex) + if (isLastChild) { + packetSize = packetData.length + (isFirstChild ? 9 : 1); + } - let packetData = array[imgIndex][imgPackIndex][childPacketIndex]; + const buffer = new ArrayBuffer(packetSize); + const dataView = new DataView(buffer); - let buffer = new ArrayBuffer(packetSize); - let dataView = new DataView(buffer); - - let sortNo = currentPacket.toString(16).padStart(4, '0'); - // console.log("11111"); let start = 0; - if ((currentPacket - 1) % 56 === 0) { + if (isFirstChild) { // 填充头部 dataView.setUint8(0, 0xFA); // 帧头 dataView.setUint8(1, 0x09); // 帧类型:开机画面 dataView.setUint8(2, 0x0C); dataView.setUint8(3, 0x84); - - dataView.setUint8(4, 0xFD); dataView.setUint8(5, 0x09); dataView.setUint8(6, imgIndex); dataView.setUint8(7, imgPackIndex + 1); start = 8; } - console.log("222222"); + for (let i = 0; i < packetData.length; i++) { - dataView.setUint8(start + i, '0x' + packetData[i]); + dataView.setUint8(start + i, these.toByteValue(packetData[i])); } - // console.log("333333333"); - if ((currentPacket - 1) % 56 === 55) { - dataView.setUint8(200, 0xFF); + + if (isLastChild) { + dataView.setUint8(packetSize - 1, 0xFF); } - // console.log("444444"); let inteval = parseInt(this.inteval ? this.inteval : 80); ble.sendData(f.deviceId, buffer, f.writeServiceId, f - .wirteCharactId, ).then(() => { + .wirteCharactId).then(() => { if (ReSendNo) { - resolve(); return; } // 更新进度 this.currentPacket = currentPacket; - updateLoading(these,{ - text:'正在发送:'+currentPacket+"/"+totalPackets + updateLoading(these, { + text: '正在发送:' + currentPacket + "/" + + totalPackets }); - childPacketIndex++; - if (childPacketIndex == 7) { - imgPackIndex++; - if (imgPackIndex == 8) { - imgIndex++; - imgPackIndex = 0; - } + if (childPacketIndex >= childPacketsGroup.length) { childPacketIndex = 0; + imgPackIndex++; + if (imgPackIndex >= array[imgIndex].length) { + imgPackIndex = 0; + imgIndex++; + } } // 发送下一个包(添加延迟避免蓝牙缓冲区溢出) currentPacket++; - - setTimeout(sendNextPacket, inteval); }).catch(err => { if (err.code == 10007) { @@ -1092,40 +1126,36 @@ } console.error(err.errMsg + ",发送失败了" + currentPacket); - updateLoading(these,{text:"发送失败,"+err.errMsg}); + updateLoading(these, { + text: "发送失败," + err.errMsg + }); reject(err); }); }; - - - // console.log("111111") - sendNextPacket(); - }); } - return sendImagePackets(); - - - } uni.chooseVideo({ sourceType: ['album'], success: function(res) { - console.log("res=",res); + console.log("res=", res); let path = res.tempFilePath; - let width = res.width; - let height = res.height; + // iOS可能返回浮点数,需要转换为整数进行比较 + let width = Math.round(res.width); + let height = Math.round(res.height); let duration = res.duration; + console.log("视频信息 - 宽度:", width, "高度:", height, "时长:", duration); let err = []; if (duration < 2) { err.push("视频时长至少2秒"); } - if (width != 160 || height != 80) { - err.push("视频宽高必须是160*80"); + // 使用容差比较,允许1像素的误差(iOS可能有精度问题) + if (Math.abs(width - 160) > 1 || Math.abs(height - 80) > 1) { + err.push("视频宽高必须是160*80,当前分辨率:" + width + "*" + height); } if (err.length > 0) { err = err.join(";"); @@ -1143,30 +1173,51 @@ setTimeout(() => { uplploadVideo(path).then(result => { - videoCutPacket(result.data).then(array => { - - let start = new Date(); - console.log("开始发送"); - shotVideoClick(array).then(() => { - console.log("发送完成"); - let end = new Date(); - var diff = (end.getTime() - start.getTime()) / 1000; - let s =parseInt(diff % 60); - let m =parseInt((diff - s) / 60); - console.log("发送完成,耗时:" + m + "分" + s + "秒"); - updateLoading(these,{ - text: "发送完成,耗时:" + m + "分" + s + "秒", - }); - - }).catch((ex1) => { - console.log("出现了异常", ex1) - }).finally(() => { - timeDelayCloseLoading(); - }); - - - - + let data = result.data; + let convertedData = []; + for (let i = 0; i < data.length; i += 2) { + if (i + 1 < data.length) { + const byte1 = these.toByteValue(data[i]); + const byte2 = these.toByteValue(data[i + 1]); + const rgb565 = (byte1 << 8) | byte2; + const red = (rgb565 & 0xF800) >> 11; + const green = (rgb565 & 0x07E0) >> 5; + const blue = (rgb565 & 0x001F); + const bgr565 = (blue << 11) | (green << 5) | red; + convertedData.push((bgr565 >> 8) & 0xFF); + convertedData.push(bgr565 & 0xFF); + } else { + convertedData.push(these.toByteValue(data[i])); + } + } + + videoCutPacket(convertedData).then(array => { + + let start = new Date(); + console.log("开始发送"); + shotVideoClick(array).then(() => { + console.log("发送完成"); + let end = new Date(); + var diff = (end.getTime() - start + .getTime()) / 1000; + let s = parseInt(diff % 60); + let m = parseInt((diff - s) / 60); + console.log("发送完成,耗时:" + m + "分" + + s + "秒"); + updateLoading(these, { + text: "发送完成,耗时:" + m + + "分" + s + "秒", + }); + + }).catch((ex1) => { + console.log("出现了异常", ex1) + }).finally(() => { + timeDelayCloseLoading(); + }); + + + + }).catch(err => { timeDelayCloseLoading(); }); @@ -1429,6 +1480,24 @@ these.showBleUnConnect() return; } + let err = false; + this.formData.textLines.find((txt) => { + if (txt.length === 0 || txt.length > 7) { + console.log("txt=", txt); + err = true; + return true; + } + return false; + }) + if (err) { + this.showPop({ + message: "单位、部门、姓名必须填写且最多7字", + iconUrl: "/static/images/6155/DeviceDetail/uploadErr.png", + borderColor: "#e034344d", + buttonBgColor: "#E03434", + }); + return; + } showLoading(these, { text: "请稍候..." }); @@ -1535,8 +1604,8 @@ }); console.log("result=", result); - // var str1="FA 06 01 00 FF FF F7 9F EF 6F EC F7 EA 09 CF FF AF FB EF EB EF EB EC 6B EF EB EC 6B EF EB EF FB EE 63 FF FF FF FF F7 9F EF 6F EC F7 EA 09 CF FF AF FB EF EB EF EB EC 6B EF EB EC 6B EF EB EF FB EE 63 FF FF FF FF F7 FF 81 03 ED BB DD B7 CB CF F3 C7 CD 39 BE FF FE FF C0 03 FE FB FD FB F3 F7 8F 87 FF FF FF FF FE FF FE FF FE FF C0 03 FF FB FD FB FD FB FD FB FD FB FB FB FB FF F7 F7 EF F7 9F 8F FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF" - // var str2="FA 07 01 00 FF FF EE DD EE DF EF 5B AB DF AA 03 AE FF AE FF EE 03 EE FF EE FF EE 03 EE FF EE FF EE E3 FF FF FF FF EE DD EE DF EF 5B AB DF AA 03 AE FF AE FF EE 03 EE FF EE FF EE 03 EE FF EE FF EE E3 FF FF FF FF EF 77 EF 73 EF 7F 80 01 EF 7F EF 7F EF 03 E7 3B 8E BB EE D7 EE EF ED E7 ED 9B 8B 7D FF FF FF FF FF FF F7 EF F7 F7 EF F7 DF FB FF FF FF FF FE FF 80 01 FE 7F FD BF FB DF F7 E7 9F F9 FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF" + // var str1="FA 06 01 00 FF FF F7 9F EF 6F EC F7 EA 09 CF FF AF FB EF EB EF EB EC 6B EF EB EC 6B EF EB EF FB EE 63 FF FF FF FF F7 9F EF 6F EC F7 EA 09 CF FF AF FB EF EB EF EB EC 6B EF EB EC 6B EF EB EF FB EE 63 FF FF FF FF F7 FF 81 03 ED BB DD B7 CB CF F3 C7 CD 39 BE FF FE FF C0 03 FE FB FD FB F3 F7 8F 87 FF FF FF FF FE FF FE FF FE FF C0 03 FF FB FD FB FD FB FD FB FD FB FB FB FB FF F7 F7 EF F7 9F 8F FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF" + // var str2="FA 07 01 00 FF FF EE DD EE DF EF 5B AB DF AA 03 AE FF AE FF EE 03 EE FF EE FF EE 03 EE FF EE FF EE E3 FF FF FF FF EE DD EE DF EF 5B AB DF AA 03 AE FF AE FF EE 03 EE FF EE FF EE 03 EE FF EE FF EE E3 FF FF FF FF EF 77 EF 73 EF 7F 80 01 EF 7F EF 7F EF 03 E7 3B 8E BB EE D7 EE EF ED E7 ED 9B 8B 7D FF FF FF FF FF FF F7 EF F7 F7 EF F7 DF FB FF FF FF FF FE FF 80 01 FE 7F FD BF FB DF F7 E7 9F F9 FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF" // var str3="FA 08 01 00 FF FF EF DF EC 01 EF FF AB FF AA 03 AA FB AE FB EE 03 EF DF EF DF EE DB ED DF ED DD EF 1F FF FF FF FF EF BF EF 87 81 77 EE F7 EC 03 81 7F EF 7F EF 7F EF 03 81 7F EF 7F EF 7D EF 7D EF 03 FF FF FF FF F9 F1 CF BF DF FF DF FF C1 FF DD 81 DD F7 DD F7 C1 F7 DF 77 FF 77 BF 77 BF 77 FF F7 FF FF FF FF FD FF FD FF FB FF FB FF F0 07 E7 F7 EF F7 D8 07 BF F7 FF F7 F8 07 FF F7 FF F7 FF C7 FF FF FF FF FF FF FF FF FF FF FE FF FE 7F FE 7F FE FF FD BF FD FF FB DF F7 EF EF F7 DF FB BF FD FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF" // let arr1=('0x'+(str1.split(' ').join(",0x"))).split(','); diff --git a/utils/BleReceive.js b/utils/BleReceive.js index b5f85e7..36aaea6 100644 --- a/utils/BleReceive.js +++ b/utils/BleReceive.js @@ -476,19 +476,18 @@ class BleReceive { let recCnt = recArr.find(v => { - return v.key.replace(/\//g, "").toLowerCase() === f.device.detailPageUrl.replaceAll( - '/', '').toLowerCase(); + return v.key.replace(/\//g, "").toLowerCase() === f.device.detailPageUrl.replace(/\//g, '').toLowerCase(); }); if (!recCnt) { if (batteryLevel <= 20) { - - uni.showModal({ - content: "设备电量低", - title: "提示" - }); + // 会弹出两个框,暂且注释掉这段代码 + // uni.showModal({ + // content: "设备电量低", + // title: "提示" + // }); } }