Merge remote-tracking branch 'origin/dev/0.6_WeChat' into dev/0.6_WeChat
This commit is contained in:
commit
df0c9890e8
@ -72,8 +72,8 @@ public class DeviceStatusConsumer {
|
||||
|
||||
private SnowflakeIdWorker snowflakeIdWorker = new SnowflakeIdWorker(2);
|
||||
|
||||
private static final String IMEI_CMD = "AT+IMEI\\r\\n";
|
||||
private static final String ICCID_CMD = "AT+ICCID\\r\\n";
|
||||
private static final String IMEI_CMD = "41542b494d45495c525c6e"; // AT+IMEI\r\n
|
||||
private static final String ICCID_CMD = "41542b49434349445c525c6e"; // AT+ICCID\r\n
|
||||
private static final int AUTO_FETCH_COOLDOWN_SECONDS = 300;
|
||||
private static final String AUTO_FETCH_KEY_PREFIX = "iot:autoFetch:imeiIccid:";
|
||||
|
||||
@ -131,6 +131,7 @@ public class DeviceStatusConsumer {
|
||||
|
||||
private void autoFetchImeiIccidIfNeeded(Device device) {
|
||||
if (device == null || StringUtils.isEmpty(device.getSerialNumber())) {
|
||||
log.info("=>设备首次上线,设备为空{}", device);
|
||||
return;
|
||||
}
|
||||
String serialNumber = device.getSerialNumber();
|
||||
@ -138,6 +139,7 @@ public class DeviceStatusConsumer {
|
||||
boolean needImei = StringUtils.isEmpty(device.getImei());
|
||||
boolean needIccid = StringUtils.isEmpty(device.getIccid());
|
||||
if (!needImei && !needIccid) {
|
||||
log.info("=>设备首次上线,设备已存在IMEI/ICCID,无需获取{}", device);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -145,6 +147,7 @@ public class DeviceStatusConsumer {
|
||||
String key = AUTO_FETCH_KEY_PREFIX + serialNumber + ":imei";
|
||||
if (!redisCache.containsKey(key)) {
|
||||
redisCache.setCacheObject(key, "1", AUTO_FETCH_COOLDOWN_SECONDS, TimeUnit.SECONDS);
|
||||
log.info("=>设备首次上线,下发AT指令获取IMEI,{}", device);
|
||||
sendAtCommand(serialNumber, IMEI_CMD);
|
||||
}
|
||||
}
|
||||
@ -153,6 +156,7 @@ public class DeviceStatusConsumer {
|
||||
String key = AUTO_FETCH_KEY_PREFIX + serialNumber + ":iccid";
|
||||
if (!redisCache.containsKey(key)) {
|
||||
redisCache.setCacheObject(key, "1", AUTO_FETCH_COOLDOWN_SECONDS, TimeUnit.SECONDS);
|
||||
log.info("=>设备首次上线,下发AT指令获取ICCID,{}", device);
|
||||
sendAtCommand(serialNumber, ICCID_CMD);
|
||||
}
|
||||
}
|
||||
|
||||
@ -661,11 +661,21 @@ export default {
|
||||
if (type === 'imei') this.imeiLoading = true;
|
||||
if (type === 'iccid') this.iccidLoading = true;
|
||||
|
||||
// FUNCTION_GET 下发链路最终会走 ByteUtils.convertToHexByteArray(command)。
|
||||
// 因此这里必须传“十六进制字节串”,而不是原始 ASCII。
|
||||
// 同时兼容两种输入:
|
||||
// 1) 用户输入 AT+IMEI\\r\\n 这类带转义的 ASCII:会先还原成真实 \r\n,再转 hex(不带空格)
|
||||
// 2) 用户直接输入 41 54 ... 或 41542b...:会清理空格后直接使用(后端也会再次清理)
|
||||
const trimmed = String(cmd).trim();
|
||||
const hexMessage = this.isHexLike(trimmed)
|
||||
? this.normalizeHexString(trimmed)
|
||||
: this.asciiCommandToHex(this.normalizeAtEscapes(trimmed));
|
||||
|
||||
await messagePost({
|
||||
message: cmd,
|
||||
message: hexMessage,
|
||||
serialNumber: this.deviceInfo.serialNumber,
|
||||
topicName: '/function/get',
|
||||
dataType: 'ascii',
|
||||
dataType: 'hex',
|
||||
});
|
||||
this.$message({ type: 'success', message: '已下发指令,等待设备回复解析…' });
|
||||
|
||||
@ -680,6 +690,45 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
normalizeAtEscapes(str) {
|
||||
// 输入框里用户通常会键入:AT+IMEI\\r\\n
|
||||
// 但你当前的设备/链路期望的不是“真实 CR/LF(0d0a)”,而是把转义串当作占位符:
|
||||
// 把 \\r\\n 期望转成 "/r/n"(即字符 '/','r','/','n',十六进制为 2f 72 2f 6e)。
|
||||
if (!str) return '';
|
||||
return String(str)
|
||||
.replace(/\\r\\n/g, '/r/n')
|
||||
.replace(/\\r/g, '/r')
|
||||
.replace(/\\n/g, '/n');
|
||||
},
|
||||
|
||||
isHexLike(hexStr) {
|
||||
if (!hexStr) return false;
|
||||
const cleaned = this.normalizeHexString(hexStr);
|
||||
if (!cleaned) return false;
|
||||
return /^[0-9a-fA-F]+$/.test(cleaned);
|
||||
},
|
||||
|
||||
normalizeHexString(hexStr) {
|
||||
if (!hexStr) return '';
|
||||
return String(hexStr)
|
||||
.trim()
|
||||
.replace(/\s+/g, '')
|
||||
.replace(/^0x/i, '');
|
||||
},
|
||||
|
||||
asciiCommandToHex(asciiStr) {
|
||||
// 把字符串按字节(低8位)转成纯16进制(无空格)
|
||||
if (!asciiStr) return '';
|
||||
let hex = '';
|
||||
for (let i = 0; i < asciiStr.length; i++) {
|
||||
const c = asciiStr.charCodeAt(i) & 0xff;
|
||||
let hexByte = c.toString(16).toUpperCase();
|
||||
if (hexByte.length === 1) hexByte = `0${hexByte}`;
|
||||
hex += hexByte;
|
||||
}
|
||||
return hex;
|
||||
},
|
||||
|
||||
async saveImeiIccid(type) {
|
||||
try {
|
||||
if (!this.deviceInfo || !this.deviceInfo.deviceId) return;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user