mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-23 23:53:55 +08:00
update:websocket播报6位验证码 (#821)
This commit is contained in:
@@ -52,4 +52,7 @@ public interface ErrorCode {
|
||||
int PARAM_BOOLEAN_INVALID = 10038;
|
||||
int PARAM_ARRAY_INVALID = 10039;
|
||||
int PARAM_JSON_INVALID = 10040;
|
||||
|
||||
int OTA_DEVICE_NOT_FOUND = 10041;
|
||||
int OTA_DEVICE_NEED_BIND = 10042;
|
||||
}
|
||||
|
||||
+7
-1
@@ -9,6 +9,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import xiaozhi.common.exception.ErrorCode;
|
||||
import xiaozhi.common.exception.RenException;
|
||||
import xiaozhi.common.redis.RedisKeys;
|
||||
import xiaozhi.common.redis.RedisUtils;
|
||||
@@ -83,7 +84,12 @@ public class ConfigServiceImpl implements ConfigService {
|
||||
// 根据MAC地址查找设备
|
||||
DeviceEntity device = deviceService.getDeviceByMacAddress(macAddress);
|
||||
if (device == null) {
|
||||
throw new RenException("设备未找到");
|
||||
// 如果设备,去redis里看看有没有需要连接的设备
|
||||
String cachedCode = deviceService.geCodeByDeviceId(macAddress);
|
||||
if (StringUtils.isNotBlank(cachedCode)) {
|
||||
throw new RenException(ErrorCode.OTA_DEVICE_NEED_BIND, cachedCode);
|
||||
}
|
||||
throw new RenException(ErrorCode.OTA_DEVICE_NOT_FOUND, "not found device");
|
||||
}
|
||||
// 获取智能体信息
|
||||
AgentEntity agent = agentService.getAgentById(device.getAgentId());
|
||||
|
||||
@@ -37,9 +37,7 @@ public class OTAController {
|
||||
@PostMapping
|
||||
public ResponseEntity<String> checkOTAVersion(
|
||||
@RequestBody DeviceReportReqDTO deviceReportReqDTO,
|
||||
|
||||
@Parameter(name = "Device-Id", description = "设备唯一标识", required = true, in = ParameterIn.HEADER) @RequestHeader("Device-Id") String deviceId,
|
||||
|
||||
@Parameter(name = "Client-Id", description = "客户端标识", required = true, in = ParameterIn.HEADER) @RequestHeader("Client-Id") String clientId) {
|
||||
if (StringUtils.isAnyBlank(deviceId, clientId)) {
|
||||
return createResponse(DeviceReportRespDTO.createError("Device ID is required"));
|
||||
@@ -50,10 +48,9 @@ public class OTAController {
|
||||
if (!deviceId.equals(macAddress) || !macAddressValid || deviceReportReqDTO.getApplication() == null) {
|
||||
return createResponse(DeviceReportRespDTO.createError("Invalid OTA request"));
|
||||
}
|
||||
return createResponse(deviceService.checkDeviceActive(macAddress, deviceId, clientId, deviceReportReqDTO));
|
||||
return createResponse(deviceService.checkDeviceActive(macAddress, clientId, deviceReportReqDTO));
|
||||
}
|
||||
|
||||
@Operation(summary = "获取 OTA 提示信息")
|
||||
@GetMapping
|
||||
public ResponseEntity<String> getOTAPrompt() {
|
||||
return createResponse(DeviceReportRespDTO.createError("请提交正确的ota参数"));
|
||||
|
||||
@@ -19,7 +19,7 @@ public interface DeviceService {
|
||||
/**
|
||||
* 检查设备是否激活
|
||||
*/
|
||||
DeviceReportRespDTO checkDeviceActive(String macAddress, String deviceId, String clientId,
|
||||
DeviceReportRespDTO checkDeviceActive(String macAddress, String clientId,
|
||||
DeviceReportReqDTO deviceReport);
|
||||
|
||||
/**
|
||||
@@ -74,4 +74,12 @@ public interface DeviceService {
|
||||
* @return 设备信息
|
||||
*/
|
||||
DeviceEntity getDeviceByMacAddress(String macAddress);
|
||||
|
||||
/**
|
||||
* 根据设备ID获取激活码
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @return 激活码
|
||||
*/
|
||||
String geCodeByDeviceId(String deviceId);
|
||||
}
|
||||
+59
-37
@@ -120,7 +120,7 @@ public class DeviceServiceImpl extends BaseServiceImpl<DeviceDao, DeviceEntity>
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeviceReportRespDTO checkDeviceActive(String macAddress, String deviceId, String clientId,
|
||||
public DeviceReportRespDTO checkDeviceActive(String macAddress, String clientId,
|
||||
DeviceReportReqDTO deviceReport) {
|
||||
DeviceReportRespDTO response = new DeviceReportRespDTO();
|
||||
response.setServer_time(buildServerTime());
|
||||
@@ -132,46 +132,12 @@ public class DeviceServiceImpl extends BaseServiceImpl<DeviceDao, DeviceEntity>
|
||||
firmware.setUrl("http://localhost:8002/xiaozhi/ota/download");
|
||||
response.setFirmware(firmware);
|
||||
|
||||
DeviceEntity deviceById = getDeviceById(deviceId);
|
||||
DeviceEntity deviceById = getDeviceById(macAddress);
|
||||
if (deviceById != null) { // 如果设备存在,则更新上次连接时间
|
||||
deviceById.setLastConnectedAt(new Date());
|
||||
deviceDao.updateById(deviceById);
|
||||
} else { // 如果设备不存在,则生成激活码
|
||||
String safeDeviceId = deviceId.replace(":", "_").toLowerCase();
|
||||
String dataKey = String.format("ota:activation:data:%s", safeDeviceId);
|
||||
|
||||
Map<Object, Object> cacheMap = redisTemplate.opsForHash().entries(dataKey);
|
||||
DeviceReportRespDTO.Activation code = new DeviceReportRespDTO.Activation();
|
||||
|
||||
if (cacheMap != null && cacheMap.containsKey("activation_code")) {
|
||||
String cachedCode = (String) cacheMap.get("activation_code");
|
||||
code.setCode(cachedCode);
|
||||
code.setMessage(frontedUrl + "\n" + cachedCode);
|
||||
} else {
|
||||
String newCode = RandomUtil.randomNumbers(6);
|
||||
code.setCode(newCode);
|
||||
code.setMessage(frontedUrl + "\n" + newCode);
|
||||
|
||||
Map<String, Object> dataMap = new HashMap<>();
|
||||
dataMap.put("id", deviceId);
|
||||
dataMap.put("mac_address", macAddress);
|
||||
dataMap.put("board", (deviceReport.getChipModelName() != null) ? deviceReport.getChipModelName()
|
||||
: (deviceReport.getBoard() != null ? deviceReport.getBoard().getType() : "unknown"));
|
||||
dataMap.put("app_version", (deviceReport.getApplication() != null)
|
||||
? deviceReport.getApplication().getVersion()
|
||||
: null);
|
||||
dataMap.put("deviceId", deviceId);
|
||||
dataMap.put("activation_code", newCode);
|
||||
|
||||
// 写入主数据 key
|
||||
redisTemplate.opsForHash().putAll(dataKey, dataMap);
|
||||
redisTemplate.expire(dataKey, 24, TimeUnit.HOURS);
|
||||
|
||||
// 写入反查激活码 key
|
||||
String codeKey = "ota:activation:code:" + newCode;
|
||||
redisTemplate.opsForValue().set(codeKey, deviceId, 24, TimeUnit.HOURS);
|
||||
}
|
||||
|
||||
DeviceReportRespDTO.Activation code = buildActivation(macAddress, deviceReport);
|
||||
response.setActivation(code);
|
||||
}
|
||||
|
||||
@@ -258,4 +224,60 @@ public class DeviceServiceImpl extends BaseServiceImpl<DeviceDao, DeviceEntity>
|
||||
serverTime.setTimezone_offset(tz.getOffset(System.currentTimeMillis()) / (60 * 1000));
|
||||
return serverTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String geCodeByDeviceId(String deviceId) {
|
||||
String dataKey = getDeviceCacheKey(deviceId);
|
||||
|
||||
Map<Object, Object> cacheMap = redisTemplate.opsForHash().entries(dataKey);
|
||||
if (cacheMap != null && cacheMap.containsKey("activation_code")) {
|
||||
String cachedCode = (String) cacheMap.get("activation_code");
|
||||
return cachedCode;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getDeviceCacheKey(String deviceId) {
|
||||
String safeDeviceId = deviceId.replace(":", "_").toLowerCase();
|
||||
String dataKey = String.format("ota:activation:data:%s", safeDeviceId);
|
||||
return dataKey;
|
||||
}
|
||||
|
||||
public DeviceReportRespDTO.Activation buildActivation(String deviceId, DeviceReportReqDTO deviceReport) {
|
||||
DeviceReportRespDTO.Activation code = new DeviceReportRespDTO.Activation();
|
||||
|
||||
String cachedCode = geCodeByDeviceId(deviceId);
|
||||
|
||||
if (StringUtils.isNotBlank(cachedCode)) {
|
||||
code.setCode(cachedCode);
|
||||
code.setMessage(frontedUrl + "\n" + cachedCode);
|
||||
} else {
|
||||
String newCode = RandomUtil.randomNumbers(6);
|
||||
code.setCode(newCode);
|
||||
code.setMessage(frontedUrl + "\n" + newCode);
|
||||
|
||||
Map<String, Object> dataMap = new HashMap<>();
|
||||
dataMap.put("id", deviceId);
|
||||
dataMap.put("mac_address", deviceId);
|
||||
|
||||
dataMap.put("board", (deviceReport.getChipModelName() != null) ? deviceReport.getChipModelName()
|
||||
: (deviceReport.getBoard() != null ? deviceReport.getBoard().getType() : "unknown"));
|
||||
dataMap.put("app_version", (deviceReport.getApplication() != null)
|
||||
? deviceReport.getApplication().getVersion()
|
||||
: null);
|
||||
|
||||
dataMap.put("deviceId", deviceId);
|
||||
dataMap.put("activation_code", newCode);
|
||||
|
||||
// 写入主数据 key
|
||||
String dataKey = getDeviceCacheKey(deviceId);
|
||||
redisTemplate.opsForHash().putAll(dataKey, dataMap);
|
||||
redisTemplate.expire(dataKey, 24, TimeUnit.HOURS);
|
||||
|
||||
// 写入反查激活码 key
|
||||
String codeKey = "ota:activation:code:" + newCode;
|
||||
redisTemplate.opsForValue().set(codeKey, deviceId, 24, TimeUnit.HOURS);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
}
|
||||
@@ -41,3 +41,6 @@
|
||||
10038=\u53C2\u6570\u503C\u5FC5\u987B\u662Ftrue\u6216false
|
||||
10039=\u53C2\u6570\u503C\u5FC5\u987B\u662F\u6709\u6548\u7684JSON\u6570\u7EC4\u683C\u5F0F
|
||||
10040=\u53C2\u6570\u503C\u5FC5\u987B\u662F\u6709\u6548\u7684JSON\u683C\u5F0F
|
||||
|
||||
10041=\u8BBE\u5907\u672A\u627E\u5230
|
||||
10042={0}
|
||||
|
||||
@@ -40,4 +40,7 @@
|
||||
10037=Parameter value must be a valid number
|
||||
10038=Parameter value must be true or false
|
||||
10039=Parameter value must be a valid JSON array format
|
||||
10040=Parameter value must be a valid JSON format
|
||||
10040=Parameter value must be a valid JSON format
|
||||
|
||||
10041=Device not found
|
||||
10042={0}
|
||||
@@ -40,4 +40,7 @@
|
||||
10037=\u53C2\u6570\u503C\u5FC5\u987B\u662F\u6709\u6548\u7684\u6570\u5B57
|
||||
10038=\u53C2\u6570\u503C\u5FC5\u987B\u662Ftrue\u6216false
|
||||
10039=\u53C2\u6570\u503C\u5FC5\u987B\u662F\u6709\u6548\u7684JSON\u6570\u7EC4\u683C\u5F0F
|
||||
10040=\u53C2\u6570\u503C\u5FC5\u987B\u662F\u6709\u6548\u7684JSON\u683C\u5F0F
|
||||
10040=\u53C2\u6570\u503C\u5FC5\u987B\u662F\u6709\u6548\u7684JSON\u683C\u5F0F
|
||||
|
||||
10041=\u8BBE\u5907\u672A\u627E\u5230
|
||||
10042={0}
|
||||
@@ -40,4 +40,7 @@
|
||||
10037=\u53C3\u6578\u503C\u5FC5\u9808\u662F\u6709\u6548\u7684\u6578\u5B57
|
||||
10038=\u53C3\u6578\u503C\u5FC5\u9808\u662Ftrue\u6216false
|
||||
10039=\u53C3\u6578\u503C\u5FC5\u9808\u662F\u6709\u6548\u7684JSON\u6578\u7D44\u683C\u5F0F
|
||||
10040=\u53C3\u6578\u503C\u5FC5\u9808\u662F\u6709\u6548\u7684JSON\u683C\u5F0F
|
||||
10040=\u53C3\u6578\u503C\u5FC5\u9808\u662F\u6709\u6548\u7684JSON\u683C\u5F0F
|
||||
|
||||
10041=\u8A2D\u5099\u672A\u627E\u5230
|
||||
10042={0}
|
||||
@@ -33,3 +33,5 @@ timbre.ttsModelId.require=\u97F3\u8272\u7684tts\u4E3B\u952E\u4E0D\u53EF\u4EE5\u4
|
||||
timbre.ttsVoice.require=\u97F3\u8272\u7684\u7F16\u7801\u4E0D\u53EF\u4EE5\u4E3A\u7A7A
|
||||
timbre.voiceDemo.require=\u97F3\u8272\u7684\u64AD\u653EDemo\u4E0D\u53EF\u4EE5\u4E3A\u7A7A
|
||||
|
||||
ota.device.not.found=\u8BBE\u5907\u672A\u627E\u5230
|
||||
ota.device.need.bind={0}
|
||||
|
||||
@@ -32,3 +32,5 @@ timbre.ttsModelId.require=The TTS model ID of the timbre cannot be empty
|
||||
timbre.ttsVoice.require=The TTS voice of the timbre cannot be empty
|
||||
timbre.voiceDemo.require=The voice demo of the timbre cannot be empty
|
||||
|
||||
ota.device.not.found=Device not found
|
||||
ota.device.need.bind={0}
|
||||
@@ -32,3 +32,5 @@ timbre.ttsModelId.require=\u97F3\u8272\u7684tts\u4E3B\u9375\u4E0D\u53EF\u4EE5\u7
|
||||
timbre.ttsVoice.require=\u97F3\u8272\u7684\u7DE8\u78BC\u4E0D\u53EF\u4EE5\u70BA\u7A7A
|
||||
timbre.voiceDemo.require=\u97F3\u8272\u7684\u64AD\u653E\u5730\u5740\u4E0D\u53EF\u4EE5\u70BA\u7A7A
|
||||
|
||||
ota.device.not.found=\u8A2D\u5099\u672A\u627E\u5230
|
||||
ota.device.need.bind={0}
|
||||
@@ -31,3 +31,6 @@ timbre.remark.require=\u97F3\u8272\u7684\u5907\u6CE8\u4E0D\u53EF\u4EE5\u4E3A\u7A
|
||||
timbre.ttsModelId.require=\u97F3\u8272\u7684tts\u4E3B\u952E\u4E0D\u53EF\u4EE5\u4E3A\u7A7A
|
||||
timbre.ttsVoice.require=\u97F3\u8272\u7684\u7F16\u7801\u4E0D\u53EF\u4EE5\u4E3A\u7A7A
|
||||
timbre.voiceDemo.require=\u97F3\u8272\u7684\u64AD\u653EDemo\u4E0D\u53EF\u4EE5\u4E3A\u7A7A
|
||||
|
||||
ota.device.not.found=\u8A2D\u5099\u672A\u627E\u5230
|
||||
ota.device.need.bind={0}
|
||||
Reference in New Issue
Block a user