Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8ccc37cb93 | |||
| ebbac4232a | |||
| 362b752087 | |||
| 5c69e32c2d | |||
| e247acdd5e |
@ -100,7 +100,6 @@
|
||||
if (options.dotColors) {
|
||||
this.colorIndex = 0
|
||||
}
|
||||
this.visible = true;
|
||||
},
|
||||
|
||||
// 阻止触摸移动事件
|
||||
|
||||
@ -24,8 +24,7 @@
|
||||
"Geolocation" : {},
|
||||
"Maps" : {},
|
||||
"Record" : {},
|
||||
"VideoPlayer" : {},
|
||||
"Push" : {}
|
||||
"VideoPlayer" : {}
|
||||
},
|
||||
/* 应用发布信息 */
|
||||
"distribute" : {
|
||||
|
||||
@ -48,9 +48,8 @@
|
||||
|
||||
<view class="warnnig" :class="{'displayNone':formData.sta_sosadd===''}">
|
||||
<view>闯入报警!</view>
|
||||
<view>
|
||||
<view class="netContent">
|
||||
{{getWarDevice(formData.sta_sosadd)}}
|
||||
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@ -172,9 +171,10 @@
|
||||
hideLoading,
|
||||
updateLoading
|
||||
} from '@/utils/loading.js'
|
||||
import request, {
|
||||
import {
|
||||
request,
|
||||
baseURL
|
||||
} from '@/utils/request.js'
|
||||
} from '../../utils/request';
|
||||
|
||||
import Common from '@/utils/Common.js'
|
||||
const pagePath = "/pages/102/HBY102";
|
||||
@ -432,7 +432,6 @@
|
||||
|
||||
},
|
||||
methods: {
|
||||
|
||||
actionSett(item, index) {
|
||||
if (item.group == 'sta_LedType') {
|
||||
this.sosSetting(item, index);
|
||||
@ -737,7 +736,20 @@
|
||||
urls: [img]
|
||||
})
|
||||
},
|
||||
|
||||
getWarDevice(macStr){//获取正在报警的设备名
|
||||
let f = this.groupDevices.find(v => {
|
||||
return v.deviceMac === macStr;
|
||||
});
|
||||
if (f) {
|
||||
return f.deviceName;
|
||||
}
|
||||
|
||||
if(macStr == this.device.deviceMac) {
|
||||
return this.device.deviceName;
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
bleValueNotify(receive, device, path, recArr) { //订阅消息
|
||||
if (receive.deviceId !== this.formData.deviceId) {
|
||||
return;
|
||||
@ -758,21 +770,14 @@
|
||||
this.formData[key] = json[key];
|
||||
}
|
||||
});
|
||||
|
||||
let msg = [];
|
||||
if (this.formData.sta_PowerPercent <= 20) {
|
||||
msg.push("设备电量低");
|
||||
}
|
||||
if (json.sta_sosadd_off == this.formData.sta_sosadd) {
|
||||
this.formData.sta_sosadd = "";
|
||||
let name=this.getWarDevice(json.sta_sosadd_off);
|
||||
msg.push('"' + name + '"取消报警');
|
||||
}
|
||||
|
||||
|
||||
if (this.formData.sta_sosadd !== "") {
|
||||
console.log("查询设备中");
|
||||
this.searchDevice(this.formData.sta_sosadd).catch(ex => {}).then(dev => {
|
||||
console.log("dev=", dev);
|
||||
if (dev) {
|
||||
msg.push('"' + dev.deviceName + '"闯入报警中');
|
||||
} else {
|
||||
@ -793,9 +798,9 @@
|
||||
// this.formData.sta_IntrusTime=instrusionTime;
|
||||
// }, 1000);
|
||||
} else {
|
||||
// clearInterval(instrusionTime);
|
||||
// instrusionTime = 0;
|
||||
// this.formData.sta_IntrusTime = 0;
|
||||
clearInterval(instrusionTime);
|
||||
instrusionTime = 0;
|
||||
this.formData.sta_IntrusTime = 0;
|
||||
}
|
||||
if (msg.length > 0) {
|
||||
this.showMsg(msg.join(','));
|
||||
@ -803,26 +808,6 @@
|
||||
|
||||
|
||||
},
|
||||
|
||||
getWarDevice(macStr) {
|
||||
if (macStr) {
|
||||
|
||||
if (!macStr.includes(':')) {
|
||||
macStr = macStr.replace(/(.{2})/g, '$1:').slice(0, -1)
|
||||
}
|
||||
|
||||
let f = this.groupDevices.find(v => {
|
||||
return v.deviceMac === macStr;
|
||||
});
|
||||
|
||||
if (f) {
|
||||
return f.deviceName;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
},
|
||||
|
||||
searchDevice(macStr) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (macStr.includes(':')) {
|
||||
@ -834,59 +819,45 @@
|
||||
let f = this.groupDevices.find(v => {
|
||||
return v.deviceMac === macStr;
|
||||
});
|
||||
console.log("111111111");
|
||||
if (f) {
|
||||
console.log("找到设备", f);
|
||||
resolve(f);
|
||||
return;
|
||||
}
|
||||
console.log("111111111");
|
||||
|
||||
if (macStr == this.device.deviceMac) {
|
||||
console.log("当前设备", this.device);
|
||||
resolve(this.device);
|
||||
return;
|
||||
}
|
||||
console.log("111111111");
|
||||
try {
|
||||
|
||||
request({
|
||||
url: '/app/device/getDeviceInfoByDeviceMac',
|
||||
method: 'GET',
|
||||
data: {
|
||||
deviceMac: these.device.macAddress
|
||||
}
|
||||
}).then(res => {
|
||||
|
||||
request({
|
||||
url: '/app/device/getDeviceInfoByDeviceMac',
|
||||
method: 'GET',
|
||||
data: {
|
||||
deviceMac: macStr
|
||||
console.log("获取设备信息", res);
|
||||
if (res && res.code == 200) {
|
||||
console.log("res=", res);
|
||||
let data = res.data;
|
||||
if (data) {
|
||||
this.groupDevices.push({
|
||||
deviceMac: data.deviceMac,
|
||||
deviceName: data.deviceName
|
||||
})
|
||||
resolve(data);
|
||||
return;
|
||||
}
|
||||
}).then(res => {
|
||||
}
|
||||
|
||||
console.log("获取设备信息", res);
|
||||
if (res && res.code == 200) {
|
||||
console.log("res=", res);
|
||||
let data = res.data;
|
||||
if (data) {
|
||||
this.groupDevices.push({
|
||||
deviceMac: data.deviceMac,
|
||||
deviceName: data.deviceName
|
||||
})
|
||||
resolve(data);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
console.log("222222222");
|
||||
}
|
||||
|
||||
resolve(null);
|
||||
|
||||
}).catch(ex => {
|
||||
console.error("查询设备出现异常:", ex);
|
||||
resolve(null);
|
||||
|
||||
}).finally(com => {
|
||||
console.log("complete")
|
||||
});
|
||||
} catch (err) {
|
||||
console.error("err=", err);
|
||||
resolve(null);
|
||||
}
|
||||
|
||||
}).catch(ex => {
|
||||
|
||||
resolve(null);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
@ -108,15 +108,15 @@
|
||||
|
||||
<view class="item">
|
||||
<text class="lbl">单位:</text>
|
||||
<input class="value" v-model="formData.textLines[0]" placeholder="请输入单位" placeholder-class="usrplace" />
|
||||
<input class="value" v-model.trim="formData.textLines[0]" placeholder="请输入单位" placeholder-class="usrplace" />
|
||||
</view>
|
||||
<view class="item">
|
||||
<text class="lbl">部门:</text>
|
||||
<input class="value" v-model="formData.textLines[1]" placeholder="请输入姓名" placeholder-class="usrplace" />
|
||||
<input class="value" v-model.trim="formData.textLines[1]" placeholder="请输入姓名" placeholder-class="usrplace" />
|
||||
</view>
|
||||
<view class="item">
|
||||
<text class="lbl">姓名:</text>
|
||||
<input class="value" v-model="formData.textLines[2]" placeholder="请输入职位" placeholder-class="usrplace" />
|
||||
<input class="value" v-model.trim="formData.textLines[2]" placeholder="请输入职位" placeholder-class="usrplace" />
|
||||
</view>
|
||||
|
||||
</view>
|
||||
@ -175,7 +175,7 @@
|
||||
baseURL
|
||||
} from '@/utils/request.js';
|
||||
|
||||
var pagePath = "/pages/6155/deviceDetail";
|
||||
var pagePath = "/pages/6155/HBY6155";
|
||||
|
||||
var ble = null;
|
||||
var these = null;
|
||||
@ -575,7 +575,7 @@
|
||||
keys.forEach((key) => {
|
||||
if (key in these.formData) {
|
||||
// 确保响应式更新
|
||||
// console.log(`更新字段 ${key}: ${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 中,跳过更新`);
|
||||
@ -584,7 +584,7 @@
|
||||
|
||||
// 强制触发视图更新,确保电量显示同步
|
||||
these.$forceUpdate();
|
||||
// console.log("更新后的电量:", these.formData.battary);
|
||||
console.log("更新后的电量:", these.formData.battary);
|
||||
|
||||
if (this.formData.battary <= 20) {
|
||||
this.showPop({
|
||||
@ -911,7 +911,7 @@
|
||||
"clientid": clientid
|
||||
},
|
||||
formData: {
|
||||
code: 1,
|
||||
code: 2,
|
||||
width: width,
|
||||
height: height
|
||||
},
|
||||
@ -919,7 +919,7 @@
|
||||
fail: (ex) => {
|
||||
|
||||
updateLoading(these, {
|
||||
text: '视频文件上传失败了,请检查网络连接'
|
||||
text : '视频文件上传失败了,请检查网络连接'
|
||||
});
|
||||
|
||||
reject(ex);
|
||||
@ -942,8 +942,6 @@
|
||||
resolve(res.data);
|
||||
|
||||
return;
|
||||
}else{
|
||||
console.log("res.data=",res.data);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1089,7 +1087,7 @@
|
||||
dataView.setUint8(packetSize - 1, 0xFF);
|
||||
}
|
||||
let inteval = parseInt(this.inteval ? this.inteval : 80);
|
||||
// console.log(inteval, 'intevalinteval');
|
||||
console.log(inteval, 'intevalinteval');
|
||||
ble.sendData(f.deviceId, buffer, f.writeServiceId, f
|
||||
.wirteCharactId).then(() => {
|
||||
if (ReSendNo) {
|
||||
@ -1295,9 +1293,14 @@
|
||||
case "fu":
|
||||
title = '辅灯模式';
|
||||
items = [{
|
||||
text: '泛光',
|
||||
icon: '/static/images/6155/DeviceDetail/fan.png'
|
||||
}];
|
||||
text: '泛光',
|
||||
icon: '/static/images/6155/DeviceDetail/fan.png'
|
||||
},
|
||||
{
|
||||
text: '强+泛光',
|
||||
icon: '/static/images/6155/DeviceDetail/fan.png'
|
||||
},
|
||||
];
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1332,29 +1335,22 @@
|
||||
},
|
||||
|
||||
setMode(mode, type) {
|
||||
|
||||
let dataValue = 0;
|
||||
|
||||
|
||||
switch (mode) {
|
||||
case 0:
|
||||
|
||||
|
||||
if (type == 'main') {
|
||||
|
||||
dataValue = 0x01;
|
||||
} else if (type == 'fu') {
|
||||
|
||||
dataValue = 0x04;
|
||||
}
|
||||
|
||||
break;
|
||||
case 1:
|
||||
dataValue = 0x02;
|
||||
if (type == 'main') {
|
||||
dataValue = 0x02;
|
||||
} else if (type == 'fu') {
|
||||
dataValue = 0x0A; //强泛光
|
||||
}
|
||||
break;
|
||||
// case 2:
|
||||
// dataValue = 0x02;
|
||||
// break;
|
||||
case 2:
|
||||
dataValue = 0x03;
|
||||
break;
|
||||
@ -1363,7 +1359,7 @@
|
||||
break;
|
||||
|
||||
}
|
||||
// console.log("dataValue=", dataValue)
|
||||
console.log("dataValue=", dataValue)
|
||||
// 构建数据包
|
||||
var buffer = new ArrayBuffer(6);
|
||||
var dataView = new DataView(buffer);
|
||||
@ -1526,156 +1522,73 @@
|
||||
});
|
||||
this.setBleFormData();
|
||||
let task = async () => {
|
||||
var sendTxtPackge = (rgbdata, type, str) => {
|
||||
|
||||
var promise = new Promise((resolve, reject) => {
|
||||
try {
|
||||
// 设备协议:FA 06/07/08 01 00 + 256字节数据 + FF
|
||||
// 每个文本行只需要一个261字节的包
|
||||
const bufferSize = 261;
|
||||
const dataSize = 256; // 数据部分固定256字节
|
||||
|
||||
let buffer = new ArrayBuffer(bufferSize);
|
||||
let dataView = new DataView(buffer);
|
||||
|
||||
// 写入头部:FA 06/07/08 01 00
|
||||
dataView.setUint8(0, 0xFA);
|
||||
dataView.setUint8(1, type);
|
||||
dataView.setUint8(2, 0x01);
|
||||
dataView.setUint8(3, 0x00);
|
||||
|
||||
// 写入数据(最多256字节),确保数据是数字格式
|
||||
let actualDataSize = Math.min(rgbdata.length, dataSize);
|
||||
for (let i = 0; i < actualDataSize; i++) {
|
||||
// 确保数据是数字格式,如果是字符串则转换
|
||||
let byteValue = typeof rgbdata[i] === 'string' ? these.toByteValue(rgbdata[i]) : rgbdata[i];
|
||||
dataView.setUint8(4 + i, byteValue);
|
||||
}
|
||||
|
||||
// 用0填充剩余数据部分(如果数据不足256字节)
|
||||
for (let i = 4 + actualDataSize; i < bufferSize - 1; i++) {
|
||||
dataView.setUint8(i, 0x00);
|
||||
}
|
||||
|
||||
// 写入尾部:FF
|
||||
dataView.setUint8(bufferSize - 1, 0xFF);
|
||||
|
||||
console.log(`发送文本数据包: type=0x${type.toString(16)}, 数据长度=${actualDataSize}, 总长度=${bufferSize}`);
|
||||
|
||||
// 发送数据包
|
||||
ble.sendData(f.deviceId, buffer, f.writeServiceId, f
|
||||
.wirteCharactId, 100).then(() => {
|
||||
resolve();
|
||||
}).catch(err => {
|
||||
if (err.code == '10007') {
|
||||
// 重试
|
||||
setTimeout(() => {
|
||||
ble.sendData(f.deviceId, buffer, f.writeServiceId, f
|
||||
.wirteCharactId, 100).then(() => {
|
||||
resolve();
|
||||
}).catch(reject);
|
||||
}, 100);
|
||||
} else {
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
|
||||
} catch (ex) {
|
||||
console.log("构建数据包异常:", ex);
|
||||
reject(ex);
|
||||
}
|
||||
});
|
||||
|
||||
return promise;
|
||||
|
||||
}
|
||||
|
||||
console.log("11111");
|
||||
var result = null;
|
||||
try {
|
||||
console.log("this.$refs.textToHex=", this.$refs.textToHex);
|
||||
// 获取像素数据(组件内部会自动预热画布)
|
||||
result = await this.$refs.textToHex.drawAndGetPixels();
|
||||
} catch (ex) {
|
||||
console.log("获取画布数据异常:", ex);
|
||||
}
|
||||
if (!result) {
|
||||
hideLoading(this);
|
||||
return;
|
||||
}
|
||||
console.log("result=", result);
|
||||
result = result.map(level1 => {
|
||||
return level1.flat(Infinity).map(item => {
|
||||
// 确保数据转换为数字格式,避免字符串格式导致的问题
|
||||
return typeof item === 'string' ? these.toByteValue(item) : item;
|
||||
});
|
||||
});
|
||||
console.log("result=", result);
|
||||
// 预热画布,确保画布和字体完全准备好(解决APP重新打开后第一次获取数据不完整的问题)
|
||||
console.log("预热画布...");
|
||||
await this.$refs.textToHex.drawAndGetPixels();
|
||||
await new Promise(resolve => setTimeout(resolve, 200)); // 等待预热完成
|
||||
|
||||
// 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(',');
|
||||
// let arr2=('0x'+(str2.split(' ').join(",0x"))).split(',');
|
||||
// let arr3=('0x'+(str3.split(' ').join(",0x"))).split(',');
|
||||
|
||||
// result=[arr1,arr2,arr3];
|
||||
|
||||
|
||||
// console.log("result=",result);
|
||||
|
||||
|
||||
let h3dic = [0x06, 0x07, 0x08];
|
||||
let pros = [];
|
||||
let flag = true;
|
||||
// 在开始发送前添加延迟,确保数据完全准备好(解决第一次发送第一个字缺失的问题)
|
||||
await new Promise(resolve => setTimeout(resolve, 500));
|
||||
|
||||
for (var i = 0; i < result.length; i++) {
|
||||
|
||||
let str = this.formData.textLines[i];
|
||||
|
||||
if (str.length > 0) {
|
||||
|
||||
let width = str.length * 16;
|
||||
var rgb = result[i];
|
||||
|
||||
// 确保数据是数组且已转换
|
||||
if (!Array.isArray(rgb)) {
|
||||
console.error(`第${i+1}行数据格式错误:`, rgb);
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// 第一次发送前额外延迟,确保设备完全准备好
|
||||
if (i === 0) {
|
||||
console.log("准备发送第一个文本行,等待设备准备好...");
|
||||
await new Promise(resolve => setTimeout(resolve, 500));
|
||||
}
|
||||
|
||||
try {
|
||||
console.log(`开始发送第${i+1}个文本行 (type=0x${h3dic[i].toString(16)})`);
|
||||
await sendTxtPackge(rgb, h3dic[i], str);
|
||||
console.log(`第${i+1}个文本行发送完成`);
|
||||
|
||||
// 每个文本行发送完成后,添加延迟确保设备处理完成
|
||||
if (i < result.length - 1) {
|
||||
await new Promise(resolve => setTimeout(resolve, 300));
|
||||
}
|
||||
} catch (ex) {
|
||||
flag = false;
|
||||
console.error(`发送第${i+1}个文本行出现异常:`, ex);
|
||||
break;
|
||||
}
|
||||
// 1. 获取所有文本行的像素数据
|
||||
const allPixels = await this.$refs.textToHex.drawAndGetPixels();
|
||||
if (!allPixels) {
|
||||
throw new Error("无法生成像素数据");
|
||||
}
|
||||
|
||||
// 2. 将所有像素数据合并到一个大数组中
|
||||
let combinedData = [];
|
||||
for (let i = 0; i < 3; i++) {
|
||||
const linePixels = (allPixels[i] || []).flat(Infinity).map(item =>
|
||||
typeof item === 'string' ? these.toByteValue(item) : item
|
||||
);
|
||||
// 补齐到256字节
|
||||
while (linePixels.length < 256) {
|
||||
linePixels.push(0x00);
|
||||
}
|
||||
combinedData = combinedData.concat(linePixels.slice(0, 256));
|
||||
}
|
||||
|
||||
}
|
||||
// 3. 构建完整的逻辑大包
|
||||
const logicalPacketSize = 4 + combinedData.length + 1; // Header + Data + Footer
|
||||
const logicalBuffer = new ArrayBuffer(logicalPacketSize);
|
||||
const logicalDataView = new DataView(logicalBuffer);
|
||||
|
||||
hideLoading(these);
|
||||
if (flag) {
|
||||
console.log("发送成功");
|
||||
// 写入头部
|
||||
logicalDataView.setUint8(0, 0xFA);
|
||||
logicalDataView.setUint8(1, 0x06);
|
||||
logicalDataView.setUint8(2, 0x03);
|
||||
logicalDataView.setUint8(3, 0x00);
|
||||
|
||||
// 写入数据
|
||||
for (let i = 0; i < combinedData.length; i++) {
|
||||
logicalDataView.setUint8(4 + i, combinedData[i]);
|
||||
}
|
||||
|
||||
// 写入尾部
|
||||
logicalDataView.setUint8(logicalPacketSize - 1, 0xFF);
|
||||
|
||||
// 4. 将逻辑大包分包发送
|
||||
const CHUNK_SIZE = 20; // 每个物理包的大小
|
||||
const totalChunks = Math.ceil(logicalPacketSize / CHUNK_SIZE);
|
||||
|
||||
updateLoading(these, {
|
||||
text: `准备发送,共 ${totalChunks} 个数据包...`
|
||||
});
|
||||
|
||||
for (let i = 0; i < totalChunks; i++) {
|
||||
const start = i * CHUNK_SIZE;
|
||||
const end = Math.min(start + CHUNK_SIZE, logicalPacketSize);
|
||||
const chunk = logicalBuffer.slice(start, end);
|
||||
|
||||
updateLoading(these, {
|
||||
text: `正在发送 ${i + 1} / ${totalChunks}`
|
||||
});
|
||||
|
||||
await ble.sendData(f.deviceId, chunk, f.writeServiceId, f.wirteCharactId, 50);
|
||||
await new Promise(resolve => setTimeout(resolve, 50)); // 包之间延迟
|
||||
}
|
||||
|
||||
// 5. 发送成功处理
|
||||
hideLoading(these);
|
||||
this.showPop({
|
||||
message: "发送成功",
|
||||
iconUrl: "/static/images/6155/DeviceDetail/uploadSuccess.png",
|
||||
@ -1683,9 +1596,6 @@
|
||||
buttonBgColor: '#BBE600'
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
let json = {
|
||||
deviceId: these.device.id,
|
||||
name: these.formData.textLines[1],
|
||||
@ -1693,17 +1603,18 @@
|
||||
unitName: these.formData.textLines[2],
|
||||
code: ""
|
||||
};
|
||||
usrApi.sendUsr(json)
|
||||
} else {
|
||||
usrApi.sendUsr(json);
|
||||
|
||||
} catch (ex) {
|
||||
hideLoading(these);
|
||||
this.showPop({
|
||||
message: "出现异常发送失败",
|
||||
message: "发送失败: " + (ex.msg || ex.message),
|
||||
iconUrl: "/static/images/6155/DeviceDetail/uploadErr.png",
|
||||
borderColor: "#e034344d",
|
||||
buttonBgColor: "#E03434",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
setTimeout(task, 0);
|
||||
},
|
||||
getDetail() {
|
||||
|
||||
1947
pages/BlueTooth/ModeSetting/HBY6155.vue
Normal file
1947
pages/BlueTooth/ModeSetting/HBY6155.vue
Normal file
File diff suppressed because it is too large
Load Diff
1925
pages/BlueTooth/ModeSetting/HBY6155V1.vue
Normal file
1925
pages/BlueTooth/ModeSetting/HBY6155V1.vue
Normal file
File diff suppressed because it is too large
Load Diff
1892
pages/BlueTooth/ModeSetting/HBY650.vue
Normal file
1892
pages/BlueTooth/ModeSetting/HBY650.vue
Normal file
File diff suppressed because it is too large
Load Diff
1899
pages/BlueTooth/ModeSetting/HBY650_1.vue
Normal file
1899
pages/BlueTooth/ModeSetting/HBY650_1.vue
Normal file
File diff suppressed because it is too large
Load Diff
2837
pages/BlueTooth/ModeSetting/HBY670V1.vue
Normal file
2837
pages/BlueTooth/ModeSetting/HBY670V1.vue
Normal file
File diff suppressed because it is too large
Load Diff
1499
pages/BlueTooth/ModeSetting/ModeSetting.vue
Normal file
1499
pages/BlueTooth/ModeSetting/ModeSetting.vue
Normal file
File diff suppressed because it is too large
Load Diff
472
pages/BlueTooth/ModeSetting/VideoSend.vue
Normal file
472
pages/BlueTooth/ModeSetting/VideoSend.vue
Normal file
@ -0,0 +1,472 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<canvas canvas-id="flashCanvas"
|
||||
style="width: 160px; height: 80px; z-index: 9999;position: fixed; top:-9999px;left:-9999px;"></canvas>
|
||||
|
||||
<f-video ref="compARef" :src="videoPath" :direction="-90" :autoplay="true" @shotVideoClick="shotVideoClick"
|
||||
:videoWidth="videoWidth" :videoHeight="videoHeight"></f-video>
|
||||
|
||||
|
||||
<view>
|
||||
<text>发送间隔</text>
|
||||
<input type="text" v-model="inteval" />
|
||||
</view>
|
||||
<view>
|
||||
<button @click="checkVideo">选择视频</button>
|
||||
<!-- <button @click="CutImg">发送</button> -->
|
||||
<button @click="uploadVideo">发送</button>
|
||||
</view>
|
||||
|
||||
|
||||
<view class="sending-progress" v-if="isSending">
|
||||
<view class="progress-bar">
|
||||
<view class="progress-fill" :style="{ width: progress + '%' }"></view>
|
||||
</view>
|
||||
<text>正在发送: {{ progress }}% ({{ currentPacket }}/{{ totalPackets }})</text>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Common from '@/utils/Common';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
videoPath: '',
|
||||
inteval: 0,
|
||||
progress: 0,
|
||||
currentPacket: 0,
|
||||
totalPackets: 100,
|
||||
|
||||
connectedDeviceId: '',
|
||||
serviceId: '0xFFE1',
|
||||
writeCharacteristicId: '0xFFE1',
|
||||
notifyCharacteristicId: '0xFFE2',
|
||||
isSending: "",
|
||||
textProgress: "",
|
||||
|
||||
imgs: [],
|
||||
videoWidth: 320,
|
||||
videoHeight: 160,
|
||||
videoDuration: 2,
|
||||
|
||||
hexArray: []
|
||||
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
const eventChannel = this.getOpenerEventChannel();
|
||||
|
||||
eventChannel.on('receiveDevice', (data) => {
|
||||
this.connectedDeviceId = data.connectedDeviceId;
|
||||
this.serviceId = data.serviceId;
|
||||
this.writeCharacteristicId = data.writeCharacteristicId;
|
||||
this.notifyCharacteristicId = data.notifyCharacteristicId;
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
checkVideo: function() {
|
||||
uni.chooseVideo({
|
||||
sourceType: ['album', 'camera'],
|
||||
compressed: false,
|
||||
maxDuration: 2,
|
||||
camera: 'back',
|
||||
success: (res) => {
|
||||
this.videoPath = res.tempFilePath;
|
||||
|
||||
this.imgs = [];
|
||||
this.hexArray = [];
|
||||
this.$refs.compARef.base64 = [];
|
||||
this.videoWidth = res.width;
|
||||
this.videoHeight = res.height;
|
||||
this.videoDuration = res.duration;
|
||||
console.log("视频宽:" + res.width + ",视频高:" + res.height + ",视频时长:" + res.duration);
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
uploadVideo: function() {
|
||||
|
||||
if (this.hexArray.length > 0) {
|
||||
console.log("开始处理,无需上传");
|
||||
this.shotVideoClick(this.hexArray, 'rgb565');
|
||||
return;
|
||||
|
||||
}
|
||||
if(!this.videoPath){
|
||||
uni.showToast({
|
||||
title: "请选择视频",
|
||||
icon: 'fail'
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("正在上传视频");
|
||||
uni.showLoading({
|
||||
title: "上传中"
|
||||
});
|
||||
|
||||
let p2=new Promise((resolve,reject)=>{
|
||||
let start = new Date();
|
||||
console.log("Common.baseURL="+Common.baseURL);
|
||||
uni.uploadFile({
|
||||
url:Common.baseURL+'video/upload',
|
||||
filePath: this.videoPath,
|
||||
name: 'file',
|
||||
header: {
|
||||
"Method": "POST",
|
||||
"Content-Type": "multipart/form-data"
|
||||
},
|
||||
timeout: 600000,
|
||||
fail: (ex) => {
|
||||
//console.log("上传视频失败" + JSON.stringify(ex));
|
||||
uni.showToast({
|
||||
title: "视频文件上传失败了,请检查网络连接",
|
||||
icon: 'fail'
|
||||
})
|
||||
uni.hideLoading();
|
||||
reject(ex);
|
||||
},
|
||||
success: (res) => {
|
||||
let end = new Date();
|
||||
var diff = (end.getTime() - start.getTime()) / 1000;
|
||||
let s = diff % 60;
|
||||
let m = (diff - s) / 60;
|
||||
console.log("上传完成,耗时:" + m + "分" + s + "秒");
|
||||
uni.hideLoading();
|
||||
resolve(res);
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
let p1=this.HoldYouHand();
|
||||
|
||||
Promise.all([p2,p1]).then((arr)=>{
|
||||
|
||||
if(arr[1]===true){
|
||||
let res=arr[0];
|
||||
res = JSON.parse(res.data);
|
||||
|
||||
if (res.data) {
|
||||
this.hexArray = res.data;
|
||||
uni.showLoading({
|
||||
title: "正在发送"
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
this.shotVideoClick(res.data, 'rgb565');
|
||||
}, 0)
|
||||
|
||||
} else {
|
||||
console.log("res")
|
||||
uni.showModal({
|
||||
content: "服务器未返回RGB565数据",
|
||||
title: '错误'
|
||||
})
|
||||
}
|
||||
}else{
|
||||
uni.showModal({
|
||||
content:"与设备握手失败了",
|
||||
title:"错误"
|
||||
})
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
shotVideoClick: function(array, type) {
|
||||
//console.log("处理视频完成", array);
|
||||
//console.log("type=" + type)
|
||||
//console.log("array=", array);
|
||||
this.imgs = array;
|
||||
|
||||
|
||||
|
||||
var sendImagePackets = (imageData) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
this.isSending = true;
|
||||
this.progress = 0;
|
||||
this.currentPacket = 0;
|
||||
|
||||
// 总数据包数
|
||||
const totalPackets = 1536;
|
||||
this.totalPackets = totalPackets;
|
||||
let currentPacket = 1;
|
||||
|
||||
// 发送单个数据包
|
||||
const sendNextPacket = () => {
|
||||
////console.log("currentPacket="+currentPacket+",imageData.length="+imageData.length);
|
||||
if (currentPacket > totalPackets) {
|
||||
this.isSending = false;
|
||||
resolve();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 计算当前包的数据
|
||||
let packetSize = 250;
|
||||
if (type == 'rgb565') {
|
||||
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);
|
||||
|
||||
|
||||
if (type == 'rgb565') {
|
||||
for (let i = 0; i < packetData.length; i++) {
|
||||
dataView.setUint8(6 + i, '0x' + packetData[i]);
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < packetData.length; i++) {
|
||||
dataView.setUint16(6 + i * 2, packetData[i], false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let inteval = parseInt(this.inteval ? this.inteval : 0);
|
||||
this.sendData(buffer).then(() => {
|
||||
// 更新进度
|
||||
this.currentPacket = currentPacket;
|
||||
this.progress = Math.round((currentPacket / totalPackets) *
|
||||
100);
|
||||
//console.log(`发送数据包完成 ${currentPacket}/${totalPackets}`);
|
||||
|
||||
// 发送下一个包(添加延迟避免蓝牙缓冲区溢出)
|
||||
currentPacket++;
|
||||
|
||||
|
||||
setTimeout(sendNextPacket, inteval);
|
||||
}).catch(err => {
|
||||
|
||||
// console.log(err.errMsg + ",发送失败了,正在补偿:" + currentPacket);
|
||||
setTimeout(sendNextPacket, inteval);
|
||||
// uni.showToast({
|
||||
// title:"发送失败"+JSON.stringify(err)
|
||||
// })
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
sendNextPacket();
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (type == 'rgb565') {
|
||||
let start = new Date();
|
||||
console.log("开始发送");
|
||||
sendImagePackets(array).then(() => {
|
||||
console.log("发送完成");
|
||||
let end = new Date();
|
||||
var diff = (end.getTime() - start.getTime()) / 1000;
|
||||
let s = diff % 60;
|
||||
let m = (diff-s) / 60;
|
||||
console.log("发送完成,耗时:" + m + "分" + s + "秒");
|
||||
uni.showToast({
|
||||
title: "发送完成,耗时:" + m + "分" + s + "秒",
|
||||
icon: 'success'
|
||||
})
|
||||
}).catch((ex1) => {
|
||||
//console.log("出现了异常", ex1)
|
||||
}).finally(() => {
|
||||
uni.hideLoading();
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
HoldYouHand() {
|
||||
|
||||
var promise=new Promise((resolve,reject)=>{
|
||||
try{
|
||||
let start=new Date();
|
||||
var str = "video transmit start"; //握手的协议字符串
|
||||
console.log("开始握手:"+str)
|
||||
|
||||
// 1. 创建 ArrayBuffer 和 DataView
|
||||
const buffer = new ArrayBuffer(str.length);
|
||||
const dataView = new DataView(buffer);
|
||||
|
||||
// 2. 将字符串转换为 ASCII 码并写入 DataView
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
dataView.setUint8(i, str.charCodeAt(i));
|
||||
}
|
||||
//console.log("111111");
|
||||
this.sendData(buffer).then(() => {
|
||||
// 开始发送第一个包
|
||||
setTimeout(()=>{
|
||||
|
||||
let end = new Date();
|
||||
var diff = (end.getTime() - start.getTime()) / 1000;
|
||||
let s = diff % 60;
|
||||
let m = (diff - s) / 60;
|
||||
|
||||
console.log("握手成功并完成2200ms等待,耗时"+m+"分"+s+"秒");
|
||||
|
||||
resolve(true);
|
||||
}, 2200);
|
||||
|
||||
}).catch(err => {
|
||||
//console.log("握手没有成功");
|
||||
reject(err);
|
||||
});
|
||||
}catch(ex){
|
||||
reject(ex);
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
return promise;
|
||||
|
||||
},
|
||||
sendData(buffer) {
|
||||
////console.log("deviceId=" + this.connectedDeviceId);
|
||||
////console.log("serviceId=" + this.serviceId);
|
||||
|
||||
return new Promise(async (resolve, reject) => {
|
||||
|
||||
// //console.log("开始发送数据,buffer");
|
||||
|
||||
|
||||
var promise = new Promise((succ, err) => {
|
||||
uni.writeBLECharacteristicValue({
|
||||
deviceId: this.connectedDeviceId,
|
||||
serviceId: this.serviceId,
|
||||
characteristicId: this.writeCharacteristicId,
|
||||
value: buffer,
|
||||
writeType: plus.os.name == 'iOS' ? 'write' : 'writeNoResponse',
|
||||
success: () => {
|
||||
// //console.log("发送数据成功");
|
||||
succ();
|
||||
},
|
||||
fail: (ex) => {
|
||||
//console.log("发送数据失败", ex);
|
||||
err(ex);
|
||||
},
|
||||
complete: function() {
|
||||
// //console.log("123456");
|
||||
}
|
||||
});
|
||||
});
|
||||
if (plus.os.name == 'iOS') {
|
||||
|
||||
function timeout(ms) {
|
||||
return new Promise((_, err) => {
|
||||
setTimeout(() => {
|
||||
err({
|
||||
code: -1,
|
||||
errMsg: '超时了'
|
||||
})
|
||||
}, ms);
|
||||
});
|
||||
}
|
||||
|
||||
let inteval = parseInt(this.inteval ? this.inteval : 0);
|
||||
|
||||
Promise.race([promise, timeout(inteval)]).then(resolve).catch((ex) => {
|
||||
//console.log("ex=", ex);
|
||||
if (ex.code == -1) {
|
||||
resolve();
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
|
||||
}).finally(() => {
|
||||
//console.log("完成了")
|
||||
});
|
||||
} else {
|
||||
promise.then(resolve).catch(reject);
|
||||
}
|
||||
});
|
||||
},
|
||||
CutImg: function() {
|
||||
if (this.imgs.length == 30) {
|
||||
this.shotVideoClick(this.imgs, 'img');
|
||||
return;
|
||||
}
|
||||
//console.log("开始处理视频")
|
||||
uni.showLoading({
|
||||
title: '开始处理'
|
||||
});
|
||||
this.$refs.compARef.shotVideoClick(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.sending-progress {
|
||||
margin-top: 30rpx;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
height: 12rpx;
|
||||
background-color: #e0e0e0;
|
||||
border-radius: 6rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress-fill {
|
||||
height: 100%;
|
||||
background-color: #409eff;
|
||||
transition: width 0.3s;
|
||||
}
|
||||
|
||||
input {
|
||||
border: 2rpx solid #000000;
|
||||
}
|
||||
|
||||
button {
|
||||
height: 100rpx;
|
||||
line-height: 100rpx;
|
||||
font-size: 28rpx;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 100vw;
|
||||
height: 300px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
517
pages/BlueTooth/ModeSetting/VideoSend_1.vue
Normal file
517
pages/BlueTooth/ModeSetting/VideoSend_1.vue
Normal file
@ -0,0 +1,517 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<canvas canvas-id="flashCanvas"
|
||||
style="width: 160px; height: 80px; z-index: 9999;position: fixed; top:-9999px;left:-9999px;"></canvas>
|
||||
|
||||
<f-video ref="compARef" :src="videoPath" :direction="-90" :autoplay="true" @shotVideoClick="shotVideoClick"
|
||||
:videoWidth="videoWidth" :videoHeight="videoHeight"></f-video>
|
||||
|
||||
<view>
|
||||
<text>并发包数量</text>
|
||||
<input type="text" v-model="packgeCnt" />
|
||||
</view>
|
||||
<view>
|
||||
<text>发送间隔</text>
|
||||
<input type="text" v-model="inteval" />
|
||||
</view>
|
||||
<view>
|
||||
<button @click="checkVideo">选择视频</button>
|
||||
<!-- <button @click="CutImg">发送</button> -->
|
||||
<button @click="uploadVideo">发送</button>
|
||||
</view>
|
||||
|
||||
|
||||
<view class="sending-progress" v-if="isSending">
|
||||
<view class="progress-bar">
|
||||
<view class="progress-fill" :style="{ width: progress + '%' }"></view>
|
||||
</view>
|
||||
<text>正在发送: {{ progress }}% ({{ currentPacket }}/{{ totalPackets }})</text>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
videoPath: '',
|
||||
packgeCnt: 20,
|
||||
inteval: 0,
|
||||
progress: 0,
|
||||
currentPacket: 0,
|
||||
totalPackets: 100,
|
||||
|
||||
connectedDeviceId: '',
|
||||
serviceId: '0xFFE1',
|
||||
writeCharacteristicId: '0xFFE1',
|
||||
notifyCharacteristicId: '0xFFE2',
|
||||
isSending: "",
|
||||
textProgress: "",
|
||||
|
||||
imgs: [],
|
||||
videoWidth: 320,
|
||||
videoHeight: 160,
|
||||
videoDuration: 2,
|
||||
|
||||
hexArray: []
|
||||
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
const eventChannel = this.getOpenerEventChannel();
|
||||
|
||||
eventChannel.on('receiveDevice', (data) => {
|
||||
this.connectedDeviceId = data.connectedDeviceId;
|
||||
this.serviceId = data.serviceId;
|
||||
this.writeCharacteristicId = data.writeCharacteristicId;
|
||||
this.notifyCharacteristicId = data.notifyCharacteristicId;
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
checkVideo: function() {
|
||||
uni.chooseVideo({
|
||||
sourceType: ['album', 'camera'],
|
||||
compressed: false,
|
||||
maxDuration: 2,
|
||||
camera: 'back',
|
||||
success: (res) => {
|
||||
this.videoPath = res.tempFilePath;
|
||||
|
||||
this.imgs = [];
|
||||
this.hexArray = [];
|
||||
this.$refs.compARef.base64 = [];
|
||||
this.videoWidth = res.width;
|
||||
this.videoHeight = res.height;
|
||||
this.videoDuration = res.duration;
|
||||
console.log("视频宽:" + res.width + ",视频高:" + res.height + ",视频时长:" + res.duration);
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
uploadVideo: function() {
|
||||
|
||||
if (this.hexArray.length > 0) {
|
||||
console.log("开始处理,无需上传");
|
||||
this.shotVideoClick(this.hexArray, 'rgb565');
|
||||
return;
|
||||
|
||||
}
|
||||
if(!this.videoPath){
|
||||
uni.showToast({
|
||||
title: "请选择视频",
|
||||
icon: 'fail'
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("正在上传视频");
|
||||
uni.showLoading({
|
||||
title: "上传中"
|
||||
});
|
||||
|
||||
let p2=new Promise((resolve,reject)=>{
|
||||
console.log("Common.baseURL="+Common.baseURL);
|
||||
let start = new Date();
|
||||
uni.uploadFile({
|
||||
url: Common.baseURL+'video/upload',
|
||||
// url: 'http://192.168.110.169:5000/video/upload',
|
||||
filePath: this.videoPath,
|
||||
name: 'file',
|
||||
header: {
|
||||
"Method": "POST",
|
||||
"Content-Type": "multipart/form-data"
|
||||
},
|
||||
timeout: 600000,
|
||||
fail: (ex) => {
|
||||
//console.log("上传视频失败" + JSON.stringify(ex));
|
||||
uni.showToast({
|
||||
title: "视频文件上传失败了,请检查网络连接",
|
||||
icon: 'fail'
|
||||
})
|
||||
uni.hideLoading();
|
||||
reject(ex);
|
||||
},
|
||||
success: (res) => {
|
||||
let end = new Date();
|
||||
var diff = (end.getTime() - start.getTime()) / 1000;
|
||||
let s = diff % 60;
|
||||
let m = (diff - s) / 60;
|
||||
console.log("上传完成,耗时:" + m + "分" + s + "秒");
|
||||
uni.hideLoading();
|
||||
resolve(res);
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
let p1=this.HoldYouHand();
|
||||
|
||||
Promise.all([p2,p1]).then((arr)=>{
|
||||
if(arr[1]===true){
|
||||
let res=arr[0];
|
||||
res = JSON.parse(res.data);
|
||||
|
||||
if (res.data) {
|
||||
this.hexArray = res.data;
|
||||
uni.showLoading({
|
||||
title: "正在发送"
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
this.shotVideoClick(res.data, 'rgb565');
|
||||
}, 0)
|
||||
|
||||
} else {
|
||||
console.log("res")
|
||||
uni.showModal({
|
||||
content: "服务器未返回RGB565数据",
|
||||
title: '错误'
|
||||
})
|
||||
}
|
||||
}else{
|
||||
uni.showModal({
|
||||
content:"与设备握手失败了",
|
||||
title:"错误"
|
||||
})
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
pause(e) {
|
||||
////console.log('pause--------------------------', e);
|
||||
},
|
||||
shotVideoClick: function(array, type) {
|
||||
//console.log("处理视频完成", array);
|
||||
//console.log("type=" + type)
|
||||
//console.log("array=", array);
|
||||
this.imgs = array;
|
||||
|
||||
|
||||
|
||||
var sendImagePackets = (imageData) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
this.isSending = true;
|
||||
this.progress = 0;
|
||||
this.currentPacket = 0;
|
||||
|
||||
// 总数据包数
|
||||
const totalPackets = 1536;
|
||||
this.totalPackets = totalPackets;
|
||||
let currentPacket = 1;
|
||||
let promises = [];
|
||||
// 发送单个数据包
|
||||
const sendNextPacket = () => {
|
||||
////console.log("currentPacket="+currentPacket+",imageData.length="+imageData.length);
|
||||
if (currentPacket > totalPackets) {
|
||||
this.isSending = false;
|
||||
resolve();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 计算当前包的数据
|
||||
let packetSize = 250;
|
||||
if (type == 'rgb565') {
|
||||
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);
|
||||
|
||||
|
||||
if (type == 'rgb565') {
|
||||
for (let i = 0; i < packetData.length; i++) {
|
||||
dataView.setUint8(6 + i, '0x' + packetData[i]);
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < packetData.length; i++) {
|
||||
dataView.setUint16(6 + i * 2, packetData[i], false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let inteval = parseInt(this.inteval ? this.inteval : 0);
|
||||
let promise = this.sendData(buffer);
|
||||
promises.push(promise);
|
||||
let packgeCnt = parseInt(this.packgeCnt || 20);
|
||||
if (currentPacket % packgeCnt == 0 || (currentPacket >= totalPackets &&
|
||||
promises.length > 0)) {
|
||||
Promise.all(promises).then(() => {
|
||||
if (currentPacket >= totalPackets) {
|
||||
this.isSending = false;
|
||||
resolve();
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
this.currentPacket = currentPacket;
|
||||
this.progress = Math.round((currentPacket / totalPackets) *
|
||||
100);
|
||||
currentPacket++;
|
||||
setTimeout(sendNextPacket, inteval);
|
||||
})
|
||||
} else {
|
||||
currentPacket++;
|
||||
sendNextPacket();
|
||||
}
|
||||
// .then(() => {
|
||||
// // 更新进度
|
||||
// this.currentPacket = currentPacket;
|
||||
// this.progress = Math.round((currentPacket / totalPackets) *
|
||||
// 100);
|
||||
|
||||
// currentPacket++;
|
||||
|
||||
|
||||
// setTimeout(sendNextPacket, inteval);
|
||||
// }).catch(err => {
|
||||
|
||||
// console.log(err.errMsg+",发送失败了,正在补偿:" + currentPacket);
|
||||
// setTimeout(sendNextPacket, inteval);
|
||||
|
||||
// });
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
|
||||
sendNextPacket();
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (type == 'rgb565') {
|
||||
let start = new Date();
|
||||
console.log("开始发送");
|
||||
sendImagePackets(array).then(() => {
|
||||
|
||||
let end = new Date();
|
||||
|
||||
var diff = (end.getTime() - start.getTime()) / 1000;
|
||||
let s = diff % 60;
|
||||
let m = (diff - s) / 60;
|
||||
console.log("发送完成,耗时:" + m + "分" + s + "秒");
|
||||
uni.showToast({
|
||||
title: "发送完成,耗时:" + m + "分" + s + "秒",
|
||||
icon: 'success',
|
||||
|
||||
})
|
||||
}).catch((ex1) => {
|
||||
//console.log("出现了异常", ex1)
|
||||
}).finally(() => {
|
||||
uni.hideLoading();
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
HoldYouHand() {
|
||||
|
||||
var promise=new Promise((resolve,reject)=>{
|
||||
try{
|
||||
let start=new Date();
|
||||
var str = "video transmit start"; //握手的协议字符串
|
||||
console.log("开始握手:"+str)
|
||||
|
||||
// 1. 创建 ArrayBuffer 和 DataView
|
||||
const buffer = new ArrayBuffer(str.length);
|
||||
const dataView = new DataView(buffer);
|
||||
|
||||
// 2. 将字符串转换为 ASCII 码并写入 DataView
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
dataView.setUint8(i, str.charCodeAt(i));
|
||||
}
|
||||
//console.log("111111");
|
||||
this.sendData(buffer).then(() => {
|
||||
// 开始发送第一个包
|
||||
setTimeout(()=>{
|
||||
|
||||
let end = new Date();
|
||||
var diff = (end.getTime() - start.getTime()) / 1000;
|
||||
let s = diff % 60;
|
||||
let m = (diff - s) / 60;
|
||||
|
||||
console.log("握手成功并完成2200ms等待,耗时"+m+"分"+s+"秒");
|
||||
|
||||
resolve(true);
|
||||
}, 2200);
|
||||
|
||||
}).catch(err => {
|
||||
//console.log("握手没有成功");
|
||||
reject(err);
|
||||
});
|
||||
}catch(ex){
|
||||
reject(ex);
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
return promise;
|
||||
|
||||
},
|
||||
sendData(buffer) {
|
||||
let sendBuffer = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
var promise = new Promise((succ, err) => {
|
||||
uni.writeBLECharacteristicValue({
|
||||
deviceId: this.connectedDeviceId,
|
||||
serviceId: this.serviceId,
|
||||
characteristicId: this.writeCharacteristicId,
|
||||
value: buffer,
|
||||
writeType: plus.os.name == 'iOS' ? 'write' : 'writeNoResponse',
|
||||
success: () => {
|
||||
// console.log("发送数据成功");
|
||||
succ();
|
||||
},
|
||||
fail: (ex) => {
|
||||
if (ex.code == '10007') {
|
||||
// console.log("失败重试");
|
||||
setTimeout(() => {
|
||||
sendBuffer().then(succ).catch(err);
|
||||
}, this.inteval || 0)
|
||||
// succ()
|
||||
|
||||
} else
|
||||
|
||||
{
|
||||
// console.log("发送数据失败",ex);
|
||||
err(ex);
|
||||
}
|
||||
},
|
||||
complete: function() {
|
||||
//console.log("123456");
|
||||
}
|
||||
});
|
||||
});
|
||||
if (plus.os.name == 'iOS') {
|
||||
|
||||
function timeout(ms) {
|
||||
return new Promise((_, err) => {
|
||||
setTimeout(() => {
|
||||
err({
|
||||
code: -1,
|
||||
errMsg: '超时了'
|
||||
})
|
||||
}, ms);
|
||||
});
|
||||
}
|
||||
|
||||
Promise.race([promise, timeout(this.inteval ? this.inteval : 0)]).then(() => {
|
||||
// console.log("成功了");
|
||||
resolve();
|
||||
})
|
||||
.catch((ex) => {
|
||||
|
||||
if (ex.code == -1) {
|
||||
// console.log("超时了")
|
||||
resolve();
|
||||
} else {
|
||||
reject(ex);
|
||||
// console.log("异常了", ex);
|
||||
//sendBuffer().then(resolve).catch(reject);
|
||||
}
|
||||
|
||||
});
|
||||
} else {
|
||||
|
||||
promise.then(() => {
|
||||
//console.log("then........")
|
||||
resolve();
|
||||
}).catch(() => {
|
||||
//console.log("catch.........")
|
||||
reject()
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return sendBuffer();
|
||||
},
|
||||
CutImg: function() {
|
||||
if (this.imgs.length == 30) {
|
||||
this.shotVideoClick(this.imgs, 'img');
|
||||
return;
|
||||
}
|
||||
//console.log("开始处理视频")
|
||||
uni.showLoading({
|
||||
title: '开始处理'
|
||||
});
|
||||
this.$refs.compARef.shotVideoClick(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.sending-progress {
|
||||
margin-top: 30rpx;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
height: 12rpx;
|
||||
background-color: #e0e0e0;
|
||||
border-radius: 6rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress-fill {
|
||||
height: 100%;
|
||||
background-color: #409eff;
|
||||
transition: width 0.3s;
|
||||
}
|
||||
|
||||
input {
|
||||
border: 2rpx solid #000000;
|
||||
}
|
||||
|
||||
button {
|
||||
height: 100rpx;
|
||||
line-height: 100rpx;
|
||||
font-size: 28rpx;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 100vw;
|
||||
height: 300px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
537
pages/BlueTooth/ModeSetting/VideoSend_670.vue
Normal file
537
pages/BlueTooth/ModeSetting/VideoSend_670.vue
Normal file
@ -0,0 +1,537 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<canvas canvas-id="flashCanvas"
|
||||
style="width: 160px; height: 80px; z-index: 9999;position: fixed; top:-9999px;left:-9999px;"></canvas>
|
||||
|
||||
<view>
|
||||
<view>
|
||||
选择的视频:{{videoPath}}</view>
|
||||
</view>
|
||||
<view>
|
||||
重发包序号:{{reSendNumber}}
|
||||
</view>
|
||||
<view>
|
||||
<text>发送间隔</text>
|
||||
<input type="text" v-model="inteval" />
|
||||
</view>
|
||||
<view>
|
||||
<button @click="checkVideo">选择视频</button>
|
||||
|
||||
<button @click="uploadVideo">发送</button>
|
||||
</view>
|
||||
|
||||
|
||||
<view class="sending-progress" v-if="isSending">
|
||||
<view class="progress-bar">
|
||||
<view class="progress-fill" :style="{ width: progress + '%' }"></view>
|
||||
</view>
|
||||
<text>正在发送: {{ progress }}% ({{ currentPacket }}/{{ totalPackets }})</text>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Common from '../../../utils/Common';
|
||||
var mqttClient=null;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
videoPath: '',
|
||||
inteval: 0,
|
||||
progress: 0,
|
||||
currentPacket: 0,
|
||||
totalPackets: 100,
|
||||
|
||||
connectedDeviceId: '',
|
||||
serviceId: '0xFFE1',
|
||||
writeCharacteristicId: '0xFFE1',
|
||||
notifyCharacteristicId: '0xFFE2',
|
||||
isSending: "",
|
||||
textProgress: "",
|
||||
netMode:"ble",
|
||||
IMEI:"",
|
||||
|
||||
|
||||
imgs: [],
|
||||
videoWidth: 320,
|
||||
videoHeight: 160,
|
||||
videoDuration: 2,
|
||||
|
||||
hexArray: [],
|
||||
reSendNumber:""
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
const eventChannel = this.getOpenerEventChannel();
|
||||
|
||||
eventChannel.on('receiveDevice', (data) => {
|
||||
this.connectedDeviceId = data.connectedDeviceId;
|
||||
this.serviceId = data.serviceId;
|
||||
this.writeCharacteristicId = data.writeCharacteristicId;
|
||||
this.notifyCharacteristicId = data.notifyCharacteristicId;
|
||||
this.netMode=data.netMode;
|
||||
mqttClient=data.mqttClient;
|
||||
this.IMEI=data.IMEI;
|
||||
});
|
||||
|
||||
eventChannel.on('ReSendVideo',(data)=>{
|
||||
//重新发送某一包
|
||||
this.reSendNumber=data.videoNo;
|
||||
setTimeout(()=>{
|
||||
this.shotVideoClick(this.hexArray,'rgb565',data.videoNo);
|
||||
},0);
|
||||
|
||||
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
checkVideo: function() {
|
||||
uni.chooseVideo({
|
||||
sourceType: ['album', 'camera'],
|
||||
compressed: false,
|
||||
maxDuration: 2,
|
||||
camera: 'back',
|
||||
success: (res) => {
|
||||
this.videoPath = res.tempFilePath;
|
||||
|
||||
this.imgs = [];
|
||||
this.hexArray = [];
|
||||
|
||||
this.videoWidth = res.width;
|
||||
this.videoHeight = res.height;
|
||||
this.videoDuration = res.duration;
|
||||
console.log("视频宽:" + res.width + ",视频高:" + res.height + ",视频时长:" + res.duration);
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
uploadVideo: function() {
|
||||
|
||||
if (this.hexArray.length > 0) {
|
||||
console.log("开始处理,无需上传");
|
||||
this.shotVideoClick(this.hexArray, 'rgb565');
|
||||
return;
|
||||
|
||||
}
|
||||
if(!this.videoPath){
|
||||
uni.showToast({
|
||||
title: "请选择视频",
|
||||
icon: 'fail'
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("正在上传视频");
|
||||
uni.showLoading({
|
||||
title: "上传中"
|
||||
});
|
||||
|
||||
let p2=new Promise((resolve,reject)=>{
|
||||
let start = new Date();
|
||||
console.log("Common.baseURL="+Common.baseURL);
|
||||
uni.uploadFile({
|
||||
url:Common.baseURL+'video/upload',
|
||||
filePath: this.videoPath,
|
||||
name: 'file',
|
||||
header: {
|
||||
"Method": "POST",
|
||||
"Content-Type": "multipart/form-data"
|
||||
},
|
||||
timeout: 600000,
|
||||
fail: (ex) => {
|
||||
//console.log("上传视频失败" + JSON.stringify(ex));
|
||||
uni.showToast({
|
||||
title: "视频文件上传失败了,请检查网络连接",
|
||||
icon: 'fail'
|
||||
})
|
||||
uni.hideLoading();
|
||||
reject(ex);
|
||||
},
|
||||
success: (res) => {
|
||||
let end = new Date();
|
||||
var diff = (end.getTime() - start.getTime()) / 1000;
|
||||
let s = diff % 60;
|
||||
let m = (diff - s) / 60;
|
||||
console.log("上传完成,耗时:" + m + "分" + s + "秒");
|
||||
uni.hideLoading();
|
||||
resolve(res);
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
let p1=this.HoldYouHand();
|
||||
|
||||
Promise.all([p2,p1]).then((arr)=>{
|
||||
|
||||
if(arr[1]===true){
|
||||
let res=arr[0];
|
||||
res = JSON.parse(res.data);
|
||||
|
||||
if (res.data) {
|
||||
this.hexArray = res.data;
|
||||
uni.showLoading({
|
||||
title: "正在发送"
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
this.shotVideoClick(res.data, 'rgb565');
|
||||
}, 0)
|
||||
|
||||
} else {
|
||||
console.log("res")
|
||||
uni.showModal({
|
||||
content: "服务器未返回RGB565数据",
|
||||
title: '错误'
|
||||
})
|
||||
}
|
||||
}else{
|
||||
uni.showModal({
|
||||
content:"与设备握手失败了",
|
||||
title:"错误"
|
||||
})
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
shotVideoClick: function(array, type,ReSendNo) {
|
||||
//console.log("处理视频完成", array);
|
||||
//console.log("type=" + type)
|
||||
//console.log("array=", array);
|
||||
this.imgs = array;
|
||||
|
||||
|
||||
|
||||
var sendImagePackets = (imageData) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
this.isSending = true;
|
||||
this.progress = 0;
|
||||
this.currentPacket = 0;
|
||||
|
||||
// 总数据包数
|
||||
var totalPackets = 1536;
|
||||
this.totalPackets = totalPackets;
|
||||
let currentPacket = 1;
|
||||
if(ReSendNo){
|
||||
this.progress = ReSendNo-1;
|
||||
this.currentPacket = ReSendNo-1;
|
||||
currentPacket=ReSendNo;
|
||||
totalPackets=ReSendNo;
|
||||
this.totalPackets=ReSendNo;
|
||||
}
|
||||
// 发送单个数据包
|
||||
const sendNextPacket = () => {
|
||||
////console.log("currentPacket="+currentPacket+",imageData.length="+imageData.length);
|
||||
if (currentPacket > totalPackets) {
|
||||
this.isSending = false;
|
||||
if(!ReSendNo){
|
||||
this.bleSendComplete();
|
||||
}else{
|
||||
// this.reSendNumber="";
|
||||
}
|
||||
|
||||
resolve();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 计算当前包的数据
|
||||
let packetSize = 250;
|
||||
if (type == 'rgb565') {
|
||||
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);
|
||||
|
||||
|
||||
if (type == 'rgb565') {
|
||||
for (let i = 0; i < packetData.length; i++) {
|
||||
dataView.setUint8(6 + i, '0x' + packetData[i]);
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < packetData.length; i++) {
|
||||
dataView.setUint16(6 + i * 2, packetData[i], false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let inteval = parseInt(this.inteval ? this.inteval : 0);
|
||||
this.sendData(buffer).then(() => {
|
||||
// 更新进度
|
||||
this.currentPacket = currentPacket;
|
||||
this.progress = Math.round((currentPacket / totalPackets) *
|
||||
100);
|
||||
console.log(`发送数据包完成 ${currentPacket}/${totalPackets}`);
|
||||
|
||||
// 发送下一个包(添加延迟避免蓝牙缓冲区溢出)
|
||||
currentPacket++;
|
||||
|
||||
|
||||
setTimeout(sendNextPacket, inteval);
|
||||
}).catch(err => {
|
||||
|
||||
console.log(err.errMsg + ",发送失败了,正在补偿:" + currentPacket);
|
||||
setTimeout(sendNextPacket, inteval);
|
||||
// uni.showToast({
|
||||
// title:"发送失败"+JSON.stringify(err)
|
||||
// })
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
sendNextPacket();
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (type == 'rgb565') {
|
||||
let start = new Date();
|
||||
console.log("开始发送");
|
||||
sendImagePackets(array).then(() => {
|
||||
console.log("发送完成");
|
||||
let end = new Date();
|
||||
var diff = (end.getTime() - start.getTime()) / 1000;
|
||||
let s = diff % 60;
|
||||
let m = (diff-s) / 60;
|
||||
console.log("发送完成,耗时:" + m + "分" + s + "秒");
|
||||
uni.showModal({
|
||||
content: "发送完成,耗时:" + m + "分" + s + "秒",
|
||||
title: 'success'
|
||||
});
|
||||
|
||||
}).catch((ex1) => {
|
||||
console.log("出现了异常", ex1)
|
||||
}).finally(() => {
|
||||
uni.hideLoading();
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
HoldYouHand() {
|
||||
|
||||
var promise=new Promise((resolve,reject)=>{
|
||||
try{
|
||||
let start=new Date();
|
||||
var str = "video transmit start"; //握手的协议字符串
|
||||
console.log("开始握手:"+str)
|
||||
|
||||
// 1. 创建 ArrayBuffer 和 DataView
|
||||
const buffer = new ArrayBuffer(str.length);
|
||||
const dataView = new DataView(buffer);
|
||||
|
||||
// 2. 将字符串转换为 ASCII 码并写入 DataView
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
dataView.setUint8(i, str.charCodeAt(i));
|
||||
}
|
||||
//console.log("111111");
|
||||
this.sendData(buffer).then(() => {
|
||||
// 开始发送第一个包
|
||||
setTimeout(()=>{
|
||||
|
||||
let end = new Date();
|
||||
var diff = (end.getTime() - start.getTime()) / 1000;
|
||||
let s = diff % 60;
|
||||
let m = (diff - s) / 60;
|
||||
|
||||
console.log("握手成功并完成2200ms等待,耗时"+m+"分"+s+"秒");
|
||||
|
||||
resolve(true);
|
||||
}, 2200);
|
||||
|
||||
}).catch(err => {
|
||||
//console.log("握手没有成功");
|
||||
reject(err);
|
||||
});
|
||||
}catch(ex){
|
||||
reject(ex);
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
return promise;
|
||||
|
||||
},
|
||||
bleSendComplete() {
|
||||
var str = "transmit complete"; //握手的协议字符串
|
||||
let buffer = new ArrayBuffer(str.length);
|
||||
let dataView = new DataView(buffer);
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
dataView.setUint8(i, str.charCodeAt(i));
|
||||
}
|
||||
setTimeout(()=>{
|
||||
this.sendData(buffer).then(() => {
|
||||
console.log("完成指令发送成功");
|
||||
}).catch(err => {
|
||||
console.log("完成指令发送失败");
|
||||
});
|
||||
},1500)
|
||||
|
||||
},
|
||||
sendData(buffer) {
|
||||
if(this.netMode=='ble'){
|
||||
return this.sendBle(buffer);
|
||||
|
||||
}
|
||||
|
||||
return this.sendMQ(buffer);
|
||||
},
|
||||
sendBle(buffer){
|
||||
return new Promise(async (resolve, reject) => {
|
||||
|
||||
// //console.log("开始发送数据,buffer");
|
||||
|
||||
|
||||
var promise = new Promise((succ, err) => {
|
||||
uni.writeBLECharacteristicValue({
|
||||
deviceId: this.connectedDeviceId,
|
||||
serviceId: this.serviceId,
|
||||
characteristicId: this.writeCharacteristicId,
|
||||
value: buffer,
|
||||
writeType: plus.os.name == 'iOS' ? 'write' : 'writeNoResponse',
|
||||
success: () => {
|
||||
// //console.log("发送数据成功");
|
||||
succ();
|
||||
},
|
||||
fail: (ex) => {
|
||||
//console.log("发送数据失败", ex);
|
||||
err(ex);
|
||||
},
|
||||
complete: function() {
|
||||
// //console.log("123456");
|
||||
}
|
||||
});
|
||||
});
|
||||
if (plus.os.name == 'iOS') {
|
||||
|
||||
function timeout(ms) {
|
||||
return new Promise((_, err) => {
|
||||
setTimeout(() => {
|
||||
err({
|
||||
code: -1,
|
||||
errMsg: '超时了'
|
||||
})
|
||||
}, ms);
|
||||
});
|
||||
}
|
||||
|
||||
let inteval = parseInt(this.inteval ? this.inteval : 0);
|
||||
|
||||
Promise.race([promise, timeout(inteval)]).then(resolve).catch((ex) => {
|
||||
//console.log("ex=", ex);
|
||||
if (ex.code == -1) {
|
||||
resolve();
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
|
||||
}).finally(() => {
|
||||
//console.log("完成了")
|
||||
});
|
||||
} else {
|
||||
promise.then(resolve).catch(reject);
|
||||
}
|
||||
});
|
||||
},
|
||||
sendMQ(message) {
|
||||
|
||||
const topic = `B/${this.IMEI}`;
|
||||
return new Promise((resolve, reject) => {
|
||||
if(!mqttClient){
|
||||
reject("MQTT未连接");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
let flag=mqttClient.publish(topic, message, {
|
||||
qos: 1
|
||||
});
|
||||
if(flag){
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
reject("MQTT未连接,无法发布消息");
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.sending-progress {
|
||||
margin-top: 30rpx;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
height: 12rpx;
|
||||
background-color: #e0e0e0;
|
||||
border-radius: 6rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress-fill {
|
||||
height: 100%;
|
||||
background-color: #409eff;
|
||||
transition: width 0.3s;
|
||||
}
|
||||
|
||||
input {
|
||||
border: 2rpx solid #000000;
|
||||
}
|
||||
|
||||
button {
|
||||
height: 100rpx;
|
||||
line-height: 100rpx;
|
||||
font-size: 28rpx;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 100vw;
|
||||
height: 300px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
115
pages/BlueTooth/ModeSetting/index.vue
Normal file
115
pages/BlueTooth/ModeSetting/index.vue
Normal file
@ -0,0 +1,115 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="grid">
|
||||
<view class="cell" @click="goToDetail(item.name)" v-for="item,index in options">{{item.url}}</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
options: [{
|
||||
name: '/pages/BlueTooth/ModeSetting/ModeSetting',
|
||||
url: '7307'
|
||||
},
|
||||
{
|
||||
name: '/pages/BlueTooth/ModeSetting/HBY650',
|
||||
url: 'HBY650'
|
||||
},
|
||||
{
|
||||
name: '/pages/BlueTooth/ModeSetting/HBY650_1',
|
||||
url: 'HBY650_V1'
|
||||
},
|
||||
|
||||
{
|
||||
name: '/pages/BlueTooth/ModeSetting/HBY6155',
|
||||
url: '6155'
|
||||
},
|
||||
{
|
||||
name: '/pages/BlueTooth/ModeSetting/HBY6155V1',
|
||||
url: '6155_V1'
|
||||
},
|
||||
{
|
||||
name: "/pages/BlueTooth/ModeSetting/HBY670V1",
|
||||
url: 'HBY670'
|
||||
},
|
||||
|
||||
{
|
||||
name: '/pages/MapTest/MapTest',
|
||||
url: '地图测试'
|
||||
},
|
||||
{
|
||||
name: '',
|
||||
url: '更多'
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
}
|
||||
},
|
||||
onShow: () => {
|
||||
|
||||
},
|
||||
methods: {
|
||||
goToDetail: function(url) {
|
||||
console.log("url=" + url)
|
||||
let qd = () => {
|
||||
uni.showToast({
|
||||
title: '敬请期待',
|
||||
duration: 2000,
|
||||
icon: "none"
|
||||
});
|
||||
|
||||
};
|
||||
if (url) {
|
||||
uni.navigateTo({
|
||||
url: url,
|
||||
success: () => {
|
||||
|
||||
},
|
||||
fail: () => {
|
||||
qd();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
qd();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
padding: 15px;
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: flex;
|
||||
align-content: space-around;
|
||||
align-items: stretch;
|
||||
justify-items: center;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.cell {
|
||||
padding: 0rpx 20rpx;
|
||||
border: 2rpx solid rgba(0, 0, 0, 0.3);
|
||||
border-radius: 15rpx;
|
||||
font-size: 28rpx;
|
||||
height: 70rpx;
|
||||
line-height: 70rpx;
|
||||
margin-left: 30rpx;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
</style>
|
||||
273
pages/BlueTooth/ModeSetting/update.vue
Normal file
273
pages/BlueTooth/ModeSetting/update.vue
Normal file
@ -0,0 +1,273 @@
|
||||
<template>
|
||||
<view class="update-container">
|
||||
<!-- 进度条 -->
|
||||
<view v-if="showProgress" class="progress-container">
|
||||
<view class="progress-title">正在更新 {{ progress }}%</view>
|
||||
<view class="progress-bar">
|
||||
<view class="progress" :style="{ width: progress + '%' }"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 更新提示弹窗 -->
|
||||
<view v-if="showUpdateDialog" class="dialog-mask">
|
||||
<view class="dialog">
|
||||
<view class="dialog-title">发现新版本 v{{ newVersion }}</view>
|
||||
<view class="dialog-content">{{ updateInfo.desc || '有新的功能和优化,建议立即更新' }}</view>
|
||||
<view class="dialog-buttons">
|
||||
<button v-if="!updateInfo.force" class="cancel-btn" @click="showUpdateDialog = false">稍后更新</button>
|
||||
<button class="confirm-btn" @click="startUpdate">立即更新</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 当前版本
|
||||
currentVersion: '',
|
||||
// 最新版本
|
||||
newVersion: '',
|
||||
// 更新信息
|
||||
updateInfo: {},
|
||||
// 是否显示更新弹窗
|
||||
showUpdateDialog: false,
|
||||
// 是否显示进度条
|
||||
showProgress: false,
|
||||
// 更新进度
|
||||
progress: 0
|
||||
};
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
// 初始化时检查版本
|
||||
this.checkVersion();
|
||||
},
|
||||
|
||||
methods: {
|
||||
/**
|
||||
* 检查当前版本
|
||||
*/
|
||||
async checkVersion() {
|
||||
try {
|
||||
// 获取当前应用版本
|
||||
const versionInfo = plus.runtime.version;
|
||||
this.currentVersion = versionInfo;
|
||||
console.log('当前版本:', this.currentVersion);
|
||||
|
||||
// 调用后端接口检查最新版本
|
||||
// 这里替换为你的后端接口地址
|
||||
const res = await this.$http.get('/api/checkVersion', {
|
||||
platform: uni.getSystemInfoSync().platform,
|
||||
version: this.currentVersion
|
||||
});
|
||||
|
||||
if (res.code === 0 && res.data.hasUpdate) {
|
||||
this.newVersion = res.data.version;
|
||||
this.updateInfo = res.data;
|
||||
// 显示更新提示
|
||||
this.showUpdateDialog = true;
|
||||
} else {
|
||||
console.log('当前已是最新版本');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('版本检查失败:', error);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 开始更新
|
||||
*/
|
||||
startUpdate() {
|
||||
if (!this.updateInfo.downloadUrl) {
|
||||
uni.showToast({
|
||||
title: '更新地址不存在',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this.showUpdateDialog = false;
|
||||
this.showProgress = true;
|
||||
this.downloadWgt(this.updateInfo.downloadUrl);
|
||||
},
|
||||
|
||||
/**
|
||||
* 下载wgt包
|
||||
*/
|
||||
downloadWgt(url) {
|
||||
const downloadTask = uni.downloadFile({
|
||||
url: url,
|
||||
success: (downloadResult) => {
|
||||
if (downloadResult.statusCode === 200) {
|
||||
// 下载成功,安装wgt包
|
||||
this.installWgt(downloadResult.tempFilePath);
|
||||
} else {
|
||||
this.showProgress = false;
|
||||
uni.showToast({
|
||||
title: '下载失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
this.showProgress = false;
|
||||
console.error('下载失败:', err);
|
||||
uni.showToast({
|
||||
title: '下载失败,请稍后重试',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 监听下载进度
|
||||
downloadTask.onProgressUpdate((res) => {
|
||||
this.progress = res.progress;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 安装wgt包
|
||||
*/
|
||||
installWgt(path) {
|
||||
plus.runtime.install(
|
||||
path,
|
||||
{
|
||||
force: false // 是否强制安装
|
||||
},
|
||||
() => {
|
||||
console.log('安装成功');
|
||||
this.showProgress = false;
|
||||
|
||||
// 安装成功后提示重启
|
||||
uni.showModal({
|
||||
title: '更新完成',
|
||||
content: '应用已更新,是否立即重启?',
|
||||
showCancel: !this.updateInfo.force,
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
// 重启应用
|
||||
plus.runtime.restart();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
(err) => {
|
||||
console.error('安装失败:', err);
|
||||
this.showProgress = false;
|
||||
uni.showToast({
|
||||
title: '更新失败: ' + err.message,
|
||||
icon: 'none',
|
||||
duration: 3000
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.update-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
/* 进度条样式 */
|
||||
.progress-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
padding: 10rpx 20rpx;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.progress-title {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
margin-bottom: 10rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
height: 8rpx;
|
||||
background-color: #eee;
|
||||
border-radius: 4rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress {
|
||||
height: 100%;
|
||||
background-color: #007aff;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
|
||||
/* 弹窗样式 */
|
||||
.dialog-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.dialog {
|
||||
width: 600rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 16rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.dialog-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
padding: 30rpx;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.dialog-content {
|
||||
font-size: 32rpx;
|
||||
color: #666;
|
||||
padding: 40rpx 30rpx;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.dialog-buttons {
|
||||
display: flex;
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
|
||||
.cancel-btn, .confirm-btn {
|
||||
flex: 1;
|
||||
height: 100rpx;
|
||||
line-height: 100rpx;
|
||||
font-size: 32rpx;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.cancel-btn {
|
||||
color: #666;
|
||||
border-right: 1px solid #eee;
|
||||
}
|
||||
|
||||
.confirm-btn {
|
||||
color: #007aff;
|
||||
}
|
||||
</style>
|
||||
@ -165,16 +165,19 @@
|
||||
},
|
||||
|
||||
onUnload() {
|
||||
ble.StopSearch();
|
||||
ble.removeAllCallback(pagePath);
|
||||
|
||||
if (ble) {
|
||||
ble.StopSearch();
|
||||
ble.removeAllCallback(pagePath);
|
||||
}
|
||||
},
|
||||
onLoad(option) {
|
||||
let search = option.search;
|
||||
ble = bleTool.getBleTool();
|
||||
these = this;
|
||||
eventChannel = this.getOpenerEventChannel();
|
||||
const systemInfo = uni.getSystemInfoSync();
|
||||
|
||||
ble = bleTool.getBleTool(); // Ensure ble is initialized
|
||||
|
||||
if (systemInfo.uniPlatform == 'web') {
|
||||
|
||||
|
||||
@ -217,7 +220,9 @@
|
||||
}
|
||||
let StartSubsrib = () => {
|
||||
these.EquipMents = [];
|
||||
|
||||
if (!ble) {
|
||||
ble = bleTool.getBleTool();
|
||||
}
|
||||
//蓝牙不可用的回调
|
||||
ble.addStateBreakCallback(res => {
|
||||
if (these.Status.isPageHidden) {
|
||||
@ -234,19 +239,6 @@
|
||||
these.showOpenSetting();
|
||||
|
||||
}, pagePath);
|
||||
//蓝牙再次可用的回调
|
||||
ble.addStateRecoveryCallback(res => {
|
||||
if (these.Status.isPageHidden) {
|
||||
return;
|
||||
}
|
||||
uni.showToast({
|
||||
icon: 'success',
|
||||
title: '蓝牙恢复可用'
|
||||
});
|
||||
these.Status.BottomMenu.show = false;
|
||||
these.EquipMents = [];
|
||||
these.refreshBleList();
|
||||
}, pagePath);
|
||||
|
||||
//蓝牙断开连接的回调
|
||||
ble.addDisposeCallback(res => {
|
||||
@ -263,109 +255,113 @@
|
||||
|
||||
|
||||
}, pagePath);
|
||||
//蓝牙连接已恢复的回调
|
||||
ble.addRecoveryCallback(res => {
|
||||
|
||||
// --- Start: Logic for Pairing Mode Only ---
|
||||
if (these.device) {
|
||||
console.log("进入配对模式,启用连接恢复和验证逻辑。");
|
||||
//蓝牙连接已恢复的回调
|
||||
ble.addRecoveryCallback(res => {
|
||||
if (these.Status.isPageHidden) {
|
||||
return;
|
||||
}
|
||||
// hideLoading(these);
|
||||
these.EquipMents.find(function(v, ind) {
|
||||
if (v.deviceId == res.deviceId) {
|
||||
these.PairEquip.push(v);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (these.device) {
|
||||
clearInterval(this.Status.intval);
|
||||
showLoading(these, {
|
||||
text: '蓝牙连接已恢复,正在验证设备'
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
these.DeviceVerdict(res.deviceId);
|
||||
}, 0);
|
||||
} else {
|
||||
hideLoading(these);
|
||||
}
|
||||
|
||||
|
||||
}, pagePath);
|
||||
|
||||
//收到设备的消息回调
|
||||
ble.addReceiveCallback((receivData, f, path, arr) => {
|
||||
if (these.Status.isPageHidden) {
|
||||
return;
|
||||
}
|
||||
if (f.macAddress && these.device) {
|
||||
clearInterval(this.Status.intval);
|
||||
this.Status.intval = null;
|
||||
this.Status.time = null;
|
||||
|
||||
showLoading(these, {
|
||||
text: '正在验证设备'
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
these.DeviceVerdict(f.deviceId);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
|
||||
}, pagePath);
|
||||
}
|
||||
// --- End: Logic for Pairing Mode Only ---
|
||||
|
||||
//搜索到新设备的回调 (Always active)
|
||||
ble.addDeviceFound((arr) => {
|
||||
console.log("--- 收到原始扫描数据 ---", JSON.stringify(arr));
|
||||
if (these.Status.isPageHidden) {
|
||||
return;
|
||||
}
|
||||
// hideLoading(these);
|
||||
these.EquipMents.find(function(v, ind) {
|
||||
if (v.deviceId == res.deviceId) {
|
||||
these.PairEquip.push(v);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (these.device) {
|
||||
clearInterval(this.Status.intval);
|
||||
showLoading(these, {
|
||||
text: '蓝牙连接已恢复,正在验证设备'
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
these.DeviceVerdict(res.deviceId);
|
||||
}, 0);
|
||||
} else {
|
||||
hideLoading(these);
|
||||
}
|
||||
|
||||
|
||||
}, pagePath);
|
||||
//搜索到新设备的回调
|
||||
|
||||
ble.addDeviceFound((arr) => {
|
||||
// console.log("发现设备", arr);
|
||||
if (these.Status.isPageHidden) {
|
||||
if (!arr || !arr.devices) {
|
||||
return;
|
||||
}
|
||||
arr = arr.devices;
|
||||
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
console.log(`本次扫描批次发现 ${arr.length} 个设备`);
|
||||
|
||||
arr[i].linkStatu = false;
|
||||
if (!arr[i].name) {
|
||||
continue;
|
||||
}
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
let device = arr[i];
|
||||
device.linkStatu = false;
|
||||
|
||||
let f = these.EquipMents.find((v, index) => {
|
||||
if (v.deviceId == arr[i].deviceId) {
|
||||
|
||||
these.$set(these.EquipMents[index], 'RSSI', arr[i].RSSI);
|
||||
|
||||
if (v.deviceId == device.deviceId) {
|
||||
console.log(`更新设备信号: ${device.name || device.deviceId}, RSSI: ${device.RSSI}`);
|
||||
these.$set(these.EquipMents[index], 'RSSI', device.RSSI);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if (!f) {
|
||||
console.log("发现新设备,", arr[i]);
|
||||
console.log("+++ 发现新设备,准备添加到列表:", JSON.stringify(device));
|
||||
|
||||
if (these.device && these.device.bluetoothName) {
|
||||
if (these.device.bluetoothName === arr[i].name || arr[i].name.indexOf(these
|
||||
.device.bluetoothName) > -1 || these.device.bluetoothName.indexOf(arr[
|
||||
i].name) > -1) {
|
||||
arr[i].isTarget = true;
|
||||
if (these.device && these.device.bluetoothName && device.name) {
|
||||
if (these.device.bluetoothName === device.name || (device.name && device.name.indexOf(these
|
||||
.device.bluetoothName) > -1) || (device.name && this.device.bluetoothName.indexOf(
|
||||
device.name) > -1)) {
|
||||
device.isTarget = true;
|
||||
}
|
||||
}
|
||||
arr[i].name = arr[i].name.replace('JQZM-', '');
|
||||
these.EquipMents.push(arr[i]);
|
||||
if (device.name) {
|
||||
device.name = device.name.replace('JQZM-', '');
|
||||
}
|
||||
these.EquipMents.push(device);
|
||||
}
|
||||
}
|
||||
// console.log("EquipMents=", these.EquipMents)
|
||||
}, pagePath);
|
||||
//收到设备的消息回调
|
||||
ble.addReceiveCallback((receivData, f, path, arr) => {
|
||||
if (these.Status.isPageHidden) {
|
||||
return;
|
||||
}
|
||||
if (f.macAddress && these.device) {
|
||||
clearInterval(this.Status.intval);
|
||||
this.Status.intval = null;
|
||||
this.Status.time = null;
|
||||
|
||||
showLoading(these, {
|
||||
text: '正在验证设备'
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
these.DeviceVerdict(f.deviceId);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
|
||||
}, pagePath);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
StartSubsrib();
|
||||
|
||||
|
||||
eventChannel.on('detailData', function(rec) {
|
||||
console.log("接收到父页面的参数:", rec);
|
||||
these.device = rec.data;
|
||||
console.log("11111")
|
||||
|
||||
these.refreshBleList();
|
||||
});
|
||||
@ -377,41 +373,92 @@
|
||||
this.refreshBleList();
|
||||
},
|
||||
methods: {
|
||||
refreshBleList() {
|
||||
if (!ble) {
|
||||
checkAndRequestLocationPermission() {
|
||||
return new Promise((resolve) => {
|
||||
|
||||
if (uni.getSystemInfoSync().platform !== 'android') {
|
||||
return resolve(true);
|
||||
}
|
||||
|
||||
plus.android.requestPermissions(
|
||||
['android.permission.ACCESS_FINE_LOCATION'],
|
||||
(result) => {
|
||||
if (result.granted.length > 0) {
|
||||
console.log('定位权限已授予');
|
||||
resolve(true);
|
||||
} else {
|
||||
console.warn('定位权限被拒绝');
|
||||
uni.showModal({
|
||||
title: '权限提醒',
|
||||
content: '为了正常扫描蓝牙设备,需要您开启定位权限',
|
||||
showCancel: false,
|
||||
success: () => {
|
||||
uni.openSetting(); // 引导用户去设置页
|
||||
}
|
||||
});
|
||||
resolve(false);
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
console.error('请求定位权限失败:', error);
|
||||
uni.showToast({
|
||||
title: '权限请求异常',
|
||||
icon: 'none'
|
||||
});
|
||||
resolve(false);
|
||||
}
|
||||
);
|
||||
|
||||
resolve(true);
|
||||
});
|
||||
},
|
||||
async refreshBleList() {
|
||||
|
||||
const hasPermission = await this.checkAndRequestLocationPermission();
|
||||
if (!hasPermission) {
|
||||
console.log("缺少定位权限,已中止蓝牙扫描。");
|
||||
return;
|
||||
}
|
||||
let promis = [];
|
||||
for (let index = 0; index < this.PairEquip.length; index++) {
|
||||
let item = this.PairEquip[index];
|
||||
promis.push(ble.disconnectDevice(item.deviceId));
|
||||
|
||||
|
||||
|
||||
if (!ble) {
|
||||
ble = bleTool.getBleTool();
|
||||
if (!ble) {
|
||||
console.error("BLE helper not initialized!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Promise.allSettled(promis).finally(() => {
|
||||
ble.StopSearch().finally(res => {
|
||||
console.log("停止搜索成功");
|
||||
|
||||
ble.StopSearch().finally(() => {
|
||||
|
||||
let disconnectPromises = [];
|
||||
if (ble.data && ble.data.LinkedList) {
|
||||
ble.data.LinkedList.forEach(device => {
|
||||
console.log(`Requesting disconnect for ${device.deviceId}`);
|
||||
disconnectPromises.push(ble.disconnectDevice(device.deviceId));
|
||||
});
|
||||
}
|
||||
|
||||
Promise.allSettled(disconnectPromises).finally(() => {
|
||||
|
||||
these.EquipMents = [];
|
||||
these.PairEquip = [];
|
||||
|
||||
ble.StartSearch().then(result => {
|
||||
console.log("开始搜索成功");
|
||||
console.log("Fresh scan started successfully.");
|
||||
}).catch(err => {
|
||||
console.error("开始搜索失败,err=", err);
|
||||
if (err.code === 10001) {
|
||||
console.error("Failed to start fresh scan:", err);
|
||||
if (err.code === 10001) {
|
||||
these.showOpenSetting();
|
||||
} else {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '出现异常:' + err.msg
|
||||
content: '开始搜索失败:' + err.msg
|
||||
});
|
||||
}
|
||||
});
|
||||
}).catch(ex => {
|
||||
console.error("ex=", ex);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
isItemLink: function(item, index) {
|
||||
let src = '/static/images/BLEAdd/noLink.png';
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
@ -74,9 +74,9 @@ class BleHelper {
|
||||
stateRecoveryCallback: [], //蓝牙适配器恢复可用事件
|
||||
stateBreakCallback: [] //蓝牙适配器不可用事件
|
||||
}
|
||||
this.addReceiveCallback((receive, f, path, recArr) => {
|
||||
recei.ReceiveData(receive, f, path, recArr);
|
||||
}, "BleReceiveData");
|
||||
// this.addReceiveCallback((a, b, c) => {
|
||||
// recei.ReceiveData(a, b, c);
|
||||
// }, "BleReceiveData");
|
||||
this.dic = {
|
||||
errRemarks: [{
|
||||
key: '10000',
|
||||
@ -639,7 +639,7 @@ class BleHelper {
|
||||
|
||||
console.log("111111111")
|
||||
uni.onBluetoothDeviceFound((res) => {
|
||||
//console.log("发现新设备:" + JSON.stringify(res,'name'));
|
||||
// console.log("发现新设备:" + JSON.stringify(res,'name'));
|
||||
let arr = [];
|
||||
for (var i = 0; i < res.devices.length; i++) {
|
||||
let item = res.devices[i];
|
||||
@ -653,7 +653,7 @@ class BleHelper {
|
||||
});
|
||||
if (f) {
|
||||
|
||||
// console.log("发现目标设备:", item);
|
||||
// console.log("发现目标设备:", item);
|
||||
arr.push(item);
|
||||
}
|
||||
|
||||
@ -678,14 +678,12 @@ class BleHelper {
|
||||
});
|
||||
}
|
||||
|
||||
}else{
|
||||
console.error("无人订阅发现设备的回调");
|
||||
}
|
||||
});
|
||||
|
||||
uni.onBLECharacteristicValueChange((receive) => {
|
||||
//订阅消息
|
||||
// console.log("收到订阅消息", receive);
|
||||
console.log("收到订阅消息", receive);
|
||||
let f = this.data.LinkedList.find((v) => {
|
||||
return v.deviceId == receive.deviceId;
|
||||
})
|
||||
@ -840,10 +838,10 @@ class BleHelper {
|
||||
}
|
||||
})
|
||||
} else {
|
||||
console.error("无人订阅消息");
|
||||
console.log("无人订阅消息");
|
||||
}
|
||||
} else {
|
||||
console.error("无人订阅receivDataCallback,不处理数据");
|
||||
console.log("无人订阅receivDataCallback,不处理数据");
|
||||
}
|
||||
} catch (ex) {
|
||||
console.error("处理订阅消息失败,ex=", ex);
|
||||
|
||||
@ -46,20 +46,20 @@ class BleReceive {
|
||||
let handler = null;
|
||||
let keys = Object.keys(this.HandlerMap);
|
||||
let devKey = f.device.detailPageUrl ? f.device.detailPageUrl.replace(/\//g, '').toLowerCase() : '';
|
||||
// console.log("查找handler - detailPageUrl:", f.device.detailPageUrl, "转换后:", devKey);
|
||||
console.log("查找handler - detailPageUrl:", f.device.detailPageUrl, "转换后:", devKey);
|
||||
for (let index = 0; index < keys.length; index++) {
|
||||
let devKey = f.device.detailPageUrl ? f.device.detailPageUrl.replace(/\//g, "").toLowerCase() : '';
|
||||
let key = keys[index].replace(/\//g, '').toLowerCase();
|
||||
if (key == devKey) {
|
||||
handler = this.HandlerMap[keys[index]];
|
||||
// console.log("找到匹配的handler:", keys[index]);
|
||||
console.log("找到匹配的handler:", keys[index]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (handler) {
|
||||
let data = handler(receive, f, path, recArr);
|
||||
// console.log("设备"+f.device.deviceName+"收到消息,数据:", data);
|
||||
console.log("设备"+f.device.deviceName+"收到消息,handler返回的数据:", data);
|
||||
return data;
|
||||
} else {
|
||||
console.error("已收到消息,但无指定处理程序, deviceUrl:", f.device.detailPageUrl, "可用handlers:", keys);
|
||||
@ -162,7 +162,7 @@ class BleReceive {
|
||||
|
||||
if (iswarn) {
|
||||
uni.showModal({
|
||||
content: "'"+f.device.deviceName+"'环境存在漏电电源",
|
||||
content: "环境存在漏电电源",
|
||||
title: "警告",
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
@ -330,7 +330,7 @@ class BleReceive {
|
||||
if (this.formData.staticWarn) { //有静止报警
|
||||
uni.showModal({
|
||||
title: "警告",
|
||||
content: "设备'"+f.device.deviceName+"'静止报警中",
|
||||
content: "设备静止报警中",
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
@ -420,23 +420,19 @@ class BleReceive {
|
||||
let name = "";
|
||||
switch (type) {
|
||||
case 0x02:
|
||||
// name = '弱光';
|
||||
name=1;
|
||||
name = '弱光';
|
||||
break;
|
||||
case 0x04:
|
||||
name = '工作光';
|
||||
break;
|
||||
case 0x01:
|
||||
// name = '强光';
|
||||
name=0;
|
||||
name = '强光';
|
||||
break;
|
||||
case 0x03:
|
||||
// name = '爆闪';
|
||||
name=2;
|
||||
name = '爆闪';
|
||||
break;
|
||||
case 0x00:
|
||||
// name = '关闭';
|
||||
name=3;
|
||||
name = '关闭';
|
||||
break;
|
||||
}
|
||||
return name;
|
||||
@ -476,7 +472,8 @@ class BleReceive {
|
||||
formData.statu = warn;
|
||||
formData.xuhang = lightingTime;
|
||||
|
||||
|
||||
console.log("7305解析结果 - 电量:", batteryLevel, "续航:", lightingTime, "完整数据:", formData);
|
||||
|
||||
let recCnt = recArr.find(v => {
|
||||
|
||||
return v.key.replace(/\//g, "").toLowerCase() === f.device.detailPageUrl.replace(/\//g, '').toLowerCase();
|
||||
@ -487,10 +484,10 @@ class BleReceive {
|
||||
if (!recCnt) {
|
||||
if (batteryLevel <= 20) {
|
||||
// 会弹出两个框,暂且注释掉这段代码
|
||||
uni.showModal({
|
||||
content: "设备'"+f.device.deviceName+"'电量低",
|
||||
title: "提示"
|
||||
});
|
||||
// uni.showModal({
|
||||
// content: "设备电量低",
|
||||
// title: "提示"
|
||||
// });
|
||||
}
|
||||
}
|
||||
|
||||
@ -521,7 +518,7 @@ class BleReceive {
|
||||
if (receiveData.sta_PowerPercent<=20) {
|
||||
uni.showModal({
|
||||
title: "提示",
|
||||
content: "设备'"+f.device.deviceName+"'电量低",
|
||||
content: "设备电量低",
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
@ -550,7 +547,7 @@ class BleReceive {
|
||||
if (receiveData.sta_battery<=20) {
|
||||
uni.showModal({
|
||||
title: "提示",
|
||||
content: "设备'"+f.device.deviceName+"'电量低",
|
||||
content: "设备电量低",
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
@ -580,7 +577,7 @@ class BleReceive {
|
||||
if (receiveData.sta_PowerPercent<=20) {
|
||||
uni.showModal({
|
||||
title: "提示",
|
||||
content: "设备'"+f.device.deviceName+"'电量低",
|
||||
content: "设备电量低",
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
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 request = (options) => {
|
||||
console.log("options" + JSON.stringify(options), BASE.BASE_URL)
|
||||
|
||||
Reference in New Issue
Block a user