diff --git a/components/TextToHex/textToDotMatrixFor7305.vue b/components/TextToHex/textToDotMatrixFor7305.vue
index 7160bf5..48fbea8 100644
--- a/components/TextToHex/textToDotMatrixFor7305.vue
+++ b/components/TextToHex/textToDotMatrixFor7305.vue
@@ -35,7 +35,9 @@
currentCanvasWidth: 0,
currentCanvasHeight: 0,
// Canvas上下文(复用)
- ctx: null
+ ctx: null,
+ // 标记画布是否已预热(解决首次发送像素不完整问题)
+ canvasWarmed: false
};
},
computed: {
@@ -63,10 +65,63 @@
this.ctx.fillRect(0, 0, this.currentCanvasWidth, this.currentCanvasHeight);
},
+ /**
+ * 预热画布,防止 APP 首次调用时获取到的像素数据不完整
+ */
+ async warmupCanvas() {
+ if (this.canvasWarmed) {
+ return;
+ }
+
+ try {
+ // 先用一个最小画布绘制测试字形,触发字体和 canvas 初始化
+ this.currentCanvasWidth = 16;
+ this.currentCanvasHeight = 16;
+ this.clearCanvas();
+ this.ctx.setFillStyle(this.color);
+ this.ctx.setFontSize(this.fontSize);
+ this.ctx.font = `${this.fontSize}px "PingFangBold", "PingFang SC", Arial, sans-serif`;
+ this.ctx.setTextBaseline('middle');
+ this.ctx.fillText('测', 0, 8);
+
+ await new Promise((resolve) => {
+ this.ctx.draw(false, () => {
+ // 读取一次数据,确保 canvasGetImageData 就绪
+ setTimeout(() => {
+ uni.canvasGetImageData({
+ canvasId: 'reusableCanvas',
+ x: 0,
+ y: 0,
+ width: 16,
+ height: 16,
+ success: () => {
+ this.canvasWarmed = true;
+ resolve();
+ },
+ fail: () => {
+ // 即便失败也认为已尝试过,避免反复预热阻塞流程
+ this.canvasWarmed = true;
+ resolve();
+ }
+ });
+ }, 100);
+ });
+ });
+ // 额外等待,确保字体完全加载
+ await new Promise(resolve => setTimeout(resolve, 200));
+ } catch (ex) {
+ console.log("画布预热异常:", ex);
+ this.canvasWarmed = true;
+ }
+ },
+
/**
* 复用单个Canvas处理所有文本行
*/
async drawAndGetPixels() {
+ // 首次调用先做预热,避免第一次上报缺字
+ await this.warmupCanvas();
+
let binaryToHex = (binaryArray) => {
if (!Array.isArray(binaryArray) || binaryArray.length !== 8) {
throw new Error("输入必须是包含8个元素的二进制数组");
@@ -92,7 +147,7 @@
let convertCharToMatrix = (imageData, item) => {
const charWidth = 13;
- const charHeight = 12;
+ const charHeight = 13;
const pixels = [];
for (let i = 0; i < imageData.length; i += 4) {
const R = imageData[i];
@@ -123,7 +178,7 @@
// 1. 动态调整Canvas尺寸
this.currentCanvasWidth = 13;
- this.currentCanvasHeight = 12;
+ this.currentCanvasHeight = 13;
// 2. 清空Canvas(绘制背景)
this.clearCanvas();
diff --git a/pages/210/HBY210.vue b/pages/210/HBY210.vue
index 1df05ba..6719e92 100644
--- a/pages/210/HBY210.vue
+++ b/pages/210/HBY210.vue
@@ -199,11 +199,47 @@
删除文件
+
+
+ 已上传文件:{{ soundFileList.map(item => item.name).join('、') }}
+
+
+
+
+
+
@@ -292,9 +328,23 @@
console.log('自动报警确认');
// 这里可以添加自动报警的逻辑
}
+ },
+ // 报警声音上传成功
+ soundUpload: {
+ config: {
+ icon: '/static/images/common/upload.png',
+ message: '报警声音上传成功',
+ showCancel: false
+ }
+ },
+ // 报警声音删除成功
+ soundDelete: {
+ config: {
+ icon: '/static/images/common/sendSucc.png',
+ message: '报警声音删除成功',
+ showCancel: false
+ }
}
-
-
}
import MqttClient from '@/utils/mqtt.js';
import {
@@ -400,7 +450,11 @@
radioSelected: 0, // -1表示未选中任何项
deviceType: '',
popupType: '', //弹框类型
- lightModeC: false
+ lightModeC: false,
+ // 新增:报警声音文件相关
+ soundFileList: [],
+ deleteSoundMode: false,
+ selectedSoundFiles: []
}
},
methods: {
@@ -408,11 +462,112 @@
closePopup() {
this.lightModeA = false;
this.lightModeB = false;
+ this.lightModeC = false;
+ },
+ // 关闭删除报警声音弹窗
+ closeDeleteSoundPopup() {
+ this.deleteSoundMode = false;
+ this.selectedSoundFiles = []; // 清空选中状态
+ this.lightModeC = true; // 回到报警声音上传弹窗
+ },
+
+ handleSoundFileSelect() {
+ console.log("选中的报警声音文件:", this.selectedSoundFiles);
+ },
+ // 确认删除选中的报警声音文件
+ confirmDeleteSound() {
+ this.soundFileList = this.soundFileList.filter(file => !this.selectedSoundFiles.includes(file));
+ this.showPopup('soundDelete');
+ this.selectedSoundFiles = [];
+ this.closeDeleteSoundPopup();
+ },
+ // 上传报警声音文件
+ uploadFile() {
+ uni.chooseFile({
+ count: 1,
+ success: (res) => {
+ const file = res.tempFiles[0];
+ const fileSize = file.size || 0;
+ // 限制文件大小(示例:5MB)
+ if (fileSize > 5 * 1024 * 1024) {
+ uni.showToast({
+ title: '文件大小不能超过5MB',
+ icon: 'none',
+ duration: 3000
+ });
+ return;
+ }
+ // 显示上传中加载提示
+ uni.showLoading({
+ title: '上传中...',
+ mask: true
+ });
+ // 调用上传接口
+ uni.uploadFile({
+ url: baseURL + '/app/device/uploadSound', // 替换为真实的报警声音上传接口
+ filePath: file.path,
+ name: 'file',
+ formData: {
+ deviceId: this.deviceID,
+ },
+ header: {
+ 'Authorization': 'Bearer ' + getToken(),
+ 'clientid': clientid(),
+ },
+ complete: (res) => {
+ uni.hideLoading();
+ try {
+ const responseData = JSON.parse(res.data);
+ if (responseData.code === 200) {
+ // 上传成功,添加到文件列表
+ this.soundFileList.push({
+ name: file.name,
+ url: responseData.data.url // 接口返回的文件地址
+ });
+ this.showPopup('soundUpload');
+ } else {
+ uni.showToast({
+ title: responseData.msg,
+ icon: 'none'
+ });
+ }
+ } catch (e) {
+ uni.showToast({
+ title: '上传失败',
+ icon: 'none'
+ });
+ }
+ }
+ });
+ },
+ fail: (err) => {
+ console.error('选择文件失败:', err);
+ uni.showToast({
+ title: '选择文件失败',
+ icon: 'none'
+ });
+ }
+ });
+ },
+ deleteQ() {
+ if (this.soundFileList.length === 0) {
+ uni.showToast({
+ title: "暂无可删除的报警声音文件",
+ icon: "none"
+ });
+ return;
+ }
+ this.lightModeC = false;
+ this.deleteSoundMode = true;
+ },
+ // 报警声音上传弹窗确定按钮
+ handleSoundUpload() {
+ uni.showToast({
+ title: "报警声音配置确认成功",
+ icon: "success"
+ });
+ this.closePopup();
},
- // 上传文件
- uploadFile() {},
- // 删除文件
- deleteQ() {},
// 打开弹框
showPopup(type) {
this.currentPopup = {
@@ -497,7 +652,7 @@
uploadStartup() {
this.lightModeB = true
},
- // 上传开机画面
+ // 上传开机画面-选择图片
checkImgUpload() {
uni.chooseImage({
count: 1,
@@ -766,7 +921,6 @@
title: '加载中...'
})
eventChannel.on('detailData', (data) => {
- console.log(data, '这是传过来的惨呼啊');
this.itemInfo = data.data;
this.deviceID = data.data.id;
this.navTitle = data.data.deviceName;
@@ -777,7 +931,7 @@
this.isRightIconVisible = this.apiType === 'listA';
// 初始化并连接MQTT
this.mqttClient = new MqttClient();
- this.mqttClient.connect(() => {
+ this.mqttClient.connect(() => {
console.log('MQTT 连接成功,开始订阅主题');
// 订阅来自设备的状态更新
const statusTopic = `A/${this.itemInfo.deviceImei}`;
@@ -1380,4 +1534,30 @@
margin-top: 60rpx;
position: relative;
}
+
+ /* 新增:删除文件列表样式 */
+ .file-list-tip {
+ margin-top: 20rpx;
+ font-size: 26rpx;
+ color: #666;
+ }
+ .empty-tip {
+ text-align: center;
+ color: #999;
+ padding: 20rpx 0;
+ }
+ .file-list {
+ padding: 10rpx 0;
+ }
+ .file-item {
+ display: flex;
+ align-items: center;
+ padding: 10rpx 0;
+ border-bottom: 1px solid #eee;
+ }
+ .file-name {
+ margin-left: 10rpx;
+ font-size: 28rpx;
+ color: rgba(255, 255, 255, 0.87);
+ }
\ No newline at end of file
diff --git a/pages/7305/BJQ7305.vue b/pages/7305/BJQ7305.vue
index 5c92671..1f3a581 100644
--- a/pages/7305/BJQ7305.vue
+++ b/pages/7305/BJQ7305.vue
@@ -27,19 +27,19 @@
{{device.deviceName}}
- Mac地址
- {{device.deviceMac}}
-
+ Mac地址
+ {{device.deviceMac}}
+
设备状态
- {{formData.statu}}
+ {{formData.statu}}
蓝牙名称
{{device.bluetoothName}}
-
-
+
+
蓝牙状态
{{formData.bleStatu?'已连接':'未连接'}}
@@ -314,7 +314,7 @@
}
these.formData.blename = f.name ? f.name : "Unname";
these.formData.deviceName = device.deviceName;
-
+
these.formData.id = device.id;
these.formData.deviceId = f.deviceId;
these.formData.bleStatu = false;
@@ -390,6 +390,7 @@
}
if (res.deviceId == these.formData.deviceId) {
this.formData.bleStatu = true;
+ // 重新连接后状态以设备上报为准
setTimeout(() => {
hideLoading(these, 1000);
});
@@ -406,6 +407,9 @@
}
if (res.deviceId == these.formData.deviceId) {
this.formData.bleStatu = false;
+ // 断开连接时先将充电状态复位,避免保持旧值
+ this.formData.statu = '未充电';
+ this.setBleFormData();
setTimeout(() => {
hideLoading(these, 1000);
});
@@ -491,7 +495,10 @@
}
});
if ('statu' in json) {
- these.formData.statu = json.statu == '1' ? '充电中' : '未充电';
+ const chargingVal = json.statu;
+ const isCharging = chargingVal === 1 || chargingVal === '1' || chargingVal === true ||
+ chargingVal === '充电中';
+ these.formData.statu = isCharging ? '充电中' : '未充电';
}
if ('xuhang' in json) {
these.formData.xuhang = json.xuhang;
diff --git a/pages/common/aboutUs/index.vue b/pages/common/aboutUs/index.vue
index 693daf6..5a624a8 100644
--- a/pages/common/aboutUs/index.vue
+++ b/pages/common/aboutUs/index.vue
@@ -19,7 +19,7 @@
}
.deviceTitle{
color: rgba(255, 255, 255, 0.87);
- line-height: 45mnrpx;
+ line-height: 45rpx;
font-size: 28rpx;
}
\ No newline at end of file