diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/controller/AppAuthController.java b/fys-admin/src/main/java/com/fuyuanshen/app/controller/AppAuthController.java index 0cd57e28..7be1be8b 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/controller/AppAuthController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/controller/AppAuthController.java @@ -72,10 +72,8 @@ public class AppAuthController { private final AppLoginService loginService; private final AppRegisterService registerService; - private final ISysConfigService configService; private final ISysTenantService tenantService; private final ISysClientService clientService; - private final ISysDictTypeService dictTypeService; /** diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/controller/AppDeviceController.java b/fys-admin/src/main/java/com/fuyuanshen/app/controller/AppDeviceController.java index 402244e4..02976bfc 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/controller/AppDeviceController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/controller/AppDeviceController.java @@ -92,4 +92,5 @@ public class AppDeviceController extends BaseController { public R getDeviceInfo(String deviceMac) { return R.ok(appDeviceService.getDeviceInfo(deviceMac)); } + } diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/controller/AppDeviceShareController.java b/fys-admin/src/main/java/com/fuyuanshen/app/controller/AppDeviceShareController.java index 388c84f7..9cb4249e 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/controller/AppDeviceShareController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/controller/AppDeviceShareController.java @@ -44,10 +44,9 @@ import static com.fuyuanshen.common.core.constant.GlobalConstants.DEVICE_SHARE_C @RequestMapping("/app/deviceShare") public class AppDeviceShareController extends BaseController { - private final IAppDeviceShareService deviceShareService; - private final AppDeviceShareService appDeviceShareService; + /** * 分享管理列表 */ @@ -95,6 +94,7 @@ public class AppDeviceShareController extends BaseController { return toAjax(appDeviceShareService.remove(ids)); } + /** * 短信验证码 * @@ -116,4 +116,5 @@ public class AppDeviceShareController extends BaseController { } return R.ok(); } + } diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/controller/AppFileController.java b/fys-admin/src/main/java/com/fuyuanshen/app/controller/AppFileController.java index 6c236218..012887f2 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/controller/AppFileController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/controller/AppFileController.java @@ -25,6 +25,7 @@ public class AppFileController extends BaseController { private final AppFileService appFileService; + /** * 查询文件列表 */ @@ -33,6 +34,7 @@ public class AppFileController extends BaseController { return R.ok(appFileService.list(bo)); } + /** * 上传文件 */ @@ -52,4 +54,5 @@ public class AppFileController extends BaseController { } return toAjax(appFileService.delete(ids)); } + } diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/controller/AppOperationVideoController.java b/fys-admin/src/main/java/com/fuyuanshen/app/controller/AppOperationVideoController.java index c695db74..5338ba2c 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/controller/AppOperationVideoController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/controller/AppOperationVideoController.java @@ -25,6 +25,7 @@ public class AppOperationVideoController extends BaseController { private final IAppOperationVideoService appOperationVideoService; + /** * 查询操作视频列表 */ @@ -68,4 +69,5 @@ public class AppOperationVideoController extends BaseController { public R deleteOperationVideo(@PathVariable Long id) { return toAjax(appOperationVideoService.deleteWithValidByIds(List.of(id), true)); } + } diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/receiver/DeviceMessageHandler.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/receiver/DeviceMessageHandler.java new file mode 100644 index 00000000..93217e87 --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/receiver/DeviceMessageHandler.java @@ -0,0 +1,277 @@ +package com.fuyuanshen.global.mqtt.receiver; + +import cn.hutool.core.lang.Dict; +import com.fuyuanshen.common.core.constant.GlobalConstants; +import com.fuyuanshen.common.core.utils.ImageToCArrayConverter; +import com.fuyuanshen.common.json.utils.JsonUtils; +import com.fuyuanshen.common.redis.utils.RedisUtils; +import com.fuyuanshen.global.mqtt.base.MqttRuleContext; +import com.fuyuanshen.global.mqtt.base.MqttRuleEngine; +import com.fuyuanshen.global.mqtt.base.MqttXinghanCommandType; +import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants; +import com.fuyuanshen.global.queue.MqttMessageQueueConstants; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHandler; +import org.springframework.messaging.MessageHeaders; +import org.springframework.messaging.MessagingException; +import org.springframework.stereotype.Service; + +import java.time.Duration; +import java.util.Objects; + +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX; + +/** + * @author: 默苍璃 + * @date: 2025-11-05 17:41 + */ +@Service +@Slf4j +public class DeviceMessageHandler implements MessageHandler { + + @Autowired + private MqttRuleEngine ruleEngine; + + + @Override + public void handleMessage(Message message) throws MessagingException { + Object payload = message.getPayload(); + MessageHeaders headers = message.getHeaders(); + String receivedTopic = Objects.requireNonNull(headers.get("mqtt_receivedTopic")).toString(); + String receivedQos = Objects.requireNonNull(headers.get("mqtt_receivedQos")).toString(); + String timestamp = Objects.requireNonNull(headers.get("timestamp")).toString(); + + log.info("MQTT payload= {} \n receivedTopic = {} \n receivedQos = {} \n timestamp = {}", + payload, receivedTopic, receivedQos, timestamp); + + Dict payloadDict = JsonUtils.parseMap(payload.toString()); + if (receivedTopic == null || payloadDict == null) { + return; + } + + // 解析设备IMEI + String[] subStr = receivedTopic.split("/"); + String deviceImei = subStr[1]; + + // 处理设备在线状态 + handleDeviceOnlineStatus(deviceImei); + + // 处理不同类型的设备信息 + processDeviceInformation(payloadDict, deviceImei); + + // 执行规则引擎处理 + executeRuleEngine(payloadDict, deviceImei); + } + + + /** + * 处理设备在线状态 + */ + private void handleDeviceOnlineStatus(String deviceImei) { + if (StringUtils.isNotBlank(deviceImei)) { + // 添加去重队列 + String queueKey = MqttMessageQueueConstants.MQTT_MESSAGE_QUEUE_KEY; + String dedupKey = MqttMessageQueueConstants.MQTT_MESSAGE_DEDUP_KEY; + RedisUtils.offerDeduplicated(queueKey, dedupKey, deviceImei, Duration.ofSeconds(900)); + + // 设置设备在线状态 + String deviceOnlineStatusRedisKey = GlobalConstants.GLOBAL_REDIS_KEY + + DEVICE_KEY_PREFIX + deviceImei + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX; + RedisUtils.setCacheObject(deviceOnlineStatusRedisKey, "1", Duration.ofSeconds(360)); + } + } + + + /** + * 处理不同类型的设备信息 + */ + private void processDeviceInformation(Dict payloadDict, String deviceImei) { + // 开机画面 + if (payloadDict.containsKey("bootScreen")) { + handleBootScreen(payloadDict, deviceImei); + } + + // 人员信息 + if (payloadDict.containsKey("personInfo")) { + handlePersonInfo(payloadDict, deviceImei); + } + + // 设备信息 + if (payloadDict.containsKey("deviceInfo")) { + handleDeviceInfo(payloadDict, deviceImei); + } + + // 经纬度 + if (payloadDict.containsKey("latitude") && payloadDict.containsKey("longitude")) { + handleLocation(payloadDict, deviceImei); + } + + // 电子地图 + if (payloadDict.containsKey("mapData")) { + handleMapData(payloadDict, deviceImei); + } + + // 电池电量 + if (payloadDict.containsKey("batteryLevel")) { + handleBatteryLevel(payloadDict, deviceImei); + } + + // 开启/关闭状态 + if (payloadDict.containsKey("powerState")) { + handlePowerState(payloadDict, deviceImei); + } + + // 海拔高度 + if (payloadDict.containsKey("altitude")) { + handleAltitude(payloadDict, deviceImei); + } + + // 相对高度 + if (payloadDict.containsKey("relativeHeight")) { + handleRelativeHeight(payloadDict, deviceImei); + } + + // 群呼/单呼 + if (payloadDict.containsKey("callType")) { + handleCallType(payloadDict, deviceImei); + } + + // 文字信息 + if (payloadDict.containsKey("textMessage")) { + handleTextMessage(payloadDict, deviceImei); + } + } + + /** + * 处理开机画面 + */ + private void handleBootScreen(Dict payloadDict, String deviceImei) { + log.info("处理设备{}的开机画面信息", deviceImei); + // 实现具体的开机画面处理逻辑 + } + + /** + * 处理人员信息 + */ + private void handlePersonInfo(Dict payloadDict, String deviceImei) { + log.info("处理设备{}的人员信息", deviceImei); + // 实现具体的人员信息处理逻辑 + } + + /** + * 处理设备信息 + */ + private void handleDeviceInfo(Dict payloadDict, String deviceImei) { + log.info("处理设备{}的设备信息", deviceImei); + // 实现具体的设备信息处理逻辑 + } + + /** + * 处理位置信息 + */ + private void handleLocation(Dict payloadDict, String deviceImei) { + log.info("处理设备{}的位置信息: 纬度={}, 经度={}", + deviceImei, payloadDict.getStr("latitude"), payloadDict.getStr("longitude")); + // 实现具体的位置信息处理逻辑 + } + + /** + * 处理电子地图数据 + */ + private void handleMapData(Dict payloadDict, String deviceImei) { + log.info("处理设备{}的电子地图数据", deviceImei); + // 实现具体的电子地图数据处理逻辑 + } + + /** + * 处理电池电量 + */ + private void handleBatteryLevel(Dict payloadDict, String deviceImei) { + log.info("处理设备{}的电池电量: {}", deviceImei, payloadDict.getStr("batteryLevel")); + // 实现具体的电池电量处理逻辑 + } + + /** + * 处理开关状态 + */ + private void handlePowerState(Dict payloadDict, String deviceImei) { + String powerState = payloadDict.getStr("powerState"); + log.info("处理设备{}的开关状态: {}", deviceImei, powerState); + // 实现具体的开关状态处理逻辑 + } + + /** + * 处理海拔高度 + */ + private void handleAltitude(Dict payloadDict, String deviceImei) { + log.info("处理设备{}的海拔高度: {}", deviceImei, payloadDict.getStr("altitude")); + // 实现具体的海拔高度处理逻辑 + } + + /** + * 处理相对高度 + */ + private void handleRelativeHeight(Dict payloadDict, String deviceImei) { + log.info("处理设备{}的相对高度: {}", deviceImei, payloadDict.getStr("relativeHeight")); + // 实现具体的相对高度处理逻辑 + } + + /** + * 处理呼叫类型 + */ + private void handleCallType(Dict payloadDict, String deviceImei) { + String callType = payloadDict.getStr("callType"); + log.info("处理设备{}的呼叫类型: {}", deviceImei, callType); + // 实现具体的呼叫类型处理逻辑 + } + + /** + * 处理文字信息 + */ + private void handleTextMessage(Dict payloadDict, String deviceImei) { + String textMessage = payloadDict.getStr("textMessage"); + log.info("处理设备{}的文字信息: {}", deviceImei, textMessage); + // 实现具体的文字信息处理逻辑 + } + + /** + * 执行规则引擎处理 + */ + private void executeRuleEngine(Dict payloadDict, String deviceImei) { + String state = payloadDict.getStr("state"); + Object[] convertArr = ImageToCArrayConverter.convertByteStringToMixedObjectArray(state); + + if (convertArr.length > 0) { + Byte val1 = (Byte) convertArr[0]; + MqttRuleContext context = new MqttRuleContext(); + context.setCommandType(val1); + context.setConvertArr(convertArr); + context.setDeviceImei(deviceImei); + context.setPayloadDict(payloadDict); + + boolean ruleExecuted = ruleEngine.executeRule(context); + + if (!ruleExecuted) { + log.warn("未找到匹配的规则来处理命令类型: {}", val1); + } + } + + /* ===== 追加:根据报文内容识别格式并统一解析 ===== */ + int intType = MqttXinghanCommandType.computeVirtualCommandType(payloadDict); + if (intType > 0) { + MqttRuleContext newCtx = new MqttRuleContext(); + newCtx.setCommandType((byte) intType); + newCtx.setDeviceImei(deviceImei); + newCtx.setPayloadDict(payloadDict); + + boolean ok = ruleEngine.executeRule(newCtx); + if (!ok) { + log.warn("新规则引擎未命中, imei={}", deviceImei); + } + } + } + +} diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/receiver/ReceiverMessageHandler.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/receiver/ReceiverMessageHandler.java index 55f24c6f..5b266129 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/receiver/ReceiverMessageHandler.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/receiver/ReceiverMessageHandler.java @@ -90,4 +90,5 @@ public class ReceiverMessageHandler implements MessageHandler { } } } + } diff --git a/fys-admin/src/main/java/com/fuyuanshen/mp/controller/MPAuthController.java b/fys-admin/src/main/java/com/fuyuanshen/mp/controller/MPAuthController.java index cec5b4a9..fc04d02c 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/mp/controller/MPAuthController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/mp/controller/MPAuthController.java @@ -63,10 +63,6 @@ import java.util.Map; @RequestMapping("/mp") public class MPAuthController { - private final AppLoginService loginService; - private final SysRegisterService registerService; - private final ISysConfigService configService; - private final ISysTenantService tenantService; private final ISysClientService clientService; private final MPAuthService mpAuthService; private final MPService mpService; @@ -74,7 +70,7 @@ public class MPAuthController { @Operation(summary = "小程序登录授权") @PostMapping(value = "/login") - public ResponseEntity login(@RequestBody AuthUserDto authUser, HttpServletRequest request) throws Exception { + public ResponseEntity login(@RequestBody AuthUserDto authUser) throws Exception { Long phoneNumber = authUser.getPhoneNumber(); // 判断小程序用户是否存在,不存在创建 diff --git a/fys-admin/src/main/java/com/fuyuanshen/mp/service/MPAuthService.java b/fys-admin/src/main/java/com/fuyuanshen/mp/service/MPAuthService.java index 7ab05c37..c6a59be3 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/mp/service/MPAuthService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/mp/service/MPAuthService.java @@ -60,9 +60,9 @@ import java.util.function.Supplier; @Service public class MPAuthService { - private final ISysUserService userService; private final AppUserService appUserService; + /** * 小程序注册 */ @@ -128,6 +128,7 @@ public class MPAuthService { return loginVo; } + /** * 构建登录用户 */ @@ -160,5 +161,4 @@ public class MPAuthService { } - } diff --git a/fys-admin/src/main/java/com/fuyuanshen/mp/service/MPService.java b/fys-admin/src/main/java/com/fuyuanshen/mp/service/MPService.java index 720720ff..0835ecaa 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/mp/service/MPService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/mp/service/MPService.java @@ -10,11 +10,8 @@ import org.springframework.stereotype.Service; * * @author Lion Li */ - - public interface MPService { - /** * 获取小程序用户信息 * @@ -23,4 +20,5 @@ public interface MPService { UserApp getMpUser(Long phoneNumber); UserApp loadUserByUsername(String username); + } diff --git a/fys-admin/src/main/java/com/fuyuanshen/mp/service/impl/MPAuthServiceImpl.java b/fys-admin/src/main/java/com/fuyuanshen/mp/service/impl/MPAuthServiceImpl.java index 11a05e7f..724294f0 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/mp/service/impl/MPAuthServiceImpl.java +++ b/fys-admin/src/main/java/com/fuyuanshen/mp/service/impl/MPAuthServiceImpl.java @@ -8,5 +8,4 @@ package com.fuyuanshen.mp.service.impl; public class MPAuthServiceImpl { - } diff --git a/fys-admin/src/main/java/com/fuyuanshen/mp/service/impl/MPServiceImpl.java b/fys-admin/src/main/java/com/fuyuanshen/mp/service/impl/MPServiceImpl.java index 05063142..80b22147 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/mp/service/impl/MPServiceImpl.java +++ b/fys-admin/src/main/java/com/fuyuanshen/mp/service/impl/MPServiceImpl.java @@ -19,11 +19,9 @@ import org.springframework.stereotype.Service; @RequiredArgsConstructor public class MPServiceImpl implements MPService { - private final AppUserService appUserService; - /** * 获取小程序用户信息 * diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/controller/CaptchaController.java b/fys-admin/src/main/java/com/fuyuanshen/web/controller/CaptchaController.java index 30d7106e..c0d9c39b 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/controller/CaptchaController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/controller/CaptchaController.java @@ -51,6 +51,7 @@ public class CaptchaController { private final CaptchaProperties captchaProperties; private final MailProperties mailProperties; + /** * 短信验证码 * diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceXinghanController.java b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceXinghanController.java index 5e95b70c..7ab4f902 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceXinghanController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceXinghanController.java @@ -160,4 +160,5 @@ public class DeviceXinghanController extends BaseController { RedisUtils.setCacheObject(versionKey, json, Duration.ofDays(30)); return R.ok(); } + } diff --git a/fys-admin/src/main/resources/application-dev.yml b/fys-admin/src/main/resources/application-dev.yml index bf89eda2..169c4bfe 100644 --- a/fys-admin/src/main/resources/application-dev.yml +++ b/fys-admin/src/main/resources/application-dev.yml @@ -279,11 +279,11 @@ justauth: # MQTT配置 mqtt: username: admin - password: #YtvpSfCNG - url: tcp://www.cnxhyc.com:2883 + password: fys123456 + url: tcp://47.107.152.87:1883 subClientId: fys_subClient - subTopic: A/# - pubTopic: B/# + subTopic: A/#,status/tenantCode/#,report/tenantCode/# + pubTopic: B/#,command/tenantCode/# pubClientId: fys_pubClient diff --git a/fys-admin/src/main/resources/josn b/fys-admin/src/main/resources/josn new file mode 100644 index 00000000..4ae99751 --- /dev/null +++ b/fys-admin/src/main/resources/josn @@ -0,0 +1,10 @@ +{ + "requestId": "123456789", + "imei": "864865082081523", +"timestamp": 1761025080000, + "funcType": "1", + "data": { + "mainLightMode": 1, + "mainLightBrightness": 100 + } +} \ No newline at end of file diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/dto/AppDeviceBo.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/dto/AppDeviceBo.java index 5f440df4..0e631128 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/dto/AppDeviceBo.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/dto/AppDeviceBo.java @@ -12,6 +12,7 @@ import lombok.EqualsAndHashCode; */ @Data public class AppDeviceBo { + /** * 设备IMEI */ @@ -25,10 +26,11 @@ public class AppDeviceBo { /** * 通讯方式 0:4G;1:蓝牙,2 4G&蓝牙 */ - @NotNull(message = "通讯方式不能为空", groups = { EditGroup.class }) + @NotNull(message = "通讯方式不能为空", groups = {EditGroup.class}) private Integer communicationMode; private String sendMsg; private Long deviceId; + } diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/AppDeviceVo.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/AppDeviceVo.java index 760fc3a4..214fd8a2 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/AppDeviceVo.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/AppDeviceVo.java @@ -86,4 +86,5 @@ public class AppDeviceVo implements Serializable { * 设备详情页面 */ private String detailPageUrl; + } diff --git a/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceMapper.xml b/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceMapper.xml index eb66b484..b57f59e2 100644 --- a/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceMapper.xml +++ b/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceMapper.xml @@ -227,6 +227,7 @@ FROM device WHERE original_device_id = #{originalDeviceId} + +