670加入用户确认收到消息

This commit is contained in:
liub
2025-11-20 16:40:14 +08:00
parent 3a75d4df2b
commit 294d854867
8 changed files with 433 additions and 50 deletions

View File

@ -2,7 +2,7 @@
"name" : "星汉物联", "name" : "星汉物联",
"appid" : "__UNI__A21EF43", "appid" : "__UNI__A21EF43",
"description" : "设备管控", "description" : "设备管控",
"versionName" : "1.0.6", "versionName" : "1.0.7",
"versionCode" : "100", "versionCode" : "100",
"transformPx" : false, "transformPx" : false,
/* 5+App */ /* 5+App */

View File

@ -3,7 +3,7 @@
<view class="eq"> <view class="eq">
<view class="leftImg" @click.stop="previewImg(device.devicePic?device.devicePic:formData.img)"> <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> <image class="img" :src="device.devicePic?device.devicePic:formData.img" mode="aspectFit"></image>
</view> </view>
<view class="rightTxt"> <view class="rightTxt">
<view class="row"> <view class="row">
@ -23,15 +23,15 @@
</view> </view>
</view> </view>
<view class="eqinfo"> <view class="eqinfo">
<view class="item"> <view class="item">
<text class="lbl">设备名称</text> <text class="lbl">设备名称</text>
<text class="value">{{device.deviceName}}</text> <text class="value">{{device.deviceName}}</text>
</view> </view>
<view class="item"> <view class="item">
<text class="lbl">Mac地址</text> <text class="lbl">Mac地址</text>
<text class="value">{{device.deviceMac}}</text> <text class="value">{{device.deviceMac}}</text>
</view> </view>
<view class="item"> <view class="item">
<text class="lbl">设备状态</text> <text class="lbl">设备状态</text>
<text class="value">{{formData.statu}}</text> <text class="value">{{formData.statu}}</text>
@ -86,6 +86,15 @@
<text class="smallTxt">上传</text> <text class="smallTxt">上传</text>
</view> </view>
</view> </view>
<view class="mode fleft marginLeft" v-on:click.stop="UploadOpenVideo()">
<view class="leftImg">
<image class="img" src="/static/images/common/video.png" mode="aspectFit"></image>
</view>
<view class="rightTxt">
<text class="bigTxt">开机视频</text>
<text class="smallTxt">上传</text>
</view>
</view>
<view class="clear"></view> <view class="clear"></view>
</view> </view>
<view class="usrinfo"> <view class="usrinfo">
@ -162,6 +171,10 @@
updateLoading updateLoading
} from '@/utils/loading.js' } from '@/utils/loading.js'
import BleReceive from '@/utils/BleReceive'; import BleReceive from '@/utils/BleReceive';
import {
baseURL
} from '@/utils/request.js';
var pagePath = "/pages/6155/HBY6155"; var pagePath = "/pages/6155/HBY6155";
var ble = null; var ble = null;
@ -246,7 +259,7 @@
mode: '', mode: '',
bleStatu: '' bleStatu: ''
}, },
inteval: 200, inteval: 80,
device: { device: {
id: "", id: "",
deviceName: "", deviceName: "",
@ -360,7 +373,7 @@
} }
these.formData.blename = f.name ? f.name : "Unname"; these.formData.blename = f.name ? f.name : "Unname";
these.formData.deviceName = device.deviceName; these.formData.deviceName = device.deviceName;
these.formData.id = device.id; these.formData.id = device.id;
these.formData.deviceId = f.deviceId; these.formData.deviceId = f.deviceId;
these.formData.bleStatu = false; these.formData.bleStatu = false;
@ -619,7 +632,7 @@
// 创建RGB565格式的像素数据 // 创建RGB565格式的像素数据
// console.log("pixels=",pixels); // console.log("pixels=",pixels);
const arr = ble.convertToRGB565(pixels, 'bgr'); const arr = ble.convertToRGB565(pixels, 'bgr');
var list = []; var list = [];
let index = 0; // 用于追踪arr的当前位置 let index = 0; // 用于追踪arr的当前位置
let packetSize = 3200; let packetSize = 3200;
@ -631,12 +644,12 @@
// 中层循环每个主要元素包含9个子数组j从1到9 // 中层循环每个主要元素包含9个子数组j从1到9
for (let j = 1; j < 9; j++) { for (let j = 1; j < 9; j++) {
// 确定当前子数组的长度前8个是254第9个是64 // 确定当前子数组的长度前8个是254第9个是64
let thirdLevel = []; let thirdLevel = [];
// 从arr中提取相应数量的元素 // 从arr中提取相应数量的元素
for (let k = 0; k < cSize && index < arr.length; k++) { for (let k = 0; k < cSize && index < arr.length; k++) {
if (secondCnt == packetSize) { if (secondCnt == packetSize) {
break; break;
} }
@ -644,14 +657,14 @@
secondCnt++; secondCnt++;
index++; index++;
} }
secondLevel.push(thirdLevel); secondLevel.push(thirdLevel);
} }
list.push(secondLevel); list.push(secondLevel);
} }
console.log("list=", list); console.log("list=", list);
let length = 0; let length = 0;
for (let i = 0; i < list.length; i++) { for (let i = 0; i < list.length; i++) {
const item = list[i]; const item = list[i];
@ -661,8 +674,8 @@
console.log("第" + i + "包,第" + j + "小包,长度:" + element.length) console.log("第" + i + "包,第" + j + "小包,长度:" + element.length)
length += element.length; length += element.length;
clength += element.length; clength += element.length;
} }
} }
// 分包发送 // 分包发送
@ -680,37 +693,39 @@
let currentPacket = 1; let currentPacket = 1;
let childPacket = 1; let childPacket = 1;
let totalChildPacket = 8; let totalChildPacket = 8;
// 发送单个数据包 // 发送单个数据包
const sendNextPacket = () => { const sendNextPacket = () => {
if (currentPacket > totalPackets) { if (currentPacket > totalPackets) {
updateLoading(these,{text:'发送完成,等待设备30秒'}); updateLoading(these, {
text: '发送完成,等待设备30秒'
});
setTimeout(() => { setTimeout(() => {
hideLoading(these); hideLoading(these);
these.Status.BottomMenu.show = false; these.Status.BottomMenu.show = false;
these.showPop({ these.showPop({
message: "上传成功", message: "上传成功",
iconUrl: "/static/images/6155/DeviceDetail/uploadSuccess.png", iconUrl: "/static/images/6155/DeviceDetail/uploadSuccess.png",
borderColor: '#BBE600', borderColor: '#BBE600',
buttonBgColor: '#BBE600' buttonBgColor: '#BBE600'
}); });
resolve(); resolve();
}, 0) }, 0)
return; return;
} }
var packetData = imageData[currentPacket - 1][childPacket - 1]; var packetData = imageData[currentPacket - 1][childPacket - 1];
console.log("childPacket=", childPacket); console.log("childPacket=", childPacket);
console.log("packetData=", packetData); console.log("packetData=", packetData);
let start = 0; let start = 0;
let bufferSize = packetData.length * 2; let bufferSize = packetData.length * 2;
if (childPacket == 1) { if (childPacket == 1) {
bufferSize = bufferSize + 8 bufferSize = bufferSize + 8
start = 8; start = 8;
@ -718,8 +733,8 @@
if (childPacket == 8) { //|| (currentPacket==7 && childPacket==3 if (childPacket == 8) { //|| (currentPacket==7 && childPacket==3
bufferSize = bufferSize + 1 bufferSize = bufferSize + 1
} }
//FA 09 0C 84 FB 09 00 [01~08] + 3200字节 +FF 数据格式 //FA 09 0C 84 FB 09 00 [01~08] + 3200字节 +FF 数据格式
var buffer = new ArrayBuffer(bufferSize); var buffer = new ArrayBuffer(bufferSize);
var dataView = new DataView(buffer); var dataView = new DataView(buffer);
@ -733,7 +748,7 @@
dataView.setUint8(6, 0x00); // 帧头 dataView.setUint8(6, 0x00); // 帧头
dataView.setUint8(7, currentPacket); //包序号 dataView.setUint8(7, currentPacket); //包序号
} }
for (let i = 0; i < packetData.length; i++) { for (let i = 0; i < packetData.length; i++) {
dataView.setUint16(start + i * 2, packetData[i], false); //本包数据,大端字节序 dataView.setUint16(start + i * 2, packetData[i], false); //本包数据,大端字节序
} }
@ -742,19 +757,19 @@
if (childPacket == 8) { // || (currentPacket==7 && childPacket==3 if (childPacket == 8) { // || (currentPacket==7 && childPacket==3
dataView.setUint8(bufferSize - 1, 0xFF); dataView.setUint8(bufferSize - 1, 0xFF);
} }
//发送数据包 //发送数据包
ble.sendData(f.deviceId, buffer, f.writeServiceId, f.wirteCharactId, ble.sendData(f.deviceId, buffer, f.writeServiceId, f.wirteCharactId,
30) 30)
.then(() => { .then(() => {
let curr = childPacket + (currentPacket - 1) * let curr = childPacket + (currentPacket - 1) *
totalChildPacket; totalChildPacket;
console.log("第" + currentPacket + "大包,第" + childPacket + console.log("第" + currentPacket + "大包,第" + childPacket +
"小包发送完成,总计:" + curr); "小包发送完成,总计:" + curr);
updateLoading(these, { updateLoading(these, {
text: "正在发送" + curr + "/64" text: "正在发送" + curr + "/64"
}) })
if (childPacket == 8) { if (childPacket == 8) {
currentPacket++; currentPacket++;
@ -762,16 +777,16 @@
} else { } else {
childPacket++; childPacket++;
} }
setTimeout(sendNextPacket, 100); setTimeout(sendNextPacket, 100);
}).catch(err => { }).catch(err => {
if (err.code == 10007) { if (err.code == 10007) {
setTimeout(sendNextPacket, 100); setTimeout(sendNextPacket, 100);
return; return;
} }
console.log("发送数据包失败了", err); console.log("发送数据包失败了", err);
these.Status.BottomMenu.show = false; these.Status.BottomMenu.show = false;
these.showPop({ these.showPop({
message: "发送数据包失败了" + err.msg, message: "发送数据包失败了" + err.msg,
@ -779,14 +794,14 @@
borderColor: "#e034344d", borderColor: "#e034344d",
buttonBgColor: "#E03434", buttonBgColor: "#E03434",
}); });
hideLoading(these); hideLoading(these);
reject(err); reject(err);
}); });
} }
// 开始发送数据 // 开始发送数据
sendNextPacket(); sendNextPacket();
}); });
} }
@ -828,6 +843,344 @@
} }
}); });
}, },
UploadOpenVideo: function() { //开机动画
let f = these.getDevice();
if (!f) {
these.showBleUnConnect();
return;
}
let timeDelayCloseLoading = () => {
setTimeout(() => {
hideLoading(these);
}, 1500);
}
//视频上传
let uplploadVideo = (videoPath) => {
return new Promise((resolve, reject) => {
let start = new Date();
let token = uni.getStorageSync('token');
let clientid = uni.getStorageSync('clientID');
uni.uploadFile({
url: baseURL + "/app/video/upload",
filePath: videoPath,
name: 'file',
header: {
"Method": "POST",
"Content-Type": "multipart/form-data",
"Authorization": 'Bearer ' + token,
"clientid": clientid
},
formData: {
code: 2
},
timeout: 600000,
fail: (ex) => {
updateLoading(these, {
text: '视频文件上传失败了,请检查网络连接'
});
reject(ex);
},
success: (res) => {
// console.error(res);
let end = new Date();
var diff = (end.getTime() - start.getTime()) / 1000;
let s = diff % 60;
let m = parseInt((diff - s) / 60);
console.log("res.statusCode==", res.statusCode);
res.data = JSON.parse(res.data);
if (res.statusCode === 200) {
if (res.data.code == 200) {
console.log("上传完成,耗时:" + m + "分" + s + "秒");
updateLoading(these,{text:"上传完成,耗时:" + m + "分" + s + "秒,正在切片。"})
resolve(res.data);
return;
}
}
console.error("上传完成,耗时:" + m + "分" + s + "秒");
reject(res);
}
});
});
}
//视频切片
let videoCutPacket = (array) => {
return new Promise((resolve, reject) => {
try {
let imgSize = 25600;
let packetSize = 3200;
let tdSize = 500;
let results = [];
for (let i = 0; i < 30; i++) { //先切出30张每张25600字节
let packet = array.slice(0, imgSize);
array.splice(0, imgSize)
let secondLevel = [];
for (let j = 0; j < 8; j++) { //每张切8大包每包3200字节
let childPacket = packet.slice(0, packetSize);
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);
}
secondLevel.push(thirdLevel);
}
results.push(secondLevel);
}
updateLoading(these,{text:'切片完成,正在发送'});
resolve(results);
} catch (error) {
updateLoading(these, {
text: '视频切片发生异常'
});
reject(error);
}
});
}
//发送视频到设备
let shotVideoClick = (array, type, ReSendNo) => {
var sendImagePackets = () => {
return new Promise((resolve, reject) => {
this.currentPacket = 0;
// 总数据包数
var totalPackets = 1680;
this.totalPackets = totalPackets;
let currentPacket = 1;
let imgIndex = 0;
let imgPackIndex = 0;
let childPacketIndex = 0;
if (ReSendNo) {
this.currentPacket = ReSendNo - 1;
currentPacket = ReSendNo;
totalPackets = ReSendNo;
this.totalPackets = ReSendNo;
}
// 发送单个数据包
const sendNextPacket = () => {
// console.log("111111")
if (currentPacket > totalPackets) {
resolve();
return;
}
// console.log("111111")
// 计算当前包的数据
let packetSize = 500;
if ((currentPacket - 1) % 56 === 0) {
packetSize = 508;
}
if (childPacketIndex === 6) {
packetSize = 200;
}
if ((currentPacket - 1) % 56 === 55) {
packetSize = 201;
}
console.log("imgIndex=" + imgIndex + ",imgPackIndex=" +
imgPackIndex +
",childPacketIndex=" + childPacketIndex)
let packetData = array[imgIndex][imgPackIndex][childPacketIndex];
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) {
// 填充头部
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]);
}
// console.log("333333333");
if ((currentPacket - 1) % 56 === 55) {
dataView.setUint8(200, 0xFF);
}
// console.log("444444");
let inteval = parseInt(this.inteval ? this.inteval : 80);
ble.sendData(f.deviceId, buffer, f.writeServiceId, f
.wirteCharactId, ).then(() => {
if (ReSendNo) {
resolve();
return;
}
// 更新进度
this.currentPacket = currentPacket;
updateLoading(these,{
text:'正在发送:'+currentPacket+"/"+totalPackets
});
childPacketIndex++;
if (childPacketIndex == 7) {
imgPackIndex++;
if (imgPackIndex == 8) {
imgIndex++;
imgPackIndex = 0;
}
childPacketIndex = 0;
}
// 发送下一个包(添加延迟避免蓝牙缓冲区溢出)
currentPacket++;
setTimeout(sendNextPacket, inteval);
}).catch(err => {
if (err.code == 10007) {
console.error(err.errMsg + ",发送失败了,正在补偿:" +
currentPacket);
setTimeout(sendNextPacket, 100);
return;
}
console.error(err.errMsg + ",发送失败了" + currentPacket);
updateLoading(these,{text:"发送失败,"+err.errMsg});
reject(err);
});
};
// console.log("111111")
sendNextPacket();
});
}
return sendImagePackets();
}
uni.chooseVideo({
sourceType: ['album'],
success: function(res) {
console.log("res=",res);
let path = res.tempFilePath;
let width = res.width;
let height = res.height;
let duration = res.duration;
let err = [];
if (duration < 2) {
err.push("视频时长至少2秒");
}
if (width != 160 || height != 80) {
err.push("视频宽高必须是160*80");
}
if (err.length > 0) {
err = err.join(";");
these.showPop({
message: err,
iconUrl: "/static/images/6155/DeviceDetail/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
});
return;
}
showLoading(these, {
text: '正在上传'
});
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();
});
}).catch(err => {
timeDelayCloseLoading();
});
}).catch(ex => {
timeDelayCloseLoading();
});
}, 0);
}
});
},
UploadOpenImg: function() { UploadOpenImg: function() {
//上传开机画面 //上传开机画面
this.Status.BottomMenu.menuItems = []; this.Status.BottomMenu.menuItems = [];

View File

@ -1007,7 +1007,7 @@
dataView.setUint8(6 + i, '0x' + packetData[i]); dataView.setUint8(6 + i, '0x' + packetData[i]);
} }
let inteval = 50; let inteval = 30;
console.log("开始发送一段视频"); // console.log("开始发送一段视频"); //
ble.sendData(f.deviceId, buffer, f.writeServiceId, f ble.sendData(f.deviceId, buffer, f.writeServiceId, f
.wirteCharactId, 10).then(() => { .wirteCharactId, 10).then(() => {

View File

@ -309,6 +309,8 @@
data() { data() {
return { return {
Status: { Status: {
msgOkIntval:null,//紧急通知等待的时间
msgOkTime:null,//
pageHide: false, pageHide: false,
apiType: "listA", apiType: "listA",
navbar: { navbar: {
@ -465,6 +467,8 @@
onUnload() { onUnload() {
console.log("页面卸载,释放资源"); console.log("页面卸载,释放资源");
let statusTopic = `A/${this.formData.imei?this.formData.imei:this.device.deviceImei}`; let statusTopic = `A/${this.formData.imei?this.formData.imei:this.device.deviceImei}`;
clearInterval(these.Status.staticWarn.inteval);
clearInterval(this.Status.msgOkIntval);
ble.removeAllCallback(pagePath); ble.removeAllCallback(pagePath);
if (mqttClient) { if (mqttClient) {
mqttClient.unsubscribe(statusTopic); mqttClient.unsubscribe(statusTopic);
@ -863,10 +867,22 @@
// console.log("收到文本回复", payload); // console.log("收到文本回复", payload);
// // this.SendTxtMQ(json); // // this.SendTxtMQ(json);
// } // }
// else if (keys.indexOf('sta_BreakNews') > -1) { //紧急通知 if (keys.indexOf('sta_BreakNews') > -1) { //紧急通知
// console.log("收到紧急消息回复", payload); if(json.sta_BreakNews==='I get it')// && this.Status.msgOkTime && this.Status.msgOkIntval){
// // this.sendUrgentMQ(json); {
// } these.showPop({
showPop: true,
message: "用户已确认收到紧急通知",
iconUrl: "/static/images/6155/DeviceDetail/uploadSuccess.png"
});
// this.Status.msgOkTime=null
// clearInterval(this.Status.msgOkIntval);
}
}
// else { // else {
// console.log("收到不能处理的数据", payload); // console.log("收到不能处理的数据", payload);
// } // }
@ -2498,7 +2514,7 @@
buttonBgColor: '#BBE600', buttonBgColor: '#BBE600',
buttonTextColor: '#232323DE', buttonTextColor: '#232323DE',
iconUrl: '/static/images/6155/DeviceDetail/sendSucc.png', iconUrl: '/static/images/6155/DeviceDetail/sendSucc.png',
message: '发送成功', message: '发送成功,待用户确认',
buttonText: '确定', buttonText: '确定',
clickEvt: 'SendUsr', clickEvt: 'SendUsr',
visiblePrompt: false, visiblePrompt: false,
@ -2506,6 +2522,20 @@
modelValue: '', modelValue: '',
visibleClose: true visibleClose: true
}); });
// clearInterval(this.Status.msgOkIntval);
// this.Status.msgOkTime=0;
// this.Status.msgOkIntval=setInterval(()=>{
// this.Status.msgOkTime++;
// if(this.Status.msgOkTime>180){
// this.Status.msgOkTime=null
// clearInterval(this.Status.msgOkIntval);
// this.Status.msgOkIntval=null;
// }
// });
} else { } else {
these.showPop({ these.showPop({
message: res.msg, message: res.msg,

View File

@ -604,7 +604,7 @@
console.log("res=", res); console.log("res=", res);
linkCallback(res); linkCallback(res);
}).catch(ex => { }).catch(ex => {
console.log("ex=", ex) console.error("ex=", ex)
uni.showModal({ uni.showModal({
content: "连接失败:" + ex.msg content: "连接失败:" + ex.msg
}); });

View File

@ -798,7 +798,7 @@ class BleHelper {
if (isUpdate) { if (isUpdate) {
this.updateCache(); this.updateCache();
} }
console.log("str1=", str); // console.log("str1=", str);
} catch (ex) { } catch (ex) {
console.error("将数据转文本失败", ex); console.error("将数据转文本失败", ex);
} }
@ -1480,7 +1480,7 @@ class BleHelper {
deviceId: deviceId, deviceId: deviceId,
timeout: 30000, timeout: 30000,
success: (info) => { success: (info) => {
// console.log("新连接成功", this.data.LinkedList); console.log("新连接成功", this.data.LinkedList);
this.getLinkBlue().then((arr) => { this.getLinkBlue().then((arr) => {
let cr = arr.devices.find(c => { let cr = arr.devices.find(c => {
if (c.deviceId == deviceId) { if (c.deviceId == deviceId) {

View File

@ -59,10 +59,10 @@ class BleReceive {
if (handler) { if (handler) {
let data = handler(receive, f, path, recArr); let data = handler(receive, f, path, recArr);
console.log("handler返回的数据:", data); console.log("设备"+f.device.deviceName+"收到消息,handler返回的数据:", data);
return data; return data;
} else { } else {
console.log("已收到消息,但无指定处理程序, deviceUrl:", f.device.detailPageUrl, "可用handlers:", keys); console.error("已收到消息,但无指定处理程序, deviceUrl:", f.device.detailPageUrl, "可用handlers:", keys);
} }
} else { } else {

View File

@ -1,5 +1,5 @@
import config from '../config/index.js'; import config from '../config/index.js';
export const env = 'development'; //production development //开发of线上 改这里就行 export const env = 'production'; //production development //开发of线上 改这里就行
const BASE = config[env]; const BASE = config[env];
const request = (options) => { const request = (options) => {
console.log("options" + JSON.stringify(options), BASE.BASE_URL) console.log("options" + JSON.stringify(options), BASE.BASE_URL)