1
0
forked from dyf/APP
Files
APP/utils/SendBatchData.js
2026-05-19 17:38:56 +08:00

1022 lines
24 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import request, {
baseURL
} from '@/utils/request.js';
import {
showLoading,
hideLoading,
updateLoading
} from '@/utils/loading.js';
import {
MsgSuccess,
MsgError,
MsgClose,
MsgWarning,
showPop
} from '@/utils/MsgPops.js';
import Common from '@/utils/Common.js';
import api from '@/api/670/HBY670.js'
import gbk from '@/utils/gbk.js'
class SendBatchData {
constructor(_these, _f, _ble) {
this.videoHexArray = [];
this.rgb565Data = [];
this.these = _these;
this.f = _f;
this.ble = _ble;
}
//发送开机视频1536包
SendVideo(bufferSize) {
const systemInfo = uni.getSystemInfoSync();
const platform = systemInfo.platform;
const isIOS = platform === 'ios';
let these = this.these;
let f = this.f;
let ble = this.ble;
if (!bufferSize) {
bufferSize = 504;
}
let timeDelayCloseLoading = () => {
setTimeout(() => {
hideLoading(these);
}, 1500);
}
let sendVideoPackets = (ReSendNo) => {
console.log("开始发送分片数据");
return new Promise((resolve, reject) => {
if (f) {
ble.data.voiceUploading = true;
// 总数据包数
var totalPackets = 1536; //36;
let currentPacket = 1;
console.log("发送数据准备中,总共" + totalPackets);
if (ReSendNo) {
totalPackets = ReSendNo;
currentPacket = ReSendNo;
}
// 发送单个数据包
const sendNextVideoPacket = () => {
// console.log("准备发送一段数据");
if (currentPacket > totalPackets) {
ble.data.voiceUploading = false;
if (!ReSendNo) {
setTimeout(() => {
ble.sendString(f.deviceId, "transmit complete", f
.writeServiceId, f.wirteCharactId, 20)
.then(
() => {
console.log("全部发送完毕")
}).catch((ex) => {
console.log("出现异常", ex);
});
}, 2000);
}
hideLoading(these);
showPop({
showPop: true,
message: "上传成功",
iconUrl: "/static/images/common/success.png"
}, these);
these.videoHexArray = null;
resolve();
return;
}
// 计算当前包的数据
let packetSize = 500;
// 创建数据包
const startIndex = (currentPacket - 1) * packetSize;
const endIndex = Math.min(startIndex + packetSize, these.videoHexArray
.length);
if (startIndex > endIndex) {
resolve();
return;
}
////console.log("111111");
const packetData = these.videoHexArray.slice(startIndex, endIndex);
// 构建数据包
////console.log("packetData.length"+packetData.length);
const buffer = new ArrayBuffer(bufferSize);
const dataView = new DataView(buffer);
// 填充头部
dataView.setUint8(0, 0x55); // 帧头
dataView.setUint8(1, 0x04); // 帧类型:开机画面
dataView.setUint16(2, currentPacket, false); // 包序号
let beginIndex = 4;
if (bufferSize == 506) {
beginIndex = 6;
dataView.setUint16(4, packetSize, false); //数据长度
}
for (let i = 0; i < packetData.length; i++) {
dataView.setUint8(beginIndex + i, parseInt(packetData[i], 16));
}
let inteval = isIOS ? 300 : 80;
ble.sendData(f.deviceId, buffer, f.writeServiceId, f
.wirteCharactId, 10).then(() => {
updateLoading(these, {
text: "正在发送:" + currentPacket + "/" +
totalPackets
});
currentPacket++;
// console.log("发送一段成功,发送下一段");
setTimeout(sendNextVideoPacket, inteval);
}).catch(err => {
console.log("发送失败了", err);
if (err.code == '10007') { //遇到这个错误自动重新发送
console.log(err.errMsg + ",发送失败了,正在补偿:" +
currentPacket);
setTimeout(sendNextVideoPacket, 800);
} else {
ble.data.voiceUploading = false;
hideLoading(these);
showPop({
showPop: true,
message: err.msg + ",发送失败了",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
buttonText: "确定",
iconUrl: "/static/images/common/uploadErr.png"
}, these);
reject(err);
these.videoHexArray = null;
return;
}
});
};
sendNextVideoPacket();
} else {
console.log("Fail.......")
}
});
}
var sendVideo = (videoPath) => {
let uploadVideo = () => {
these.videoHexArray = [];
console.log("开始处理,正在上传");
showLoading(these, {
text: "上传中"
});
let p1 = new Promise((resolve, reject) => {
ble.sendString(f.deviceId, "video transmit start", f
.writeServiceId, f.wirteCharactId).then(res => {
ble.data.voiceUploading = true;
setTimeout(() => {
console.log("握手成功了");
resolve(true);
}, 2200)
}).catch(ex => {
reject(ex);
});
});
let p2 = new Promise((succ, err) => {
const token = uni.getStorageSync('token');
const clientid = uni.getStorageSync('clientID');
if (!token) {
err({
code: 401,
msg: "请先登陆后再试"
});
hideLoading(these);
return;
}
console.log("baseURL=", baseURL);
console.log("token", token);
console.log("clientID", clientid);
uni.uploadFile({
// url: 'http://114.55.111.217/video/upload',
url: baseURL + "/app/video/upload",
filePath: videoPath,
name: 'file',
header: {
"Method": "POST",
"Content-Type": "multipart/form-data",
"Authorization": 'Bearer ' + token,
"clientid": clientid
},
timeout: 600000,
fail: (ex) => {
console.log("上传视频失败" + JSON.stringify(ex));
err(ex);
},
success: (res) => {
console.log("上传完成,向蓝牙设备发送");
succ(res);
}
});
});
Promise.all([p1, p2]).then((arr) => {
if (arr[0].status == 'rejected') {
MsgError("设备准备未就绪,请重试", '', these);
return;
}
if (arr[1].status == 'rejected') {
MsgError("读取视频失败", '', these);
return;
}
let res = arr[1];
// console.log("11111111111111111111111",res);
res = JSON.parse(res.data);
// console.log("22222222222222222222");
if (res.data) {
these.videoHexArray = res.data;
updateLoading(these, {
text: "正在发送:0/1536"
});
shotVideoClick(res.data);
} else {
console.log("服务器未返回正确的数据");
showPop({
message: "与服务器连接出现异常,请检查网络设置",
iconUrl: "/static/images/common/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
}, these);
}
}).catch((ex) => {
console.log("出现异常,", ex)
hideLoading(these);
showPop({
message: "出现异常," + ex.msg,
iconUrl: "/static/images/common/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
}, these);
})
}
let shotVideoClick = () => {
console.log("正在开始发送");
sendVideoPackets().then(() => {
console.log("发送完成");
}).catch((ex1) => {
//console.log("出现了异常", ex1)
}).finally(() => {
hideLoading(these);
});
}
uploadVideo();
}
uni.chooseVideo({
sourceType: ['album'],
compressed: false, // 关闭视频压缩,确保上传原始文件
success: function(res) {
console.log("res=", res);
let path = res.tempFilePath;
// iOS可能返回浮点数需要转换为整数进行比较
let width = Math.round(res.width);
let height = Math.round(res.height);
let duration = res.duration;
// 获取平台信息
console.log("平台:", platform, "uni.chooseVideo返回 - 宽度:", width, "高度:", height,
"时长:", duration);
// iOS特殊处理如果返回的是80*40很可能是160*80的一半iOS的bug
if (isIOS && width === 80 && height === 40) {
console.log("检测到iOS特殊情况返回80*40实际应该是160*80进行修正");
width = 160;
height = 80;
}
// 检查分辨率是否符合要求
let checkResolution = (w, h) => {
// 使用容差比较允许1像素的误差
return Math.abs(w - 160) <= 1 && Math.abs(h - 80) <= 1;
};
let err = [];
if (duration < 2) {
err.push("视频时长至少2秒");
}
if (!checkResolution(width, height)) {
err.push("视频宽高必须是160*80当前分辨率" + width + "*" + height);
}
if (err.length > 0) {
err = err.join(";");
showPop({
message: err,
iconUrl: "/static/images/common/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
}, these);
return;
}
showLoading(these, {
text: '正在上传'
});
setTimeout(() => {
sendVideo(path);
}, 0);
}
});
}
//发送图片52包
SendImg() {
let these = this.these;
let f = this.f;
let ble = this.ble;
var sendImagePackets = function(ReSendNo) {
return new Promise((resolve, reject) => {
// 总数据包数
let totalPackets = 52;
let currentPacket = 1;
if (ReSendNo) {
totalPackets = ReSendNo;
currentPacket = ReSendNo;
}
if (f) {
// 发送单个数据包
const sendNextPacket = () => {
if (currentPacket > totalPackets) {
hideLoading(these);
if (these.closeAction) {
these.closeAction();
}
showPop({
showPop: true,
message: "上传成功",
iconUrl: "/static/images/common/success.png",
}, these);
setTimeout(() => {
ble.sendString(f.deviceId, "transmit complete", f
.writeServiceId, f
.wirteCharactId);
}, 1000);
these.rgb565Data = null;
resolve();
return;
}
// 计算当前包的数据
let packetSize = 250;
// if (currentPacket <= 51) {
// packetSize = 250; // 前51个包每个500字节
// } else {
// packetSize = 50; // 最后一个包100字节
// }
// 创建数据包
const startIndex = (currentPacket - 1) * packetSize;
const endIndex = Math.min(startIndex + packetSize, these.rgb565Data
.length);
if (startIndex > endIndex) {
return;
}
const packetData = these.rgb565Data.slice(startIndex,
endIndex);
// 构建数据包
const bufferSize = 505; // 5 + packetData.length * 2; // 头部5字节 + 数据部分
const buffer = new ArrayBuffer(bufferSize);
const dataView = new DataView(buffer);
// 填充头部
dataView.setUint8(0, 0x55); // 帧头
dataView.setUint8(1, 0x02); // 帧类型:开机画面
dataView.setUint8(2, currentPacket); // 包序号
dataView.setUint16(3, packetData.length * 2, false); // 包t长度
// 填充数据每个RGB565值占2字节
for (let i = 0; i < packetData.length; i++) {
dataView.setUint16(5 + i * 2, packetData[i], false); // 大端字节序
}
//发送数据包
ble.sendData(f.deviceId, buffer, f.writeServiceId, f.wirteCharactId,
10)
.then(() => {
updateLoading(these, {
text: "正在发送:" + currentPacket + "/" +
totalPackets
})
currentPacket++;
setTimeout(sendNextPacket, these.inteval ? these.inteval : 80);
}).catch(err => {
console.log("发送数据包失败了" + JSON.stringify(err));
if (err.code == '10007') {
setTimeout(sendNextPacket, 800);
return;
}
if (these.closeAction) {
these.closeAction();
}
showPop({
message: err.msg,
iconUrl: "/static/images/common/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
}, these);
hideLoading(these);
these.rgb565Data = null;
reject(err);
});
}
if (ReSendNo) {
sendNextPacket(ReSendNo);
return;
}
// 开始牵手
ble.sendString(f.deviceId, "picture transmit start", f.writeServiceId,
f.wirteCharactId).then(() => {
setTimeout(sendNextPacket, 120);
}).catch((err) => {
console.log("握手没有成功");
showPop({
message: err.msg,
iconUrl: "/static/images/common/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
}, these);
hideLoading(these);
reject(err);
});
}
});
}
uni.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: function(res) {
uni.navigateTo({
url: "/pages/common/ImgCrop/ImgCrop",
events: {
ImgCutOver: function(data) {
showLoading(these, {
text: "正在发送0/52"
});
these.rgb565Data = Common.convertToRGB565(data.piexls);
setTimeout(function() {
sendImagePackets().catch(() => {
});
}, 0)
}
},
success(ev) {
ev.eventChannel.emit('checkImg', {
data: res.tempFiles[0].path
})
},
fail(ex) {
console.log("跳转页面失败" + JSON.stringify(ex));
}
});
}
});
}
//发送人员信息(点阵)
SendUsr(totalRows) {
let these = this.these;
let f = this.f;
let ble = this.ble;
if (!totalRows) {
totalRows = 3;
}
let toByteValue = (value) => {
if (typeof value === 'number') {
return value;
}
if (typeof value === 'string') {
if (value.startsWith('0x') || value.startsWith('0X')) {
return parseInt(value, 16);
}
return parseInt(`0x${value}`, 16);
}
return 0;
}
these.formData.textLines = [these.formData.company, these.formData.usrname, these.formData.job];
if (totalRows == 4) {
these.formData.textLines.push(these.formData.usrid);
}
console.log("data=", these.formData.textLines);
showLoading(these, {
text: "发送中"
});
//握手
let holdHand = (hexs, time) => {
return new Promise((resolve, reject) => {
console.log("11111");
ble.sendString(f.deviceId, hexs, null, null, 15).then(res => {
console.log("22222")
setTimeout(() => {
resolve(res)
}, time);
}).catch(ex => {
console.log("33333", ex);
console.error("握手失败")
reject(ex)
});
});
}
//画图
let drawText = () => {
return new Promise((resolve, reject) => {
these.$refs.textToHex.drawAndGetPixels().then(allPixels => {
if (!allPixels) {
reject("文本初始化失败");
return;
}
console.log("画图成功");
resolve(allPixels);
}).catch(compEx => {
reject(compEx);
});
});
}
//发送3个分包的数据
let task = (allPixels) => {
try {
let combinedData = [];
for (let i = 0; i < totalRows; i++) {
let linePixels = (allPixels[i] || []).flat(Infinity).map(item =>
typeof item === 'string' ? toByteValue(item) : item
);
for (var j = linePixels.length; j < 256; j++) {
linePixels.push(0x00);
}
linePixels = [0xFA, 0x06, 0x03, i + 1].concat(linePixels);
linePixels.push(0xFF)
combinedData.push(linePixels);
}
let curr = 1;
let len = combinedData.length;
//分包发送
let sendPacket = () => {
if (combinedData.length === curr - 1) {
setTimeout(() => {
holdHand('transmit complete', 200).then(res => {
let json = {
deviceId: these.device.id,
name: these.formData.usrname,
position: these.formData.job,
unitName: these.formData.company,
code: these.formData.usrid
};
api.sendUsr(json);
MsgSuccess("人员信息发送成功", "确定", these);
hideLoading(these);
these.setBleFormData();
});
}, 300);
hideLoading(these);
return;
}
let array = combinedData[curr - 1];
console.log("array=", array);
ble.sendHexs(f.deviceId, array, null, null, 15).then(
res => {
curr++;
console.log("发送成功", curr);
updateLoading(these, {
text: '发送中,' + (curr - 1) + '/' + combinedData.length
})
setTimeout(sendPacket, 250);
}).catch(err => {
console.error("err:", err);
if (err.code == '10007') {
setTimeout(sendPacket, 250);
} else {
console.error("err:", err);
MsgError('发送失败:' + (err.msg || err.code), 'OK', these);
hideLoading(these);
}
});
}
setTimeout(sendPacket, 0);
// 5. 发送成功处理
} catch (ex) {
console.error("ex=", ex)
MsgError('发送失败' + (ex.msg || ex.code), '确定', these);
}
}
setTimeout(() => {
Promise.allSettled([holdHand('word transmit start', 2200), drawText()]).then(results => {
if (results[0].status == 'rejected') {
MsgError("与蓝牙设备握手失败,请重试," + results[0].reason, '', these);
setTimeout(() => {
hideLoading(these)
}, 500);
return;
}
if (results[1].status == 'rejected') {
MsgError("读取文字点阵失败,请重试", '', these);
return;
}
task(results[1].value);
})
}, 0);
}
//发送识别指令
SendDisc() {
let these = this.these;
let f = this.f;
let ble = this.ble;
var json = {
ins_disc: 1
}
ble.sendString(f.deviceId, json, f.writeServiceId, f.wirteCharactId, 30).then(res => {
}).catch(ex => {
console.error("蓝牙发送失败", ex);
}).finally(() => {
});
}
SendMsgByGBK(txts, _mq) {
debugger;
let these = this.these;
let f = this.f;
let ble = this.ble;
let mq = _mq;
if (!these.permissions.includes('5') && these.Status.apiType !== 'listA') {
showPop({
message: '无操作权限',
iconUrl: "/static/images/common/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
buttonTextColor: "#FFFFFFde",
okCallback: null,
buttonText: "确定"
}, these)
return;
}
showLoading(these, {
text: "请稍候..."
});
let send = (txt) => {
return mq.publish("B/" + these.device.deviceImei, txt);
}
let curr = 0;
let sendNext = () => {
if (curr >= txts.length) {
hideLoading(these);
MsgSuccess("发送成功", '', these);
return;
}
let txt = txts[curr];
let arr = gbk.encode(txt)
console.log("正在发送:", txt);
let json = {
ins_msg: [curr + 1]
}
let gbkData = gbk.arr2hex(arr);
for (let i = 0; i < gbkData.length; i += 2) {
let value = parseInt(gbkData[i] + "" + gbkData[i + 1], 16);
json.ins_msg.push(value);
}
txt = JSON.stringify(json);
updateLoading(these, {
text: '正在发送' + (curr + 1) + '/' + txts.length
});
if (send(txt)) {
curr++;
setTimeout(sendNext, 200);
} else {
MsgError("发送失败了,请检查网络连接后重试", '', these);
}
}
setTimeout(sendNext, 2200);
}
HoldYouHand(cmd, timeout) {
let these = this.these;
let f = this.f;
let ble = this.ble;
return new Promise((resolve, reject) => {
ble.sendString(f.deviceId, cmd, f
.writeServiceId, f.wirteCharactId).then(res => {
if (timeout) {
setTimeout(() => {
console.log("握手成功了");
resolve(true);
}, timeout);
return;
}
resolve(true);
}).catch(ex => {
reject(ex);
console.error("发送文本‘" + cmd + "’失败");
console.error("ex=", ex);
});
});
}
sendUsrByGBK(textLines, ReSendNo) {
let these = this.these;
let f = this.f;
let ble = this.ble;
if (!these.permissions.includes('4') && these.Status.apiType !== 'listA') {
showPop({
message: '无操作权限',
iconUrl: "/static/images/common/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
okCallback: null,
buttonText: "确定"
}, these)
return;
}
showLoading(these, {
text: "请稍候..."
});
var sendText = () => {
// 总数据包数
let totalPackets = textLines.length;
let currentPacket = 1;
// console.log("currentPacket=",currentPacket);
// console.log("ReSendNo=",ReSendNo);
if (ReSendNo) {
totalPackets = ReSendNo;
currentPacket = ReSendNo;
}
// console.log("currentPacket=",currentPacket);
// 发送单个数据包
const sendNextPacket = () => {
if (currentPacket > totalPackets) {
if (!ReSendNo) {
setTimeout(() => {
this.HoldYouHand("transmit complete");
}, 500);
}
showPop({
showPop: true, //是否显示弹窗
popType: 'custom',
bgColor: '#383934bd',
borderColor: '#BBE600',
textColor: '#ffffffde',
buttonBgColor: '#BBE600',
buttonTextColor: '#232323DE',
iconUrl: '/static/images/6155/DeviceDetail/sendSucc.png',
message: '人员信息发送成功',
buttonText: '确定',
clickEvt: 'SendUsr',
visiblePrompt: false,
promptTitle: '',
modelValue: '',
visibleClose: true
}, these);
these.setBleFormData();
let json = {
deviceId: these.device.id,
name: these.formData.name,
position: these.formData.job,
unitName: these.formData.company,
code: these.formData.id
};
api.sendUsr(json)
return;
}
// 获取当前行文字
const text = textLines[currentPacket - 1] || '';
let arr = gbk.encode(text)
let gbkData = gbk.arr2hex(arr);
console.log("正在发送:" + text);
console.log("正在发送:" + arr);
// 构建数据包
const bufferSize = 5 + gbkData.length / 2; // 头部4字节 + 数据部分
const buffer = new ArrayBuffer(bufferSize);
const dataView = new DataView(buffer);
// 填充头部
dataView.setUint8(0, 0x55); // 帧头
dataView.setUint8(1, 0x03); // 帧类型:文字
dataView.setUint8(2, currentPacket.toString(16)); // 包序号
dataView.setUint16(3, text.length, false); // 数据长度
// 填充数据
let index = 0;
for (var i = 0; i < gbkData.length; i += 2) {
let value = parseInt(gbkData[i] + "" + gbkData[i + 1], 16);
console.log("value=", value)
dataView.setUint8(5 + index, value);
index++;
}
// 发送数据包
ble.sendData(f.deviceId, buffer, f.writeServiceId, f.wirteCharactId, 10).then(() => {
// 更新进度
console.log(
`发送文字数据包 ${currentPacket}/${totalPackets}: ${text}`
);
// 发送下一个包
currentPacket++;
setTimeout(sendNextPacket, 80);
}).catch(err => {
showPop({
message: "文字发送失败," + err.msg,
iconUrl: "/static/images/common/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
}, these);
}).finally(() => {
hideLoading(these);
});
};
// 开始发送第一个包
sendNextPacket();
}
if (ReSendNo) {
sendText(ReSendNo);
return;
}
setTimeout(() => {
this.HoldYouHand("word transmit start", 120).then(
() => {
setTimeout(sendText, 200);
}).catch((ex) => {
console.log("握手没有成功", ex);
hideLoading(these);
showPop({
message: ex.msg,
iconUrl: "/static/images/common/uploadErr.png",
borderColor: "#e034344d",
buttonBgColor: "#E03434",
}, these);
});
}, 0);
}
}
export default SendBatchData;