更新mqtt

This commit is contained in:
微微一笑
2025-08-14 17:04:12 +08:00
parent 9bac0995a3
commit 106320bfd5
8 changed files with 8826 additions and 3169 deletions

View File

@ -300,8 +300,6 @@ export default {
touchStartX: 0,
touchStartY: 0,
pageLoading: true,
mainMode: 'string',
secondaryMode: 'string',
navBarHeight: 70 + uni.getSystemInfoSync().statusBarHeight,
navTitle: "",
sliderValue: 25,
@ -331,16 +329,17 @@ export default {
popupConfirmText: '确认',
showUploadPopup: false,
selectedImage: null, // 添加这个变量来存储选择的图片
file: '',
selectedItemIndex: 0,
popupType: 'person', //弹框类型
isLaserOn: false,
isSending: false,
isGettingStatus: false,
isProcessing: false
}
},
computed: {
computedDeviceId() {
return this.apiType === 'listA' ? this.deviceID : this.itemInfo.deviceId;
},
popupTitle() {
return this.modeType === 'main' ? '灯光模式' : '激光模式';
}
@ -350,11 +349,17 @@ export default {
* 获取设备状态(带自动轮询)
* @param {number} val - 功能模式
* @param {string} batchId - 批次ID
* @param {number} [interval=1000] - 轮询间隔(毫秒)
* @param {number} [interval=800] - 轮询间隔(毫秒)
* @param {number} [maxRetries=10] - 最大重试次数
*/
async getdeviceSTatus(val, batchId, interval = 800) {
async getdeviceSTatus(val, batchId, interval = 800, maxRetries = 10) {
let retries = 0;
const checkStatus = async () => {
if (retries >= maxRetries) {
throw new Error('超过最大重试次数');
}
retries++;
try {
const data = {
functionMode: val,
@ -473,7 +478,7 @@ export default {
type: 'light'
});
let data = {
deviceId: this.deviceID,
deviceId: this.computedDeviceId,
instructValue: this.sliderValue + '.00',
deviceImei: this.itemInfo.deviceImei,
}
@ -491,7 +496,7 @@ export default {
}
this.sliderValue = value;
let data = {
deviceId: this.apiType === 'listA' ? this.deviceID : this.itemInfo.deviceId,
deviceId: this.computedDeviceId,
instructValue: this.sliderValue + '.00',
deviceImei: this.itemInfo.deviceImei,
}
@ -579,7 +584,7 @@ export default {
const selectedItem = this.items[this.selectedItemIndex];
// 准备请求数据
let data = {
deviceId: this.apiType === 'listA' ? this.deviceID : this.itemInfo.deviceId,
deviceId: this.computedDeviceId,
instructValue: selectedItem.instructValue,
deviceImei: this.itemInfo.deviceImei,
typeName: this.itemInfo.typeName,
@ -631,7 +636,7 @@ export default {
this.isProcessing = true
const instructValue = this.isLaserOn ? 0 : 1;
let data = {
deviceId: this.apiType === 'listA' ? this.deviceID : this.itemInfo.deviceId,
deviceId: this.computedDeviceId,
instructValue: instructValue,
deviceImei: this.itemInfo.deviceImei,
typeName: this.itemInfo.typeName,
@ -727,7 +732,7 @@ export default {
filePath: this.selectedImage,
name: 'file',
formData: {
deviceId: this.apiType === 'listA' ? this.deviceID : this.itemInfo.deviceId,
deviceId: this.computedDeviceId,
deviceImei: this.itemInfo.deviceImei,
typeName: this.itemInfo.typeName,
},
@ -735,49 +740,46 @@ export default {
'Authorization': 'Bearer ' + getToken(),
'clientid': clientid(),
},
complete: async (res) => {
complete: (res) => { // 使用 complete 确保 hideLoading 总能被调用
try {
const responseData = JSON.parse(res.data);
if (responseData.code === 200) {
try {
// 获取设备状态
const statusRes = await this.getdeviceSTatus(1);
if (statusRes.data.functionAccess === 'OK') {
uni.hideLoading(); // ✅ 只有成功才关闭
this.selectedImage = '';
this.file = null;
this.popupType = 'logo';
this.showPopupFlag = true;
this.popupMessage = '上传成功';
this.lightModeB = false
}
} catch (error) {
uni.hideLoading();
uni.showToast({
title: error.message,
icon: 'none'
// 异步操作链
this.getdeviceSTatus(1)
.then(statusRes => {
if (statusRes.data.functionAccess === 'OK') {
this.selectedImage = '';
this.popupType = 'logo';
this.showPopupFlag = true;
this.popupMessage = '上传成功';
this.lightModeB = false;
}
})
.catch(error => {
uni.showToast({
title: error.message,
icon: 'none'
});
})
.finally(() => {
uni.hideLoading(); // 在所有异步操作完成后关闭loading
});
}
} else {
uni.hideLoading();
uni.showToast({
title: responseData.msg,
title: responseData.msg || '上传失败',
icon: 'none'
});
uni.hideLoading();
}
} catch (e) {
uni.hideLoading();
uni.showToast({
title: e.message,
title: '解析响应失败',
icon: 'none'
});
uni.hideLoading();
}
// finally {
// uni.hideLoading();
// }
}
})
});
},
// 分享
shareUp() {
@ -842,7 +844,7 @@ export default {
name: this.personnelInfo.name,
position: this.personnelInfo.position,
unitName: this.personnelInfo.unitName,
deviceId: this.apiType === 'listA' ? this.deviceID : this.itemInfo.deviceId,
deviceId: this.computedDeviceId,
deviceImei: this.itemInfo.deviceImei
};
// 3. 注册人员信息
@ -892,7 +894,7 @@ export default {
// 2. 准备请求数据
const batchId = generateShortId();
const data = {
deviceIds: this.apiType === 'listA' ? [this.deviceID] : [this.itemInfo.deviceId],
deviceIds: [this.computedDeviceId],
batchId: batchId,
typeName: this.itemInfo.typeName,
deviceImeiList: [this.itemInfo.deviceImei],
@ -915,7 +917,7 @@ export default {
icon: 'none'
});
// 刷新详情接口
this.fetchDeviceDetail(this.deviceID);
this.fetchDeviceDetail(this.computedDeviceId, true);
uni.$emit('deviceStatusUpdate', {});
this.showPopupFlag = false
}
@ -951,7 +953,7 @@ export default {
const batchId = generateShortId();
const data = {
sendMsg: this.messageToSend,
deviceIds: this.apiType === 'listA' ? [this.deviceID] : [this.itemInfo.deviceId],
deviceIds: [this.computedDeviceId],
typeName: this.itemInfo.typeName,
batchId: batchId,
deviceImeiList: [this.itemInfo.deviceImei]
@ -984,27 +986,29 @@ export default {
}
},
// 统一处理返回方法
handleDeviceData(res, isFromShared = false) {
handleDeviceData(res, isFromShared = false, isUpdate = false) {
if (res.code == 200) {
// 最后关闭加载状态
this.pageLoading = false
this.deviceInfo = res.data
this.personnelInfo = {
unitName: res.data.personnelInfo?.unitName || '',
name: res.data.personnelInfo?.name || '',
code: res.data.personnelInfo?.code || '',
position: res.data.personnelInfo?.position || '',
if (!isUpdate) {
this.personnelInfo = {
unitName: res.data.personnelInfo.unitName || '',
name: res.data.personnelInfo.name || '',
code: res.data.personnelInfo.code || '',
position: res.data.personnelInfo.position || '',
};
this.messageToSend = res.data.sendMsg || '';
}
// 将权限字符串转换为数组 ["1", "2"]
if (isFromShared) {
this.isSharedDevice = true
this.activePermissions = res.data.permission ?
res.data.permission.split(',') : []
this.isSharedDevice = true;
this.activePermissions = res.data.permission ? res.data.permission.split(',') : [];
} else {
this.isSharedDevice = false
this.activePermissions = [] // 非分享设备清空权限
}
this.messageToSend = res.data.sendMsg || ''
this.isSharedDevice = false;
this.activePermissions = []; // 非分享设备清空权限
}
// 关闭加载中
uni.hideLoading()
}
@ -1018,10 +1022,10 @@ export default {
return this.activePermissions.includes(permissionCode)
},
// 获取设备详情(普通详情)
async fetchDeviceDetail(id) {
async fetchDeviceDetail(id, isUpdate = false) {
try {
const res = await deviceDetail(id)
this.handleDeviceData(res, false)
this.handleDeviceData(res, false, isUpdate)
} catch (error) {
uni.showToast({
title: '获取详情失败',
@ -1043,25 +1047,37 @@ export default {
},
// 操作说明
operatingInst() {
let id = this.apiType === 'listA' ? this.deviceID : this.itemInfo.deviceId
let id = this.computedDeviceId
uni.navigateTo({
url: `/pages/common/operatingInstruct/index?id=${id}`
})
},
// 产品参数
productparams() {
let id = this.apiType === 'listA' ? this.deviceID : this.itemInfo.deviceId
let id = this.computedDeviceId
uni.navigateTo({
url: `/pages/common/productDes/index?id=${id}`
})
},
// 操作视频
operatingVideo() {
let id = this.apiType === 'listA' ? this.deviceID : this.itemInfo.deviceId
let id = this.computedDeviceId
uni.navigateTo({
url: `/pages/common/operationVideo/index?id=${id}`
})
},
// 发送mqtt查询设备信息
queryDeviceStatus() {
if (this.mqttClient && this.mqttClient.isConnected()) {
const topic = `B/${this.itemInfo.deviceImei}`;
const message = '{"instruct":[12,0,0,0,0]}';
this.mqttClient.publish(topic, message, {
qos: 1
});
} else {
console.log('MQTT not connected, cannot query status.');
}
},
},
onLoad(options) {
@ -1086,22 +1102,57 @@ export default {
this.mqttClient.subscribe(statusTopic, (payload) => {
try {
console.log(`收到来自 ${statusTopic} 的消息:`, payload);
//收到电量上报。延迟20s请求接口数据
//收到电量上报。
const parsedMessage = typeof payload === 'string' ? JSON.parse(
payload) :
payload;
const deviceState = parsedMessage.state; // 直接取 state 数组
if (deviceState[0] === 12) {
// 这里延迟20s解决,经纬度,逆解析问题
setTimeout(() => {
this.fetchDeviceDetail(data.data.id);
}, 20000);
// 这里判断电量低于20%,弹框提示
if (this.deviceInfo.batteryPercentage < 20) {
this.popupType = 'bettery'
this.popupMessage = '请及时充电';
this.showPopupFlag = true;
if (deviceState && deviceState[0] === 12) {
// 根据协议直接更新设备状态,提供即时反馈
const mainLightMode = deviceState[1];
switch (mainLightMode) {
case 0:
this.currentMainMode = '关闭';
break;
case 1:
this.currentMainMode = '强光';
break;
case 2:
this.currentMainMode = '弱光';
break;
case 3:
this.currentMainMode = '爆闪';
break;
case 4:
this.currentMainMode = '泛光';
break;
default:
console.log('未知的灯光模式:', mainLightMode);
}
const laserMode = deviceState[2];
this.isLaserOn = laserMode === 1;
this.currentlaserMode = this.isLaserOn ? "开启" : "关闭";
if (this.deviceInfo) {
this.deviceInfo.batteryPercentage = deviceState[3];
this.deviceInfo.chargeState = deviceState[4];
this.deviceInfo.batteryRemainingTime = deviceState[5];
}
// 这里的10秒延迟是为了解决一个特定的后端问题
// GPS坐标上报后逆地址解析将坐标转换为地址需要一些时间。
// 如果立即请求设备详情,地址字段可能尚未更新。
// 这是一个临时解决方案,理想情况下应由后端通过消息通知或其他机制来确保数据一致性。
setTimeout(() => {
this.fetchDeviceDetail(data.data.id, true).then(() => {
// 在获取到最新信息后,再判断电量
if (this.deviceInfo.batteryPercentage < 20) {
this.popupType = 'bettery';
this.popupMessage = '请及时充电';
this.showPopupFlag = true;
}
});
}, 10000);
// ✅ 发送全局事件通知主页面更新
uni.$emit('deviceStatusUpdate', {
message: parsedMessage, // 消息内容
@ -1112,6 +1163,8 @@ export default {
console.log('解析MQTT消息失败:', error, '原始消息:', payload);
}
});
// 连接成功后,立即查询一次设备状态
this.queryDeviceStatus();
})
if (this.apiType === 'listA') {
this.fetchDeviceDetail(data.data.id)
@ -1132,9 +1185,6 @@ export default {
if (this.mqttClient) {
this.mqttClient.disconnect();
}
if (this.mqttClient) {
this.mqttClient.disconnect();
}
},
}