diff --git a/pages/6155/deviceDetail.vue b/pages/6155/deviceDetail.vue
index 9745cca..d07fd03 100644
--- a/pages/6155/deviceDetail.vue
+++ b/pages/6155/deviceDetail.vue
@@ -108,15 +108,15 @@
单位:
-
+
部门:
-
+
姓名:
-
+
@@ -919,7 +919,7 @@
fail: (ex) => {
updateLoading(these, {
- text: '视频文件上传失败了,请检查网络连接'
+ text : '视频文件上传失败了,请检查网络连接'
});
reject(ex);
@@ -1295,9 +1295,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 +1337,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 +1361,7 @@
break;
}
- // console.log("dataValue=", dataValue)
+ console.log("dataValue=", dataValue)
// 构建数据包
var buffer = new ArrayBuffer(6);
var dataView = new DataView(buffer);
@@ -1526,156 +1524,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 +1598,6 @@
buttonBgColor: '#BBE600'
});
-
-
-
let json = {
deviceId: these.device.id,
name: these.formData.textLines[1],
@@ -1693,17 +1605,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() {
diff --git a/pages/common/addBLE/addEquip.vue b/pages/common/addBLE/addEquip.vue
index d4fd506..d0fa275 100644
--- a/pages/common/addBLE/addEquip.vue
+++ b/pages/common/addBLE/addEquip.vue
@@ -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,110 +255,119 @@
}, pagePath);
- //蓝牙连接已恢复的回调
- ble.addRecoveryCallback(res => {
+
+
+
+ //搜索到新设备的回调 (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: '正在验证设备'
+ }
+
+ let startValidDevice=()=>{
+ 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;
});
-
- setTimeout(() => {
- these.DeviceVerdict(f.deviceId);
- }, 0);
- }
-
-
- }, pagePath);
-
+ 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) => {
+ console.log("000000");
+ if (these.Status.isPageHidden) {
+ return;
+ }
+ console.log("1111111");
+ if (f.macAddress && these.device) {
+ console.log("222222");
+ 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")
-
+ startValidDevice();
these.refreshBleList();
});
@@ -377,41 +378,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';