From bbf55c58f0b1c9535ee95c5dfc5dff3067439f84 Mon Sep 17 00:00:00 2001 From: liub Date: Mon, 25 Aug 2025 17:13:13 +0800 Subject: [PATCH] =?UTF-8?q?650=E5=AE=8C=E6=88=90=EF=BC=8C670=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E9=83=A8=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App.vue | 9 +- components/TextToHex/TextToHexV1.vue | 194 ++ pages.json | 88 +- pages/6155/ImgCrop.vue | 16 +- pages/650/HBY650.vue | 446 +-- pages/670/HBY670.vue | 1841 +++++++++++ pages/BlueTooth/ModeSetting/HBY6155.vue | 1947 +++++++++++ pages/BlueTooth/ModeSetting/HBY6155V1.vue | 1925 +++++++++++ pages/BlueTooth/ModeSetting/HBY650.vue | 1892 +++++++++++ pages/BlueTooth/ModeSetting/HBY650_1.vue | 1899 +++++++++++ pages/BlueTooth/ModeSetting/HBY670.vue | 2837 +++++++++++++++++ pages/BlueTooth/ModeSetting/ModeSetting.vue | 1499 +++++++++ pages/BlueTooth/ModeSetting/VideoSend.vue | 472 +++ pages/BlueTooth/ModeSetting/VideoSend_1.vue | 517 +++ pages/BlueTooth/ModeSetting/VideoSend_670.vue | 537 ++++ pages/BlueTooth/ModeSetting/index.vue | 115 + pages/BlueTooth/ModeSetting/update.vue | 273 ++ pages/common/login/index.vue | 36 +- utils/BleHelper.js | 9 +- utils/BleReceive.js | 188 +- utils/Common.js | 218 ++ utils/mqtt.js | 7 +- utils/update.js | 153 + 23 files changed, 16897 insertions(+), 221 deletions(-) create mode 100644 components/TextToHex/TextToHexV1.vue create mode 100644 pages/670/HBY670.vue create mode 100644 pages/BlueTooth/ModeSetting/HBY6155.vue create mode 100644 pages/BlueTooth/ModeSetting/HBY6155V1.vue create mode 100644 pages/BlueTooth/ModeSetting/HBY650.vue create mode 100644 pages/BlueTooth/ModeSetting/HBY650_1.vue create mode 100644 pages/BlueTooth/ModeSetting/HBY670.vue create mode 100644 pages/BlueTooth/ModeSetting/ModeSetting.vue create mode 100644 pages/BlueTooth/ModeSetting/VideoSend.vue create mode 100644 pages/BlueTooth/ModeSetting/VideoSend_1.vue create mode 100644 pages/BlueTooth/ModeSetting/VideoSend_670.vue create mode 100644 pages/BlueTooth/ModeSetting/index.vue create mode 100644 pages/BlueTooth/ModeSetting/update.vue create mode 100644 utils/Common.js create mode 100644 utils/update.js diff --git a/App.vue b/App.vue index 3a29b8e..bb9d0c3 100644 --- a/App.vue +++ b/App.vue @@ -1,15 +1,16 @@ + + \ No newline at end of file diff --git a/pages.json b/pages.json index 0f32fea..1267e35 100644 --- a/pages.json +++ b/pages.json @@ -1,11 +1,19 @@ { "pages": [ + { "path": "pages/common/login/index", "style": { "navigationStyle": "custom" } }, + { + "path" : "pages/BlueTooth/ModeSetting/index", + "style" : + { + "navigationBarTitleText" : "设备类型" + } + }, { "path": "pages/common/index/index", "style": { @@ -191,7 +199,85 @@ "style": { "navigationBarTitleText": "呼叫" } - } + }, + { + "path" : "pages/670/HBY670", + "style" : + { + "navigationBarTitleText" : "HBY670" + } + }, + + + + { + "path": "pages/BlueTooth/ModeSetting/VideoSend", + "style": { + "navigationBarTitleText": "发送视频" + + + } + }, + { + "path": "pages/BlueTooth/ModeSetting/VideoSend_1", + "style": { + "navigationBarTitleText": "发送视频" + + + } + }, + { + "path": "pages/BlueTooth/ModeSetting/VideoSend_670", + "style": { + "navigationBarTitleText": "发送视频" + + + } + }, + { + "path": "pages/BlueTooth/ModeSetting/HBY650", + "style": { + "navigationBarTitleText": "HBY650" + } + }, + { + "path": "pages/BlueTooth/ModeSetting/HBY650_1", + "style": { + "navigationBarTitleText": "HBY650" + } + }, + { + "path": "pages/BlueTooth/ModeSetting/ModeSetting", + "style": { + "navigationBarTitleText": "7307-0.96TFT" + } + }, + { + "path": "pages/BlueTooth/ModeSetting/update", + "style": { + "navigationBarTitleText": "版本更新" + } + }, + { + "path": "pages/BlueTooth/ModeSetting/HBY6155", + "style": { + "navigationBarTitleText": "HBY6155" + } + }, + { + "path": "pages/BlueTooth/ModeSetting/HBY6155V1", + "style": { + "navigationBarTitleText": "HBY6155_V1" + } + }, + { + "path": "pages/BlueTooth/ModeSetting/HBY670", + "style": { + "navigationBarTitleText": "HBY670" + } + } + + ], "tabBar": { "color": "#fff", diff --git a/pages/6155/ImgCrop.vue b/pages/6155/ImgCrop.vue index cf66c28..6c2fafe 100644 --- a/pages/6155/ImgCrop.vue +++ b/pages/6155/ImgCrop.vue @@ -25,18 +25,21 @@ onLoad: function(option) { const eventChannel = this.getOpenerEventChannel(); var these = this; - eventChannel.on('checkImg', function(data) { + eventChannel.on('checkImg', (data)=> { console.log("我收到你的消息了,消息内容是:" + JSON.stringify(data)); - these.src = data.data; + this.src = data.data; + console.log("我收到你的消息了,消息内容是:",data); }) }, methods: { handleCrop(e) { + var these = this; + this.Statu = true; console.log("裁剪完成"); console.log(e.tempFilePath); - + // const ctx = uni.createCanvasContext('splashCanvas', this); ctx.drawImage( e.tempFilePath, @@ -53,11 +56,12 @@ height: 80, success: (res) => { // 处理像素数据并发送 + const eventChannel = these.getOpenerEventChannel(); console.log("res.data.length="+res.data.length); - // this.processAndSendImageData(res.data).then( - // resolve).catch(reject); - const eventChannel = these.getOpenerEventChannel(); + + eventChannel.emit('ImgCutOver',res.data); + eventChannel.emit('ImgCutOver_Path',e.tempFilePath); uni.navigateBack(); }, fail: (err) => { diff --git a/pages/650/HBY650.vue b/pages/650/HBY650.vue index 00ac682..12222c2 100644 --- a/pages/650/HBY650.vue +++ b/pages/650/HBY650.vue @@ -77,7 +77,7 @@ + v-on:click.stop="ShowUpload()"> @@ -89,19 +89,19 @@ - + 人员信息登记 - + - + - 发送 + 发送 @@ -235,7 +235,7 @@ maskBgColor: '#00000066', showClose: false }, - + usrToggle: true, }, formData: { img: '/static/images/6155/DeviceDetail/equip.png', @@ -251,17 +251,14 @@ macAddress: '', cMode: false, modeCurr: 'low', - usrToggle: true, + company: '黄石消防支队', name: '菜英俊', job: '小队长', id: 'HSXF01061', iswarn: false - }, - - - + rgb565Data: [], videoHexArray: [] } }, @@ -377,19 +374,41 @@ return className; }, bleValueNotify: function(receive, device, path) { //订阅消息 - + let data = recei.ReceiveData(receive, device, pagePath); - +console.log("收到设备的数据",data) if (data) { - console.log("收到订阅消息", receive); + if ("staBlue_picture" in data) { + //重发图片 + console.log("收到重新发送图片的命令"); + this.checkImgUpload('img', data.staBlue_picture); + return; + } else if ("staBlue_text" in data) { + //重发文本 + console.log("收到重新发送文本的命令"); + this.sendUsr(data.staBlue_text); + return; + } else if ("staBlue_vidio" in data) { + //重发视频 + console.log("收到重新发送视频的命令"); + this.checkImgUpload('video', data.staBlue_vidio); + return; + } else if ("staBlue" in data) { + if (data.staBlue == "finish") { + console.log("收到设备回复,全部传输完成"); + } + return; + } + let keys = Object.keys(data); for (var i = 0; i < keys.length; i++) { let key = keys[i]; - these.formData[key] = data[key]; + if(key in these.formData){ + these.formData[key] = data[key]; + } + } - - - + if (these.formData.iswarn) { these.showPop({ message: "环境存在漏电电源", @@ -398,7 +417,7 @@ buttonBgColor: "#E03434", }); } - + these.setBleFormData(); } @@ -412,8 +431,8 @@ }, getDevice: function() { - console.log("LinkedList=", ble.data.LinkedList); - console.log("formData=", these.formData); + // console.log("LinkedList=", ble.data.LinkedList); + // console.log("formData=", these.formData); let f = ble.data.LinkedList.find((v) => { return v.deviceId == these.formData.deviceId; }); @@ -558,33 +577,22 @@ } }); }, - checkImgUpload: function() { + checkImgUpload: function(type, index) { console.log("123213213213"); - - - // 处理像素数据并发送 - var processAndSendImageData = function(pixels) { - return new Promise((resolve, reject) => { - // 创建RGB565格式的像素数据 - const rgb565Data = ble.convertToRGB565(pixels); - - // 分包发送 - sendImagePackets(rgb565Data).then(resolve).catch(reject); - }); - } - - - + let f = these.getDevice(); // 分包发送图片数据 - var sendImagePackets = function(imageData) { + var sendImagePackets = function(ReSendNo) { return new Promise((resolve, reject) => { // 总数据包数 - const totalPackets = 52; + let totalPackets = 52; let currentPacket = 1; - let f = these.getDevice(); + if (ReSendNo) { + totalPackets = ReSendNo; + currentPacket = ReSendNo; + } if (f) { // 发送单个数据包 @@ -597,6 +605,13 @@ message: "上传成功", iconUrl: "/static/images/6155/DeviceDetail/uploadSuccess.png", }); + if (!ReSendNo) { + setTimeout(()=>{ + these.HoldYouHand("transmit complete", 0, f.deviceId, f + .writeServiceId, f.wirteCharactId); + },500); + + } resolve(); return; @@ -604,23 +619,23 @@ // 计算当前包的数据 let packetSize = 250; - if (currentPacket <= 51) { - packetSize = 250; // 前51个包每个500字节 - } else { - packetSize = 50; // 最后一个包100字节 - } + // if (currentPacket <= 51) { + // packetSize = 250; // 前51个包每个500字节 + // } else { + // packetSize = 50; // 最后一个包100字节 + // } // 创建数据包 const startIndex = (currentPacket - 1) * packetSize; - const endIndex = Math.min(startIndex + packetSize, imageData + const endIndex = Math.min(startIndex + packetSize, these.rgb565Data .length); if (startIndex > endIndex) { return; } - const packetData = imageData.slice(startIndex, + const packetData = these.rgb565Data.slice(startIndex, endIndex); // 构建数据包 - const bufferSize = 5 + packetData.length * 2; // 头部5字节 + 数据部分 + const bufferSize =505;// 5 + packetData.length * 2; // 头部5字节 + 数据部分 const buffer = new ArrayBuffer(bufferSize); const dataView = new DataView(buffer); @@ -644,6 +659,11 @@ dataView.setUint16(5 + i * 2, packetData[i], false); // 大端字节序 } + if (currentPacket > 51) { //第52包补FF + for (var i = 105; i < bufferSize; i++) { + dataView.setUint8(i, 0xFF); + } + } @@ -681,7 +701,10 @@ }); } - + if (ReSendNo) { + sendNextPacket(ReSendNo); + return; + } // 开始牵手 these.HoldYouHand("picture transmit start", 120, f.deviceId, f.writeServiceId, f.wirteCharactId).then(() => { @@ -713,8 +736,9 @@ }); these.Status.BottomMenu.show = false; + these.rgb565Data = ble.convertToRGB565(data); setTimeout(function() { - processAndSendImageData(data).catch(() => { + sendImagePackets().catch(() => { }); }, 0) @@ -730,6 +754,137 @@ }); } + + let sendVideoPackets = (ReSendNo) => { + console.log("开始发送分片数据"); + return new Promise((resolve, reject) => { + if (f) { + // 总数据包数 + var totalPackets = 1536; + + let currentPacket = 1; + console.log("发送数据准备中,总共" + totalPackets); + if (ReSendNo) { + totalPackets = ReSendNo; + currentPacket = ReSendNo; + } + this.totalPackets = totalPackets; + // 发送单个数据包 + const sendNextVideoPacket = () => { + console.log("准备发送一段数据"); + if (currentPacket > totalPackets) { + if (!ReSendNo) { + setTimeout(()=>{ + these.HoldYouHand("transmit complete", 0, f.deviceId, f + .writeServiceId, f.wirteCharactId).then(()=>{ + console.log("全部发送完毕") + }).catch((ex)=>{ + console.log("出现异常",ex); + }); + },500); + + } + these.Status.BottomMenu.show = false; + hideLoading(these); + these.showPop({ + showPop: true, + message: "上传成功", + iconUrl: "/static/images/6155/DeviceDetail/uploadSuccess.png" + }); + + + + + resolve(); + + return; + } + + // 计算当前包的数据 + let packetSize = 500; + + + // 创建数据包 + const startIndex = (currentPacket - 1) * packetSize; + const endIndex = Math.min(startIndex + packetSize, these.videoHexArray + .length); + if (startIndex > endIndex) { + resolve(); + return; + } + ////console.log("111111"); + const packetData = these.videoHexArray.slice(startIndex, endIndex); + + // 构建数据包 + ////console.log("packetData.length"+packetData.length); + const bufferSize = 506; // 头部5字节 + 数据部分 + const buffer = new ArrayBuffer(bufferSize); + const dataView = new DataView(buffer); + + let sortNo = currentPacket.toString(16).padStart(4, '0'); + + // 填充头部 + dataView.setUint8(0, 0x55); // 帧头 + dataView.setUint8(1, 0x04); // 帧类型:开机画面 + dataView.setUint8(2, '0x' + sortNo.substring(0, 2)); // 包序号 + dataView.setUint8(3, '0x' + sortNo.substring(2, 4)); // 包序号 + + dataView.setUint8(4, 0x01); + dataView.setUint8(5, 0xF4); + + for (let i = 0; i < packetData.length; i++) { + dataView.setUint8(6 + i, '0x' + packetData[i]); + } + + let inteval = 50; + console.log("开始发送一段视频"); // + ble.sendData(f.deviceId, buffer, f.writeServiceId, f + .wirteCharactId, 10).then(() => { + + updateLoading(these, { + text: "正在发送:" + currentPacket + "/" + + totalPackets + }) + + currentPacket++; + + console.log("发送一段成功,发送下一段"); + setTimeout(sendNextVideoPacket, inteval); + }).catch(err => { + console.log("发送失败了"); + if (err.code == '10007') { //遇到这个错误自动重新发送 + console.log(err.errMsg + ",发送失败了,正在补偿:" + + currentPacket); + setTimeout(sendNextVideoPacket, inteval); + } else { + these.Status.BottomMenu.show = false; + hideLoading(these); + + these.showPop({ + showPop: true, + message: err.msg + ",发送失败了", + borderColor: "#e034344d", + buttonBgColor: "#E03434", + buttonText: "确定", + iconUrl: "/static/images/6155/DeviceDetail/uploadErr.png" + }); + reject(err); + return; + } + + }); + }; + + + sendNextVideoPacket(); + + + } else { + console.log("Fail.......") + } + }); + } + var sendVideo = (videoPath) => { let uploadVideo = () => { @@ -740,7 +895,7 @@ } console.log("开始处理,正在上传"); - let f = this.getDevice(); + showLoading(these, { text: "上传中" }); @@ -809,123 +964,13 @@ }) } let f = these.getDevice(); - console.log("f=", f); - - let sendVideoPackets = (imageData) => { - console.log("开始发送分片数据"); - return new Promise((resolve, reject) => { - if (f) { - // 总数据包数 - const totalPackets = 1536; - this.totalPackets = totalPackets; - let currentPacket = 1; - console.log("发送数据准备中,总共" + totalPackets); - // 发送单个数据包 - const sendNextVideoPacket = () => { - console.log("准备发送一段数据"); - if (currentPacket > totalPackets) { - these.Status.BottomMenu.show = false; - hideLoading(these); - these.showPop({ - showPop: true, - message: "上传成功", - iconUrl: "/static/images/6155/DeviceDetail/uploadSuccess.png" - }); - these.videoHexArray = []; - - resolve(); - - return; - } - - // 计算当前包的数据 - let packetSize = 500; - // 创建数据包 - const startIndex = (currentPacket - 1) * packetSize; - const endIndex = Math.min(startIndex + packetSize, imageData - .length); - if (startIndex > endIndex) { - resolve(); - return; - } - ////console.log("111111"); - const packetData = imageData.slice(startIndex, endIndex); - - // 构建数据包 - ////console.log("packetData.length"+packetData.length); - const bufferSize = 506; // 头部5字节 + 数据部分 - const buffer = new ArrayBuffer(bufferSize); - const dataView = new DataView(buffer); - - let sortNo = currentPacket.toString(16).padStart(4, '0'); - - // 填充头部 - dataView.setUint8(0, 0x55); // 帧头 - dataView.setUint8(1, 0x04); // 帧类型:开机画面 - dataView.setUint8(2, '0x' + sortNo.substring(0, 2)); // 包序号 - dataView.setUint8(3, '0x' + sortNo.substring(2, 4)); // 包序号 - - dataView.setUint8(4, 0x01); - dataView.setUint8(5, 0xF4); - - for (let i = 0; i < packetData.length; i++) { - dataView.setUint8(6 + i, '0x' + packetData[i]); - } - - let inteval = 50; - console.log("开始发送一段视频"); // - ble.sendData(f.deviceId, buffer, f.writeServiceId, f - .wirteCharactId, 10).then(() => { - updateLoading(these, { - text: "正在发送:" + currentPacket + "/" + - totalPackets - }) - - currentPacket++; - - console.log("发送一段成功,发送下一段"); - setTimeout(sendNextVideoPacket, inteval); - }).catch(err => { - if (err.code == '10007') { //遇到这个错误自动重新发送 - console.log(err.errMsg + ",发送失败了,正在补偿:" + - currentPacket); - setTimeout(sendNextVideoPacket, inteval); - } else { - these.Status.BottomMenu.show = false; - hideLoading(these); - - these.showPop({ - showPop: true, - message: err.msg + ",发送失败了", - borderColor: "#e034344d", - buttonBgColor: "#E03434", - buttonText: "确定", - iconUrl: "/static/images/6155/DeviceDetail/uploadErr.png" - }); - reject(err); - return; - } - - }); - }; - - - sendNextVideoPacket(); - - - } else { - console.log("Fail.......") - } - }); - } - - let shotVideoClick = (array) => { + let shotVideoClick = () => { console.log("正在开始发送"); - sendVideoPackets(array).then(() => { + sendVideoPackets().then(() => { console.log("发送完成"); }).catch((ex1) => { @@ -940,6 +985,14 @@ } + if (type) { + if (type == 'img') { + sendImagePackets(index); + } else if (type == 'video') { + sendVideoPackets(index); + } + return; + } uni.chooseMedia({ count: 1, mediaType: ['image', 'video'], @@ -968,16 +1021,9 @@ } }); - // uni.chooseImage({ - // count: 1, - // sizeType: ['original', 'compressed'], - // sourceType: ['album'], - // success: function(res) { - // gotoCutImg(res.tempFiles[0].path); - // } - // }); + }, - UploadOpenImg: function() { + ShowUpload: function() { //上传开机画面 this.Status.BottomMenu.menuItems = []; this.Status.BottomMenu.title = "上传开机画面"; @@ -1043,7 +1089,7 @@ } these.Status.Pop.showPop = true; }, - sendUsr: function() { + sendUsr: function(ReSendNo) { @@ -1052,7 +1098,6 @@ this.formData.name, this.formData.job, this.formData.id - ]; @@ -1070,17 +1115,28 @@ text: "请稍候..." }); var sendText = function() { - - - - // 总数据包数 - const totalPackets = textLines.length; + let totalPackets = textLines.length; let currentPacket = 1; - + // console.log("currentPacket=",currentPacket); + // console.log("ReSendNo=",ReSendNo); + if (ReSendNo) { + totalPackets = ReSendNo; + currentPacket = ReSendNo; + } + // console.log("currentPacket=",currentPacket); // 发送单个数据包 const sendNextPacket = () => { + if (currentPacket > totalPackets) { + if (!ReSendNo) { + setTimeout(()=>{ + these.HoldYouHand("transmit complete", 0, f.deviceId, f.writeServiceId, f + .wirteCharactId); + },500); + + } + these.showPop({ showPop: true, //是否显示弹窗 popType: 'custom', @@ -1107,9 +1163,9 @@ let arr = gbk.encode(text) let gbkData = gbk.arr2hex(arr); - console.log(JSON.stringify(gbkData)); + // 构建数据包 - const bufferSize = 5 + text.length * 2; // 头部4字节 + 数据部分 + const bufferSize = 5 + gbkData.length / 2; // 头部4字节 + 数据部分 const buffer = new ArrayBuffer(bufferSize); const dataView = new DataView(buffer); @@ -1118,19 +1174,16 @@ dataView.setUint8(1, 0x03); // 帧类型:文字 dataView.setUint8(2, currentPacket.toString(16)); // 包序号 dataView.setUint16(3, (text.length * 2).toString(16)); // 数据长度 - console.log("gbkData.length=" + gbkData.length) - // 填充数据 - for (let i = 1; i <= text.length * 2; i++) { - const highNibble = gbkData[i * 2 - 2]; // 高4位 - const lowNibble = gbkData[i * 2 - 1]; // 低4位(如果是奇数长度,补0) - //console.log("i=" + i + "," + highNibble + lowNibble) - // 组合高低位并转换为字节值 - const byteValue = parseInt(highNibble + lowNibble, 16); - dataView.setUint8(5 + i - 1, byteValue); + + // 填充数据 + let index = 0; + for (var i = 0; i < gbkData.length; i += 2) { + let value = parseInt(gbkData[i] + "" + gbkData[i + 1], 16); + dataView.setUint8(5 + index, value); + index++; } - - - console.log("dataView.length=" + dataView.byteLength) + + // 发送数据包 @@ -1166,7 +1219,10 @@ } - + if(ReSendNo){ + sendText(ReSendNo); + return; + } setTimeout(() => { these.HoldYouHand("word transmit start", 120, f.deviceId, f.writeServiceId, f .wirteCharactId).then( diff --git a/pages/670/HBY670.vue b/pages/670/HBY670.vue new file mode 100644 index 0000000..df45013 --- /dev/null +++ b/pages/670/HBY670.vue @@ -0,0 +1,1841 @@ + + + + + \ No newline at end of file diff --git a/pages/BlueTooth/ModeSetting/HBY6155.vue b/pages/BlueTooth/ModeSetting/HBY6155.vue new file mode 100644 index 0000000..3ff9f9a --- /dev/null +++ b/pages/BlueTooth/ModeSetting/HBY6155.vue @@ -0,0 +1,1947 @@ + + + + + \ No newline at end of file diff --git a/pages/BlueTooth/ModeSetting/HBY6155V1.vue b/pages/BlueTooth/ModeSetting/HBY6155V1.vue new file mode 100644 index 0000000..06aa86a --- /dev/null +++ b/pages/BlueTooth/ModeSetting/HBY6155V1.vue @@ -0,0 +1,1925 @@ + + + + + \ No newline at end of file diff --git a/pages/BlueTooth/ModeSetting/HBY650.vue b/pages/BlueTooth/ModeSetting/HBY650.vue new file mode 100644 index 0000000..07ebe45 --- /dev/null +++ b/pages/BlueTooth/ModeSetting/HBY650.vue @@ -0,0 +1,1892 @@ + + + + + \ No newline at end of file diff --git a/pages/BlueTooth/ModeSetting/HBY650_1.vue b/pages/BlueTooth/ModeSetting/HBY650_1.vue new file mode 100644 index 0000000..8338463 --- /dev/null +++ b/pages/BlueTooth/ModeSetting/HBY650_1.vue @@ -0,0 +1,1899 @@ + + + + + \ No newline at end of file diff --git a/pages/BlueTooth/ModeSetting/HBY670.vue b/pages/BlueTooth/ModeSetting/HBY670.vue new file mode 100644 index 0000000..c457ae4 --- /dev/null +++ b/pages/BlueTooth/ModeSetting/HBY670.vue @@ -0,0 +1,2837 @@ + + + + + \ No newline at end of file diff --git a/pages/BlueTooth/ModeSetting/ModeSetting.vue b/pages/BlueTooth/ModeSetting/ModeSetting.vue new file mode 100644 index 0000000..c464993 --- /dev/null +++ b/pages/BlueTooth/ModeSetting/ModeSetting.vue @@ -0,0 +1,1499 @@ + + + + + \ No newline at end of file diff --git a/pages/BlueTooth/ModeSetting/VideoSend.vue b/pages/BlueTooth/ModeSetting/VideoSend.vue new file mode 100644 index 0000000..3ea69bb --- /dev/null +++ b/pages/BlueTooth/ModeSetting/VideoSend.vue @@ -0,0 +1,472 @@ + + + + + \ No newline at end of file diff --git a/pages/BlueTooth/ModeSetting/VideoSend_1.vue b/pages/BlueTooth/ModeSetting/VideoSend_1.vue new file mode 100644 index 0000000..1c1eadb --- /dev/null +++ b/pages/BlueTooth/ModeSetting/VideoSend_1.vue @@ -0,0 +1,517 @@ + + + + + \ No newline at end of file diff --git a/pages/BlueTooth/ModeSetting/VideoSend_670.vue b/pages/BlueTooth/ModeSetting/VideoSend_670.vue new file mode 100644 index 0000000..1e26ab4 --- /dev/null +++ b/pages/BlueTooth/ModeSetting/VideoSend_670.vue @@ -0,0 +1,537 @@ + + + + + \ No newline at end of file diff --git a/pages/BlueTooth/ModeSetting/index.vue b/pages/BlueTooth/ModeSetting/index.vue new file mode 100644 index 0000000..88dc2cb --- /dev/null +++ b/pages/BlueTooth/ModeSetting/index.vue @@ -0,0 +1,115 @@ + + + + + \ No newline at end of file diff --git a/pages/BlueTooth/ModeSetting/update.vue b/pages/BlueTooth/ModeSetting/update.vue new file mode 100644 index 0000000..e814728 --- /dev/null +++ b/pages/BlueTooth/ModeSetting/update.vue @@ -0,0 +1,273 @@ + + + + + diff --git a/pages/common/login/index.vue b/pages/common/login/index.vue index e8e6bee..f4dd3a8 100644 --- a/pages/common/login/index.vue +++ b/pages/common/login/index.vue @@ -146,10 +146,31 @@ } try { + + console.log('44444'); + if(uni.getStorageSync("token") && uni.getStorageSync("clientID")){//免登陆 + + let time=uni.getStorageSync("tokenTime"); + if(!time){ + time=0; + } + let currTime=new Date().getTime(); + if(currTime { //订阅消息 + console.log("收到订阅消息",receive); let f=this.data.LinkedList.find((v) => { return v.deviceId == receive.deviceId; }) @@ -505,10 +506,8 @@ class BleHelper { this.cfg.receivDataCallback.forEach((rec) => { if (rec.callback) { - - } - rec.callback(recData, f, path); - + rec.callback(recData, f, path); + } }) } } else { @@ -1142,7 +1141,7 @@ class BleHelper { })); //没有找到指定设备 return; } - console.log("device=", device); + // console.log("device=", device); uni.writeBLECharacteristicValue({ deviceId: device.deviceId, serviceId: device.writeServiceId, diff --git a/utils/BleReceive.js b/utils/BleReceive.js index 6b495bc..ad07427 100644 --- a/utils/BleReceive.js +++ b/utils/BleReceive.js @@ -55,7 +55,10 @@ class BleReceive { console.log("该设备是650"); return this.Receive_650(receive,f,path); } - + if(f.detailPageUrl=='/pages/670/HBY670'){ + console.log("该设备是670"); + return this.Receive_670(receive,f,path); + } } console.log("已收到该消息,但无法处理",f); @@ -63,7 +66,7 @@ class BleReceive { } Receive_650(receive,f,path) { - console.log("通用程序正在处理650的数据"); + console.log("通用程序正在处理650的数据",receive); var parseData = () => { let bytes = receive.bytes; @@ -74,6 +77,7 @@ class BleReceive { let staticLevelByte = bytes[1]; let staticLevelText = '未知'; let modeCurr = ""; + switch (staticLevelByte) { case 0x65: staticLevelText = '高档'; @@ -190,6 +194,46 @@ class BleReceive { this.setBleFormData(formData,f); return formData; } + else{ + let receiveData={a:1}; + try { + let json=JSON.parse(str); + + if("staBlue_picture" in json){ + //重发图片 + console.log("收到重新发送图片的命令"); + receiveData=json; + } + else if("staBlue_text" in json){ + //重发文本 + console.log("收到重新发送文本的命令"); + receiveData=json; + } + else if("staBlue_vidio" in json){ + //重发视频 + console.log("收到重新发送视频的命令"); + receiveData=json; + } + else if("staBlue" in json){ + if(json.staBlue=="finish"){ + console.log("收到设备回复,全部传输完成"); + receiveData=json; + } + + } + else{ + receiveData={}; + console.log("无法解析该文本"); + } + + + + } catch (error) { + receiveData={}; + console.log("文本解析失败") + } + return receiveData; + } return null; } catch (ex) { return null; @@ -199,11 +243,149 @@ class BleReceive { } let data=parseData(); - + console.log("data=",data); return data; } + Receive_670(receive,f,path){ + + var todo = (bytes) =>{ + + let receiveData = {}; + if (bytes[0] == 0x55) { + try { + // 跳过帧头(第一个字节),从第二个字节开始解析 + let staticLevelByte = bytes[1]; + let staticLevelText = '未知'; + switch (staticLevelByte) { + case 0x65: + staticLevelText = '高档'; + break + case 0x66: + staticLevelText = '中档'; + break + case 0x67: + staticLevelText = '低档'; + break + case 0x68: + staticLevelText = '关闭'; + break + } + + // 解析照明档位 + let lightingLevelByte = bytes[2]; + let lightingLevelText = lightingLevelByte === 0x6d ? '强光': lightingLevelByte === 0x6e ? '弱光': '关闭'; + + // 解析剩余照明时间(第三和第四字节,小端序) + let lightingTime = (bytes[3] << 8) | bytes[4]; + + // 解析剩余电量 // 电量百分比范围检查 + let batteryLevelByte = bytes[5]; + + let batteryLevel = Math.max(0, Math.min(100, batteryLevelByte)); + + let warn = bytes[6]; + if (warn == 0x00) { + warn = '无预警'; + } else if (warn == 0x01) { + warn = '弱预警'; + } else if (warn == 0x02) { + warn = '中预警'; + } else if (warn == 0x03) { + warn = '强预警'; + } else if (warn == 0x04) { + warn = '非常强预警'; + } + + let staticWarn = bytes[7] == 0x01 ? '静止报警': '无静止报警'; + let fourGStrenth = bytes[8]; //4g信号强度 + let sosTxt = bytes[9] == 0x00 ? '关闭' : bytes[9] == 0x01 ? '爆闪模式' : '红蓝模式'; + + receiveData.staticLevel = staticLevelText; + receiveData.lightingLevel = lightingLevelText; + receiveData.lightingTime = lightingTime ; + receiveData.batteryLevel = batteryLevel; + receiveData.warnLevel = warn; + receiveData.staticWarn = staticWarn; + receiveData.fourGStrenth = fourGStrenth; + receiveData.SOS=sosTxt; + } catch(error) { + console.log('数据解析错误:', error); + } + } else { + try { + let uint8Array = new Uint8Array(receive.value); + let str = ''; + for (let i = 0; i < uint8Array.length; i++) { + // 将每个字节转换为对应的字符 + str += String.fromCharCode(uint8Array[i]); + } + if (str.indexOf('mac address:') == 0) { + receiveData.macAddress = str.split(':').slice(1).join(":"); + console.log('收到mac地址:', +this.receiveData.macAddress); + } else if (str.indexOf('imei:') == 0) { + receiveData.IMEI = str.split(':')[1]; + console.log('收到IEMI:', +this.receiveData.macAddress); + + } else if (str.indexOf('longitude:') == 0) { + receiveData.Lon = str.split(':')[1]; + console.log('收到经度:', +this.receiveData.macAddress); + } else if (str.indexOf('latitude:') == 0) { + receiveData.Lat = str.split(':')[1]; + console.log('收到纬度:', +this.receiveData.macAddress); + } else { + try { + let json=JSON.parse(str); + if("staBlue_picture" in json){ + //重发图片 + console.log("收到重新发送图片的命令"); + receiveData=json; + } + else if("staBlue_text" in json){ + //重发文本 + console.log("收到重新发送文本的命令"); + receiveData=json; + } + else if("staBlue_vidio" in json){ + //重发视频 + console.log("收到重新发送视频的命令"); + receiveData=json; + } + else if("staBlue" in json){ + if(json.staBlue=="finish"){ + console.log("收到设备回复,全部传输完成"); + receiveData=json; + } + + } + else{ + receiveData={}; + console.log("无法解析该文本"); + } + + + + } catch (error) { + receiveData={}; + console.log("文本解析失败") + } + } + } catch(ex) { + receiveData={}; + console.log('将数据转文本失败', ex); + } + } + + this.setBleFormData(receiveData,f); + return receiveData; + } + + + let data=todo(); + + return data; + } Receive_6155() { console.log("通用程序正在处理6155的数据"); } diff --git a/utils/Common.js b/utils/Common.js new file mode 100644 index 0000000..1daf10b --- /dev/null +++ b/utils/Common.js @@ -0,0 +1,218 @@ +var cfg={ + Version:'Uat',//Dev:开发环境,Uat:Uat环境,Relese正式环境 + DevApi:'http://192.168.110.54:8000/',//开发环境 + UatApi:'http://114.55.111.217/',//UAT环境 + ReleseApi:'http://relese:3169/api/'//Relese环境 +} +export default { + baseURL : cfg.Version=='Dev'?cfg.DevApi:(cfg.Version=='Uat'?cfg.UatApi:cfg.ReleseApi), + guid:function generateUUID() { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { + const r = Math.random() * 16 | 0; + const v = c === 'x' ? r : (r & 0x3 | 0x8); + return v.toString(16); + }); + }, + alert: function(title, content, callback) { + if(!title){ + title='提示' + } + if(!content){ + content=title; + } + + uni.showModal({ + title: title, + content: content, + success: function(res) { + if (res.confirm) { + console.log('用户点击确定'); + } else if (res.cancel) { + console.log('用户点击取消'); + } + + if (callback) { + callback(res); + } + } + }); + }, + + showLoading:function(title,mask){ + uni.showLoading({ + title:title, + mask:mask, + }) + }, + hideLoading:function(){ + uni.hideLoading(); + }, + showToast:function(title,mask,duration,callback){ + if(!duration){ + duration=1500; + } + if(mask==undefined){ + mask=false; + } + uni.showToast({ + title:title, + mask:mask, + duration:duration, + callback:callback, + icon: 'none' + }) + }, + GetData:function(url,data,method,contentType,succ,err,complete){ + var these=this; + if(!url){ + console.error("url为空"); + return; + } + + if(url.toLowerCase().indexOf('http://')==-1 || url.toLowerCase().indexOf('https://')==-1){ + if(url.indexOf('/')==0){ + url=url.substr(1,url.length-1); + } + let ServerPath=these.DevApi; + if(these.Version==='Dev'){ + ServerPath=these.DevApi; + } + else if(these.Version==='Uat'){ + ServerPath=these.UatApi; + } + else if(these.Version==='Relese'){ + ServerPath=these.ReleseApi; + }else{ + these.DevApi + } + url=ServerPath+url; + } + + var these=this; + if(!method){ + method='POST'; + } + method=method.toUpperCase(); + + if(!contentType){ + contentType='application/json;charset=UTF-8'; + } + + these.checkLAN( + + function(){ + these.showLoading('请稍候..',true); + setTimeout(function(){ + uni.request({ + url:url, + data:data, + header:{ + "Content-Type":contentType + }, + method:method, + timeout:60000, + dataType:'json', + success:function(json){ + + if(succ){ + succ(json); + } + }, + fail:function(ex){ + + if(err){ + err(ex); + } + }, + complete:function(){ + + if(complete){ + complete(); + } + } + }); + + },0); + + } + + ,function(){ + these.showToast('无网络连接'); + }); + }, + checkLAN:function(succ,error){ + uni.getNetworkType({ + success: (res) => { + const networkType = res.networkType; + + + // 判断网络是否连接 + if (networkType === 'none') { + console.error('无网络连接') + if(error){ + error(); + } + }else{ + if(succ){ + succ(); + } + + } + }, + fail: (err) => { + console.error('获取网络状态失败:', err); + if(error){ + error(); + } + } + }); + + }, + DateFormat: function(date, format) { + if(!date){ + date=new Date(); + } + if(!format){ + format='yyyy-MM-dd HH:mm:ss'; + } + // 处理参数默认值 + if (typeof date === 'string' || typeof date === 'number') { + date = new Date(date); + } + date = date instanceof Date ? date : new Date(); + format = format || 'yyyy-MM-dd'; + + // 检查日期是否有效 + if (isNaN(date.getTime())) { + return 'Invalid Date'; + } + + // 定义格式化映射 + const formatMap = { + 'yyyy': date.getFullYear(), + 'MM': String(date.getMonth() + 1).padStart(2, '0'), + 'dd': String(date.getDate()).padStart(2, '0'), + 'HH': String(date.getHours()).padStart(2, '0'), + 'mm': String(date.getMinutes()).padStart(2, '0'), + 'ss': String(date.getSeconds()).padStart(2, '0'), + 'SSS': String(date.getMilliseconds()).padStart(3, '0'), + 'M': date.getMonth() + 1, + 'd': date.getDate(), + 'H': date.getHours(), + 'm': date.getMinutes(), + 's': date.getSeconds(), + 'S': date.getMilliseconds() + }; + + // 替换格式字符串中的占位符 + return format.replace(/(yyyy|MM|dd|HH|mm|ss|SSS|M|d|H|m|s|S)/g, (match) => { + return formatMap[match]; + }); + } + + + + + + +} \ No newline at end of file diff --git a/utils/mqtt.js b/utils/mqtt.js index 5e53fce..e682683 100644 --- a/utils/mqtt.js +++ b/utils/mqtt.js @@ -1,6 +1,7 @@ // 兼容性补丁:为 Paho MQTT 提供 uni-app 环境下的 WebSocket 实现 (function(root) { // 如果未能找到全局对象,则无法应用补丁。 + console.log("root=",root); if (!root) { console.error("MQTT Polyfill: 未能找到全局对象 (global/window/self 均未定义)。"); return; @@ -165,13 +166,13 @@ class MqttClient { this.client.onMessageArrived = (message) => { const topic = message.destinationName; - const payload = message.payloadString; + const payload = message.payloadString; console.log(`收到消息, 主题: ${topic}, 内容: ${payload}`); const potentialJsons = payload.replace(/}\s*{/g, '}|{').split('|'); potentialJsons.forEach(jsonString => { if (jsonString.trim() === '') return; if (this.messageCallbacks.has(topic)) { - this.messageCallbacks.get(topic)(jsonString); + this.messageCallbacks.get(topic)(jsonString,message); } }); }; @@ -281,8 +282,10 @@ class MqttClient { mqttMessage.qos = 1; this.client.send(mqttMessage); console.log(`成功发布消息到主题 ${topic}: ${message}`); + return true; } else { console.error('MQTT未连接,无法发布'); + return false; } } diff --git a/utils/update.js b/utils/update.js new file mode 100644 index 0000000..ceb5613 --- /dev/null +++ b/utils/update.js @@ -0,0 +1,153 @@ +/** + * 检查并执行wgt热更新 + * @param {String} updateUrl - 检查更新的接口地址 + */ +function checkAndUpdateWgt(updateUrl) { + if(!plus){ + return; + } + // 显示加载提示 + + + // 1. 获取当前应用版本信息 + plus.runtime.getProperty(plus.runtime.appid, (widgetInfo) => { + const currentVersion = widgetInfo.version; + console.log("当前版本:" + currentVersion); + // 2. 调用后端接口检查是否有更新 + uni.request({ + url: updateUrl, + method: 'GET', + data: { + currentVersion: currentVersion, + platform: uni.getSystemInfoSync().platform + }, + success: (res) => { + uni.hideLoading(); + console.log("res=", res) + if (res.statusCode === 200) { + + const updateInfo = res.data.data; + if (!updateInfo.hasUpdate) { + return; + } + // 3. 显示更新提示 + uni.showModal({ + title: '检测到更新', + content: updateInfo.description || '有新版本可用,是否立即更新?', + confirmText: '立即更新', + cancelText: '稍后更新', + success: (modalRes) => { + if (modalRes.confirm) { + downloadAndInstallWgt(updateInfo.downloadUrl); + } + } + }); + } else { + uni.showToast({ + title: '当前已是最新版本', + icon: 'none', + duration: 2000 + }); + } + }, + fail: (err) => { + uni.hideLoading(); + uni.showToast({ + title: '检查更新失败', + icon: 'none', + duration: 2000 + }); + console.error('检查更新失败:', err); + } + }); + }); +} + +/** + * 下载并安装wgt更新包 + * @param {String} wgtUrl - wgt包下载地址 + */ +function downloadAndInstallWgt(wgtUrl) { + // 显示下载进度 + var wating=plus.nativeUI.showWaiting({ + title:"下载中0%" + }); + // uni.showLoading({ + // title: '更新下载中...', + // mask: true + // }); + + // 1. 下载wgt包 + const downloadTask = uni.downloadFile({ + url: wgtUrl, + success: (downloadRes) => { + wating.setTitle("下载完成,正在安装"); + if (downloadRes.statusCode === 200) { + // 2. 安装wgt包 + plus.runtime.install(downloadRes.tempFilePath, { + force: true // 是否强制安装 + }, () => { + uni.removeSavedFile({ + filePath: downloadRes.tempFilePath, + success() { + console.log("临时文件已删除"); + }, + fail() { + console.log("无法删除临时文件"); + }, + complete() { + wating.close(); + uni.showModal({ + title: '更新完成', + content: '应用已更新,是否重启应用?', + showCancel: false, + success: () => { + // 3. 重启应用 + plus.runtime.restart(); + } + }); + } + }); + + }, (error) => { + + wating.close(); + uni.showToast({ + title: '安装失败: ' + error.message, + icon: 'none', + duration: 3000 + }); + console.error('wgt安装失败:', error); + }); + + } else { + wating.close(); + uni.showToast({ + title: '下载失败', + icon: 'none', + duration: 2000 + }); + } + }, + fail: (err) => { + uni.hideLoading(); + uni.showToast({ + title: '下载失败: ' + err.errMsg, + icon: 'none', + duration: 2000 + }); + console.error('wgt下载失败:', err); + } + }); + + // 监听下载进度 + downloadTask.onProgressUpdate((progress) => { + console.log('下载进度: ' + progress.progress + '%'); + wating.setTitle("下载中"+ progress.progress + '%'); + // 可以在这里更新自定义进度条 + }); +} + +export default { + checkAndUpdateWgt +}; \ No newline at end of file