From 67764a733ef48bd9a65f6d7756e2b341b6b6b84e Mon Sep 17 00:00:00 2001 From: chenyouting <514333061@qq.com> Date: Wed, 6 Aug 2025 10:38:21 +0800 Subject: [PATCH 01/47] =?UTF-8?q?=E8=AE=BE=E5=A4=87=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E7=94=B5=E9=87=8F=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98=EF=BC=8C?= =?UTF-8?q?=E6=89=93=E5=8D=B0=E6=97=A5=E5=BF=97=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fuyuanshen/app/service/AppDeviceBizService.java | 3 --- .../com/fuyuanshen/global/mqtt/config/MqttGateway.java | 6 ------ .../fuyuanshen/global/mqtt/publish/MqttMessageSender.java | 7 +------ .../fuyuanshen/global/mqtt/rule/DeviceBootLogoRule.java | 2 +- .../fuyuanshen/global/mqtt/rule/DeviceSendMessageRule.java | 2 +- .../com/fuyuanshen/global/mqtt/rule/LocationDataRule.java | 2 +- fys-admin/src/main/resources/application-prod.yml | 6 +++--- 7 files changed, 7 insertions(+), 21 deletions(-) diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceBizService.java b/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceBizService.java index ac36e82f..98142e9d 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceBizService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceBizService.java @@ -166,13 +166,10 @@ public class AppDeviceBizService { } String location = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_LOCATION_KEY_PREFIX + item.getDeviceImei()); - // 获取电量 if(StringUtils.isNotBlank(location)){ JSONObject jsonObject = JSONObject.parseObject(location); item.setLatitude(jsonObject.getString("latitude")); item.setLongitude(jsonObject.getString("longitude")); - }else{ - item.setBattery("0"); } } }); diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/config/MqttGateway.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/config/MqttGateway.java index a1b8eb24..822e5bf4 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/config/MqttGateway.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/config/MqttGateway.java @@ -4,12 +4,6 @@ import org.springframework.integration.annotation.MessagingGateway; import org.springframework.integration.mqtt.support.MqttHeaders; import org.springframework.messaging.handler.annotation.Header; -/** - * @Author: HarryLin - * @Date: 2025/3/20 17:06 - * @Company: 北京红山信息科技研究院有限公司 - * @Email: linyun@***.com.cn - **/ @MessagingGateway(defaultRequestChannel = "mqttOutboundChannel") public interface MqttGateway { public abstract void sendMsgToMqtt(@Header(value = MqttHeaders.TOPIC) String topic, String payload); diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/publish/MqttMessageSender.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/publish/MqttMessageSender.java index dcb429cd..bb001248 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/publish/MqttMessageSender.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/publish/MqttMessageSender.java @@ -6,12 +6,7 @@ import org.springframework.integration.mqtt.support.MqttHeaders; import org.springframework.messaging.handler.annotation.Header; import org.springframework.stereotype.Service; -/** - * @Author: HarryLin - * @Date: 2025/3/20 16:16 - * @Company: 北京红山信息科技研究院有限公司 - * @Email: linyun@***.com.cn - **/ + @Service public class MqttMessageSender { @Autowired diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/DeviceBootLogoRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/DeviceBootLogoRule.java index af5bc109..288a78ac 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/DeviceBootLogoRule.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/DeviceBootLogoRule.java @@ -51,7 +51,7 @@ public class DeviceBootLogoRule implements MqttMessageRule { byte[] arr = ImageToCArrayConverter.convertStringToByteArray(data); byte[] specificChunk = ImageToCArrayConverter.getChunk(arr, (val2 - 1), 512); - System.out.println("第" + val2 + "块数据大小: " + specificChunk.length + " 字节"); + log.info("第{}块数据大小: {} 字节", val2, specificChunk.length); // System.out.println("第" + val2 + "块数据: " + Arrays.toString(specificChunk)); ArrayList intData = new ArrayList<>(); diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/DeviceSendMessageRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/DeviceSendMessageRule.java index fab1fdee..6c2176b7 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/DeviceSendMessageRule.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/DeviceSendMessageRule.java @@ -50,7 +50,7 @@ public class DeviceSendMessageRule implements MqttMessageRule { byte[] arr = ImageToCArrayConverter.convertStringToByteArray(data); byte[] specificChunk = ImageToCArrayConverter.getChunk(arr, (val2 - 1), 512); - System.out.println("第" + val2 + "块数据大小: " + specificChunk.length + " 字节"); + log.info("第{}块数据大小: {} 字节", val2, specificChunk.length); // System.out.println("第" + val2 + "块数据: " + Arrays.toString(specificChunk)); ArrayList intData = new ArrayList<>(); diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/LocationDataRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/LocationDataRule.java index 16dec3b5..71e9403c 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/LocationDataRule.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/LocationDataRule.java @@ -181,7 +181,7 @@ public class LocationDataRule implements MqttMessageRule { // RedisUtils.expire(trajectoryKey, Duration.ofDays(30)); // 清理30天前的数据(冗余保护) - long thirtyDaysAgo = System.currentTimeMillis() - (90L * 24 * 60 * 60 * 1000); + long thirtyDaysAgo = System.currentTimeMillis() - (7L * 24 * 60 * 60 * 1000); RedisUtils.zRemoveRangeByScore(trajectoryKey, 0, thirtyDaysAgo); } catch (Exception e) { log.error("存储设备轨迹到Redis(ZSet)失败: device={}, error={}", deviceImei, e.getMessage(), e); diff --git a/fys-admin/src/main/resources/application-prod.yml b/fys-admin/src/main/resources/application-prod.yml index 45255dbd..8f210fb9 100644 --- a/fys-admin/src/main/resources/application-prod.yml +++ b/fys-admin/src/main/resources/application-prod.yml @@ -107,7 +107,7 @@ spring.data: # 数据库索引 database: 1 # redis 密码必须配置 - password: re_fs_11520631 + password: xhYc_djkl382^#780! # 连接超时时间 timeout: 10s # 是否开启ssl @@ -280,8 +280,8 @@ mqtt: password: #YtvpSfCNG url: tcp://47.120.79.150:2883 subClientId: fys_subClient - subTopic: worker/alert/#,worker/location/# - pubTopic: worker/location + subTopic: A/#,B/#,worker/location/# + pubTopic: B/# pubClientId: fys_pubClient From f67e84825630482174f135f6cd4a0a2f8bf01d8c Mon Sep 17 00:00:00 2001 From: chenyouting <514333061@qq.com> Date: Thu, 7 Aug 2025 15:41:57 +0800 Subject: [PATCH 02/47] =?UTF-8?q?=E6=99=B6=E5=85=A86710?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/controller/AppDeviceController.java | 102 ----- .../device/AppDeviceBJQController.java | 119 ++++++ .../device/AppDeviceHBYController.java | 112 +++++ .../app/service/AppDeviceBizService.java | 42 +- .../device/AppDeviceBJQBizService.java | 388 ++++++++++++++++++ .../constants/DeviceRedisKeyConstants.java | 50 ++- .../mqtt/receiver/ReceiverMessageHandler.java | 4 +- .../BjqActiveReportingDeviceDataRule.java} | 15 +- .../mqtt/rule/bjq6170/BjqAlarmRule.java | 69 ++++ .../BjqBootLogoRule.java} | 13 +- .../BjqLocationDataRule.java} | 13 +- .../global/mqtt/rule/bjq6170/BjqModeRule.java | 75 ++++ .../BjqSendMessageRule.java} | 11 +- .../src/main/resources/application-dev.yml | 2 +- .../app/domain/vo/AppDeviceDetailVo.java | 5 + .../equipment/domain/vo/AppDeviceVo.java | 5 + 16 files changed, 871 insertions(+), 154 deletions(-) create mode 100644 fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceBJQController.java create mode 100644 fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceHBYController.java create mode 100644 fys-admin/src/main/java/com/fuyuanshen/app/service/device/AppDeviceBJQBizService.java rename fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/{ActiveReportingDeviceDataRule.java => bjq6170/BjqActiveReportingDeviceDataRule.java} (91%) create mode 100644 fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqAlarmRule.java rename fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/{DeviceBootLogoRule.java => bjq6170/BjqBootLogoRule.java} (81%) rename fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/{LocationDataRule.java => bjq6170/BjqLocationDataRule.java} (95%) create mode 100644 fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqModeRule.java rename fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/{DeviceSendMessageRule.java => bjq6170/BjqSendMessageRule.java} (83%) 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 1151c88e..beb899ef 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 @@ -1,31 +1,20 @@ package com.fuyuanshen.app.controller; -import cn.hutool.json.JSON; -import com.alibaba.fastjson2.JSONObject; -import com.fuyuanshen.app.domain.bo.AppPersonnelInfoBo; import com.fuyuanshen.app.domain.dto.APPReNameDTO; -import com.fuyuanshen.app.domain.dto.AppDeviceLogoUploadDto; -import com.fuyuanshen.app.domain.dto.DeviceInstructDto; import com.fuyuanshen.app.domain.vo.APPDeviceTypeVo; -import com.fuyuanshen.app.domain.vo.AppDeviceDetailVo; import com.fuyuanshen.app.service.AppDeviceBizService; import com.fuyuanshen.common.core.domain.R; -import com.fuyuanshen.common.core.validate.AddGroup; import com.fuyuanshen.common.mybatis.core.page.PageQuery; import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; import com.fuyuanshen.common.web.core.BaseController; import com.fuyuanshen.equipment.domain.dto.AppDeviceBo; -import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo; import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria; import com.fuyuanshen.equipment.domain.vo.AppDeviceVo; -import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; import java.util.List; -import java.util.Map; /** * APP设备信息管理 @@ -83,95 +72,4 @@ public class AppDeviceController extends BaseController { appDeviceService.reName(reNameDTO); return R.ok("重命名成功!!!"); } - - /** - * 获取设备详细信息 - * - * @param id 主键 - */ - @GetMapping("/{id}") - public R getInfo(@NotNull(message = "主键不能为空") - @PathVariable Long id) { - return R.ok(appDeviceService.getInfo(id)); - } - - /** - * 人员信息登记 - */ - @PostMapping(value = "/registerPersonInfo") - public R registerPersonInfo(@Validated(AddGroup.class) @RequestBody AppPersonnelInfoBo bo) { - return toAjax(appDeviceService.registerPersonInfo(bo)); - } - - /** - * 发送信息 - */ - @PostMapping(value = "/sendMessage") - public R sendMessage(@RequestBody AppDeviceSendMsgBo bo) { - return toAjax(appDeviceService.sendMessage(bo)); - } - - /** - * 发送报警信息 - */ - @PostMapping(value = "/sendAlarmMessage") - public R sendAlarmMessage(@RequestBody AppDeviceSendMsgBo bo) { - return toAjax(appDeviceService.sendAlarmMessage(bo)); - } - - /** - * 上传设备logo图片 - */ - @PostMapping("/uploadLogo") - public R upload(@Validated @ModelAttribute AppDeviceLogoUploadDto bo) { - - MultipartFile file = bo.getFile(); - if(file.getSize()>1024*1024*2){ - return R.warn("图片不能大于2M"); - } - appDeviceService.uploadDeviceLogo(bo); - - return R.ok(); - } - - /** - * 灯光模式 - * 0(关灯),1(强光模式),2(弱光模式), 3(爆闪模式), 4(泛光模式) - */ - @PostMapping("/lightModeSettings") - public R lightModeSettings(@RequestBody DeviceInstructDto params) { - // params 转 JSONObject - appDeviceService.lightModeSettings(params); - return R.ok(); - } - - /** - * 灯光亮度设置 - * - */ - @PostMapping("/lightBrightnessSettings") - public R lightBrightnessSettings(@RequestBody DeviceInstructDto params) { - appDeviceService.lightBrightnessSettings(params); - return R.ok(); - } - - /** - * 激光模式设置 - * - */ - @PostMapping("/laserModeSettings") - public R laserModeSettings(@RequestBody DeviceInstructDto params) { - appDeviceService.laserModeSettings(params); - return R.ok(); - } - - /** - * 地图逆解析 - * - */ - @PostMapping("/mapReverseGeocoding") - public R mapReverseGeocoding(@RequestBody DeviceInstructDto params) { - String mapJson = appDeviceService.mapReverseGeocoding(params); - return R.ok(mapJson); - } } diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceBJQController.java b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceBJQController.java new file mode 100644 index 00000000..2f7caf8b --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceBJQController.java @@ -0,0 +1,119 @@ +package com.fuyuanshen.app.controller.device; + +import com.fuyuanshen.app.domain.bo.AppPersonnelInfoBo; +import com.fuyuanshen.app.domain.dto.AppDeviceLogoUploadDto; +import com.fuyuanshen.app.domain.dto.DeviceInstructDto; +import com.fuyuanshen.app.domain.vo.AppDeviceDetailVo; +import com.fuyuanshen.app.service.device.AppDeviceBJQBizService; +import com.fuyuanshen.common.core.domain.R; +import com.fuyuanshen.common.core.validate.AddGroup; +import com.fuyuanshen.common.web.core.BaseController; +import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +/** + * BJQ6170设备控制类 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/app/bjq/device") +public class AppDeviceBJQController extends BaseController { + + private final AppDeviceBJQBizService appDeviceService; + + /** + * 获取设备详细信息 + * + * @param id 主键 + */ + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(appDeviceService.getInfo(id)); + } + + /** + * 人员信息登记 + */ + @PostMapping(value = "/registerPersonInfo") + public R registerPersonInfo(@Validated(AddGroup.class) @RequestBody AppPersonnelInfoBo bo) { + return toAjax(appDeviceService.registerPersonInfo(bo)); + } + + /** + * 发送信息 + */ + @PostMapping(value = "/sendMessage") + public R sendMessage(@RequestBody AppDeviceSendMsgBo bo) { + return toAjax(appDeviceService.sendMessage(bo)); + } + + /** + * 发送报警信息 + */ + @PostMapping(value = "/sendAlarmMessage") + public R sendAlarmMessage(@RequestBody AppDeviceSendMsgBo bo) { + return toAjax(appDeviceService.sendAlarmMessage(bo)); + } + + /** + * 上传设备logo图片 + */ + @PostMapping("/uploadLogo") + public R upload(@Validated @ModelAttribute AppDeviceLogoUploadDto bo) { + + MultipartFile file = bo.getFile(); + if(file.getSize()>1024*1024*2){ + return R.warn("图片不能大于2M"); + } + appDeviceService.uploadDeviceLogo(bo); + + return R.ok(); + } + + /** + * 灯光模式 + * 0(关灯),1(强光模式),2(弱光模式), 3(爆闪模式), 4(泛光模式) + */ + @PostMapping("/lightModeSettings") + public R lightModeSettings(@RequestBody DeviceInstructDto params) { + // params 转 JSONObject + appDeviceService.lightModeSettings(params); + return R.ok(); + } + + /** + * 灯光亮度设置 + * + */ + @PostMapping("/lightBrightnessSettings") + public R lightBrightnessSettings(@RequestBody DeviceInstructDto params) { + appDeviceService.lightBrightnessSettings(params); + return R.ok(); + } + + /** + * 激光模式设置 + * + */ + @PostMapping("/laserModeSettings") + public R laserModeSettings(@RequestBody DeviceInstructDto params) { + appDeviceService.laserModeSettings(params); + return R.ok(); + } + + /** + * 地图逆解析 + * + */ + @PostMapping("/mapReverseGeocoding") + public R mapReverseGeocoding(@RequestBody DeviceInstructDto params) { + String mapJson = appDeviceService.mapReverseGeocoding(params); + return R.ok(mapJson); + } +} diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceHBYController.java b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceHBYController.java new file mode 100644 index 00000000..93a2204c --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceHBYController.java @@ -0,0 +1,112 @@ +package com.fuyuanshen.app.controller.device; + +import com.fuyuanshen.app.domain.bo.AppPersonnelInfoBo; +import com.fuyuanshen.app.domain.dto.AppDeviceLogoUploadDto; +import com.fuyuanshen.app.domain.dto.DeviceInstructDto; +import com.fuyuanshen.app.domain.vo.AppDeviceDetailVo; +import com.fuyuanshen.app.service.AppDeviceBizService; +import com.fuyuanshen.common.core.domain.R; +import com.fuyuanshen.common.core.validate.AddGroup; +import com.fuyuanshen.common.web.core.BaseController; +import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +/** + * HBY210设备控制类 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/app/hby/device") +public class AppDeviceHBYController extends BaseController { + + private final AppDeviceBizService appDeviceService; + + + /** + * 获取设备详细信息 + * + * @param id 主键 + */ + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(appDeviceService.getInfo(id)); + } + + /** + * 人员信息登记 + */ + @PostMapping(value = "/registerPersonInfo") + public R registerPersonInfo(@Validated(AddGroup.class) @RequestBody AppPersonnelInfoBo bo) { + return toAjax(appDeviceService.registerPersonInfo(bo)); + } + + /** + * 发送信息 + */ + @PostMapping(value = "/sendMessage") + public R sendMessage(@RequestBody AppDeviceSendMsgBo bo) { + return toAjax(appDeviceService.sendMessage(bo)); + } + + /** + * 上传设备logo图片 + */ + @PostMapping("/uploadLogo") + public R upload(@Validated @ModelAttribute AppDeviceLogoUploadDto bo) { + + MultipartFile file = bo.getFile(); + if(file.getSize()>1024*1024*2){ + return R.warn("图片不能大于2M"); + } + appDeviceService.uploadDeviceLogo(bo); + + return R.ok(); + } + + /** + * 灯光模式 + * 0(关灯),1(强光模式),2(弱光模式), 3(爆闪模式), 4(泛光模式) + */ + @PostMapping("/lightModeSettings") + public R lightModeSettings(@RequestBody DeviceInstructDto params) { + // params 转 JSONObject + appDeviceService.lightModeSettings(params); + return R.ok(); + } + + /** + * 灯光亮度设置 + * + */ + @PostMapping("/lightBrightnessSettings") + public R lightBrightnessSettings(@RequestBody DeviceInstructDto params) { + appDeviceService.lightBrightnessSettings(params); + return R.ok(); + } + + /** + * 激光模式设置 + * + */ + @PostMapping("/laserModeSettings") + public R laserModeSettings(@RequestBody DeviceInstructDto params) { + appDeviceService.laserModeSettings(params); + return R.ok(); + } + + /** + * 地图逆解析 + * + */ + @PostMapping("/mapReverseGeocoding") + public R mapReverseGeocoding(@RequestBody DeviceInstructDto params) { + String mapJson = appDeviceService.mapReverseGeocoding(params); + return R.ok(mapJson); + } +} diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceBizService.java b/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceBizService.java index 98142e9d..80e74f1d 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceBizService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceBizService.java @@ -54,6 +54,7 @@ import static com.fuyuanshen.common.core.constant.GlobalConstants.GLOBAL_REDIS_K import static com.fuyuanshen.common.core.utils.Bitmap80x12Generator.buildArr; import static com.fuyuanshen.common.core.utils.Bitmap80x12Generator.generateFixedBitmapData; import static com.fuyuanshen.common.core.utils.ImageToCArrayConverter.convertHexToDecimal; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.*; @Slf4j @@ -101,14 +102,14 @@ public class AppDeviceBizService { // String backgroundImagePath = "D:\\background.png"; // 替换为实际背景图片路径 byte[] largeData = ImageWithTextGenerate.generate160x80ImageWithText2(bo.getSendMsg(), inputStream, 25600); int[] ints = convertHexToDecimal(largeData); - RedisUtils.setCacheObject(GLOBAL_REDIS_KEY+"app_send_message_data:" + device.getDeviceImei(), Arrays.toString(ints), Duration.ofSeconds(30 * 60L)); + RedisUtils.setCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DEVICE_SEND_MESSAGE_KEY_PREFIX , Arrays.toString(ints), Duration.ofSeconds(30 * 60L)); - String data = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+"app_send_message_data:" + device.getDeviceImei()); + String data = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DEVICE_SEND_MESSAGE_KEY_PREFIX); byte[] arr = ImageToCArrayConverter.convertStringToByteArray(data); byte[] specificChunk = ImageToCArrayConverter.getChunk(arr, 0, 512); - System.out.println("第0块数据大小: " + specificChunk.length + " 字节"); - System.out.println("第0块数据: " + Arrays.toString(specificChunk)); + log.info("发送信息第0块数据大小: {} 字节",specificChunk.length); +// log.info("第0块数据: {}", Arrays.toString(specificChunk)); ArrayList intData = new ArrayList<>(); intData.add(6); @@ -121,7 +122,7 @@ public class AppDeviceBizService { Map map = new HashMap<>(); map.put("instruct", intData); mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(), 1 , JSON.toJSONString(map)); - log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),JSON.toJSONString(map)); + log.info("发送信息点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),JSON.toJSONString(map)); UpdateWrapper updateWrapper = new UpdateWrapper<>(); updateWrapper.eq("id", deviceId) @@ -129,7 +130,7 @@ public class AppDeviceBizService { .set("send_msg", bo.getSendMsg()); deviceMapper.update(updateWrapper); } catch (Exception e) { - log.info("设备发送信息失败:{}" ,deviceId); + log.info("发送信息设备发送信息失败:{}" ,deviceId); } } @@ -149,14 +150,14 @@ public class AppDeviceBizService { if(item.getCommunicationMode()!=null && item.getCommunicationMode() == 0){ //设备在线状态 - String onlineStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX + item.getDeviceImei()); + String onlineStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ item.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX); if(StringUtils.isNotBlank(onlineStatus)){ item.setOnlineStatus(1); }else{ item.setOnlineStatus(0); } - String deviceStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_STATUS_KEY_PREFIX + item.getDeviceImei()); + String deviceStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX+ item.getDeviceImei() + DEVICE_STATUS_KEY_PREFIX); // 获取电量 if(StringUtils.isNotBlank(deviceStatus)){ JSONObject jsonObject = JSONObject.parseObject(deviceStatus); @@ -165,12 +166,17 @@ public class AppDeviceBizService { item.setBattery("0"); } - String location = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_LOCATION_KEY_PREFIX + item.getDeviceImei()); + String location = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY +DEVICE_KEY_PREFIX+ item.getDeviceImei()+ DEVICE_LOCATION_KEY_PREFIX); if(StringUtils.isNotBlank(location)){ JSONObject jsonObject = JSONObject.parseObject(location); item.setLatitude(jsonObject.getString("latitude")); item.setLongitude(jsonObject.getString("longitude")); } + + String alarmStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY +DEVICE_KEY_PREFIX+ item.getDeviceImei()+ DEVICE_ALARM_KEY_PREFIX); + if(StringUtils.isNotBlank(alarmStatus)){ + item.setAlarmStatus(alarmStatus); + } } }); } @@ -333,13 +339,13 @@ public class AppDeviceBizService { vo.setPersonnelInfo(personnelInfoVo); } //设备在线状态 - String onlineStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX + device.getDeviceImei()); + String onlineStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX); if(StringUtils.isNotBlank(onlineStatus)){ vo.setOnlineStatus(1); }else{ vo.setOnlineStatus(0); } - String deviceStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_STATUS_KEY_PREFIX + device.getDeviceImei()); + String deviceStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX); // 获取电量 if(StringUtils.isNotBlank(deviceStatus)){ JSONObject jsonObject = JSONObject.parseObject(deviceStatus); @@ -353,7 +359,7 @@ public class AppDeviceBizService { } // 获取经度纬度 - String locationKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_LOCATION_KEY_PREFIX + device.getDeviceImei(); + String locationKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DEVICE_LOCATION_KEY_PREFIX; String locationInfo = RedisUtils.getCacheObject(locationKey); if(StringUtils.isNotBlank(locationInfo)){ JSONObject jsonObject = JSONObject.parseObject(locationInfo); @@ -430,19 +436,19 @@ public class AppDeviceBizService { MultipartFile file = bo.getFile(); byte[] largeData = ImageToCArrayConverter.convertImageToCArray(file.getInputStream(), 160, 80, 25600); - System.out.println("长度:" + largeData.length); + log.info("长度:" + largeData.length); - System.out.println("原始数据大小: " + largeData.length + " 字节"); + log.info("原始数据大小: {} 字节", largeData.length); int[] ints = convertHexToDecimal(largeData); - RedisUtils.setCacheObject(GLOBAL_REDIS_KEY+"app_logo_data:" + device.getDeviceImei(), Arrays.toString(ints), Duration.ofSeconds(30 * 60L)); + RedisUtils.setCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DEVICE_BOOT_LOGO_KEY_PREFIX, Arrays.toString(ints), Duration.ofSeconds(30 * 60L)); - String data = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+"app_logo_data:" + device.getDeviceImei()); + String data = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DEVICE_BOOT_LOGO_KEY_PREFIX); byte[] arr = ImageToCArrayConverter.convertStringToByteArray(data); byte[] specificChunk = ImageToCArrayConverter.getChunk(arr, 0, 512); - System.out.println("第0块数据大小: " + specificChunk.length + " 字节"); - System.out.println("第0块数据: " + Arrays.toString(specificChunk)); + log.info("第0块数据大小: {} 字节", specificChunk.length); +// log.info("第0块数据: {}", Arrays.toString(specificChunk)); ArrayList intData = new ArrayList<>(); intData.add(3); diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/device/AppDeviceBJQBizService.java b/fys-admin/src/main/java/com/fuyuanshen/app/service/device/AppDeviceBJQBizService.java new file mode 100644 index 00000000..8dd1a966 --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/app/service/device/AppDeviceBJQBizService.java @@ -0,0 +1,388 @@ +package com.fuyuanshen.app.service.device; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.fuyuanshen.app.domain.AppPersonnelInfo; +import com.fuyuanshen.app.domain.bo.AppPersonnelInfoBo; +import com.fuyuanshen.app.domain.dto.AppDeviceLogoUploadDto; +import com.fuyuanshen.app.domain.dto.DeviceInstructDto; +import com.fuyuanshen.app.domain.vo.AppDeviceDetailVo; +import com.fuyuanshen.app.domain.vo.AppPersonnelInfoVo; +import com.fuyuanshen.app.mapper.AppPersonnelInfoMapper; +import com.fuyuanshen.common.core.constant.GlobalConstants; +import com.fuyuanshen.common.core.exception.ServiceException; +import com.fuyuanshen.common.core.utils.*; +import com.fuyuanshen.common.redis.utils.RedisUtils; +import com.fuyuanshen.common.satoken.utils.AppLoginHelper; +import com.fuyuanshen.equipment.domain.Device; +import com.fuyuanshen.equipment.domain.DeviceType; +import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo; +import com.fuyuanshen.equipment.mapper.DeviceMapper; +import com.fuyuanshen.equipment.mapper.DeviceTypeMapper; +import com.fuyuanshen.global.mqtt.config.MqttGateway; +import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants; +import com.fuyuanshen.global.mqtt.constants.MqttConstants; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.io.ClassPathResource; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.InputStream; +import java.time.Duration; +import java.util.*; + +import static com.fuyuanshen.common.core.constant.GlobalConstants.GLOBAL_REDIS_KEY; +import static com.fuyuanshen.common.core.utils.Bitmap80x12Generator.buildArr; +import static com.fuyuanshen.common.core.utils.Bitmap80x12Generator.generateFixedBitmapData; +import static com.fuyuanshen.common.core.utils.ImageToCArrayConverter.convertHexToDecimal; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_BOOT_LOGO_KEY_PREFIX; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX; + + +@Slf4j +@Service +@RequiredArgsConstructor +public class AppDeviceBJQBizService { + + private final DeviceMapper deviceMapper; + private final AppPersonnelInfoMapper appPersonnelInfoMapper; + private final DeviceTypeMapper deviceTypeMapper; + private final MqttGateway mqttGateway; + + public int sendMessage(AppDeviceSendMsgBo bo) { + List deviceIds = bo.getDeviceIds(); + if (deviceIds == null || deviceIds.isEmpty()) { + throw new ServiceException("请选择设备"); + } + for (Long deviceId : deviceIds) { + Device device = deviceMapper.selectById(deviceId); + if (device == null) { + throw new ServiceException("设备不存在" + deviceId); + } + + try { + ClassPathResource resource = new ClassPathResource("image/background.png"); + InputStream inputStream = resource.getInputStream(); + +// String backgroundImagePath = "D:\\background.png"; // 替换为实际背景图片路径 + byte[] largeData = ImageWithTextGenerate.generate160x80ImageWithText2(bo.getSendMsg(), inputStream, 25600); + int[] ints = convertHexToDecimal(largeData); + RedisUtils.setCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + ":app_send_message_data" , Arrays.toString(ints), Duration.ofSeconds(30 * 60L)); + + String data = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + ":app_send_message_data"); + + byte[] arr = ImageToCArrayConverter.convertStringToByteArray(data); + byte[] specificChunk = ImageToCArrayConverter.getChunk(arr, 0, 512); + log.info("发送信息第0块数据大小: {} 字节",specificChunk.length); +// log.info("第0块数据: {}", Arrays.toString(specificChunk)); + + ArrayList intData = new ArrayList<>(); + intData.add(6); + intData.add(1); + ImageToCArrayConverter.buildArr(convertHexToDecimal(specificChunk),intData); + intData.add(0); + intData.add(0); + intData.add(0); + intData.add(0); + Map map = new HashMap<>(); + map.put("instruct", intData); + mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(), 1 , JSON.toJSONString(map)); + log.info("发送信息点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),JSON.toJSONString(map)); + + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("id", deviceId) + .eq("binding_user_id", AppLoginHelper.getUserId()) + .set("send_msg", bo.getSendMsg()); + deviceMapper.update(updateWrapper); + } catch (Exception e) { + log.info("发送信息设备发送信息失败:{}" ,deviceId); + } + + } + return 1; + } + + public AppDeviceDetailVo getInfo(Long id) { + Device device = deviceMapper.selectById(id); + if (device == null) { + throw new RuntimeException("请先将设备入库!!!"); + } + AppDeviceDetailVo vo = new AppDeviceDetailVo(); + vo.setDeviceId(device.getId()); + vo.setDeviceName(device.getDeviceName()); + vo.setDevicePic(device.getDevicePic()); + vo.setDeviceImei(device.getDeviceImei()); + vo.setDeviceMac(device.getDeviceMac()); + vo.setDeviceStatus(device.getDeviceStatus()); + DeviceType deviceType = deviceTypeMapper.selectById(device.getDeviceType()); + if (deviceType != null) { + vo.setCommunicationMode(Integer.valueOf(deviceType.getCommunicationMode())); + vo.setTypeName(deviceType.getTypeName()); + } + vo.setBluetoothName(device.getBluetoothName()); + + vo.setSendMsg(device.getSendMsg()); + + QueryWrapper qw = new QueryWrapper() + .eq("device_id", device.getId()); + AppPersonnelInfo appPersonnelInfo = appPersonnelInfoMapper.selectOne(qw); + if (appPersonnelInfo != null) { + AppPersonnelInfoVo personnelInfoVo = MapstructUtils.convert(appPersonnelInfo, AppPersonnelInfoVo.class); + vo.setPersonnelInfo(personnelInfoVo); + } + //设备在线状态 + String onlineStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX + device.getDeviceImei()); + if(StringUtils.isNotBlank(onlineStatus)){ + vo.setOnlineStatus(1); + }else{ + vo.setOnlineStatus(0); + } + String deviceStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_STATUS_KEY_PREFIX + device.getDeviceImei()); + // 获取电量 + if(StringUtils.isNotBlank(deviceStatus)){ + JSONObject jsonObject = JSONObject.parseObject(deviceStatus); + vo.setMainLightMode(jsonObject.getString("mainLightMode")); + vo.setLaserLightMode(jsonObject.getString("laserLightMode")); + vo.setBatteryPercentage(jsonObject.getString("batteryPercentage")); + vo.setChargeState(jsonObject.getString("chargeState")); + vo.setBatteryRemainingTime(jsonObject.getString("batteryRemainingTime")); + }else{ + vo.setBatteryPercentage("0"); + } + + // 获取经度纬度 + String locationKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_LOCATION_KEY_PREFIX + device.getDeviceImei(); + String locationInfo = RedisUtils.getCacheObject(locationKey); + if(StringUtils.isNotBlank(locationInfo)){ + JSONObject jsonObject = JSONObject.parseObject(locationInfo); + vo.setLongitude(jsonObject.get("longitude").toString()); + vo.setLatitude(jsonObject.get("latitude").toString()); + vo.setAddress((String)jsonObject.get("address")); + } + + return vo; + } + + + public boolean registerPersonInfo(AppPersonnelInfoBo bo) { + Long deviceId = bo.getDeviceId(); + Device deviceObj = deviceMapper.selectById(deviceId); + if (deviceObj == null) { + throw new RuntimeException("请先将设备入库!!!"); + } + QueryWrapper qw = new QueryWrapper() + .eq("device_id", deviceId); + List appPersonnelInfoVos = appPersonnelInfoMapper.selectVoList(qw); +// unitName,position,name,id + byte[] unitName = generateFixedBitmapData(bo.getUnitName(), 120); + byte[] position = generateFixedBitmapData(bo.getPosition(), 120); + byte[] name = generateFixedBitmapData(bo.getName(), 120); + byte[] id = generateFixedBitmapData(bo.getCode(), 120); + ArrayList intData = new ArrayList<>(); + intData.add(2); + buildArr(convertHexToDecimal(unitName), intData); + buildArr(convertHexToDecimal(position), intData); + buildArr(convertHexToDecimal(name), intData); + buildArr(convertHexToDecimal(id), intData); + intData.add(0); + intData.add(0); + intData.add(0); + intData.add(0); + Map map = new HashMap<>(); + map.put("instruct", intData); + mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY + deviceObj.getDeviceImei(), 1, JSON.toJSONString(map)); + log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY + deviceObj.getDeviceImei(), bo); + + if (ObjectUtils.length(appPersonnelInfoVos) == 0) { + AppPersonnelInfo appPersonnelInfo = MapstructUtils.convert(bo, AppPersonnelInfo.class); + return appPersonnelInfoMapper.insertOrUpdate(appPersonnelInfo); + } else { + UpdateWrapper uw = new UpdateWrapper<>(); + uw.eq("device_id", deviceId) + .set("name", bo.getName()) + .set("position", bo.getPosition()) + .set("unit_name", bo.getUnitName()) + .set("code", bo.getCode()); + return appPersonnelInfoMapper.update(null, uw) > 0; + } + + + } + + public void uploadDeviceLogo(AppDeviceLogoUploadDto bo) { + try { + Device device = deviceMapper.selectById(bo.getDeviceId()); + if (device == null) { + throw new ServiceException("设备不存在"); + } + MultipartFile file = bo.getFile(); + + byte[] largeData = ImageToCArrayConverter.convertImageToCArray(file.getInputStream(), 160, 80, 25600); + log.info("长度:" + largeData.length); + + log.info("原始数据大小: {} 字节", largeData.length); + + int[] ints = convertHexToDecimal(largeData); + RedisUtils.setCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() +DEVICE_BOOT_LOGO_KEY_PREFIX, Arrays.toString(ints), Duration.ofSeconds(30 * 60L)); + + String data = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DEVICE_BOOT_LOGO_KEY_PREFIX); + + byte[] arr = ImageToCArrayConverter.convertStringToByteArray(data); + byte[] specificChunk = ImageToCArrayConverter.getChunk(arr, 0, 512); + log.info("第0块数据大小: {} 字节", specificChunk.length); +// log.info("第0块数据: {}", Arrays.toString(specificChunk)); + + ArrayList intData = new ArrayList<>(); + intData.add(3); + intData.add(1); + ImageToCArrayConverter.buildArr(convertHexToDecimal(specificChunk),intData); + intData.add(0); + intData.add(0); + intData.add(0); + intData.add(0); + Map map = new HashMap<>(); + map.put("instruct", intData); + mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(), 1 , JSON.toJSONString(map)); + log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),JSON.toJSONString(map)); + } catch (Exception e){ + e.printStackTrace(); + } + } + + /** + * 灯光模式 + * 0(关灯),1(强光模式),2(弱光模式), 3(爆闪模式), 4(泛光模式) + */ + public void lightModeSettings(DeviceInstructDto params) { + try { + Long deviceId = params.getDeviceId(); + Device device = deviceMapper.selectById(deviceId); + if(device == null){ + throw new ServiceException("设备不存在"); + } + Integer instructValue = Integer.parseInt(params.getInstructValue()); + ArrayList intData = new ArrayList<>(); + intData.add(1); + intData.add(instructValue); + intData.add(0); + intData.add(0); + intData.add(0); + Map map = new HashMap<>(); + map.put("instruct", intData); + mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(), 1 , JSON.toJSONString(map)); + log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),JSON.toJSONString(map)); + } catch (Exception e){ + e.printStackTrace(); + } + } + + //灯光亮度设置 + public void lightBrightnessSettings(DeviceInstructDto params) { + try { + Long deviceId = params.getDeviceId(); + Device device = deviceMapper.selectById(deviceId); + if(device == null){ + throw new ServiceException("设备不存在"); + } + String instructValue = params.getInstructValue(); + ArrayList intData = new ArrayList<>(); + intData.add(5); + String[] values = instructValue.split("\\."); + String value1 = values[0]; + String value2 = values[1]; + if(StringUtils.isNoneBlank(value1)){ + intData.add(Integer.parseInt(value1)); + } + if(StringUtils.isNoneBlank(value2)){ + intData.add(Integer.parseInt(value2)); + } + intData.add(0); + intData.add(0); + intData.add(0); + Map map = new HashMap<>(); + map.put("instruct", intData); + mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(), 1 , JSON.toJSONString(map)); + log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),JSON.toJSONString(map)); + } catch (Exception e){ + e.printStackTrace(); + } + } + + //激光模式设置 + public void laserModeSettings(DeviceInstructDto params) { + try { + Long deviceId = params.getDeviceId(); + Device device = deviceMapper.selectById(deviceId); + if(device == null){ + throw new ServiceException("设备不存在"); + } + Integer instructValue = Integer.parseInt(params.getInstructValue()); + ArrayList intData = new ArrayList<>(); + intData.add(4); + intData.add(instructValue); + intData.add(0); + intData.add(0); + intData.add(0); + Map map = new HashMap<>(); + map.put("instruct", intData); + mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(), 1 , JSON.toJSONString(map)); + log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),JSON.toJSONString(map)); + } catch (Exception e){ + e.printStackTrace(); + } + } + + public String mapReverseGeocoding(DeviceInstructDto params) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("device_imei", params.getDeviceImei()); + List devices = deviceMapper.selectList(queryWrapper); + if(ObjectUtils.length( devices) ==0){ + throw new ServiceException("设备不存在"); + } + return RedisUtils.getCacheObject("device:location:" + devices.get(0).getDeviceImei()); + } + + public int sendAlarmMessage(AppDeviceSendMsgBo bo) { + try { + List deviceIds = bo.getDeviceIds(); + if (deviceIds == null || deviceIds.isEmpty()) { + throw new ServiceException("请选择设备"); + } + for (Long deviceId : deviceIds) { + Device device = deviceMapper.selectById(deviceId); + if (device == null) { + throw new ServiceException("设备不存在" + deviceId); + } + + try { + ArrayList intData = new ArrayList<>(); + intData.add(7); + intData.add(Integer.parseInt(bo.getInstructValue())); + intData.add(0); + intData.add(0); + intData.add(0); + intData.add(0); + Map map = new HashMap<>(); + map.put("instruct", intData); + mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(), 1 , JSON.toJSONString(map)); + log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),JSON.toJSONString(map)); + + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("id", deviceId) + .eq("binding_user_id", AppLoginHelper.getUserId()) + .set("send_msg", bo.getSendMsg()); + deviceMapper.update(updateWrapper); + } catch (Exception e) { + log.info("设备发送信息失败:{}" ,deviceId); + } + + } + } catch (Exception e){ + e.printStackTrace(); + } + return 1; + } +} diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/constants/DeviceRedisKeyConstants.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/constants/DeviceRedisKeyConstants.java index d92ec38f..080debc7 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/constants/DeviceRedisKeyConstants.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/constants/DeviceRedisKeyConstants.java @@ -1,12 +1,50 @@ package com.fuyuanshen.global.mqtt.constants; public class DeviceRedisKeyConstants { - // 将设备上报状态 - public static final String DEVICE_STATUS_KEY_PREFIX = "device:status:"; + public static final String DEVICE_KEY_PREFIX = "device:"; + // 设备上报状态 + public static final String DEVICE_STATUS_KEY_PREFIX = ":status"; // 在线状态 - public static final String DEVICE_ONLINE_STATUS_KEY_PREFIX = "device:onlineStatus:"; - // 将设备状态信息存储到Redis中 - public static final String DEVICE_LOCATION_KEY_PREFIX = "device:location:"; + public static final String DEVICE_ONLINE_STATUS_KEY_PREFIX = ":onlineStatus"; + // 设备状态信息存储到Redis中 + public static final String DEVICE_LOCATION_KEY_PREFIX = ":location"; // 存储到一个列表中,保留历史位置信息 - public static final String DEVICE_LOCATION_HISTORY_KEY_PREFIX = "device:location:history:"; + public static final String DEVICE_LOCATION_HISTORY_KEY_PREFIX = ":location:history"; + + // 存储设备活跃上报信息 + public static final String DEVICE_ACTIVE_REPORTING_KEY_PREFIX = ":activeReporting"; + + // 存储设备人员信息 + public static final String DEVICE_PERSONNEL_INFO_KEY_PREFIX = ":personnelInfo"; + + // 存储设备发送消息 + public static final String DEVICE_SEND_MESSAGE_KEY_PREFIX = ":sendMessage"; + + // 存储设备启动logo + public static final String DEVICE_BOOT_LOGO_KEY_PREFIX = ":bootLogo"; + + /** + * 灯模式 + */ + public static final String DEVICE_LIGHT_MODE_KEY_PREFIX = ":lightMode"; + + /** + * 亮度模式 + */ + public static final String DEVICE_LIGHT_BRIGHTNESS_KEY_PREFIX = ":lightBrightness"; + + /** + * 激光模式 + */ + public static final String DEVICE_LASER_MODE_KEY_PREFIX = ":laserMode"; + + /** + * 地图逆地理编码 + */ + public static final String DEVICE_MAP_REVERSE_GEOCODING_KEY_PREFIX = ":mapReverseGeocoding"; + + /** + * 告警 + */ + public static final String DEVICE_ALARM_KEY_PREFIX = ":alarm"; } 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 3cd36af5..618758f7 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 @@ -20,6 +20,8 @@ import org.springframework.stereotype.Service; import java.time.Duration; import java.util.Objects; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX; + @Service @Slf4j public class ReceiverMessageHandler implements MessageHandler { @@ -46,7 +48,7 @@ public class ReceiverMessageHandler implements MessageHandler { String deviceImei = subStr[1]; if(StringUtils.isNotBlank(deviceImei)){ //在线状态 - String deviceOnlineStatusRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+ DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX + deviceImei; + String deviceOnlineStatusRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ deviceImei + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX ; RedisUtils.setCacheObject(deviceOnlineStatusRedisKey, "1", Duration.ofSeconds(60*15)); } diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/ActiveReportingDeviceDataRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqActiveReportingDeviceDataRule.java similarity index 91% rename from fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/ActiveReportingDeviceDataRule.java rename to fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqActiveReportingDeviceDataRule.java index 104bd699..e6319a8d 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/ActiveReportingDeviceDataRule.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqActiveReportingDeviceDataRule.java @@ -1,22 +1,22 @@ -package com.fuyuanshen.global.mqtt.rule; +package com.fuyuanshen.global.mqtt.rule.bjq6170; import com.fuyuanshen.common.core.constant.GlobalConstants; import com.fuyuanshen.common.json.utils.JsonUtils; import com.fuyuanshen.common.redis.utils.RedisUtils; import com.fuyuanshen.global.mqtt.base.MqttMessageRule; import com.fuyuanshen.global.mqtt.base.MqttRuleContext; -import com.fuyuanshen.global.mqtt.config.MqttGateway; import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants; import com.fuyuanshen.global.mqtt.constants.LightingCommandTypeConstants; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; -import java.time.Duration; import java.util.LinkedHashMap; import java.util.Map; import java.util.concurrent.CompletableFuture; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_STATUS_KEY_PREFIX; + /** * 主动上报设备数据命令处理 * "第1位为12表示设备主动上报设备硬件状态,第2为表示当时设备主灯档位,第3位表示当时激光灯档位,第4位电量百分比,第5位为充电状态(0没有充电,1正在充电,2为已充满) @@ -25,10 +25,7 @@ import java.util.concurrent.CompletableFuture; @Component @RequiredArgsConstructor @Slf4j -public class ActiveReportingDeviceDataRule implements MqttMessageRule { - - private final MqttGateway mqttGateway; - +public class BjqActiveReportingDeviceDataRule implements MqttMessageRule { @Override public String getCommandType() { @@ -80,10 +77,10 @@ public class ActiveReportingDeviceDataRule implements MqttMessageRule { deviceInfo.put("timestamp", System.currentTimeMillis()); // 将设备状态信息存储到Redis中 - String deviceRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_STATUS_KEY_PREFIX + deviceImei; + String deviceRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_KEY_PREFIX + deviceImei + DEVICE_STATUS_KEY_PREFIX; String deviceInfoJson = JsonUtils.toJsonString(deviceInfo); - // 存储到Redis,设置过期时间(例如24小时) + // 存储到Redis RedisUtils.setCacheObject(deviceRedisKey, deviceInfoJson); log.info("设备状态信息已异步发送到Redis: device={}, mainLightMode={}, laserLightMode={}, batteryPercentage={}", diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqAlarmRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqAlarmRule.java new file mode 100644 index 00000000..bff3a369 --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqAlarmRule.java @@ -0,0 +1,69 @@ +package com.fuyuanshen.global.mqtt.rule.bjq6170; + +import com.fuyuanshen.common.core.constant.GlobalConstants; +import com.fuyuanshen.common.core.utils.StringUtils; +import com.fuyuanshen.common.redis.utils.RedisUtils; +import com.fuyuanshen.global.mqtt.base.MqttMessageRule; +import com.fuyuanshen.global.mqtt.base.MqttRuleContext; +import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants; +import com.fuyuanshen.global.mqtt.constants.LightingCommandTypeConstants; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.concurrent.CompletableFuture; + +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.*; + +/** + * 灯光模式订阅设备回传消息 + */ +@Component +@RequiredArgsConstructor +@Slf4j +public class BjqAlarmRule implements MqttMessageRule { + + @Override + public String getCommandType() { + return LightingCommandTypeConstants.LIGHT_MODE; + } + + @Override + public void execute(MqttRuleContext context) { + try { + Object[] convertArr = context.getConvertArr(); + + String mainLightMode = convertArr[1].toString(); + if(StringUtils.isNotBlank(mainLightMode)){ + // 异步发送设备状态和位置信息到Redis + asyncSendDeviceDataToRedisWithFuture(context.getDeviceImei(),mainLightMode); + } + + } catch (Exception e) { + log.error("处理灯光模式命令时出错", e); + } + } + + /** + * 异步发送设备状态信息和位置信息到Redis(使用CompletableFuture) + * + * @param deviceImei 设备IMEI + */ + public void asyncSendDeviceDataToRedisWithFuture(String deviceImei,Object convertValue) { + CompletableFuture.runAsync(() -> { + try { + // 将设备状态信息存储到Redis中 + String deviceRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_KEY_PREFIX + deviceImei + DEVICE_ALARM_KEY_PREFIX; + + // 存储到Redis + RedisUtils.setCacheObject(deviceRedisKey, convertValue.toString()); + + } catch (Exception e) { + log.error("异步发送设备信息到Redis时出错: device={}, error={}", deviceImei, e.getMessage(), e); + } + }); + } + + + +} diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/DeviceBootLogoRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqBootLogoRule.java similarity index 81% rename from fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/DeviceBootLogoRule.java rename to fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqBootLogoRule.java index 288a78ac..dde1c812 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/DeviceBootLogoRule.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqBootLogoRule.java @@ -1,6 +1,5 @@ -package com.fuyuanshen.global.mqtt.rule; +package com.fuyuanshen.global.mqtt.rule.bjq6170; -import com.fuyuanshen.common.core.constant.GlobalConstants; import com.fuyuanshen.common.core.utils.ImageToCArrayConverter; import com.fuyuanshen.common.core.utils.StringUtils; import com.fuyuanshen.common.json.utils.JsonUtils; @@ -15,11 +14,13 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import static com.fuyuanshen.common.core.constant.GlobalConstants.GLOBAL_REDIS_KEY; import static com.fuyuanshen.common.core.utils.ImageToCArrayConverter.convertHexToDecimal; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_BOOT_LOGO_KEY_PREFIX; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX; /** * 人员信息命令处理 @@ -27,7 +28,7 @@ import static com.fuyuanshen.common.core.utils.ImageToCArrayConverter.convertHex @Component @RequiredArgsConstructor @Slf4j -public class DeviceBootLogoRule implements MqttMessageRule { +public class BjqBootLogoRule implements MqttMessageRule { private final MqttGateway mqttGateway; @@ -44,7 +45,7 @@ public class DeviceBootLogoRule implements MqttMessageRule { return; } - String data = RedisUtils.getCacheObject(GlobalConstants.GLOBAL_REDIS_KEY+"app_logo_data:" + context.getDeviceImei()); + String data = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + context.getDeviceImei() +DEVICE_BOOT_LOGO_KEY_PREFIX); if (StringUtils.isEmpty(data)) { return; } @@ -71,7 +72,7 @@ public class DeviceBootLogoRule implements MqttMessageRule { MqttConstants.GLOBAL_PUB_KEY + context.getDeviceImei(), JsonUtils.toJsonString(map)); } catch (Exception e) { - log.error("处理人员信息命令时出错", e); + log.error("处理开机LOGO时出错", e); } } } diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/LocationDataRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqLocationDataRule.java similarity index 95% rename from fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/LocationDataRule.java rename to fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqLocationDataRule.java index 71e9403c..5f8240c8 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/LocationDataRule.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqLocationDataRule.java @@ -1,6 +1,5 @@ -package com.fuyuanshen.global.mqtt.rule; +package com.fuyuanshen.global.mqtt.rule.bjq6170; -import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.fuyuanshen.common.core.constant.GlobalConstants; import com.fuyuanshen.common.core.utils.StringUtils; @@ -18,20 +17,22 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; -import java.time.Duration; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.concurrent.CompletableFuture; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_LOCATION_KEY_PREFIX; + /** * 定位数据命令处理 */ @Component @RequiredArgsConstructor @Slf4j -public class LocationDataRule implements MqttMessageRule { +public class BjqLocationDataRule implements MqttMessageRule { private final MqttGateway mqttGateway; @@ -113,7 +114,7 @@ public class LocationDataRule implements MqttMessageRule { String[] latArr = latitude.split("\\."); String[] lonArr = longitude.split("\\."); // 将位置信息存储到Redis中 - String redisKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_LOCATION_KEY_PREFIX + deviceImei; + String redisKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ deviceImei + DEVICE_LOCATION_KEY_PREFIX; String redisObj = RedisUtils.getCacheObject(redisKey); JSONObject jsonOBj = JSONObject.parseObject(redisObj); if(jsonOBj != null){ @@ -169,7 +170,7 @@ public class LocationDataRule implements MqttMessageRule { */ public void storeDeviceTrajectoryWithSortedSet(String deviceImei, String locationJson) { try { - String trajectoryKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_LOCATION_HISTORY_KEY_PREFIX + deviceImei; + String trajectoryKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + deviceImei + DeviceRedisKeyConstants.DEVICE_LOCATION_HISTORY_KEY_PREFIX; // String trajectoryKey = "device:trajectory:zset:" + deviceImei; // String locationJson = JsonUtils.toJsonString(locationInfo); long timestamp = System.currentTimeMillis(); diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqModeRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqModeRule.java new file mode 100644 index 00000000..abcc1020 --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqModeRule.java @@ -0,0 +1,75 @@ +package com.fuyuanshen.global.mqtt.rule.bjq6170; + +import com.fuyuanshen.common.core.constant.GlobalConstants; +import com.fuyuanshen.common.core.utils.StringUtils; +import com.fuyuanshen.common.redis.utils.RedisUtils; +import com.fuyuanshen.global.mqtt.base.MqttMessageRule; +import com.fuyuanshen.global.mqtt.base.MqttRuleContext; +import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants; +import com.fuyuanshen.global.mqtt.constants.LightingCommandTypeConstants; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.time.Duration; +import java.util.concurrent.CompletableFuture; + +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_LIGHT_MODE_KEY_PREFIX; + +/** + * 灯光模式订阅设备回传消息 + */ +@Component +@RequiredArgsConstructor +@Slf4j +public class BjqModeRule implements MqttMessageRule { + + @Override + public String getCommandType() { + return LightingCommandTypeConstants.LIGHT_MODE; + } + + @Override + public void execute(MqttRuleContext context) { + try { + Object[] convertArr = context.getConvertArr(); + + String mainLightMode = convertArr[1].toString(); + if(StringUtils.isNotBlank(mainLightMode)){ + if("0".equals(mainLightMode)){ + String deviceOnlineStatusRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ context.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX ; + RedisUtils.setCacheObject(deviceOnlineStatusRedisKey, "0", Duration.ofSeconds(60*15)); + } + // 异步发送设备状态和位置信息到Redis + asyncSendDeviceDataToRedisWithFuture(context.getDeviceImei(),mainLightMode); + } + + } catch (Exception e) { + log.error("处理灯光模式命令时出错", e); + } + } + + /** + * 异步发送设备状态信息和位置信息到Redis(使用CompletableFuture) + * + * @param deviceImei 设备IMEI + */ + public void asyncSendDeviceDataToRedisWithFuture(String deviceImei,Object convertValue) { + CompletableFuture.runAsync(() -> { + try { + // 将设备状态信息存储到Redis中 + String deviceRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_KEY_PREFIX + deviceImei + DEVICE_LIGHT_MODE_KEY_PREFIX; + + // 存储到Redis + RedisUtils.setCacheObject(deviceRedisKey, convertValue.toString()); + + } catch (Exception e) { + log.error("异步发送设备信息到Redis时出错: device={}, error={}", deviceImei, e.getMessage(), e); + } + }); + } + + + +} diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/DeviceSendMessageRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqSendMessageRule.java similarity index 83% rename from fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/DeviceSendMessageRule.java rename to fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqSendMessageRule.java index 6c2176b7..b1cfbbbd 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/DeviceSendMessageRule.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqSendMessageRule.java @@ -1,6 +1,5 @@ -package com.fuyuanshen.global.mqtt.rule; +package com.fuyuanshen.global.mqtt.rule.bjq6170; -import com.fuyuanshen.common.core.constant.GlobalConstants; import com.fuyuanshen.common.core.utils.ImageToCArrayConverter; import com.fuyuanshen.common.core.utils.StringUtils; import com.fuyuanshen.common.json.utils.JsonUtils; @@ -18,7 +17,9 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Map; +import static com.fuyuanshen.common.core.constant.GlobalConstants.GLOBAL_REDIS_KEY; import static com.fuyuanshen.common.core.utils.ImageToCArrayConverter.convertHexToDecimal; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX; /** * 人员信息命令处理 @@ -26,7 +27,7 @@ import static com.fuyuanshen.common.core.utils.ImageToCArrayConverter.convertHex @Component @RequiredArgsConstructor @Slf4j -public class DeviceSendMessageRule implements MqttMessageRule { +public class BjqSendMessageRule implements MqttMessageRule { private final MqttGateway mqttGateway; @@ -43,7 +44,7 @@ public class DeviceSendMessageRule implements MqttMessageRule { return; } - String data = RedisUtils.getCacheObject(GlobalConstants.GLOBAL_REDIS_KEY+"app_send_message_data:" + context.getDeviceImei()); + String data = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + context.getDeviceImei() + ":app_send_message_data"); if (StringUtils.isEmpty(data)) { return; } @@ -70,7 +71,7 @@ public class DeviceSendMessageRule implements MqttMessageRule { MqttConstants.GLOBAL_PUB_KEY + context.getDeviceImei(), JsonUtils.toJsonString(map)); } catch (Exception e) { - log.error("处理人员信息命令时出错", e); + log.error("处理发送设备信息时出错", e); } } } diff --git a/fys-admin/src/main/resources/application-dev.yml b/fys-admin/src/main/resources/application-dev.yml index e586574e..d4f0fc62 100644 --- a/fys-admin/src/main/resources/application-dev.yml +++ b/fys-admin/src/main/resources/application-dev.yml @@ -1,7 +1,7 @@ --- # 监控中心配置 spring.boot.admin.client: # 增加客户端开关 - enabled: true + enabled: false url: http://localhost:9090/admin instance: service-host-type: IP diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceDetailVo.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceDetailVo.java index 6478ea44..230a2c48 100644 --- a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceDetailVo.java +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceDetailVo.java @@ -99,4 +99,9 @@ public class AppDeviceDetailVo { // 逆解析地址 private String address; + + /** + * 告警状态(0解除告警,1告警) + */ + private String alarmStatus; } 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 1642c7f7..1d0ec238 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 @@ -76,4 +76,9 @@ public class AppDeviceVo implements Serializable { * 经度 */ private String longitude; + + /** + * 告警状态(0解除告警,1告警) + */ + private String alarmStatus; } From efed6f36839ec0307250101846f09756e4bda07c Mon Sep 17 00:00:00 2001 From: chenyouting <514333061@qq.com> Date: Thu, 7 Aug 2025 15:56:12 +0800 Subject: [PATCH 03/47] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8C=85=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rule/{bjq6170 => bjq}/BjqActiveReportingDeviceDataRule.java | 2 +- .../global/mqtt/rule/{bjq6170 => bjq}/BjqAlarmRule.java | 2 +- .../global/mqtt/rule/{bjq6170 => bjq}/BjqBootLogoRule.java | 2 +- .../global/mqtt/rule/{bjq6170 => bjq}/BjqLocationDataRule.java | 2 +- .../global/mqtt/rule/{bjq6170 => bjq}/BjqModeRule.java | 2 +- .../global/mqtt/rule/{bjq6170 => bjq}/BjqSendMessageRule.java | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) rename fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/{bjq6170 => bjq}/BjqActiveReportingDeviceDataRule.java (98%) rename fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/{bjq6170 => bjq}/BjqAlarmRule.java (97%) rename fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/{bjq6170 => bjq}/BjqBootLogoRule.java (98%) rename fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/{bjq6170 => bjq}/BjqLocationDataRule.java (99%) rename fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/{bjq6170 => bjq}/BjqModeRule.java (98%) rename fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/{bjq6170 => bjq}/BjqSendMessageRule.java (98%) diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqActiveReportingDeviceDataRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqActiveReportingDeviceDataRule.java similarity index 98% rename from fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqActiveReportingDeviceDataRule.java rename to fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqActiveReportingDeviceDataRule.java index e6319a8d..eacbcdb4 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqActiveReportingDeviceDataRule.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqActiveReportingDeviceDataRule.java @@ -1,4 +1,4 @@ -package com.fuyuanshen.global.mqtt.rule.bjq6170; +package com.fuyuanshen.global.mqtt.rule.bjq; import com.fuyuanshen.common.core.constant.GlobalConstants; import com.fuyuanshen.common.json.utils.JsonUtils; diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqAlarmRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqAlarmRule.java similarity index 97% rename from fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqAlarmRule.java rename to fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqAlarmRule.java index bff3a369..49c1af56 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqAlarmRule.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqAlarmRule.java @@ -1,4 +1,4 @@ -package com.fuyuanshen.global.mqtt.rule.bjq6170; +package com.fuyuanshen.global.mqtt.rule.bjq; import com.fuyuanshen.common.core.constant.GlobalConstants; import com.fuyuanshen.common.core.utils.StringUtils; diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqBootLogoRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqBootLogoRule.java similarity index 98% rename from fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqBootLogoRule.java rename to fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqBootLogoRule.java index dde1c812..97fd0f30 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqBootLogoRule.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqBootLogoRule.java @@ -1,4 +1,4 @@ -package com.fuyuanshen.global.mqtt.rule.bjq6170; +package com.fuyuanshen.global.mqtt.rule.bjq; import com.fuyuanshen.common.core.utils.ImageToCArrayConverter; import com.fuyuanshen.common.core.utils.StringUtils; diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqLocationDataRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqLocationDataRule.java similarity index 99% rename from fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqLocationDataRule.java rename to fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqLocationDataRule.java index 5f8240c8..b528a007 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqLocationDataRule.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqLocationDataRule.java @@ -1,4 +1,4 @@ -package com.fuyuanshen.global.mqtt.rule.bjq6170; +package com.fuyuanshen.global.mqtt.rule.bjq; import com.alibaba.fastjson2.JSONObject; import com.fuyuanshen.common.core.constant.GlobalConstants; diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqModeRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqModeRule.java similarity index 98% rename from fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqModeRule.java rename to fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqModeRule.java index abcc1020..09aeaccb 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqModeRule.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqModeRule.java @@ -1,4 +1,4 @@ -package com.fuyuanshen.global.mqtt.rule.bjq6170; +package com.fuyuanshen.global.mqtt.rule.bjq; import com.fuyuanshen.common.core.constant.GlobalConstants; import com.fuyuanshen.common.core.utils.StringUtils; diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqSendMessageRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqSendMessageRule.java similarity index 98% rename from fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqSendMessageRule.java rename to fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqSendMessageRule.java index b1cfbbbd..c9b50e10 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq6170/BjqSendMessageRule.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqSendMessageRule.java @@ -1,4 +1,4 @@ -package com.fuyuanshen.global.mqtt.rule.bjq6170; +package com.fuyuanshen.global.mqtt.rule.bjq; import com.fuyuanshen.common.core.utils.ImageToCArrayConverter; import com.fuyuanshen.common.core.utils.StringUtils; From 9de55857bcabbb997987967440da12fedcd41f5a Mon Sep 17 00:00:00 2001 From: daiyongfei <974332738@qq.com> Date: Thu, 7 Aug 2025 18:07:04 +0800 Subject: [PATCH 04/47] =?UTF-8?q?=E6=99=B6=E5=85=A8=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mqtt/DeviceReceiverMessageHandler.java | 134 ++++++++++++------ .../src/main/resources/application-dev.yml | 2 +- fys-admin/src/main/resources/application.yml | 2 +- 3 files changed, 93 insertions(+), 45 deletions(-) diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/handler/mqtt/DeviceReceiverMessageHandler.java b/fys-admin/src/main/java/com/fuyuanshen/web/handler/mqtt/DeviceReceiverMessageHandler.java index 3548e13f..b43d75f0 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/handler/mqtt/DeviceReceiverMessageHandler.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/handler/mqtt/DeviceReceiverMessageHandler.java @@ -94,6 +94,30 @@ public class DeviceReceiverMessageHandler implements MessageHandler { record.setDataSource("客户端操作"); } } + // 确保在插入前设置tenantId和deviceId + record.setTenantId(device.getTenantId()); + record.setDeviceId(device.getId()); + deviceLogMapper.insert(record); + } + + // 2. 处理 state 消息 + if (root.has("state")) { + JsonNode instructNode = root.get("state"); + if (instructNode.isArray()) { + boolean b = receivedTopicName.startsWith("B/"); + record = parseState(device, instructNode, b); + // 根据不同主题进行不同处理 + if (receivedTopicName.startsWith("A/")) { + // 处理A主题的消息(设备上传) + record.setDataSource("设备上报"); + } else if (receivedTopicName.startsWith("B/")) { + // 处理B主题的消息 (手动上传) + record.setDataSource("客户端操作"); + } + } + // 确保在插入前设置tenantId和deviceId + record.setTenantId(device.getTenantId()); + record.setDeviceId(device.getId()); deviceLogMapper.insert(record); } @@ -102,6 +126,9 @@ public class DeviceReceiverMessageHandler implements MessageHandler { record.setDeviceAction(InstructType6170.fromCode(0).getDescription()); record.setDataSource("设备上报"); record.setContent("设备启动"); + // 确保在插入前设置tenantId和deviceId + record.setTenantId(device.getTenantId()); + record.setDeviceId(device.getId()); deviceLogMapper.insert(record); } @@ -217,54 +244,75 @@ public class DeviceReceiverMessageHandler implements MessageHandler { /** - * 解析state消息 + * 解析 state 消息 * * @param device * @param array * @return */ - // private StateRecord parseState(Device device, JsonNode array) { - // StateRecord record = new StateRecord(); - // record.setDevice(device); - // record.setStateType(array.get(0).asInt()); - // - // switch (record.getStateType()) { - // case 1: // 灯光状态 - // record.setLightMode(array.get(1).asInt()); - // record.setBrightness(array.get(2).asInt()); - // break; - // - // case 2: // 设置结果 - // record.setSetResult(array.get(1).asInt() == 1); - // break; - // - // case 3: // 图片更新状态 - // record.setImagePage(array.get(1).asInt()); - // break; - // - // case 4: // 激光灯状态 - // record.setLaserStatus(array.get(1).asInt() == 1); - // break; - // - // case 5: // 亮度状态 - // record.setBrightness(array.get(1).asInt()); - // break; - // - // case 11: // 定位上报 - // record.setLatitude(array.get(1).asDouble()); - // record.setLongitude(array.get(2).asDouble()); - // break; - // - // case 12: // 设备状态 - // record.setMainLightGear(array.get(1).asInt()); - // record.setLaserLightGear(array.get(2).asInt()); - // record.setBattery(array.get(3).asInt()); - // record.setChargeStatus(array.get(4).asInt()); - // record.setDuration(array.get(5).asInt()); - // break; - // } - // return record; - // } + private DeviceLog parseState(Device device, JsonNode array, boolean b) { + DeviceLog record = new DeviceLog(); + record.setDeviceName(device.getDeviceName()); + // 设备行为 + record.setDeviceAction(InstructType6170.fromCode(array.get(0).asInt()).getDescription()); + switch (array.get(0).asInt()) { + case 1: // 灯光模式 + LightModeEnum6170 lightModeEnum6170 = LightModeEnum6170.fromCode(array.get(1).asInt()); + record.setContent(lightModeEnum6170.getDescription()); + break; + + case 2: // 单位/姓名/职位 + byte[] unitBytes = new byte[480]; + for (int i = 1; i <= 480; i++) { + unitBytes[i - 1] = (byte) array.get(i).asInt(); + } + // record.setUnitData(unitBytes); + break; + + case 3: // 开机图片 + // record.setImagePage(array.get(1).asInt()); + byte[] imageBytes = new byte[512]; + for (int i = 2; i <= 513; i++) { + imageBytes[i - 2] = (byte) array.get(i).asInt(); + } + // record.setImageData(imageBytes); + break; + + case 4: // 激光灯 + int anInt = array.get(1).asInt(); + if (anInt == 0) { + record.setContent("关闭激光灯"); + } else if (anInt == 1) { + record.setContent("开启激光灯"); + } else { + record.setContent("未知操作"); + } + break; + + case 5: // 亮度调节 + record.setContent(+array.get(1).asInt() + "%"); + break; + + case 11: // 定位数据 + if (b) { + break; + } + int i1 = array.get(1).asInt(); + int i2 = array.get(2).asInt(); + int i3 = array.get(3).asInt(); + int i4 = array.get(4).asInt(); + + // 优雅的转换方式 Longitude and latitude + double latitude = i1 + i2 / 10.0; + double Longitude = i3 + i4 / 10.0; + // 84 ==》 高德 + double[] doubles = LngLonUtil.gps84_To_Gcj02(latitude, Longitude); + String address = GetAddressFromLatUtil.getAdd(String.valueOf(doubles[1]), String.valueOf(doubles[0])); + record.setContent(address); + break; + } + return record; + } } diff --git a/fys-admin/src/main/resources/application-dev.yml b/fys-admin/src/main/resources/application-dev.yml index e586574e..d4f0fc62 100644 --- a/fys-admin/src/main/resources/application-dev.yml +++ b/fys-admin/src/main/resources/application-dev.yml @@ -1,7 +1,7 @@ --- # 监控中心配置 spring.boot.admin.client: # 增加客户端开关 - enabled: true + enabled: false url: http://localhost:9090/admin instance: service-host-type: IP diff --git a/fys-admin/src/main/resources/application.yml b/fys-admin/src/main/resources/application.yml index 60c91061..c413dff7 100644 --- a/fys-admin/src/main/resources/application.yml +++ b/fys-admin/src/main/resources/application.yml @@ -64,7 +64,7 @@ spring: # 国际化资源文件路径 basename: i18n/messages profiles: - active: @profiles.active@ + active: ${profiles.active} # 文件上传 servlet: multipart: From 9fb72e5ac01760c2b4a750eb454bd4562c9cb99c Mon Sep 17 00:00:00 2001 From: daiyongfei <974332738@qq.com> Date: Fri, 8 Aug 2025 09:49:08 +0800 Subject: [PATCH 05/47] =?UTF-8?q?=E8=AE=BE=E5=A4=87=E5=88=86=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/DeviceGroupController.java | 105 ++++++++++++++ .../DeviceRepairRecordsController.java | 105 ++++++++++++++ .../equipment/domain/DeviceGroup.java | 56 ++++++++ .../equipment/domain/DeviceRepairRecords.java | 58 ++++++++ .../equipment/domain/bo/DeviceGroupBo.java | 56 ++++++++ .../domain/bo/DeviceRepairRecordsBo.java | 60 ++++++++ .../equipment/domain/vo/DeviceGroupVo.java | 68 +++++++++ .../domain/vo/DeviceRepairRecordsVo.java | 70 +++++++++ .../equipment/mapper/DeviceGroupMapper.java | 15 ++ .../mapper/DeviceRepairRecordsMapper.java | 15 ++ .../service/IDeviceGroupService.java | 58 ++++++++ .../service/IDeviceRepairRecordsService.java | 68 +++++++++ .../service/impl/DeviceGroupServiceImpl.java | 120 ++++++++++++++++ .../impl/DeviceRepairRecordsServiceImpl.java | 135 ++++++++++++++++++ .../mapper/equipment/DeviceGroupMapper.xml | 7 + .../equipment/DeviceRepairRecordsMapper.xml | 7 + 16 files changed, 1003 insertions(+) create mode 100644 fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/controller/DeviceGroupController.java create mode 100644 fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/controller/DeviceRepairRecordsController.java create mode 100644 fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceGroup.java create mode 100644 fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceRepairRecords.java create mode 100644 fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/bo/DeviceGroupBo.java create mode 100644 fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/bo/DeviceRepairRecordsBo.java create mode 100644 fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/DeviceGroupVo.java create mode 100644 fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/DeviceRepairRecordsVo.java create mode 100644 fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceGroupMapper.java create mode 100644 fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceRepairRecordsMapper.java create mode 100644 fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/IDeviceGroupService.java create mode 100644 fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/IDeviceRepairRecordsService.java create mode 100644 fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceGroupServiceImpl.java create mode 100644 fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceRepairRecordsServiceImpl.java create mode 100644 fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceGroupMapper.xml create mode 100644 fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceRepairRecordsMapper.xml diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/controller/DeviceGroupController.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/controller/DeviceGroupController.java new file mode 100644 index 00000000..7720b37f --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/controller/DeviceGroupController.java @@ -0,0 +1,105 @@ +package com.fuyuanshen.equipment.controller; + +import java.util.List; + +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import com.fuyuanshen.common.idempotent.annotation.RepeatSubmit; +import com.fuyuanshen.common.log.annotation.Log; +import com.fuyuanshen.common.web.core.BaseController; +import com.fuyuanshen.common.mybatis.core.page.PageQuery; +import com.fuyuanshen.common.core.domain.R; +import com.fuyuanshen.common.core.validate.AddGroup; +import com.fuyuanshen.common.core.validate.EditGroup; +import com.fuyuanshen.common.log.enums.BusinessType; +import com.fuyuanshen.common.excel.utils.ExcelUtil; +import com.fuyuanshen.equipment.domain.vo.DeviceGroupVo; +import com.fuyuanshen.equipment.domain.bo.DeviceGroupBo; +import com.fuyuanshen.equipment.service.IDeviceGroupService; + +/** + * 设备分组 + * + * @author Lion Li + * @date 2025-08-08 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/fys-equipment/group") +public class DeviceGroupController extends BaseController { + + private final IDeviceGroupService deviceGroupService; + + /** + * 查询设备分组列表 + */ + @SaCheckPermission("fys-equipment:group:list") + @GetMapping("/list") + public R> list(DeviceGroupBo bo) { + List list = deviceGroupService.queryList(bo); + return R.ok(list); + } + + /** + * 导出设备分组列表 + */ + @SaCheckPermission("fys-equipment:group:export") + @Log(title = "设备分组", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(DeviceGroupBo bo, HttpServletResponse response) { + List list = deviceGroupService.queryList(bo); + ExcelUtil.exportExcel(list, "设备分组", DeviceGroupVo.class, response); + } + + /** + * 获取设备分组详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("fys-equipment:group:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(deviceGroupService.queryById(id)); + } + + /** + * 新增设备分组 + */ + @SaCheckPermission("fys-equipment:group:add") + @Log(title = "设备分组", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody DeviceGroupBo bo) { + return toAjax(deviceGroupService.insertByBo(bo)); + } + + /** + * 修改设备分组 + */ + @SaCheckPermission("fys-equipment:group:edit") + @Log(title = "设备分组", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody DeviceGroupBo bo) { + return toAjax(deviceGroupService.updateByBo(bo)); + } + + /** + * 删除设备分组 + * + * @param ids 主键串 + */ + @SaCheckPermission("fys-equipment:group:remove") + @Log(title = "设备分组", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(deviceGroupService.deleteWithValidByIds(List.of(ids), true)); + } +} diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/controller/DeviceRepairRecordsController.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/controller/DeviceRepairRecordsController.java new file mode 100644 index 00000000..1304daa6 --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/controller/DeviceRepairRecordsController.java @@ -0,0 +1,105 @@ +package com.fuyuanshen.equipment.controller; + +import java.util.List; + +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import com.fuyuanshen.common.idempotent.annotation.RepeatSubmit; +import com.fuyuanshen.common.log.annotation.Log; +import com.fuyuanshen.common.web.core.BaseController; +import com.fuyuanshen.common.mybatis.core.page.PageQuery; +import com.fuyuanshen.common.core.domain.R; +import com.fuyuanshen.common.core.validate.AddGroup; +import com.fuyuanshen.common.core.validate.EditGroup; +import com.fuyuanshen.common.log.enums.BusinessType; +import com.fuyuanshen.common.excel.utils.ExcelUtil; +import com.fuyuanshen.equipment.domain.vo.DeviceRepairRecordsVo; +import com.fuyuanshen.equipment.domain.bo.DeviceRepairRecordsBo; +import com.fuyuanshen.equipment.service.IDeviceRepairRecordsService; +import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; + +/** + * 设备维修记录 + * + * @author Lion Li + * @date 2025-08-08 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/equipment/repairRecords") +public class DeviceRepairRecordsController extends BaseController { + + private final IDeviceRepairRecordsService deviceRepairRecordsService; + + /** + * 查询设备维修记录列表 + */ + @SaCheckPermission("equipment:repairRecords:list") + @GetMapping("/list") + public TableDataInfo list(DeviceRepairRecordsBo bo, PageQuery pageQuery) { + return deviceRepairRecordsService.queryPageList(bo, pageQuery); + } + + /** + * 导出设备维修记录列表 + */ + @SaCheckPermission("equipment:repairRecords:export") + @Log(title = "设备维修记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(DeviceRepairRecordsBo bo, HttpServletResponse response) { + List list = deviceRepairRecordsService.queryList(bo); + ExcelUtil.exportExcel(list, "设备维修记录", DeviceRepairRecordsVo.class, response); + } + + /** + * 获取设备维修记录详细信息 + * + * @param recordId 主键 + */ + @SaCheckPermission("equipment:repairRecords:query") + @GetMapping("/{recordId}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long recordId) { + return R.ok(deviceRepairRecordsService.queryById(recordId)); + } + + /** + * 新增设备维修记录 + */ + @SaCheckPermission("equipment:repairRecords:add") + @Log(title = "设备维修记录", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody DeviceRepairRecordsBo bo) { + return toAjax(deviceRepairRecordsService.insertByBo(bo)); + } + + /** + * 修改设备维修记录 + */ + @SaCheckPermission("equipment:repairRecords:edit") + @Log(title = "设备维修记录", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody DeviceRepairRecordsBo bo) { + return toAjax(deviceRepairRecordsService.updateByBo(bo)); + } + + /** + * 删除设备维修记录 + * + * @param recordIds 主键串 + */ + @SaCheckPermission("equipment:repairRecords:remove") + @Log(title = "设备维修记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{recordIds}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] recordIds) { + return toAjax(deviceRepairRecordsService.deleteWithValidByIds(List.of(recordIds), true)); + } +} diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceGroup.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceGroup.java new file mode 100644 index 00000000..fa90f59f --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceGroup.java @@ -0,0 +1,56 @@ +package com.fuyuanshen.equipment.domain; + +import com.fuyuanshen.common.tenant.core.TenantEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; + +/** + * 设备分组对象 device_group + * + * @author Lion Li + * @date 2025-08-08 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("device_group") +public class DeviceGroup extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @TableId(value = "id") + private Long id; + + /** + * 分组名称 + */ + private String groupName; + + /** + * 状态:0-禁用,1-正常 + */ + private Long status; + + /** + * 父分组ID + */ + private Long parentId; + + /** + * 完整分组路径 + */ + private String fullPath; + + /** + * 删除标记:0-未删除,1-已删除 + */ + private Long isDeleted; + + +} diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceRepairRecords.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceRepairRecords.java new file mode 100644 index 00000000..3fca3c4a --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceRepairRecords.java @@ -0,0 +1,58 @@ +package com.fuyuanshen.equipment.domain; + +import com.fuyuanshen.common.tenant.core.TenantEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serial; + +/** + * 设备维修记录对象 device_repair_records + * + * @author Lion Li + * @date 2025-08-08 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("device_repair_records") +public class DeviceRepairRecords extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 维修记录ID + */ + @TableId(value = "record_id") + private Long recordId; + + /** + * 设备ID + */ + private String deviceId; + + /** + * 维修时间 + */ + private Date repairTime; + + /** + * 维修部位 + */ + private String repairPart; + + /** + * 维修原因 + */ + private String repairReason; + + /** + * 维修人员 + */ + private String repairPerson; + + +} diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/bo/DeviceGroupBo.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/bo/DeviceGroupBo.java new file mode 100644 index 00000000..187eb532 --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/bo/DeviceGroupBo.java @@ -0,0 +1,56 @@ +package com.fuyuanshen.equipment.domain.bo; + +import com.fuyuanshen.equipment.domain.DeviceGroup; +import com.fuyuanshen.common.mybatis.core.domain.BaseEntity; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; + +/** + * 设备分组业务对象 device_group + * + * @author Lion Li + * @date 2025-08-08 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = DeviceGroup.class, reverseConvertGenerate = false) +public class DeviceGroupBo extends BaseEntity { + + /** + * 主键ID + */ + @NotNull(message = "主键ID不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * 分组名称 + */ + @NotBlank(message = "分组名称不能为空", groups = { AddGroup.class, EditGroup.class }) + private String groupName; + + /** + * 状态:0-禁用,1-正常 + */ + @NotNull(message = "状态:0-禁用,1-正常不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long status; + + /** + * 父分组ID + */ + private Long parentId; + + /** + * 完整分组路径 + */ + private String fullPath; + + /** + * 删除标记:0-未删除,1-已删除 + */ + @NotNull(message = "删除标记:0-未删除,1-已删除不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long isDeleted; + + +} diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/bo/DeviceRepairRecordsBo.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/bo/DeviceRepairRecordsBo.java new file mode 100644 index 00000000..0c7529ed --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/bo/DeviceRepairRecordsBo.java @@ -0,0 +1,60 @@ +package com.fuyuanshen.equipment.domain.bo; + +import com.fuyuanshen.equipment.domain.DeviceRepairRecords; +import com.fuyuanshen.common.mybatis.core.domain.BaseEntity; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +/** + * 设备维修记录业务对象 device_repair_records + * + * @author Lion Li + * @date 2025-08-08 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = DeviceRepairRecords.class, reverseConvertGenerate = false) +public class DeviceRepairRecordsBo extends BaseEntity { + + /** + * 维修记录ID + */ + @NotNull(message = "维修记录ID不能为空", groups = { EditGroup.class }) + private Long recordId; + + /** + * 设备ID + */ + @NotBlank(message = "设备ID不能为空", groups = { AddGroup.class, EditGroup.class }) + private String deviceId; + + /** + * 维修时间 + */ + @NotNull(message = "维修时间不能为空", groups = { AddGroup.class, EditGroup.class }) + private Date repairTime; + + /** + * 维修部位 + */ + @NotBlank(message = "维修部位不能为空", groups = { AddGroup.class, EditGroup.class }) + private String repairPart; + + /** + * 维修原因 + */ + @NotBlank(message = "维修原因不能为空", groups = { AddGroup.class, EditGroup.class }) + private String repairReason; + + /** + * 维修人员 + */ + @NotBlank(message = "维修人员不能为空", groups = { AddGroup.class, EditGroup.class }) + private String repairPerson; + + +} diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/DeviceGroupVo.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/DeviceGroupVo.java new file mode 100644 index 00000000..fe453396 --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/DeviceGroupVo.java @@ -0,0 +1,68 @@ +package com.fuyuanshen.equipment.domain.vo; + +import com.fuyuanshen.equipment.domain.DeviceGroup; +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import com.fuyuanshen.common.excel.annotation.ExcelDictFormat; +import com.fuyuanshen.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + + +/** + * 设备分组视图对象 device_group + * + * @author Lion Li + * @date 2025-08-08 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = DeviceGroup.class) +public class DeviceGroupVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @ExcelProperty(value = "主键ID") + private Long id; + + /** + * 分组名称 + */ + @ExcelProperty(value = "分组名称") + private String groupName; + + /** + * 状态:0-禁用,1-正常 + */ + @ExcelProperty(value = "状态:0-禁用,1-正常") + private Long status; + + /** + * 父分组ID + */ + @ExcelProperty(value = "父分组ID") + private Long parentId; + + /** + * 完整分组路径 + */ + @ExcelProperty(value = "完整分组路径") + private String fullPath; + + /** + * 删除标记:0-未删除,1-已删除 + */ + @ExcelProperty(value = "删除标记:0-未删除,1-已删除") + private Long isDeleted; + + +} diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/DeviceRepairRecordsVo.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/DeviceRepairRecordsVo.java new file mode 100644 index 00000000..f66bb67f --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/DeviceRepairRecordsVo.java @@ -0,0 +1,70 @@ +package com.fuyuanshen.equipment.domain.vo; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fuyuanshen.equipment.domain.DeviceRepairRecords; +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import com.fuyuanshen.common.excel.annotation.ExcelDictFormat; +import com.fuyuanshen.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + + +/** + * 设备维修记录视图对象 device_repair_records + * + * @author Lion Li + * @date 2025-08-08 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = DeviceRepairRecords.class) +public class DeviceRepairRecordsVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 维修记录ID + */ + @ExcelProperty(value = "维修记录ID") + private Long recordId; + + /** + * 设备ID + */ + @ExcelProperty(value = "设备ID") + private String deviceId; + + /** + * 维修时间 + */ + @ExcelProperty(value = "维修时间") + private Date repairTime; + + /** + * 维修部位 + */ + @ExcelProperty(value = "维修部位") + private String repairPart; + + /** + * 维修原因 + */ + @ExcelProperty(value = "维修原因") + private String repairReason; + + /** + * 维修人员 + */ + @ExcelProperty(value = "维修人员") + private String repairPerson; + + +} diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceGroupMapper.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceGroupMapper.java new file mode 100644 index 00000000..a92cfad8 --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceGroupMapper.java @@ -0,0 +1,15 @@ +package com.fuyuanshen.equipment.mapper; + +import com.fuyuanshen.equipment.domain.DeviceGroup; +import com.fuyuanshen.equipment.domain.vo.DeviceGroupVo; +import com.fuyuanshen.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 设备分组Mapper接口 + * + * @author Lion Li + * @date 2025-08-08 + */ +public interface DeviceGroupMapper extends BaseMapperPlus { + +} diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceRepairRecordsMapper.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceRepairRecordsMapper.java new file mode 100644 index 00000000..eb3cec2d --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceRepairRecordsMapper.java @@ -0,0 +1,15 @@ +package com.fuyuanshen.equipment.mapper; + +import com.fuyuanshen.equipment.domain.DeviceRepairRecords; +import com.fuyuanshen.equipment.domain.vo.DeviceRepairRecordsVo; +import com.fuyuanshen.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 设备维修记录Mapper接口 + * + * @author Lion Li + * @date 2025-08-08 + */ +public interface DeviceRepairRecordsMapper extends BaseMapperPlus { + +} diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/IDeviceGroupService.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/IDeviceGroupService.java new file mode 100644 index 00000000..8cda9c83 --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/IDeviceGroupService.java @@ -0,0 +1,58 @@ +package com.fuyuanshen.equipment.service; + +import com.fuyuanshen.equipment.domain.vo.DeviceGroupVo; +import com.fuyuanshen.equipment.domain.bo.DeviceGroupBo; + +import java.util.Collection; +import java.util.List; + +/** + * 设备分组Service接口 + * + * @author Lion Li + * @date 2025-08-08 + */ +public interface IDeviceGroupService { + + /** + * 查询设备分组 + * + * @param id 主键 + * @return 设备分组 + */ + DeviceGroupVo queryById(Long id); + + + /** + * 查询符合条件的设备分组列表 + * + * @param bo 查询条件 + * @return 设备分组列表 + */ + List queryList(DeviceGroupBo bo); + + /** + * 新增设备分组 + * + * @param bo 设备分组 + * @return 是否新增成功 + */ + Boolean insertByBo(DeviceGroupBo bo); + + /** + * 修改设备分组 + * + * @param bo 设备分组 + * @return 是否修改成功 + */ + Boolean updateByBo(DeviceGroupBo bo); + + /** + * 校验并批量删除设备分组信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/IDeviceRepairRecordsService.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/IDeviceRepairRecordsService.java new file mode 100644 index 00000000..8fb838c2 --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/IDeviceRepairRecordsService.java @@ -0,0 +1,68 @@ +package com.fuyuanshen.equipment.service; + +import com.fuyuanshen.equipment.domain.vo.DeviceRepairRecordsVo; +import com.fuyuanshen.equipment.domain.bo.DeviceRepairRecordsBo; +import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; +import com.fuyuanshen.common.mybatis.core.page.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 设备维修记录Service接口 + * + * @author Lion Li + * @date 2025-08-08 + */ +public interface IDeviceRepairRecordsService { + + /** + * 查询设备维修记录 + * + * @param recordId 主键 + * @return 设备维修记录 + */ + DeviceRepairRecordsVo queryById(Long recordId); + + /** + * 分页查询设备维修记录列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 设备维修记录分页列表 + */ + TableDataInfo queryPageList(DeviceRepairRecordsBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的设备维修记录列表 + * + * @param bo 查询条件 + * @return 设备维修记录列表 + */ + List queryList(DeviceRepairRecordsBo bo); + + /** + * 新增设备维修记录 + * + * @param bo 设备维修记录 + * @return 是否新增成功 + */ + Boolean insertByBo(DeviceRepairRecordsBo bo); + + /** + * 修改设备维修记录 + * + * @param bo 设备维修记录 + * @return 是否修改成功 + */ + Boolean updateByBo(DeviceRepairRecordsBo bo); + + /** + * 校验并批量删除设备维修记录信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceGroupServiceImpl.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceGroupServiceImpl.java new file mode 100644 index 00000000..3f64a2a3 --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceGroupServiceImpl.java @@ -0,0 +1,120 @@ +package com.fuyuanshen.equipment.service.impl; + +import com.fuyuanshen.common.core.utils.MapstructUtils; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import com.fuyuanshen.equipment.domain.bo.DeviceGroupBo; +import com.fuyuanshen.equipment.domain.vo.DeviceGroupVo; +import com.fuyuanshen.equipment.domain.DeviceGroup; +import com.fuyuanshen.equipment.mapper.DeviceGroupMapper; +import com.fuyuanshen.equipment.service.IDeviceGroupService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 设备分组Service业务层处理 + * + * @author Lion Li + * @date 2025-08-08 + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class DeviceGroupServiceImpl implements IDeviceGroupService { + + private final DeviceGroupMapper baseMapper; + + /** + * 查询设备分组 + * + * @param id 主键 + * @return 设备分组 + */ + @Override + public DeviceGroupVo queryById(Long id){ + return baseMapper.selectVoById(id); + } + + + /** + * 查询符合条件的设备分组列表 + * + * @param bo 查询条件 + * @return 设备分组列表 + */ + @Override + public List queryList(DeviceGroupBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(DeviceGroupBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.orderByAsc(DeviceGroup::getId); + lqw.like(StringUtils.isNotBlank(bo.getGroupName()), DeviceGroup::getGroupName, bo.getGroupName()); + lqw.eq(bo.getStatus() != null, DeviceGroup::getStatus, bo.getStatus()); + lqw.eq(bo.getParentId() != null, DeviceGroup::getParentId, bo.getParentId()); + lqw.eq(StringUtils.isNotBlank(bo.getFullPath()), DeviceGroup::getFullPath, bo.getFullPath()); + lqw.eq(bo.getIsDeleted() != null, DeviceGroup::getIsDeleted, bo.getIsDeleted()); + return lqw; + } + + /** + * 新增设备分组 + * + * @param bo 设备分组 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(DeviceGroupBo bo) { + DeviceGroup add = MapstructUtils.convert(bo, DeviceGroup.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改设备分组 + * + * @param bo 设备分组 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(DeviceGroupBo bo) { + DeviceGroup update = MapstructUtils.convert(bo, DeviceGroup.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(DeviceGroup entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除设备分组信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } +} diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceRepairRecordsServiceImpl.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceRepairRecordsServiceImpl.java new file mode 100644 index 00000000..48569e33 --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceRepairRecordsServiceImpl.java @@ -0,0 +1,135 @@ +package com.fuyuanshen.equipment.service.impl; + +import com.fuyuanshen.common.core.utils.MapstructUtils; +import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; +import com.fuyuanshen.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import com.fuyuanshen.equipment.domain.bo.DeviceRepairRecordsBo; +import com.fuyuanshen.equipment.domain.vo.DeviceRepairRecordsVo; +import com.fuyuanshen.equipment.domain.DeviceRepairRecords; +import com.fuyuanshen.equipment.mapper.DeviceRepairRecordsMapper; +import com.fuyuanshen.equipment.service.IDeviceRepairRecordsService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 设备维修记录Service业务层处理 + * + * @author Lion Li + * @date 2025-08-08 + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class DeviceRepairRecordsServiceImpl implements IDeviceRepairRecordsService { + + private final DeviceRepairRecordsMapper baseMapper; + + /** + * 查询设备维修记录 + * + * @param recordId 主键 + * @return 设备维修记录 + */ + @Override + public DeviceRepairRecordsVo queryById(Long recordId){ + return baseMapper.selectVoById(recordId); + } + + /** + * 分页查询设备维修记录列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 设备维修记录分页列表 + */ + @Override + public TableDataInfo queryPageList(DeviceRepairRecordsBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的设备维修记录列表 + * + * @param bo 查询条件 + * @return 设备维修记录列表 + */ + @Override + public List queryList(DeviceRepairRecordsBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(DeviceRepairRecordsBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.orderByAsc(DeviceRepairRecords::getRecordId); + lqw.eq(StringUtils.isNotBlank(bo.getDeviceId()), DeviceRepairRecords::getDeviceId, bo.getDeviceId()); + lqw.eq(bo.getRepairTime() != null, DeviceRepairRecords::getRepairTime, bo.getRepairTime()); + lqw.eq(StringUtils.isNotBlank(bo.getRepairPart()), DeviceRepairRecords::getRepairPart, bo.getRepairPart()); + lqw.eq(StringUtils.isNotBlank(bo.getRepairReason()), DeviceRepairRecords::getRepairReason, bo.getRepairReason()); + lqw.eq(StringUtils.isNotBlank(bo.getRepairPerson()), DeviceRepairRecords::getRepairPerson, bo.getRepairPerson()); + return lqw; + } + + /** + * 新增设备维修记录 + * + * @param bo 设备维修记录 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(DeviceRepairRecordsBo bo) { + DeviceRepairRecords add = MapstructUtils.convert(bo, DeviceRepairRecords.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setRecordId(add.getRecordId()); + } + return flag; + } + + /** + * 修改设备维修记录 + * + * @param bo 设备维修记录 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(DeviceRepairRecordsBo bo) { + DeviceRepairRecords update = MapstructUtils.convert(bo, DeviceRepairRecords.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(DeviceRepairRecords entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除设备维修记录信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } +} diff --git a/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceGroupMapper.xml b/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceGroupMapper.xml new file mode 100644 index 00000000..36cd5e29 --- /dev/null +++ b/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceGroupMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceRepairRecordsMapper.xml b/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceRepairRecordsMapper.xml new file mode 100644 index 00000000..46af59f4 --- /dev/null +++ b/fys-modules/fys-equipment/src/main/resources/mapper/equipment/DeviceRepairRecordsMapper.xml @@ -0,0 +1,7 @@ + + + + + From 3abee42b0726d6a26086f669c74987cc11c79a37 Mon Sep 17 00:00:00 2001 From: daiyongfei <974332738@qq.com> Date: Fri, 8 Aug 2025 10:43:53 +0800 Subject: [PATCH 06/47] =?UTF-8?q?=E8=AE=BE=E5=A4=87=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E4=B8=AD=E5=BF=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../device/DeviceControlCenterController.java | 210 ++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceControlCenterController.java diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceControlCenterController.java b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceControlCenterController.java new file mode 100644 index 00000000..0f4079c5 --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceControlCenterController.java @@ -0,0 +1,210 @@ +package com.fuyuanshen.web.controller.device; + +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author: 默苍璃 + * @date: 2025-08-0810:40 + */ +@Slf4j +@Tag(name = "web后台:设备控制中心", description = "web后台:设备控制中心") +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/device") +public class DeviceControlCenterController { + + /** + * 获取设备基本信息 + * @param deviceId 设备ID + * @return 设备基本信息 + */ + @GetMapping("/info/{deviceId}") + public ResponseEntity> getDeviceInfo(@PathVariable String deviceId) { + // 实际应用中这里会从数据库查询设备信息 + Map deviceInfo = new HashMap<>(); + deviceInfo.put("deviceName", "6170零零一"); + deviceInfo.put("deviceModel", "BJQ6170"); + deviceInfo.put("deviceId", deviceId); + deviceInfo.put("status", "在线"); + deviceInfo.put("batteryLevel", 85); + + return ResponseEntity.ok(deviceInfo); + } + + /** + * 设置灯光模式 + * @param lightModeRequest 灯光模式请求 + * @return 操作结果 + */ + @PostMapping("/light-mode") + public ResponseEntity> setLightMode(@RequestBody LightModeRequest lightModeRequest) { + // 实际应用中这里会控制设备灯光 + Map response = new HashMap<>(); + response.put("code", 200); + // response.put("message", "灯光模式已设置为: " + lightModeRequest.getMode()); + // response.put("deviceId", lightModeRequest.getDeviceId()); + // response.put("mode", lightModeRequest.getMode()); + + return ResponseEntity.ok(response); + } + + /** + * 更新人员信息 + * @param personInfo 人员信息 + * @return 操作结果 + */ + @PostMapping("/person-info") + public ResponseEntity> updatePersonInfo(@RequestBody PersonInfo personInfo) { + // 实际应用中这里会更新数据库 + Map response = new HashMap<>(); + response.put("code", 200); + response.put("message", "人员信息已更新"); + // response.put("unit", personInfo.getUnit()); + // response.put("position", personInfo.getPosition()); + + return ResponseEntity.ok(response); + } + + /** + * 管理开机画面内容 + * @param bootScreenRequest 开机画面请求 + * @return 操作结果 + */ + @PostMapping("/boot-screen") + public ResponseEntity> manageBootScreen(@RequestBody BootScreenRequest bootScreenRequest) { + // 实际应用中这里会更新设备开机画面 + Map response = new HashMap<>(); + response.put("code", 200); + response.put("message", "开机画面内容已更新"); + // response.put("deviceId", bootScreenRequest.getDeviceId()); + // response.put("screens", bootScreenRequest.getScreens()); + + return ResponseEntity.ok(response); + } + + /** + * 设置灯光亮度 + * @param brightnessRequest 亮度请求 + * @return 操作结果 + */ + @PostMapping("/brightness") + public ResponseEntity> setBrightness(@RequestBody BrightnessRequest brightnessRequest) { + // 实际应用中这里会控制设备亮度 + Map response = new HashMap<>(); + response.put("code", 200); + // response.put("message", "灯光亮度已设置为: " + brightnessRequest.getBrightness() + "%"); + // response.put("deviceId", brightnessRequest.getDeviceId()); + // response.put("brightness", brightnessRequest.getBrightness()); + // response.put("forceAlarm", brightnessRequest.isForceAlarm()); + + return ResponseEntity.ok(response); + } + + /** + * 获取设备位置信息 + * @param deviceId 设备ID + * @return 位置信息 + */ + @GetMapping("/location/{deviceId}") + public ResponseEntity> getLocation(@PathVariable String deviceId) { + // 实际应用中这里会从设备获取实时位置 + Map locationInfo = new HashMap<>(); + locationInfo.put("deviceId", deviceId); + locationInfo.put("longitude", "114°7'E"); + locationInfo.put("latitude", "30'28'N"); + locationInfo.put("address", "湖北省武汉市洪山区光谷大道国际企业中心"); + locationInfo.put("timestamp", new Date()); + + return ResponseEntity.ok(locationInfo); + } + + /** + * 发送紧急消息 + * @param messageRequest 消息请求 + * @return 操作结果 + */ + @PostMapping("/send-message") + public ResponseEntity> sendMessage(@RequestBody MessageRequest messageRequest) { + // 实际应用中这里会向设备发送消息 + Map response = new HashMap<>(); + response.put("code", 200); + response.put("message", "消息已发送"); + // response.put("deviceId", messageRequest.getDeviceId()); + // response.put("content", messageRequest.getContent()); + response.put("timestamp", new Date()); + + return ResponseEntity.ok(response); + } + + /** + * 管理操作视频 + * @param videoRequest 视频请求 + * @return 操作结果 + */ + @PostMapping("/operation-video") + public ResponseEntity> manageOperationVideo(@RequestBody VideoRequest videoRequest) { + // 实际应用中这里会更新设备操作视频 + Map response = new HashMap<>(); + response.put("code", 200); + response.put("message", "操作视频已更新"); + // response.put("deviceId", videoRequest.getDeviceId()); + // response.put("videoUrl", videoRequest.getVideoUrl()); + + return ResponseEntity.ok(response); + } + + // 请求对象类定义 + public static class LightModeRequest { + private String deviceId; + private String mode; // 强光、弱光、爆闪、泛光、激光 + + // Getters and Setters + } + + public static class PersonInfo { + private String deviceId; + private String unit; // 单位 + private String position; // 职位 + + // Getters and Setters + } + + public static class BootScreenRequest { + private String deviceId; + private List screens; // 产品参数、操作说明等 + + // Getters and Setters + } + + public static class BrightnessRequest { + private String deviceId; + private int brightness; // 0-100 + private boolean forceAlarm; // 强制报警 + + // Getters and Setters + } + + public static class MessageRequest { + private String deviceId; + private String content; // 消息内容 + + // Getters and Setters + } + + public static class VideoRequest { + private String deviceId; + private String videoUrl; // 视频链接 + + // Getters and Setters + } + +} From 72cab138a7b1775e609d6d9199cad812078bd748 Mon Sep 17 00:00:00 2001 From: daiyongfei <974332738@qq.com> Date: Fri, 8 Aug 2025 10:44:49 +0800 Subject: [PATCH 07/47] =?UTF-8?q?=E8=AE=BE=E5=A4=87=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E4=B8=AD=E5=BF=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/controller/device/DeviceControlCenterController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceControlCenterController.java b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceControlCenterController.java index 0f4079c5..13b34712 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceControlCenterController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceControlCenterController.java @@ -19,7 +19,7 @@ import java.util.Map; @Tag(name = "web后台:设备控制中心", description = "web后台:设备控制中心") @RestController @RequiredArgsConstructor -@RequestMapping("/api/device") +@RequestMapping("/api/device/controlCenter") public class DeviceControlCenterController { /** From 47dbd33d568c0c92f2a157712a87979ff4835ad5 Mon Sep 17 00:00:00 2001 From: chenyouting <514333061@qq.com> Date: Fri, 8 Aug 2025 15:09:59 +0800 Subject: [PATCH 08/47] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=9C=A8=E7=BA=BF?= =?UTF-8?q?=E4=B8=8A=E6=8A=A5=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../device/AppDeviceBJQBizService.java | 6 +- .../CustomMqttInboundConfiguration.java | 122 ++-- .../mqtt/DeviceReceiverMessageHandler.java | 636 +++++++++--------- .../web/listener/UserActionListener.java | 326 ++++----- .../src/main/resources/application-prod.yml | 21 +- 5 files changed, 557 insertions(+), 554 deletions(-) diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/device/AppDeviceBJQBizService.java b/fys-admin/src/main/java/com/fuyuanshen/app/service/device/AppDeviceBJQBizService.java index 8dd1a966..db998b66 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/service/device/AppDeviceBJQBizService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/service/device/AppDeviceBJQBizService.java @@ -134,13 +134,13 @@ public class AppDeviceBJQBizService { vo.setPersonnelInfo(personnelInfoVo); } //设备在线状态 - String onlineStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX + device.getDeviceImei()); + String onlineStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei()+ DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX); if(StringUtils.isNotBlank(onlineStatus)){ vo.setOnlineStatus(1); }else{ vo.setOnlineStatus(0); } - String deviceStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_STATUS_KEY_PREFIX + device.getDeviceImei()); + String deviceStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_STATUS_KEY_PREFIX); // 获取电量 if(StringUtils.isNotBlank(deviceStatus)){ JSONObject jsonObject = JSONObject.parseObject(deviceStatus); @@ -154,7 +154,7 @@ public class AppDeviceBJQBizService { } // 获取经度纬度 - String locationKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_LOCATION_KEY_PREFIX + device.getDeviceImei(); + String locationKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_LOCATION_KEY_PREFIX; String locationInfo = RedisUtils.getCacheObject(locationKey); if(StringUtils.isNotBlank(locationInfo)){ JSONObject jsonObject = JSONObject.parseObject(locationInfo); diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/config/CustomMqttInboundConfiguration.java b/fys-admin/src/main/java/com/fuyuanshen/web/config/CustomMqttInboundConfiguration.java index faa8cb59..afefa342 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/config/CustomMqttInboundConfiguration.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/config/CustomMqttInboundConfiguration.java @@ -1,61 +1,61 @@ -package com.fuyuanshen.web.config; - -import cn.hutool.core.lang.UUID; -import com.fuyuanshen.global.mqtt.config.MqttPropertiesConfig; -import com.fuyuanshen.web.handler.mqtt.DeviceReceiverMessageHandler; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.integration.annotation.ServiceActivator; -import org.springframework.integration.channel.DirectChannel; -import org.springframework.integration.core.MessageProducer; -import org.springframework.integration.mqtt.core.MqttPahoClientFactory; -import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter; -import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter; -import org.springframework.messaging.MessageChannel; -import org.springframework.messaging.MessageHandler; - -/** - * @author: 默苍璃 - * @date: 2025-08-0110:46 - */ -@Configuration -public class CustomMqttInboundConfiguration { - - @Autowired - private MqttPropertiesConfig mqttPropertiesConfig; - @Autowired - private MqttPahoClientFactory mqttPahoClientFactory; - @Autowired - private DeviceReceiverMessageHandler deviceReceiverMessageHandler; - - - @Bean - public MessageChannel customMqttChannel(){ - return new DirectChannel(); - } - - - @Bean - public MessageProducer customMessageProducer(){ - String clientId = "custom_client_" + UUID.fastUUID(); - MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter( - mqttPropertiesConfig.getUrl(), - clientId, - mqttPahoClientFactory, - "A/#", "B/#" // 直接指定这两个主题 - ); - adapter.setQos(1); - adapter.setConverter(new DefaultPahoMessageConverter()); - adapter.setOutputChannel(customMqttChannel()); - return adapter; - } - - - @Bean - @ServiceActivator(inputChannel = "customMqttChannel") - public MessageHandler customMessageHandler(){ - return deviceReceiverMessageHandler; - } - -} +//package com.fuyuanshen.web.config; +// +//import cn.hutool.core.lang.UUID; +//import com.fuyuanshen.global.mqtt.config.MqttPropertiesConfig; +//import com.fuyuanshen.web.handler.mqtt.DeviceReceiverMessageHandler; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.context.annotation.Bean; +//import org.springframework.context.annotation.Configuration; +//import org.springframework.integration.annotation.ServiceActivator; +//import org.springframework.integration.channel.DirectChannel; +//import org.springframework.integration.core.MessageProducer; +//import org.springframework.integration.mqtt.core.MqttPahoClientFactory; +//import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter; +//import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter; +//import org.springframework.messaging.MessageChannel; +//import org.springframework.messaging.MessageHandler; +// +///** +// * @author: 默苍璃 +// * @date: 2025-08-0110:46 +// */ +//@Configuration +//public class CustomMqttInboundConfiguration { +// +// @Autowired +// private MqttPropertiesConfig mqttPropertiesConfig; +// @Autowired +// private MqttPahoClientFactory mqttPahoClientFactory; +// @Autowired +// private DeviceReceiverMessageHandler deviceReceiverMessageHandler; +// +// +// @Bean +// public MessageChannel customMqttChannel(){ +// return new DirectChannel(); +// } +// +// +// @Bean +// public MessageProducer customMessageProducer(){ +// String clientId = "custom_client_" + UUID.fastUUID(); +// MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter( +// mqttPropertiesConfig.getUrl(), +// clientId, +// mqttPahoClientFactory, +// "A/#", "B/#" // 直接指定这两个主题 +// ); +// adapter.setQos(1); +// adapter.setConverter(new DefaultPahoMessageConverter()); +// adapter.setOutputChannel(customMqttChannel()); +// return adapter; +// } +// +// +// @Bean +// @ServiceActivator(inputChannel = "customMqttChannel") +// public MessageHandler customMessageHandler(){ +// return deviceReceiverMessageHandler; +// } +// +//} diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/handler/mqtt/DeviceReceiverMessageHandler.java b/fys-admin/src/main/java/com/fuyuanshen/web/handler/mqtt/DeviceReceiverMessageHandler.java index b43d75f0..ad080ac1 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/handler/mqtt/DeviceReceiverMessageHandler.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/handler/mqtt/DeviceReceiverMessageHandler.java @@ -1,318 +1,318 @@ -package com.fuyuanshen.web.handler.mqtt; - -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fuyuanshen.common.satoken.utils.LoginHelper; -import com.fuyuanshen.equipment.domain.Device; -import com.fuyuanshen.equipment.domain.DeviceLog; -import com.fuyuanshen.equipment.mapper.DeviceLogMapper; -import com.fuyuanshen.equipment.mapper.DeviceMapper; -import com.fuyuanshen.equipment.utils.map.GetAddressFromLatUtil; -import com.fuyuanshen.equipment.utils.map.LngLonUtil; -import com.fuyuanshen.global.mqtt.constants.TenantsConstant; -import com.fuyuanshen.web.enums.InstructType6170; -import com.fuyuanshen.web.enums.LightModeEnum6170; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; -import org.springframework.messaging.Message; -import org.springframework.messaging.MessageHandler; -import org.springframework.messaging.MessageHeaders; -import org.springframework.messaging.MessagingException; -import org.springframework.stereotype.Component; - -/** - * 定义监听主题消息的处理器 - * - * @author: 默苍璃 - * @date: 2025-08-0110:19 - */ -@Component -@Data -@AllArgsConstructor -@Slf4j -public class DeviceReceiverMessageHandler implements MessageHandler { - - private final DeviceMapper deviceMapper; - private final DeviceLogMapper deviceLogMapper; - - // 使用Jackson解析JSON - private static final ObjectMapper objectMapper = new ObjectMapper(); - - - /** - * 处理接收的消息 - * - * @param message - * @throws MessagingException - */ - @Override - public void handleMessage(Message message) throws MessagingException { - // System.out.println("接收到的消息:" + message.getPayload()); - MessageHeaders headers = message.getHeaders(); - String receivedTopicName = (String) headers.get("mqtt_receivedTopic"); - System.out.println("消息来自主题:" + receivedTopicName); - - // String tenantId = LoginHelper.getTenantId(); - String tenantId = TenantsConstant.FU_YUAN_SHENG; - String payload = message.getPayload().toString(); - - if (receivedTopicName != null) { - // 1. 提取设备ID (从主题中获取) - String deviceImei = extractDeviceId(receivedTopicName); - Device device = deviceMapper.selectOne(new QueryWrapper() - .eq("tenant_id", tenantId) - .eq("device_imei", deviceImei)); - if (device == null) { - log.info("不存在的设备IMEI: {}", deviceImei); - } else { - - try { - JsonNode root = objectMapper.readTree(payload); - - DeviceLog record = new DeviceLog(); - // 手动设置租户ID - record.setTenantId(device.getTenantId()); // 从设备信息中获取租户ID - // 设备ID - record.setDeviceId(device.getId()); - // 设备名称 - record.setDeviceName(device.getDeviceName()); - - // 2. 处理instruct消息 - if (root.has("instruct")) { - JsonNode instructNode = root.get("instruct"); - if (instructNode.isArray()) { - boolean b = receivedTopicName.startsWith("B/"); - record = parseInstruct(device, instructNode, b); - // 根据不同主题进行不同处理 - if (receivedTopicName.startsWith("A/")) { - // 处理A主题的消息(设备上传) - record.setDataSource("设备上报"); - } else if (receivedTopicName.startsWith("B/")) { - // 处理B主题的消息 (手动上传) - record.setDataSource("客户端操作"); - } - } - // 确保在插入前设置tenantId和deviceId - record.setTenantId(device.getTenantId()); - record.setDeviceId(device.getId()); - deviceLogMapper.insert(record); - } - - // 2. 处理 state 消息 - if (root.has("state")) { - JsonNode instructNode = root.get("state"); - if (instructNode.isArray()) { - boolean b = receivedTopicName.startsWith("B/"); - record = parseState(device, instructNode, b); - // 根据不同主题进行不同处理 - if (receivedTopicName.startsWith("A/")) { - // 处理A主题的消息(设备上传) - record.setDataSource("设备上报"); - } else if (receivedTopicName.startsWith("B/")) { - // 处理B主题的消息 (手动上传) - record.setDataSource("客户端操作"); - } - } - // 确保在插入前设置tenantId和deviceId - record.setTenantId(device.getTenantId()); - record.setDeviceId(device.getId()); - deviceLogMapper.insert(record); - } - - if (root.has("imei")) { - // 设备行为 - record.setDeviceAction(InstructType6170.fromCode(0).getDescription()); - record.setDataSource("设备上报"); - record.setContent("设备启动"); - // 确保在插入前设置tenantId和deviceId - record.setTenantId(device.getTenantId()); - record.setDeviceId(device.getId()); - deviceLogMapper.insert(record); - } - - - // 3. 处理state消息 - // else if (root.has("state")) { - // JsonNode stateNode = root.get("state"); - // if (stateNode.isArray()) { - // StateRecord record = parseState(device, stateNode); - // stateRepo.save(record); - // } - // } - } catch (Exception e) { - log.error("消息解析失败: {}", payload, e); - } - - } - - } - } - - - /** - * 从主题中提取设备ID(IMEI) - * - * @param topic - * @return - */ - private String extractDeviceId(String topic) { - // 处理 A/# 或 B/# 格式的主题,例如 B/861556078765285 或 A/861556078765285 - String[] segments = topic.split("/"); - if (segments.length >= 2) { - // 返回第二个段,即 / 后面的部分 - return segments[1]; - } - // 如果格式不符合预期,返回原主题 - return topic; - } - - - /** - * 解析instruct消息 - * - * @param device - * @param array - * @param b - * @return - */ - private DeviceLog parseInstruct(Device device, JsonNode array, boolean b) { - DeviceLog record = new DeviceLog(); - record.setDeviceName(device.getDeviceName()); - // 设备行为 - record.setDeviceAction(InstructType6170.fromCode(array.get(0).asInt()).getDescription()); - - switch (array.get(0).asInt()) { - case 1: // 灯光模式 - LightModeEnum6170 lightModeEnum6170 = LightModeEnum6170.fromCode(array.get(1).asInt()); - record.setContent(lightModeEnum6170.getDescription()); - break; - - case 2: // 单位/姓名/职位 - byte[] unitBytes = new byte[480]; - for (int i = 1; i <= 480; i++) { - unitBytes[i - 1] = (byte) array.get(i).asInt(); - } - // record.setUnitData(unitBytes); - break; - - case 3: // 开机图片 - // record.setImagePage(array.get(1).asInt()); - byte[] imageBytes = new byte[512]; - for (int i = 2; i <= 513; i++) { - imageBytes[i - 2] = (byte) array.get(i).asInt(); - } - // record.setImageData(imageBytes); - break; - - case 4: // 激光灯 - int anInt = array.get(1).asInt(); - if (anInt == 0) { - record.setContent("关闭激光灯"); - } else if (anInt == 1) { - record.setContent("开启激光灯"); - } else { - record.setContent("未知操作"); - } - break; - - case 5: // 亮度调节 - record.setContent(+array.get(1).asInt() + "%"); - break; - - case 11: // 定位数据 - if (b) { - break; - } - int i1 = array.get(1).asInt(); - int i2 = array.get(2).asInt(); - int i3 = array.get(3).asInt(); - int i4 = array.get(4).asInt(); - - // 优雅的转换方式 Longitude and latitude - double latitude = i1 + i2 / 10.0; - double Longitude = i3 + i4 / 10.0; - // 84 ==》 高德 - double[] doubles = LngLonUtil.gps84_To_Gcj02(latitude, Longitude); - String address = GetAddressFromLatUtil.getAdd(String.valueOf(doubles[1]), String.valueOf(doubles[0])); - record.setContent(address); - break; - } - return record; - } - - - /** - * 解析 state 消息 - * - * @param device - * @param array - * @return - */ - private DeviceLog parseState(Device device, JsonNode array, boolean b) { - DeviceLog record = new DeviceLog(); - record.setDeviceName(device.getDeviceName()); - // 设备行为 - record.setDeviceAction(InstructType6170.fromCode(array.get(0).asInt()).getDescription()); - - switch (array.get(0).asInt()) { - case 1: // 灯光模式 - LightModeEnum6170 lightModeEnum6170 = LightModeEnum6170.fromCode(array.get(1).asInt()); - record.setContent(lightModeEnum6170.getDescription()); - break; - - case 2: // 单位/姓名/职位 - byte[] unitBytes = new byte[480]; - for (int i = 1; i <= 480; i++) { - unitBytes[i - 1] = (byte) array.get(i).asInt(); - } - // record.setUnitData(unitBytes); - break; - - case 3: // 开机图片 - // record.setImagePage(array.get(1).asInt()); - byte[] imageBytes = new byte[512]; - for (int i = 2; i <= 513; i++) { - imageBytes[i - 2] = (byte) array.get(i).asInt(); - } - // record.setImageData(imageBytes); - break; - - case 4: // 激光灯 - int anInt = array.get(1).asInt(); - if (anInt == 0) { - record.setContent("关闭激光灯"); - } else if (anInt == 1) { - record.setContent("开启激光灯"); - } else { - record.setContent("未知操作"); - } - break; - - case 5: // 亮度调节 - record.setContent(+array.get(1).asInt() + "%"); - break; - - case 11: // 定位数据 - if (b) { - break; - } - int i1 = array.get(1).asInt(); - int i2 = array.get(2).asInt(); - int i3 = array.get(3).asInt(); - int i4 = array.get(4).asInt(); - - // 优雅的转换方式 Longitude and latitude - double latitude = i1 + i2 / 10.0; - double Longitude = i3 + i4 / 10.0; - // 84 ==》 高德 - double[] doubles = LngLonUtil.gps84_To_Gcj02(latitude, Longitude); - String address = GetAddressFromLatUtil.getAdd(String.valueOf(doubles[1]), String.valueOf(doubles[0])); - record.setContent(address); - break; - } - return record; - } - -} +//package com.fuyuanshen.web.handler.mqtt; +// +//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +//import com.fasterxml.jackson.databind.JsonNode; +//import com.fasterxml.jackson.databind.ObjectMapper; +//import com.fuyuanshen.common.satoken.utils.LoginHelper; +//import com.fuyuanshen.equipment.domain.Device; +//import com.fuyuanshen.equipment.domain.DeviceLog; +//import com.fuyuanshen.equipment.mapper.DeviceLogMapper; +//import com.fuyuanshen.equipment.mapper.DeviceMapper; +//import com.fuyuanshen.equipment.utils.map.GetAddressFromLatUtil; +//import com.fuyuanshen.equipment.utils.map.LngLonUtil; +//import com.fuyuanshen.global.mqtt.constants.TenantsConstant; +//import com.fuyuanshen.web.enums.InstructType6170; +//import com.fuyuanshen.web.enums.LightModeEnum6170; +//import lombok.AllArgsConstructor; +//import lombok.Data; +//import lombok.extern.slf4j.Slf4j; +//import org.springframework.messaging.Message; +//import org.springframework.messaging.MessageHandler; +//import org.springframework.messaging.MessageHeaders; +//import org.springframework.messaging.MessagingException; +//import org.springframework.stereotype.Component; +// +///** +// * 定义监听主题消息的处理器 +// * +// * @author: 默苍璃 +// * @date: 2025-08-0110:19 +// */ +//@Component +//@Data +//@AllArgsConstructor +//@Slf4j +//public class DeviceReceiverMessageHandler implements MessageHandler { +// +// private final DeviceMapper deviceMapper; +// private final DeviceLogMapper deviceLogMapper; +// +// // 使用Jackson解析JSON +// private static final ObjectMapper objectMapper = new ObjectMapper(); +// +// +// /** +// * 处理接收的消息 +// * +// * @param message +// * @throws MessagingException +// */ +// @Override +// public void handleMessage(Message message) throws MessagingException { +// // System.out.println("接收到的消息:" + message.getPayload()); +// MessageHeaders headers = message.getHeaders(); +// String receivedTopicName = (String) headers.get("mqtt_receivedTopic"); +// System.out.println("消息来自主题:" + receivedTopicName); +// +// // String tenantId = LoginHelper.getTenantId(); +// String tenantId = TenantsConstant.FU_YUAN_SHENG; +// String payload = message.getPayload().toString(); +// +// if (receivedTopicName != null) { +// // 1. 提取设备ID (从主题中获取) +// String deviceImei = extractDeviceId(receivedTopicName); +// Device device = deviceMapper.selectOne(new QueryWrapper() +// .eq("tenant_id", tenantId) +// .eq("device_imei", deviceImei)); +// if (device == null) { +// log.info("不存在的设备IMEI: {}", deviceImei); +// } else { +// +// try { +// JsonNode root = objectMapper.readTree(payload); +// +// DeviceLog record = new DeviceLog(); +// // 手动设置租户ID +// record.setTenantId(device.getTenantId()); // 从设备信息中获取租户ID +// // 设备ID +// record.setDeviceId(device.getId()); +// // 设备名称 +// record.setDeviceName(device.getDeviceName()); +// +// // 2. 处理instruct消息 +// if (root.has("instruct")) { +// JsonNode instructNode = root.get("instruct"); +// if (instructNode.isArray()) { +// boolean b = receivedTopicName.startsWith("B/"); +// record = parseInstruct(device, instructNode, b); +// // 根据不同主题进行不同处理 +// if (receivedTopicName.startsWith("A/")) { +// // 处理A主题的消息(设备上传) +// record.setDataSource("设备上报"); +// } else if (receivedTopicName.startsWith("B/")) { +// // 处理B主题的消息 (手动上传) +// record.setDataSource("客户端操作"); +// } +// } +// // 确保在插入前设置tenantId和deviceId +// record.setTenantId(device.getTenantId()); +// record.setDeviceId(device.getId()); +// deviceLogMapper.insert(record); +// } +// +// // 2. 处理 state 消息 +// if (root.has("state")) { +// JsonNode instructNode = root.get("state"); +// if (instructNode.isArray()) { +// boolean b = receivedTopicName.startsWith("B/"); +// record = parseState(device, instructNode, b); +// // 根据不同主题进行不同处理 +// if (receivedTopicName.startsWith("A/")) { +// // 处理A主题的消息(设备上传) +// record.setDataSource("设备上报"); +// } else if (receivedTopicName.startsWith("B/")) { +// // 处理B主题的消息 (手动上传) +// record.setDataSource("客户端操作"); +// } +// } +// // 确保在插入前设置tenantId和deviceId +// record.setTenantId(device.getTenantId()); +// record.setDeviceId(device.getId()); +// deviceLogMapper.insert(record); +// } +// +// if (root.has("imei")) { +// // 设备行为 +// record.setDeviceAction(InstructType6170.fromCode(0).getDescription()); +// record.setDataSource("设备上报"); +// record.setContent("设备启动"); +// // 确保在插入前设置tenantId和deviceId +// record.setTenantId(device.getTenantId()); +// record.setDeviceId(device.getId()); +// deviceLogMapper.insert(record); +// } +// +// +// // 3. 处理state消息 +// // else if (root.has("state")) { +// // JsonNode stateNode = root.get("state"); +// // if (stateNode.isArray()) { +// // StateRecord record = parseState(device, stateNode); +// // stateRepo.save(record); +// // } +// // } +// } catch (Exception e) { +// log.error("消息解析失败: {}", payload, e); +// } +// +// } +// +// } +// } +// +// +// /** +// * 从主题中提取设备ID(IMEI) +// * +// * @param topic +// * @return +// */ +// private String extractDeviceId(String topic) { +// // 处理 A/# 或 B/# 格式的主题,例如 B/861556078765285 或 A/861556078765285 +// String[] segments = topic.split("/"); +// if (segments.length >= 2) { +// // 返回第二个段,即 / 后面的部分 +// return segments[1]; +// } +// // 如果格式不符合预期,返回原主题 +// return topic; +// } +// +// +// /** +// * 解析instruct消息 +// * +// * @param device +// * @param array +// * @param b +// * @return +// */ +// private DeviceLog parseInstruct(Device device, JsonNode array, boolean b) { +// DeviceLog record = new DeviceLog(); +// record.setDeviceName(device.getDeviceName()); +// // 设备行为 +// record.setDeviceAction(InstructType6170.fromCode(array.get(0).asInt()).getDescription()); +// +// switch (array.get(0).asInt()) { +// case 1: // 灯光模式 +// LightModeEnum6170 lightModeEnum6170 = LightModeEnum6170.fromCode(array.get(1).asInt()); +// record.setContent(lightModeEnum6170.getDescription()); +// break; +// +// case 2: // 单位/姓名/职位 +// byte[] unitBytes = new byte[480]; +// for (int i = 1; i <= 480; i++) { +// unitBytes[i - 1] = (byte) array.get(i).asInt(); +// } +// // record.setUnitData(unitBytes); +// break; +// +// case 3: // 开机图片 +// // record.setImagePage(array.get(1).asInt()); +// byte[] imageBytes = new byte[512]; +// for (int i = 2; i <= 513; i++) { +// imageBytes[i - 2] = (byte) array.get(i).asInt(); +// } +// // record.setImageData(imageBytes); +// break; +// +// case 4: // 激光灯 +// int anInt = array.get(1).asInt(); +// if (anInt == 0) { +// record.setContent("关闭激光灯"); +// } else if (anInt == 1) { +// record.setContent("开启激光灯"); +// } else { +// record.setContent("未知操作"); +// } +// break; +// +// case 5: // 亮度调节 +// record.setContent(+array.get(1).asInt() + "%"); +// break; +// +// case 11: // 定位数据 +// if (b) { +// break; +// } +// int i1 = array.get(1).asInt(); +// int i2 = array.get(2).asInt(); +// int i3 = array.get(3).asInt(); +// int i4 = array.get(4).asInt(); +// +// // 优雅的转换方式 Longitude and latitude +// double latitude = i1 + i2 / 10.0; +// double Longitude = i3 + i4 / 10.0; +// // 84 ==》 高德 +// double[] doubles = LngLonUtil.gps84_To_Gcj02(latitude, Longitude); +// String address = GetAddressFromLatUtil.getAdd(String.valueOf(doubles[1]), String.valueOf(doubles[0])); +// record.setContent(address); +// break; +// } +// return record; +// } +// +// +// /** +// * 解析 state 消息 +// * +// * @param device +// * @param array +// * @return +// */ +// private DeviceLog parseState(Device device, JsonNode array, boolean b) { +// DeviceLog record = new DeviceLog(); +// record.setDeviceName(device.getDeviceName()); +// // 设备行为 +// record.setDeviceAction(InstructType6170.fromCode(array.get(0).asInt()).getDescription()); +// +// switch (array.get(0).asInt()) { +// case 1: // 灯光模式 +// LightModeEnum6170 lightModeEnum6170 = LightModeEnum6170.fromCode(array.get(1).asInt()); +// record.setContent(lightModeEnum6170.getDescription()); +// break; +// +// case 2: // 单位/姓名/职位 +// byte[] unitBytes = new byte[480]; +// for (int i = 1; i <= 480; i++) { +// unitBytes[i - 1] = (byte) array.get(i).asInt(); +// } +// // record.setUnitData(unitBytes); +// break; +// +// case 3: // 开机图片 +// // record.setImagePage(array.get(1).asInt()); +// byte[] imageBytes = new byte[512]; +// for (int i = 2; i <= 513; i++) { +// imageBytes[i - 2] = (byte) array.get(i).asInt(); +// } +// // record.setImageData(imageBytes); +// break; +// +// case 4: // 激光灯 +// int anInt = array.get(1).asInt(); +// if (anInt == 0) { +// record.setContent("关闭激光灯"); +// } else if (anInt == 1) { +// record.setContent("开启激光灯"); +// } else { +// record.setContent("未知操作"); +// } +// break; +// +// case 5: // 亮度调节 +// record.setContent(+array.get(1).asInt() + "%"); +// break; +// +// case 11: // 定位数据 +// if (b) { +// break; +// } +// int i1 = array.get(1).asInt(); +// int i2 = array.get(2).asInt(); +// int i3 = array.get(3).asInt(); +// int i4 = array.get(4).asInt(); +// +// // 优雅的转换方式 Longitude and latitude +// double latitude = i1 + i2 / 10.0; +// double Longitude = i3 + i4 / 10.0; +// // 84 ==》 高德 +// double[] doubles = LngLonUtil.gps84_To_Gcj02(latitude, Longitude); +// String address = GetAddressFromLatUtil.getAdd(String.valueOf(doubles[1]), String.valueOf(doubles[0])); +// record.setContent(address); +// break; +// } +// return record; +// } +// +//} diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/listener/UserActionListener.java b/fys-admin/src/main/java/com/fuyuanshen/web/listener/UserActionListener.java index 9105a5da..49762cbc 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/listener/UserActionListener.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/listener/UserActionListener.java @@ -1,163 +1,163 @@ -package com.fuyuanshen.web.listener; - -import cn.dev33.satoken.listener.SaTokenListener; -import cn.dev33.satoken.stp.StpUtil; -import cn.dev33.satoken.stp.parameter.SaLoginParameter; -import cn.hutool.core.convert.Convert; -import cn.hutool.http.useragent.UserAgent; -import cn.hutool.http.useragent.UserAgentUtil; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import com.fuyuanshen.common.core.constant.CacheConstants; -import com.fuyuanshen.common.core.constant.Constants; -import com.fuyuanshen.common.core.domain.dto.UserOnlineDTO; -import com.fuyuanshen.common.core.utils.MessageUtils; -import com.fuyuanshen.common.core.utils.ServletUtils; -import com.fuyuanshen.common.core.utils.SpringUtils; -import com.fuyuanshen.common.core.utils.ip.AddressUtils; -import com.fuyuanshen.common.log.event.LogininforEvent; -import com.fuyuanshen.common.redis.utils.RedisUtils; -import com.fuyuanshen.common.satoken.utils.LoginHelper; -import com.fuyuanshen.common.tenant.helper.TenantHelper; -import com.fuyuanshen.web.service.SysLoginService; -import org.springframework.stereotype.Component; - -import java.time.Duration; - -/** - * 用户行为 侦听器的实现 - * - * @author Lion Li - */ -@RequiredArgsConstructor -@Component -@Slf4j -public class UserActionListener implements SaTokenListener { - - private final SysLoginService loginService; - - /** - * 每次登录时触发 - */ - @Override - public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginParameter loginParameter) { - UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent")); - String ip = ServletUtils.getClientIP(); - UserOnlineDTO dto = new UserOnlineDTO(); - dto.setIpaddr(ip); - dto.setLoginLocation(AddressUtils.getRealAddressByIP(ip)); - dto.setBrowser(userAgent.getBrowser().getName()); - dto.setOs(userAgent.getOs().getName()); - dto.setLoginTime(System.currentTimeMillis()); - dto.setTokenId(tokenValue); - String username = (String) loginParameter.getExtra(LoginHelper.USER_NAME_KEY); - String tenantId = (String) loginParameter.getExtra(LoginHelper.TENANT_KEY); - dto.setUserName(username); - dto.setClientKey((String) loginParameter.getExtra(LoginHelper.CLIENT_KEY)); - dto.setDeviceType(loginParameter.getDeviceType()); - dto.setDeptName((String) loginParameter.getExtra(LoginHelper.DEPT_NAME_KEY)); - TenantHelper.dynamic(tenantId, () -> { - if(loginParameter.getTimeout() == -1) { - RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto); - } else { - RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto, Duration.ofSeconds(loginParameter.getTimeout())); - } - }); - // 记录登录日志 - LogininforEvent logininforEvent = new LogininforEvent(); - logininforEvent.setTenantId(tenantId); - logininforEvent.setUsername(username); - logininforEvent.setStatus(Constants.LOGIN_SUCCESS); - logininforEvent.setMessage(MessageUtils.message("user.login.success")); - logininforEvent.setRequest(ServletUtils.getRequest()); - SpringUtils.context().publishEvent(logininforEvent); - // 更新登录信息 - loginService.recordLoginInfo((Long) loginParameter.getExtra(LoginHelper.USER_KEY), ip); - log.info("user doLogin, userId:{}, token:{}", loginId, tokenValue); - } - - /** - * 每次注销时触发 - */ - @Override - public void doLogout(String loginType, Object loginId, String tokenValue) { - String tenantId = Convert.toStr(StpUtil.getExtra(tokenValue, LoginHelper.TENANT_KEY)); - TenantHelper.dynamic(tenantId, () -> { - RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue); - }); - log.info("user doLogout, userId:{}, token:{}", loginId, tokenValue); - } - - /** - * 每次被踢下线时触发 - */ - @Override - public void doKickout(String loginType, Object loginId, String tokenValue) { - String tenantId = Convert.toStr(StpUtil.getExtra(tokenValue, LoginHelper.TENANT_KEY)); - TenantHelper.dynamic(tenantId, () -> { - RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue); - }); - log.info("user doKickout, userId:{}, token:{}", loginId, tokenValue); - } - - /** - * 每次被顶下线时触发 - */ - @Override - public void doReplaced(String loginType, Object loginId, String tokenValue) { - String tenantId = Convert.toStr(StpUtil.getExtra(tokenValue, LoginHelper.TENANT_KEY)); - TenantHelper.dynamic(tenantId, () -> { - RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue); - }); - log.info("user doReplaced, userId:{}, token:{}", loginId, tokenValue); - } - - /** - * 每次被封禁时触发 - */ - @Override - public void doDisable(String loginType, Object loginId, String service, int level, long disableTime) { - } - - /** - * 每次被解封时触发 - */ - @Override - public void doUntieDisable(String loginType, Object loginId, String service) { - } - - /** - * 每次打开二级认证时触发 - */ - @Override - public void doOpenSafe(String loginType, String tokenValue, String service, long safeTime) { - } - - /** - * 每次创建Session时触发 - */ - @Override - public void doCloseSafe(String loginType, String tokenValue, String service) { - } - - /** - * 每次创建Session时触发 - */ - @Override - public void doCreateSession(String id) { - } - - /** - * 每次注销Session时触发 - */ - @Override - public void doLogoutSession(String id) { - } - - /** - * 每次Token续期时触发 - */ - @Override - public void doRenewTimeout(String tokenValue, Object loginId, long timeout) { - } -} +//package com.fuyuanshen.web.listener; +// +//import cn.dev33.satoken.listener.SaTokenListener; +//import cn.dev33.satoken.stp.StpUtil; +//import cn.dev33.satoken.stp.parameter.SaLoginParameter; +//import cn.hutool.core.convert.Convert; +//import cn.hutool.http.useragent.UserAgent; +//import cn.hutool.http.useragent.UserAgentUtil; +//import lombok.RequiredArgsConstructor; +//import lombok.extern.slf4j.Slf4j; +//import com.fuyuanshen.common.core.constant.CacheConstants; +//import com.fuyuanshen.common.core.constant.Constants; +//import com.fuyuanshen.common.core.domain.dto.UserOnlineDTO; +//import com.fuyuanshen.common.core.utils.MessageUtils; +//import com.fuyuanshen.common.core.utils.ServletUtils; +//import com.fuyuanshen.common.core.utils.SpringUtils; +//import com.fuyuanshen.common.core.utils.ip.AddressUtils; +//import com.fuyuanshen.common.log.event.LogininforEvent; +//import com.fuyuanshen.common.redis.utils.RedisUtils; +//import com.fuyuanshen.common.satoken.utils.LoginHelper; +//import com.fuyuanshen.common.tenant.helper.TenantHelper; +//import com.fuyuanshen.web.service.SysLoginService; +//import org.springframework.stereotype.Component; +// +//import java.time.Duration; +// +///** +// * 用户行为 侦听器的实现 +// * +// * @author Lion Li +// */ +//@RequiredArgsConstructor +//@Component +//@Slf4j +//public class UserActionListener implements SaTokenListener { +// +// private final SysLoginService loginService; +// +// /** +// * 每次登录时触发 +// */ +// @Override +// public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginParameter loginParameter) { +// UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent")); +// String ip = ServletUtils.getClientIP(); +// UserOnlineDTO dto = new UserOnlineDTO(); +// dto.setIpaddr(ip); +// dto.setLoginLocation(AddressUtils.getRealAddressByIP(ip)); +// dto.setBrowser(userAgent.getBrowser().getName()); +// dto.setOs(userAgent.getOs().getName()); +// dto.setLoginTime(System.currentTimeMillis()); +// dto.setTokenId(tokenValue); +// String username = (String) loginParameter.getExtra(LoginHelper.USER_NAME_KEY); +// String tenantId = (String) loginParameter.getExtra(LoginHelper.TENANT_KEY); +// dto.setUserName(username); +// dto.setClientKey((String) loginParameter.getExtra(LoginHelper.CLIENT_KEY)); +// dto.setDeviceType(loginParameter.getDeviceType()); +// dto.setDeptName((String) loginParameter.getExtra(LoginHelper.DEPT_NAME_KEY)); +// TenantHelper.dynamic(tenantId, () -> { +// if(loginParameter.getTimeout() == -1) { +// RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto); +// } else { +// RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto, Duration.ofSeconds(loginParameter.getTimeout())); +// } +// }); +// // 记录登录日志 +// LogininforEvent logininforEvent = new LogininforEvent(); +// logininforEvent.setTenantId(tenantId); +// logininforEvent.setUsername(username); +// logininforEvent.setStatus(Constants.LOGIN_SUCCESS); +// logininforEvent.setMessage(MessageUtils.message("user.login.success")); +// logininforEvent.setRequest(ServletUtils.getRequest()); +// SpringUtils.context().publishEvent(logininforEvent); +// // 更新登录信息 +// loginService.recordLoginInfo((Long) loginParameter.getExtra(LoginHelper.USER_KEY), ip); +// log.info("user doLogin, userId:{}, token:{}", loginId, tokenValue); +// } +// +// /** +// * 每次注销时触发 +// */ +// @Override +// public void doLogout(String loginType, Object loginId, String tokenValue) { +// String tenantId = Convert.toStr(StpUtil.getExtra(tokenValue, LoginHelper.TENANT_KEY)); +// TenantHelper.dynamic(tenantId, () -> { +// RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue); +// }); +// log.info("user doLogout, userId:{}, token:{}", loginId, tokenValue); +// } +// +// /** +// * 每次被踢下线时触发 +// */ +// @Override +// public void doKickout(String loginType, Object loginId, String tokenValue) { +// String tenantId = Convert.toStr(StpUtil.getExtra(tokenValue, LoginHelper.TENANT_KEY)); +// TenantHelper.dynamic(tenantId, () -> { +// RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue); +// }); +// log.info("user doKickout, userId:{}, token:{}", loginId, tokenValue); +// } +// +// /** +// * 每次被顶下线时触发 +// */ +// @Override +// public void doReplaced(String loginType, Object loginId, String tokenValue) { +// String tenantId = Convert.toStr(StpUtil.getExtra(tokenValue, LoginHelper.TENANT_KEY)); +// TenantHelper.dynamic(tenantId, () -> { +// RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue); +// }); +// log.info("user doReplaced, userId:{}, token:{}", loginId, tokenValue); +// } +// +// /** +// * 每次被封禁时触发 +// */ +// @Override +// public void doDisable(String loginType, Object loginId, String service, int level, long disableTime) { +// } +// +// /** +// * 每次被解封时触发 +// */ +// @Override +// public void doUntieDisable(String loginType, Object loginId, String service) { +// } +// +// /** +// * 每次打开二级认证时触发 +// */ +// @Override +// public void doOpenSafe(String loginType, String tokenValue, String service, long safeTime) { +// } +// +// /** +// * 每次创建Session时触发 +// */ +// @Override +// public void doCloseSafe(String loginType, String tokenValue, String service) { +// } +// +// /** +// * 每次创建Session时触发 +// */ +// @Override +// public void doCreateSession(String id) { +// } +// +// /** +// * 每次注销Session时触发 +// */ +// @Override +// public void doLogoutSession(String id) { +// } +// +// /** +// * 每次Token续期时触发 +// */ +// @Override +// public void doRenewTimeout(String tokenValue, Object loginId, long timeout) { +// } +//} diff --git a/fys-admin/src/main/resources/application-prod.yml b/fys-admin/src/main/resources/application-prod.yml index 8f210fb9..67cca4f5 100644 --- a/fys-admin/src/main/resources/application-prod.yml +++ b/fys-admin/src/main/resources/application-prod.yml @@ -4,7 +4,7 @@ spring.servlet.multipart.location: /fys/server/temp --- # 监控中心配置 spring.boot.admin.client: # 增加客户端开关 - enabled: true + enabled: false url: http://localhost:9090/admin instance: service-host-type: IP @@ -16,7 +16,7 @@ spring.boot.admin.client: --- # snail-job 配置 snail-job: - enabled: true + enabled: false # 需要在 SnailJob 后台组管理创建对应名称的组,然后创建任务的时候选择对应的组,才能正确分派任务 group: "fys_group" # SnailJob 接入验证令牌 详见 script/sql/ry_job.sql `sj_group_config`表 @@ -52,9 +52,9 @@ spring: driverClassName: com.mysql.cj.jdbc.Driver # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562 # rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题) - url: jdbc:mysql://localhost:3306/fys_vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true + url: jdbc:mysql://47.120.79.150:3306/fys-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true username: root - password: Jz_5623_cl1 + password: Jq_123456# # # 从库数据源 # slave: # lazy: true @@ -101,7 +101,7 @@ spring: spring.data: redis: # 地址 - host: localhost + host: 47.120.79.150 # 端口,默认为6379 port: 6379 # 数据库索引 @@ -177,11 +177,14 @@ sms: # 框架定义的厂商名称标识,标定此配置是哪个厂商,详细请看厂商标识介绍部分 supplier: alibaba # 有些称为accessKey有些称之为apiKey,也有称为sdkKey或者appId。 - access-key-id: 您的accessKey + access-key-id: LTAI5tJdDNpZootsPQ5hdELx # 称为accessSecret有些称之为apiSecret - access-key-secret: 您的accessKeySecret - signature: 您的短信签名 - sdk-app-id: 您的sdkAppId + access-key-secret: mU4WtffcCXpHPz5tLwQpaGtLsJXONt + #模板ID 非必须配置,如果使用sendMessage的快速发送需此配置 + template-id: SMS_322180518 + #模板变量 上述模板的变量 + templateName: code + signature: 湖北星汉研创科技 config2: # 厂商标识,标定此配置是哪个厂商,详细请看厂商标识介绍部分 supplier: tencent From 0c932c686d5dcb9691b5d8317741c1f1a9d7bbe5 Mon Sep 17 00:00:00 2001 From: chenyouting <514333061@qq.com> Date: Fri, 8 Aug 2025 16:32:40 +0800 Subject: [PATCH 09/47] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=88=86=E4=BA=AB?= =?UTF-8?q?=E6=9F=A5=E7=9C=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/fuyuanshen/app/service/AppDeviceShareService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceShareService.java b/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceShareService.java index 996c97c8..ea5e1f6f 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceShareService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceShareService.java @@ -47,7 +47,7 @@ public class AppDeviceShareService { public AppDeviceShareDetailVo getInfo(Long id) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - queryWrapper.eq(AppDeviceShare::getDeviceId, id); + queryWrapper.eq(AppDeviceShare::getId, id); List appDeviceShareVos = appDeviceShareMapper.selectVoList(queryWrapper); if(appDeviceShareVos==null || appDeviceShareVos.isEmpty()){ return null; From af64984623873b8e8ceb0aee7ec8508f8874dd7d Mon Sep 17 00:00:00 2001 From: chenyouting <514333061@qq.com> Date: Sat, 9 Aug 2025 08:49:37 +0800 Subject: [PATCH 10/47] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=88=86=E4=BA=AB?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AppDeviceShareController.java | 2 +- .../app/service/AppDeviceShareService.java | 54 +++++++++++++++++++ .../app/domain/vo/AppDeviceShareVo.java | 25 +++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) 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 581c934d..09efc627 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 @@ -52,7 +52,7 @@ public class AppDeviceShareController extends BaseController { */ @GetMapping("/deviceShareList") public TableDataInfo list(AppDeviceShareBo bo, PageQuery pageQuery) { - return deviceShareService.queryPageList(bo, pageQuery); + return appDeviceShareService.queryPageList(bo, pageQuery); } /** diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceShareService.java b/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceShareService.java index ea5e1f6f..15dc7de7 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceShareService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceShareService.java @@ -1,7 +1,9 @@ package com.fuyuanshen.app.service; +import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fuyuanshen.app.domain.AppDeviceShare; import com.fuyuanshen.app.domain.AppPersonnelInfo; import com.fuyuanshen.app.domain.bo.AppDeviceShareBo; @@ -16,12 +18,15 @@ import com.fuyuanshen.common.core.exception.ServiceException; import com.fuyuanshen.common.core.exception.user.CaptchaExpireException; import com.fuyuanshen.common.core.utils.MessageUtils; import com.fuyuanshen.common.core.utils.StringUtils; +import com.fuyuanshen.common.mybatis.core.page.PageQuery; +import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; import com.fuyuanshen.common.redis.utils.RedisUtils; import com.fuyuanshen.common.satoken.utils.AppLoginHelper; import com.fuyuanshen.equipment.domain.Device; import com.fuyuanshen.equipment.domain.DeviceType; import com.fuyuanshen.equipment.mapper.DeviceMapper; import com.fuyuanshen.equipment.mapper.DeviceTypeMapper; +import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -30,6 +35,9 @@ import java.util.Arrays; import java.util.Date; import java.util.List; +import static com.fuyuanshen.common.core.constant.GlobalConstants.GLOBAL_REDIS_KEY; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.*; + @RequiredArgsConstructor @Slf4j @@ -44,6 +52,52 @@ public class AppDeviceShareService { private final AppPersonnelInfoMapper appPersonnelInfoMapper; + public TableDataInfo queryPageList(AppDeviceShareBo bo, PageQuery pageQuery) { + Long userId = AppLoginHelper.getUserId(); + bo.setCreateBy(userId); + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + Page result = appDeviceShareMapper.selectVoPage(pageQuery.build(), lqw); + List records = result.getRecords(); + records.forEach(item-> { + Device device = deviceMapper.selectById(item.getDeviceId()); + if(device != null){ + item.setDevicePic(device.getDevicePic()); + item.setDeviceName(device.getDeviceName()); + item.setDeviceImei(device.getDeviceImei()); + } + + //设备在线状态 + String onlineStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ item.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX); + if(StringUtils.isNotBlank(onlineStatus)){ + + item.setOnlineStatus(1); + }else{ + item.setOnlineStatus(0); + } + String deviceStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX+ item.getDeviceImei() + DEVICE_STATUS_KEY_PREFIX); + // 获取电量 + if(StringUtils.isNotBlank(deviceStatus)){ + JSONObject jsonObject = JSONObject.parseObject(deviceStatus); + item.setBattery(jsonObject.getString("batteryPercentage")); + }else{ + item.setBattery("0"); + } + + String location = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY +DEVICE_KEY_PREFIX+ item.getDeviceImei()+ DEVICE_LOCATION_KEY_PREFIX); + if(StringUtils.isNotBlank(location)){ + JSONObject jsonObject = JSONObject.parseObject(location); + item.setLatitude(jsonObject.getString("latitude")); + item.setLongitude(jsonObject.getString("longitude")); + } + + String alarmStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY +DEVICE_KEY_PREFIX+ item.getDeviceImei()+ DEVICE_ALARM_KEY_PREFIX); + if(StringUtils.isNotBlank(alarmStatus)){ + item.setAlarmStatus(alarmStatus); + } + }); + return TableDataInfo.build(result); + } + public AppDeviceShareDetailVo getInfo(Long id) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceShareVo.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceShareVo.java index b9ea67d8..d1f2055c 100644 --- a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceShareVo.java +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceShareVo.java @@ -73,4 +73,29 @@ public class AppDeviceShareVo implements Serializable { // 设备图片 private String devicePic; + + /** + * 在线状态(0离线,1在线) + */ + private Integer onlineStatus; + + /** + * 电量 百分比 + */ + private String battery; + + /** + * 纬度 + */ + private String latitude; + + /** + * 经度 + */ + private String longitude; + + /** + * 告警状态(0解除告警,1告警) + */ + private String alarmStatus; } From bc165f5d60de979f1a7e6507366a482a379680ab Mon Sep 17 00:00:00 2001 From: chenyouting <514333061@qq.com> Date: Sat, 9 Aug 2025 17:09:26 +0800 Subject: [PATCH 11/47] =?UTF-8?q?=E5=88=86=E4=BA=AB=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AppDeviceShareController.java | 2 +- .../app/service/AppDeviceShareService.java | 116 ++++++++++++------ .../app/domain/vo/AppDeviceShareDetailVo.java | 34 +++++ .../app/domain/vo/AppDeviceShareVo.java | 6 + .../app/mapper/AppDeviceShareMapper.java | 3 + .../mapper/app/AppDeviceShareMapper.xml | 43 ++++++- 6 files changed, 163 insertions(+), 41 deletions(-) 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 09efc627..4c743206 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 @@ -60,7 +60,7 @@ public class AppDeviceShareController extends BaseController { */ @GetMapping("/otherDeviceShareList") public TableDataInfo otherDeviceShareList(AppDeviceShareBo bo, PageQuery pageQuery) { - return deviceShareService.otherDeviceShareList(bo, pageQuery); + return appDeviceShareService.otherDeviceShareList(bo, pageQuery); } /** diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceShareService.java b/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceShareService.java index 15dc7de7..be5986c1 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceShareService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceShareService.java @@ -2,7 +2,9 @@ package com.fuyuanshen.app.service; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fuyuanshen.app.domain.AppDeviceShare; import com.fuyuanshen.app.domain.AppPersonnelInfo; @@ -55,49 +57,44 @@ public class AppDeviceShareService { public TableDataInfo queryPageList(AppDeviceShareBo bo, PageQuery pageQuery) { Long userId = AppLoginHelper.getUserId(); bo.setCreateBy(userId); - LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); - Page result = appDeviceShareMapper.selectVoPage(pageQuery.build(), lqw); + Page page = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize()); + Page result = appDeviceShareMapper.selectAppDeviceShareList(bo, page); List records = result.getRecords(); - records.forEach(item-> { - Device device = deviceMapper.selectById(item.getDeviceId()); - if(device != null){ - item.setDevicePic(device.getDevicePic()); - item.setDeviceName(device.getDeviceName()); - item.setDeviceImei(device.getDeviceImei()); - } - - //设备在线状态 - String onlineStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ item.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX); - if(StringUtils.isNotBlank(onlineStatus)){ - - item.setOnlineStatus(1); - }else{ - item.setOnlineStatus(0); - } - String deviceStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX+ item.getDeviceImei() + DEVICE_STATUS_KEY_PREFIX); - // 获取电量 - if(StringUtils.isNotBlank(deviceStatus)){ - JSONObject jsonObject = JSONObject.parseObject(deviceStatus); - item.setBattery(jsonObject.getString("batteryPercentage")); - }else{ - item.setBattery("0"); - } - - String location = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY +DEVICE_KEY_PREFIX+ item.getDeviceImei()+ DEVICE_LOCATION_KEY_PREFIX); - if(StringUtils.isNotBlank(location)){ - JSONObject jsonObject = JSONObject.parseObject(location); - item.setLatitude(jsonObject.getString("latitude")); - item.setLongitude(jsonObject.getString("longitude")); - } - - String alarmStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY +DEVICE_KEY_PREFIX+ item.getDeviceImei()+ DEVICE_ALARM_KEY_PREFIX); - if(StringUtils.isNotBlank(alarmStatus)){ - item.setAlarmStatus(alarmStatus); - } - }); + records.forEach(AppDeviceShareService::buildDeviceStatus); return TableDataInfo.build(result); } + private static void buildDeviceStatus(AppDeviceShareVo item) { + //设备在线状态 + String onlineStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ item.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX); + if(StringUtils.isNotBlank(onlineStatus)){ + + item.setOnlineStatus(1); + }else{ + item.setOnlineStatus(0); + } + String deviceStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX+ item.getDeviceImei() + DEVICE_STATUS_KEY_PREFIX); + // 获取电量 + if(StringUtils.isNotBlank(deviceStatus)){ + JSONObject jsonObject = JSONObject.parseObject(deviceStatus); + item.setBattery(jsonObject.getString("batteryPercentage")); + }else{ + item.setBattery("0"); + } + + String location = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY +DEVICE_KEY_PREFIX+ item.getDeviceImei()+ DEVICE_LOCATION_KEY_PREFIX); + if(StringUtils.isNotBlank(location)){ + JSONObject jsonObject = JSONObject.parseObject(location); + item.setLatitude(jsonObject.getString("latitude")); + item.setLongitude(jsonObject.getString("longitude")); + } + + String alarmStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY +DEVICE_KEY_PREFIX+ item.getDeviceImei()+ DEVICE_ALARM_KEY_PREFIX); + if(StringUtils.isNotBlank(alarmStatus)){ + item.setAlarmStatus(alarmStatus); + } + } + public AppDeviceShareDetailVo getInfo(Long id) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); @@ -135,7 +132,35 @@ public class AppDeviceShareService { if(appPersonnelInfoVos!=null && !appPersonnelInfoVos.isEmpty()){ shareDetailVo.setPersonnelInfo(appPersonnelInfoVos.get(0)); } + //设备在线状态 + String onlineStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei()+ DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX); + if(StringUtils.isNotBlank(onlineStatus)){ + shareDetailVo.setOnlineStatus(1); + }else{ + shareDetailVo.setOnlineStatus(0); + } + String deviceStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_STATUS_KEY_PREFIX); + // 获取电量 + if(StringUtils.isNotBlank(deviceStatus)){ + JSONObject jsonObject = JSONObject.parseObject(deviceStatus); + shareDetailVo.setMainLightMode(jsonObject.getString("mainLightMode")); + shareDetailVo.setLaserLightMode(jsonObject.getString("laserLightMode")); + shareDetailVo.setBatteryPercentage(jsonObject.getString("batteryPercentage")); + shareDetailVo.setChargeState(jsonObject.getString("chargeState")); + shareDetailVo.setBatteryRemainingTime(jsonObject.getString("batteryRemainingTime")); + }else{ + shareDetailVo.setBatteryPercentage("0"); + } + // 获取经度纬度 + String locationKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_LOCATION_KEY_PREFIX; + String locationInfo = RedisUtils.getCacheObject(locationKey); + if(StringUtils.isNotBlank(locationInfo)){ + JSONObject jsonObject = JSONObject.parseObject(locationInfo); + shareDetailVo.setLongitude(jsonObject.get("longitude").toString()); + shareDetailVo.setLatitude(jsonObject.get("latitude").toString()); + shareDetailVo.setAddress((String)jsonObject.get("address")); + } return shareDetailVo; } /** @@ -186,4 +211,17 @@ public class AppDeviceShareService { public int remove(Long[] ids) { return appDeviceShareMapper.deleteByIds(Arrays.asList(ids)); } + + public TableDataInfo otherDeviceShareList(AppDeviceShareBo bo, PageQuery pageQuery) { + String username = AppLoginHelper.getUsername(); + bo.setPhonenumber(username); + Page page = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize()); + IPage result = appDeviceShareMapper.otherDeviceShareList(bo, page); + List records = result.getRecords(); + + records.forEach(AppDeviceShareService::buildDeviceStatus); + return TableDataInfo.build(result); + } + + } diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceShareDetailVo.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceShareDetailVo.java index d11d6576..89716f64 100644 --- a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceShareDetailVo.java +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceShareDetailVo.java @@ -104,4 +104,38 @@ public class AppDeviceShareDetailVo implements Serializable { * 发送信息 */ private String sendMsg; + + //设备主灯档位 + private String mainLightMode; + + //激光灯档位 + private String laserLightMode; + + //电量百分比 + private String batteryPercentage; + + //充电状态(0没有充电,1正在充电,2为已充满) + private String chargeState; + + //电池剩余续航时间200分钟 + private String batteryRemainingTime; + + /** + * 在线状态(0离线,1在线) + */ + private Integer onlineStatus; + + // 经度 + private String longitude; + + // 纬度 + private String latitude; + + // 逆解析地址 + private String address; + + /** + * 告警状态(0解除告警,1告警) + */ + private String alarmStatus; } diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceShareVo.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceShareVo.java index d1f2055c..e5aef582 100644 --- a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceShareVo.java +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceShareVo.java @@ -57,6 +57,12 @@ public class AppDeviceShareVo implements Serializable { @ExcelProperty(value = "手机号") private String phonenumber; + /** + * 他人分享手机号 + */ + @ExcelProperty(value = "手机号") + private String otherPhonenumber; + /** * 功能权限(1:灯光模式;2:激光模式;3:开机画面;4:人员信息登记;5:发送信息;6:产品信息) 以逗号分隔 diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/mapper/AppDeviceShareMapper.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/mapper/AppDeviceShareMapper.java index 01dbf1a8..1de4c14a 100644 --- a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/mapper/AppDeviceShareMapper.java +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/mapper/AppDeviceShareMapper.java @@ -1,5 +1,6 @@ package com.fuyuanshen.app.mapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fuyuanshen.app.domain.AppDeviceShare; @@ -16,4 +17,6 @@ import org.apache.ibatis.annotations.Param; */ public interface AppDeviceShareMapper extends BaseMapperPlus { IPage otherDeviceShareList(@Param("bo") AppDeviceShareBo bo, Page page); + + Page selectAppDeviceShareList(@Param("bo") AppDeviceShareBo bo,Page page); } diff --git a/fys-modules/fys-app/src/main/resources/mapper/app/AppDeviceShareMapper.xml b/fys-modules/fys-app/src/main/resources/mapper/app/AppDeviceShareMapper.xml index 2202eae4..9b3b29c5 100644 --- a/fys-modules/fys-app/src/main/resources/mapper/app/AppDeviceShareMapper.xml +++ b/fys-modules/fys-app/src/main/resources/mapper/app/AppDeviceShareMapper.xml @@ -5,6 +5,47 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + From 61ed9f01549a66b11c631fce075f0337ca77f3ea Mon Sep 17 00:00:00 2001 From: chenyouting <514333061@qq.com> Date: Tue, 12 Aug 2025 17:03:11 +0800 Subject: [PATCH 12/47] =?UTF-8?q?=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/controller/AppDeviceController.java | 18 ++ .../device/AppDeviceBJQController.java | 18 +- .../domain/dto/AppDeviceLogoUploadDto.java | 1 + .../app/domain/dto/AppRealTimeStatusDto.java | 30 +++ .../app/service/AppDeviceBizService.java | 32 ++- .../device/AppDeviceBJQBizService.java | 9 +- .../device/status/DeviceStatusRule.java | 20 ++ .../status/constants/DeviceTypeConstants.java | 6 + .../device/status/jbq/AlarmStatusRule.java | 50 +++++ .../device/status/jbq/BootLogoStatusRule.java | 49 +++++ .../jbq/LaserModeSettingsStatusRule.java | 48 +++++ .../device/status/jbq/ModeStatusRule.java | 47 +++++ .../jbq/RegisterPersonInfoStatusRule.java | 47 +++++ .../status/jbq/SendMessageStatusRule.java | 48 +++++ .../global/mqtt/rule/bjq/BjqBootLogoRule.java | 2 +- .../global/mqtt/rule/bjq/BjqModeRule.java | 5 + .../common/core/constant/GlobalConstants.java | 3 + .../annotation/FunctionAccessAnnotation.java | 11 ++ .../FunctionAccessBatcAnnotation.java | 11 ++ .../aspectj/FunctionAccessAspect.java | 103 ++++++++++ .../aspectj/FunctionAccessBatchAspect.java | 184 ++++++++++++++++++ .../app/domain/bo/AppPersonnelInfoBo.java | 5 + .../mapper/app/AppDeviceShareMapper.xml | 7 +- .../domain/dto/AppDeviceSendMsgBo.java | 7 + 24 files changed, 742 insertions(+), 19 deletions(-) create mode 100644 fys-admin/src/main/java/com/fuyuanshen/app/domain/dto/AppRealTimeStatusDto.java create mode 100644 fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/DeviceStatusRule.java create mode 100644 fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/constants/DeviceTypeConstants.java create mode 100644 fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/jbq/AlarmStatusRule.java create mode 100644 fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/jbq/BootLogoStatusRule.java create mode 100644 fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/jbq/LaserModeSettingsStatusRule.java create mode 100644 fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/jbq/ModeStatusRule.java create mode 100644 fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/jbq/RegisterPersonInfoStatusRule.java create mode 100644 fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/jbq/SendMessageStatusRule.java create mode 100644 fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/annotation/FunctionAccessAnnotation.java create mode 100644 fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/annotation/FunctionAccessBatcAnnotation.java create mode 100644 fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/aspectj/FunctionAccessAspect.java create mode 100644 fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/aspectj/FunctionAccessBatchAspect.java 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 beb899ef..d414cff7 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 @@ -1,12 +1,14 @@ package com.fuyuanshen.app.controller; import com.fuyuanshen.app.domain.dto.APPReNameDTO; +import com.fuyuanshen.app.domain.dto.AppRealTimeStatusDto; import com.fuyuanshen.app.domain.vo.APPDeviceTypeVo; import com.fuyuanshen.app.service.AppDeviceBizService; import com.fuyuanshen.common.core.domain.R; import com.fuyuanshen.common.mybatis.core.page.PageQuery; import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; import com.fuyuanshen.common.web.core.BaseController; +import com.fuyuanshen.equipment.domain.Device; import com.fuyuanshen.equipment.domain.dto.AppDeviceBo; import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria; import com.fuyuanshen.equipment.domain.vo.AppDeviceVo; @@ -15,6 +17,7 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.util.List; +import java.util.Map; /** * APP设备信息管理 @@ -72,4 +75,19 @@ public class AppDeviceController extends BaseController { appDeviceService.reName(reNameDTO); return R.ok("重命名成功!!!"); } + + + @GetMapping("/realTimeStatus") + public R> getRealTimeStatus(AppRealTimeStatusDto statusDto) { + Map status = appDeviceService.getRealTimeStatus(statusDto); + return R.ok(status); + } + + /** + * 根据mac查询设备信息 + */ + @GetMapping("/getDeviceInfoByDeviceMac") + public R getDeviceInfo(String deviceMac) { + return R.ok(appDeviceService.getDeviceInfo(deviceMac)); + } } diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceBJQController.java b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceBJQController.java index 2f7caf8b..7427f8eb 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceBJQController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceBJQController.java @@ -7,6 +7,8 @@ import com.fuyuanshen.app.domain.vo.AppDeviceDetailVo; import com.fuyuanshen.app.service.device.AppDeviceBJQBizService; import com.fuyuanshen.common.core.domain.R; import com.fuyuanshen.common.core.validate.AddGroup; +import com.fuyuanshen.common.ratelimiter.annotation.FunctionAccessAnnotation; +import com.fuyuanshen.common.ratelimiter.annotation.FunctionAccessBatcAnnotation; import com.fuyuanshen.common.web.core.BaseController; import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo; import jakarta.validation.constraints.NotNull; @@ -41,6 +43,7 @@ public class AppDeviceBJQController extends BaseController { * 人员信息登记 */ @PostMapping(value = "/registerPersonInfo") + @FunctionAccessAnnotation("registerPersonInfo") public R registerPersonInfo(@Validated(AddGroup.class) @RequestBody AppPersonnelInfoBo bo) { return toAjax(appDeviceService.registerPersonInfo(bo)); } @@ -49,6 +52,7 @@ public class AppDeviceBJQController extends BaseController { * 发送信息 */ @PostMapping(value = "/sendMessage") + @FunctionAccessBatcAnnotation("sendMessage") public R sendMessage(@RequestBody AppDeviceSendMsgBo bo) { return toAjax(appDeviceService.sendMessage(bo)); } @@ -57,6 +61,7 @@ public class AppDeviceBJQController extends BaseController { * 发送报警信息 */ @PostMapping(value = "/sendAlarmMessage") + @FunctionAccessBatcAnnotation("sendAlarmMessage") public R sendAlarmMessage(@RequestBody AppDeviceSendMsgBo bo) { return toAjax(appDeviceService.sendAlarmMessage(bo)); } @@ -65,6 +70,7 @@ public class AppDeviceBJQController extends BaseController { * 上传设备logo图片 */ @PostMapping("/uploadLogo") + @FunctionAccessAnnotation("uploadLogo") public R upload(@Validated @ModelAttribute AppDeviceLogoUploadDto bo) { MultipartFile file = bo.getFile(); @@ -80,6 +86,7 @@ public class AppDeviceBJQController extends BaseController { * 灯光模式 * 0(关灯),1(强光模式),2(弱光模式), 3(爆闪模式), 4(泛光模式) */ + @FunctionAccessAnnotation("lightModeSettings") @PostMapping("/lightModeSettings") public R lightModeSettings(@RequestBody DeviceInstructDto params) { // params 转 JSONObject @@ -91,6 +98,7 @@ public class AppDeviceBJQController extends BaseController { * 灯光亮度设置 * */ + @FunctionAccessAnnotation("lightBrightnessSettings") @PostMapping("/lightBrightnessSettings") public R lightBrightnessSettings(@RequestBody DeviceInstructDto params) { appDeviceService.lightBrightnessSettings(params); @@ -102,18 +110,10 @@ public class AppDeviceBJQController extends BaseController { * */ @PostMapping("/laserModeSettings") + @FunctionAccessAnnotation("laserModeSettings") public R laserModeSettings(@RequestBody DeviceInstructDto params) { appDeviceService.laserModeSettings(params); return R.ok(); } - /** - * 地图逆解析 - * - */ - @PostMapping("/mapReverseGeocoding") - public R mapReverseGeocoding(@RequestBody DeviceInstructDto params) { - String mapJson = appDeviceService.mapReverseGeocoding(params); - return R.ok(mapJson); - } } diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/domain/dto/AppDeviceLogoUploadDto.java b/fys-admin/src/main/java/com/fuyuanshen/app/domain/dto/AppDeviceLogoUploadDto.java index 76dc5e2c..26db3c16 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/domain/dto/AppDeviceLogoUploadDto.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/domain/dto/AppDeviceLogoUploadDto.java @@ -8,6 +8,7 @@ public class AppDeviceLogoUploadDto { private Long deviceId; + private String deviceImei; /** * 文件 */ diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/domain/dto/AppRealTimeStatusDto.java b/fys-admin/src/main/java/com/fuyuanshen/app/domain/dto/AppRealTimeStatusDto.java new file mode 100644 index 00000000..01a13d3a --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/app/domain/dto/AppRealTimeStatusDto.java @@ -0,0 +1,30 @@ +package com.fuyuanshen.app.domain.dto; + +import lombok.Data; + +/** + * 设备实时状态 + */ +@Data +public class AppRealTimeStatusDto { + + /** + * 设备IMEI + */ + private String deviceImei; + + /** + * 设备类型 + */ + private String typeName; + + /** + * 功能类型 + */ + private String functionMode; + + /** + * 批次号 + */ + private String batchId; +} diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceBizService.java b/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceBizService.java index 80e74f1d..93ea7c2a 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceBizService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceBizService.java @@ -11,6 +11,7 @@ import com.fuyuanshen.app.domain.AppPersonnelInfo; import com.fuyuanshen.app.domain.bo.AppPersonnelInfoBo; import com.fuyuanshen.app.domain.dto.APPReNameDTO; import com.fuyuanshen.app.domain.dto.AppDeviceLogoUploadDto; +import com.fuyuanshen.app.domain.dto.AppRealTimeStatusDto; import com.fuyuanshen.app.domain.dto.DeviceInstructDto; import com.fuyuanshen.app.domain.vo.APPDeviceTypeVo; import com.fuyuanshen.app.domain.vo.AppDeviceDetailVo; @@ -18,6 +19,8 @@ import com.fuyuanshen.app.domain.vo.AppPersonnelInfoVo; import com.fuyuanshen.app.mapper.AppDeviceBindRecordMapper; import com.fuyuanshen.app.mapper.AppPersonnelInfoMapper; import com.fuyuanshen.app.mapper.equipment.APPDeviceMapper; +import com.fuyuanshen.app.service.device.status.DeviceStatusRule; +import com.fuyuanshen.app.service.device.status.RealTimeStatusEngine; import com.fuyuanshen.common.core.constant.GlobalConstants; import com.fuyuanshen.common.core.exception.ServiceException; import com.fuyuanshen.common.core.utils.*; @@ -35,7 +38,7 @@ import com.fuyuanshen.equipment.enums.BindingStatusEnum; import com.fuyuanshen.equipment.enums.CommunicationModeEnum; import com.fuyuanshen.equipment.mapper.DeviceMapper; import com.fuyuanshen.equipment.mapper.DeviceTypeMapper; -import com.fuyuanshen.equipment.utils.c.ReliableTextToBitmap; +import com.fuyuanshen.equipment.service.DeviceService; import com.fuyuanshen.global.mqtt.config.MqttGateway; import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants; import com.fuyuanshen.global.mqtt.constants.MqttConstants; @@ -68,6 +71,9 @@ public class AppDeviceBizService { private final DeviceTypeMapper deviceTypeMapper; private final MqttGateway mqttGateway; private final AppDeviceBindRecordMapper appDeviceBindRecordMapper; + private final RealTimeStatusEngine realTimeStatusEngine; + private final DeviceService deviceService; + public List getTypeList() { @@ -602,4 +608,28 @@ public class AppDeviceBizService { } return 1; } + + public Map getRealTimeStatus(AppRealTimeStatusDto statusDto) { + try { + String commandType = statusDto.getTypeName()+"_" + statusDto.getFunctionMode(); + DeviceStatusRule rule = realTimeStatusEngine.getDeviceStatusRule(commandType); + if(rule == null){ + throw new ServiceException("未匹配到处理命令"); + } + return rule.getStatus(statusDto); + } catch (Exception e){ + e.printStackTrace(); + } + return null; + } + + public Device getDeviceInfo(String deviceMac) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("device_mac", deviceMac); + List devices = deviceMapper.selectList(queryWrapper); + if(ObjectUtils.length(devices) ==0){ + return null; + } + return devices.get(0); + } } diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/device/AppDeviceBJQBizService.java b/fys-admin/src/main/java/com/fuyuanshen/app/service/device/AppDeviceBJQBizService.java index db998b66..026ee4f8 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/service/device/AppDeviceBJQBizService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/service/device/AppDeviceBJQBizService.java @@ -14,6 +14,7 @@ import com.fuyuanshen.app.mapper.AppPersonnelInfoMapper; import com.fuyuanshen.common.core.constant.GlobalConstants; import com.fuyuanshen.common.core.exception.ServiceException; import com.fuyuanshen.common.core.utils.*; +import com.fuyuanshen.common.ratelimiter.annotation.FunctionAccessAnnotation; import com.fuyuanshen.common.redis.utils.RedisUtils; import com.fuyuanshen.common.satoken.utils.AppLoginHelper; import com.fuyuanshen.equipment.domain.Device; @@ -62,12 +63,10 @@ public class AppDeviceBJQBizService { if (device == null) { throw new ServiceException("设备不存在" + deviceId); } - try { ClassPathResource resource = new ClassPathResource("image/background.png"); InputStream inputStream = resource.getInputStream(); -// String backgroundImagePath = "D:\\background.png"; // 替换为实际背景图片路径 byte[] largeData = ImageWithTextGenerate.generate160x80ImageWithText2(bo.getSendMsg(), inputStream, 25600); int[] ints = convertHexToDecimal(largeData); RedisUtils.setCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + ":app_send_message_data" , Arrays.toString(ints), Duration.ofSeconds(30 * 60L)); @@ -77,7 +76,6 @@ public class AppDeviceBJQBizService { byte[] arr = ImageToCArrayConverter.convertStringToByteArray(data); byte[] specificChunk = ImageToCArrayConverter.getChunk(arr, 0, 512); log.info("发送信息第0块数据大小: {} 字节",specificChunk.length); -// log.info("第0块数据: {}", Arrays.toString(specificChunk)); ArrayList intData = new ArrayList<>(); intData.add(6); @@ -167,6 +165,7 @@ public class AppDeviceBJQBizService { } + public boolean registerPersonInfo(AppPersonnelInfoBo bo) { Long deviceId = bo.getDeviceId(); Device deviceObj = deviceMapper.selectById(deviceId); @@ -212,6 +211,7 @@ public class AppDeviceBJQBizService { } + @FunctionAccessAnnotation("uploadDeviceLogo") public void uploadDeviceLogo(AppDeviceLogoUploadDto bo) { try { Device device = deviceMapper.selectById(bo.getDeviceId()); @@ -256,6 +256,7 @@ public class AppDeviceBJQBizService { * 灯光模式 * 0(关灯),1(强光模式),2(弱光模式), 3(爆闪模式), 4(泛光模式) */ + public void lightModeSettings(DeviceInstructDto params) { try { Long deviceId = params.getDeviceId(); @@ -280,6 +281,7 @@ public class AppDeviceBJQBizService { } //灯光亮度设置 + @FunctionAccessAnnotation("lightBrightnessSettings") public void lightBrightnessSettings(DeviceInstructDto params) { try { Long deviceId = params.getDeviceId(); @@ -312,6 +314,7 @@ public class AppDeviceBJQBizService { } //激光模式设置 + @FunctionAccessAnnotation("laserModeSettings") public void laserModeSettings(DeviceInstructDto params) { try { Long deviceId = params.getDeviceId(); diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/DeviceStatusRule.java b/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/DeviceStatusRule.java new file mode 100644 index 00000000..2c83a367 --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/DeviceStatusRule.java @@ -0,0 +1,20 @@ +package com.fuyuanshen.app.service.device.status; + +import com.fuyuanshen.app.domain.dto.AppRealTimeStatusDto; +import com.fuyuanshen.equipment.domain.Device; + +import java.util.Map; + +// 规则接口 +public interface DeviceStatusRule { + + /** + * 获取命令类型 + * @return 命令类型 + */ + String getCommandType(); + + boolean supports(String deviceType); + + Map getStatus(AppRealTimeStatusDto statusDto); +} \ No newline at end of file diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/constants/DeviceTypeConstants.java b/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/constants/DeviceTypeConstants.java new file mode 100644 index 00000000..271f6330 --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/constants/DeviceTypeConstants.java @@ -0,0 +1,6 @@ +package com.fuyuanshen.app.service.device.status.constants; + +public class DeviceTypeConstants { + public static final String TYPE_BJQ6170 = "BJQ6170"; + +} diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/jbq/AlarmStatusRule.java b/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/jbq/AlarmStatusRule.java new file mode 100644 index 00000000..14956de5 --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/jbq/AlarmStatusRule.java @@ -0,0 +1,50 @@ +package com.fuyuanshen.app.service.device.status.jbq; + +import com.fuyuanshen.app.domain.dto.AppRealTimeStatusDto; +import com.fuyuanshen.app.service.device.status.DeviceStatusRule; +import com.fuyuanshen.app.service.device.status.constants.DeviceTypeConstants; +import com.fuyuanshen.common.redis.utils.RedisUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +import static com.fuyuanshen.common.core.constant.GlobalConstants.FUNCTION_ACCESS_KEY; + + +@Slf4j +@Component +public class AlarmStatusRule implements DeviceStatusRule { + @Override + public String getCommandType() { + return DeviceTypeConstants.TYPE_BJQ6170+"_5"; + } + + @Override + public boolean supports(String deviceType) { + return true; // 适用于所有设备类型 + } + + @Override + public Map getStatus(AppRealTimeStatusDto dto) { + Map status = new HashMap<>(); + String functionAccess = RedisUtils.getCacheObject( + + FUNCTION_ACCESS_KEY + dto.getDeviceImei()); + if(functionAccess==null){ + status.put("functionAccess", "OK"); + }else{ + status.put("functionAccess", "ACTIVE"); + } + // + +// String alarmStatus = RedisUtils.getCacheObject( +// GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + dto.getDeviceImei() + DEVICE_ALARM_KEY_PREFIX); +// +// if (StringUtils.isNotBlank(alarmStatus)) { +// status.put("alarmStatus", alarmStatus); +// } + return status; + } +} \ No newline at end of file diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/jbq/BootLogoStatusRule.java b/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/jbq/BootLogoStatusRule.java new file mode 100644 index 00000000..6eea5b3e --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/jbq/BootLogoStatusRule.java @@ -0,0 +1,49 @@ +package com.fuyuanshen.app.service.device.status.jbq; + +import com.fuyuanshen.app.domain.dto.AppRealTimeStatusDto; +import com.fuyuanshen.app.service.device.status.DeviceStatusRule; +import com.fuyuanshen.app.service.device.status.constants.DeviceTypeConstants; +import com.fuyuanshen.common.redis.utils.RedisUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +import static com.fuyuanshen.common.core.constant.GlobalConstants.FUNCTION_ACCESS_KEY; + +// 上传开机图片 +@Slf4j +@Component +public class BootLogoStatusRule implements DeviceStatusRule { + @Override + public String getCommandType() { + return DeviceTypeConstants.TYPE_BJQ6170+"_3"; + } + + @Override + public boolean supports(String deviceType) { + return true; // 适用于所有设备类型 + } + + @Override + public Map getStatus(AppRealTimeStatusDto dto) { + Map status = new HashMap<>(); + String functionAccess = RedisUtils.getCacheObject( + FUNCTION_ACCESS_KEY + dto.getDeviceImei()); + if(functionAccess==null){ + status.put("functionAccess", "OK"); + }else{ + status.put("functionAccess", "ACTIVE"); + } +// String location = RedisUtils.getCacheObject( +// GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + dto.getDeviceImei() + DEVICE_LOCATION_KEY_PREFIX); +// +// if (StringUtils.isNotBlank(location)) { +// JSONObject jsonObject = JSONObject.parseObject(location); +// status.put("latitude", jsonObject.getString("latitude")); +// status.put("longitude", jsonObject.getString("longitude")); +// } + return status; + } +} \ No newline at end of file diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/jbq/LaserModeSettingsStatusRule.java b/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/jbq/LaserModeSettingsStatusRule.java new file mode 100644 index 00000000..1004dbad --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/jbq/LaserModeSettingsStatusRule.java @@ -0,0 +1,48 @@ +package com.fuyuanshen.app.service.device.status.jbq; + +import com.fuyuanshen.app.domain.dto.AppRealTimeStatusDto; +import com.fuyuanshen.app.service.device.status.DeviceStatusRule; +import com.fuyuanshen.app.service.device.status.constants.DeviceTypeConstants; +import com.fuyuanshen.common.redis.utils.RedisUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +import static com.fuyuanshen.common.core.constant.GlobalConstants.FUNCTION_ACCESS_KEY; + +// 激光模式设置 +@Slf4j +@Component +public class LaserModeSettingsStatusRule implements DeviceStatusRule { + @Override + public String getCommandType() { + return DeviceTypeConstants.TYPE_BJQ6170+"_2"; + } + + @Override + public boolean supports(String deviceType) { + return true; // 适用于所有设备类型 + } + + /** + * @param dto + * @return + */ + @Override + public Map getStatus(AppRealTimeStatusDto dto) { + Map status = new HashMap<>(); + String functionAccess = RedisUtils.getCacheObject( + FUNCTION_ACCESS_KEY + dto.getDeviceImei()); + if(functionAccess==null){ + status.put("functionAccess", "OK"); + }else{ + status.put("functionAccess", "ACTIVE"); + } +// String onlineStatus = RedisUtils.getCacheObject( +// GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + dto.getDeviceImei() + DEVICE_ONLINE_STATUS_KEY_PREFIX); +// status.put("onlineStatus", StringUtils.isNotBlank(onlineStatus) ? 1 : 0); + return status; + } +} \ No newline at end of file diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/jbq/ModeStatusRule.java b/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/jbq/ModeStatusRule.java new file mode 100644 index 00000000..a20c024a --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/jbq/ModeStatusRule.java @@ -0,0 +1,47 @@ +package com.fuyuanshen.app.service.device.status.jbq; + +import com.fuyuanshen.app.domain.dto.AppRealTimeStatusDto; +import com.fuyuanshen.app.service.device.status.DeviceStatusRule; +import com.fuyuanshen.app.service.device.status.constants.DeviceTypeConstants; +import com.fuyuanshen.common.redis.utils.RedisUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +import static com.fuyuanshen.common.core.constant.GlobalConstants.FUNCTION_ACCESS_KEY; + +// 灯光状态 +@Slf4j +@Component +public class ModeStatusRule implements DeviceStatusRule { + + @Override + public String getCommandType() { + return DeviceTypeConstants.TYPE_BJQ6170+"_1"; + } + + @Override + public boolean supports(String deviceType) { + return true; // 适用于所有设备类型 + } + + @Override + public Map getStatus(AppRealTimeStatusDto dto) { + Map status = new HashMap<>(); + String functionAccess = RedisUtils.getCacheObject( + FUNCTION_ACCESS_KEY + dto.getDeviceImei()); + status.put("functionAccess", functionAccess); +// String deviceStatus = RedisUtils.getCacheObject( +// GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + dto.getDeviceImei() + DEVICE_STATUS_KEY_PREFIX); +// +// if (StringUtils.isNotBlank(deviceStatus)) { +// JSONObject jsonObject = JSONObject.parseObject(deviceStatus); +// status.put("battery", jsonObject.getString("batteryPercentage")); +// } else { +// status.put("battery", "0"); +// } + return status; + } +} \ No newline at end of file diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/jbq/RegisterPersonInfoStatusRule.java b/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/jbq/RegisterPersonInfoStatusRule.java new file mode 100644 index 00000000..f7288faf --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/jbq/RegisterPersonInfoStatusRule.java @@ -0,0 +1,47 @@ +package com.fuyuanshen.app.service.device.status.jbq; + +import com.fuyuanshen.app.domain.dto.AppRealTimeStatusDto; +import com.fuyuanshen.app.service.device.status.DeviceStatusRule; +import com.fuyuanshen.app.service.device.status.constants.DeviceTypeConstants; +import com.fuyuanshen.common.redis.utils.RedisUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +import static com.fuyuanshen.common.core.constant.GlobalConstants.FUNCTION_ACCESS_KEY; + + +@Slf4j +@Component +public class RegisterPersonInfoStatusRule implements DeviceStatusRule { + @Override + public String getCommandType() { + return DeviceTypeConstants.TYPE_BJQ6170+"_4"; + } + + @Override + public boolean supports(String deviceType) { + return true; // 适用于所有设备类型 + } + + @Override + public Map getStatus(AppRealTimeStatusDto dto) { + Map status = new HashMap<>(); + String functionAccess = RedisUtils.getCacheObject( + FUNCTION_ACCESS_KEY + dto.getDeviceImei()); + if(functionAccess==null){ + status.put("functionAccess", "OK"); + }else{ + status.put("functionAccess", "ACTIVE"); + } +// String alarmStatus = RedisUtils.getCacheObject( +// GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + dto.getDeviceImei() + DEVICE_ALARM_KEY_PREFIX); +// +// if (StringUtils.isNotBlank(alarmStatus)) { +// status.put("alarmStatus", alarmStatus); +// } + return status; + } +} \ No newline at end of file diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/jbq/SendMessageStatusRule.java b/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/jbq/SendMessageStatusRule.java new file mode 100644 index 00000000..d4382ecd --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/jbq/SendMessageStatusRule.java @@ -0,0 +1,48 @@ +package com.fuyuanshen.app.service.device.status.jbq; + +import com.fuyuanshen.app.domain.dto.AppRealTimeStatusDto; +import com.fuyuanshen.app.service.device.status.DeviceStatusRule; +import com.fuyuanshen.app.service.device.status.constants.DeviceTypeConstants; +import com.fuyuanshen.common.redis.utils.RedisUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static com.fuyuanshen.common.core.constant.GlobalConstants.FUNCTION_ACCESS_KEY; + + +@Slf4j +@Component +public class SendMessageStatusRule implements DeviceStatusRule { + @Override + public String getCommandType() { + return DeviceTypeConstants.TYPE_BJQ6170+"_6"; + } + + @Override + public boolean supports(String deviceType) { + return true; // 适用于所有设备类型 + } + + @Override + public Map getStatus(AppRealTimeStatusDto dto) { + Map status = new HashMap<>(); + List functionAccess = RedisUtils.getCacheObject( + FUNCTION_ACCESS_KEY + dto.getBatchId()); + if(functionAccess==null){ + status.put("functionAccess", "OK"); + }else{ + status.put("functionAccess", "ACTIVE"); + } +// String alarmStatus = RedisUtils.getCacheObject( +// GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + dto.getDeviceImei() + DEVICE_ALARM_KEY_PREFIX); +// +// if (StringUtils.isNotBlank(alarmStatus)) { +// status.put("alarmStatus", alarmStatus); +// } + return status; + } +} \ No newline at end of file diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqBootLogoRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqBootLogoRule.java index 97fd0f30..309d20bd 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqBootLogoRule.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqBootLogoRule.java @@ -23,7 +23,7 @@ import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVIC import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX; /** - * 人员信息命令处理 + * 上传开机图片命令处理 */ @Component @RequiredArgsConstructor diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqModeRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqModeRule.java index 09aeaccb..6904edb5 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqModeRule.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqModeRule.java @@ -14,6 +14,7 @@ import org.springframework.stereotype.Component; import java.time.Duration; import java.util.concurrent.CompletableFuture; +import static com.fuyuanshen.common.core.constant.GlobalConstants.FUNCTION_ACCESS_KEY; import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX; import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_LIGHT_MODE_KEY_PREFIX; @@ -47,6 +48,10 @@ public class BjqModeRule implements MqttMessageRule { } catch (Exception e) { log.error("处理灯光模式命令时出错", e); + }finally { + log.info("处理灯光模式命令完成"); + String functionAccess = FUNCTION_ACCESS_KEY + context.getDeviceImei(); + RedisUtils.deleteObject(functionAccess); } } diff --git a/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/constant/GlobalConstants.java b/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/constant/GlobalConstants.java index ccec3718..305b5b03 100644 --- a/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/constant/GlobalConstants.java +++ b/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/constant/GlobalConstants.java @@ -36,4 +36,7 @@ public interface GlobalConstants { * 三方认证 redis key */ String SOCIAL_AUTH_CODE_KEY = GLOBAL_REDIS_KEY + "social_auth_codes:"; + + + String FUNCTION_ACCESS_KEY = GLOBAL_REDIS_KEY + "device:function_access:"; } diff --git a/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/annotation/FunctionAccessAnnotation.java b/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/annotation/FunctionAccessAnnotation.java new file mode 100644 index 00000000..635b5b9f --- /dev/null +++ b/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/annotation/FunctionAccessAnnotation.java @@ -0,0 +1,11 @@ +package com.fuyuanshen.common.ratelimiter.annotation;// DeviceRedisKeyAnnotation.java +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface FunctionAccessAnnotation { + String value() default ""; +} diff --git a/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/annotation/FunctionAccessBatcAnnotation.java b/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/annotation/FunctionAccessBatcAnnotation.java new file mode 100644 index 00000000..3f59cd96 --- /dev/null +++ b/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/annotation/FunctionAccessBatcAnnotation.java @@ -0,0 +1,11 @@ +package com.fuyuanshen.common.ratelimiter.annotation;// DeviceRedisKeyAnnotation.java +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface FunctionAccessBatcAnnotation { + String value() default ""; +} diff --git a/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/aspectj/FunctionAccessAspect.java b/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/aspectj/FunctionAccessAspect.java new file mode 100644 index 00000000..a46a17f7 --- /dev/null +++ b/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/aspectj/FunctionAccessAspect.java @@ -0,0 +1,103 @@ +package com.fuyuanshen.common.ratelimiter.aspectj;// DeviceRedisKeyAspect.java +import com.fuyuanshen.common.core.exception.ServiceException; +import com.fuyuanshen.common.core.utils.StringUtils; +import com.fuyuanshen.common.ratelimiter.annotation.FunctionAccessAnnotation; +import com.fuyuanshen.common.redis.utils.RedisUtils; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Component; + +import java.time.Duration; + +import static com.fuyuanshen.common.core.constant.GlobalConstants.FUNCTION_ACCESS_KEY; + +@Slf4j +@Aspect +@Component +public class FunctionAccessAspect { + + // 定义切点,拦截带有DeviceRedisKeyAnnotation注解的方法 + @Around("@annotation(functionAccessAnnotation)") + public Object addDeviceRedisKey(ProceedingJoinPoint joinPoint, FunctionAccessAnnotation functionAccessAnnotation) throws Throwable { + Object result; + String deviceImei = null; + + // 获取方法参数,查找设备ID + Object[] args = joinPoint.getArgs(); + deviceImei = extractDeviceImei(args); + + if (StringUtils.isNotBlank(deviceImei)) { + // 生成全局Redis key + String redisKey = generateDeviceRedisKey(deviceImei); + String cacheKey = RedisUtils.getCacheObject(redisKey); + if(StringUtils.isNotBlank(cacheKey) && "ACTIVE".equals(cacheKey)){ + throw new ServiceException("设备已存在访问限制,请稍后再试", 500); + } + // 存储到Redis中,设置过期时间 + RedisUtils.setCacheObject(redisKey, "ACTIVE", Duration.ofMinutes(30)); + log.info("设备Redis key已添加: {}", redisKey); + } + + // 执行原方法 + result = joinPoint.proceed(); + + return result; + } + + /** + * 从方法参数中提取设备ID + */ + private String extractDeviceImei(Object[] args) { + if (args == null || args.length == 0) { + return null; + } + + for (Object arg : args) { + if (arg == null) continue; + + // 如果参数本身就是设备ID (Long类型) + if (arg instanceof Long) { + return arg.toString(); + } + + // 如果参数是对象,尝试获取deviceId字段 + try { + // 使用反射获取deviceId字段 + java.lang.reflect.Field[] fields = arg.getClass().getDeclaredFields(); + for (java.lang.reflect.Field field : fields) { + if ("deviceImei".equalsIgnoreCase(field.getName()) || + "device_imei".equalsIgnoreCase(field.getName())) { + field.setAccessible(true); + Object value = field.get(arg); + if (value != null) { + return value.toString(); + } + } + } + + // 尝试获取getId方法 + try { + java.lang.reflect.Method getIdMethod = arg.getClass().getMethod("getDeviceImei"); + Object value = getIdMethod.invoke(arg); + if (value != null) { + return value.toString(); + } + } catch (Exception ignored) {} + + } catch (Exception e) { + log.debug("从参数中提取设备ID时出错: {}", e.getMessage()); + } + } + + return null; + } + + /** + * 生成设备的全局Redis key + */ + private String generateDeviceRedisKey(String deviceImei) { + return FUNCTION_ACCESS_KEY + deviceImei; + } +} diff --git a/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/aspectj/FunctionAccessBatchAspect.java b/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/aspectj/FunctionAccessBatchAspect.java new file mode 100644 index 00000000..0d6f79bc --- /dev/null +++ b/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/aspectj/FunctionAccessBatchAspect.java @@ -0,0 +1,184 @@ +package com.fuyuanshen.common.ratelimiter.aspectj;// DeviceRedisKeyAspect.java +import cn.hutool.json.JSON; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.fuyuanshen.common.core.exception.ServiceException; +import com.fuyuanshen.common.core.utils.StringUtils; +import com.fuyuanshen.common.ratelimiter.annotation.FunctionAccessAnnotation; +import com.fuyuanshen.common.ratelimiter.annotation.FunctionAccessBatcAnnotation; +import com.fuyuanshen.common.redis.utils.RedisUtils; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Component; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static com.fuyuanshen.common.core.constant.GlobalConstants.FUNCTION_ACCESS_KEY; + +@Slf4j +@Aspect +@Component +public class FunctionAccessBatchAspect { + + // 定义切点,拦截带有DeviceRedisKeyAnnotation注解的方法 + @Around("@annotation(functionAccessBatchAspect)") + public Object addDeviceRedisKey(ProceedingJoinPoint joinPoint, FunctionAccessBatcAnnotation functionAccessBatchAspect) throws Throwable { + Object result; + String batchId = null; + List deviceImeiList = null; + + // 获取方法参数,查找设备ID + Object[] args = joinPoint.getArgs(); + batchId = extractDeviceBatchId(args); + deviceImeiList = extractDeviceImeiList(args); + if (StringUtils.isNotBlank(batchId)) { + // 生成全局Redis key + String redisKey = generateDeviceRedisKey(batchId); + String cacheKey = RedisUtils.getCacheObject(redisKey); + if(StringUtils.isNotBlank(cacheKey) && "ACTIVE".equals(cacheKey)){ + throw new ServiceException("设备已存在访问限制,请稍后再试", 500); + } + // 存储到Redis中,设置过期时间 + RedisUtils.setCacheObject(redisKey, JSONUtil.toJsonStr(deviceImeiList), Duration.ofMinutes(30)); + log.info("设备Redis key已添加: {}", redisKey); + } + + // 执行原方法 + result = joinPoint.proceed(); + + return result; + } + + /** + * 从方法参数中提取设备IMEI列表 + */ + private List extractDeviceImeiList(Object[] args) { + if (args == null || args.length == 0) { + return null; + } + + for (Object arg : args) { + if (arg == null) continue; + + // 如果参数本身就是List类型 + if (arg instanceof List) { + List list = (List) arg; + if (!list.isEmpty() && list.get(0) instanceof String) { + // 检查是否为deviceImeiList + return (List) list; + } + } + + // 如果参数是对象,尝试获取deviceImeiList字段 + try { + // 使用反射获取deviceImeiList字段 + java.lang.reflect.Field[] fields = arg.getClass().getDeclaredFields(); + for (java.lang.reflect.Field field : fields) { + if ("deviceImeiList".equalsIgnoreCase(field.getName()) || + "device_imei_list".equalsIgnoreCase(field.getName()) || + "deviceImeis".equalsIgnoreCase(field.getName()) || + "device_imeis".equalsIgnoreCase(field.getName())) { + field.setAccessible(true); + Object value = field.get(arg); + if (value instanceof List) { + List list = (List) value; + if (!list.isEmpty() && list.get(0) instanceof String) { + return (List) list; + } + } + } + } + + // 尝试获取getDeviceImeiList方法 + try { + java.lang.reflect.Method getDeviceImeiListMethod = arg.getClass().getMethod("getDeviceImeiList"); + Object value = getDeviceImeiListMethod.invoke(arg); + if (value instanceof List) { + List list = (List) value; + if (!list.isEmpty() && list.get(0) instanceof String) { + return (List) list; + } + } + } catch (Exception ignored) {} + + // 尝试获取getDeviceImeis方法 + try { + java.lang.reflect.Method getDeviceImeisMethod = arg.getClass().getMethod("getDeviceImeis"); + Object value = getDeviceImeisMethod.invoke(arg); + if (value instanceof List) { + List list = (List) value; + if (!list.isEmpty() && list.get(0) instanceof String) { + return (List) list; + } + } + } catch (Exception ignored) {} + + } catch (Exception e) { + log.debug("从参数中提取设备IMEI列表时出错: {}", e.getMessage()); + } + } + + return null; + } + + + /** + * 从方法参数中提取设备ID + */ + private String extractDeviceBatchId(Object[] args) { + if (args == null || args.length == 0) { + return null; + } + + for (Object arg : args) { + if (arg == null) continue; + + // 如果参数本身就是设备ID (Long类型) + if (arg instanceof Long) { + return arg.toString(); + } + + // 如果参数是对象,尝试获取deviceId字段 + try { + // 使用反射获取deviceId字段 + java.lang.reflect.Field[] fields = arg.getClass().getDeclaredFields(); + for (java.lang.reflect.Field field : fields) { + if ("batchId".equalsIgnoreCase(field.getName()) || + "batch_id".equalsIgnoreCase(field.getName())) { + field.setAccessible(true); + Object value = field.get(arg); + if (value != null) { + return value.toString(); + } + } + } + + // 尝试获取getId方法 + try { + java.lang.reflect.Method getIdMethod = arg.getClass().getMethod("batchId"); + Object value = getIdMethod.invoke(arg); + if (value != null) { + return value.toString(); + } + } catch (Exception ignored) {} + + } catch (Exception e) { + log.debug("从参数中提取批次号时出错: {}", e.getMessage()); + } + } + + return null; + } + + /** + * 生成设备的全局Redis key + */ + private String generateDeviceRedisKey(String batchId) { + return FUNCTION_ACCESS_KEY + batchId; + } +} diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/bo/AppPersonnelInfoBo.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/bo/AppPersonnelInfoBo.java index da469ac4..70a79188 100644 --- a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/bo/AppPersonnelInfoBo.java +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/bo/AppPersonnelInfoBo.java @@ -25,6 +25,11 @@ public class AppPersonnelInfoBo extends BaseEntity { */ private Long id; + /** + * 设备IMEI + */ + private String deviceImei; + /** * 设备id */ diff --git a/fys-modules/fys-app/src/main/resources/mapper/app/AppDeviceShareMapper.xml b/fys-modules/fys-app/src/main/resources/mapper/app/AppDeviceShareMapper.xml index 9b3b29c5..b3b69d3d 100644 --- a/fys-modules/fys-app/src/main/resources/mapper/app/AppDeviceShareMapper.xml +++ b/fys-modules/fys-app/src/main/resources/mapper/app/AppDeviceShareMapper.xml @@ -5,8 +5,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + SELECT * FROM device_group + WHERE parent_id IS NULL + + AND group_name LIKE CONCAT('%', #{bo.groupName}, '%') + + + AND status = #{bo.status} + + ORDER BY create_time DESC + + + + + From a189d0d0f91d5f438e19b0c73b91c0e65f8a8a1a Mon Sep 17 00:00:00 2001 From: chenyouting <514333061@qq.com> Date: Thu, 14 Aug 2025 15:07:58 +0800 Subject: [PATCH 18/47] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=91=8A=E8=AD=A6?= =?UTF-8?q?=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/controller/AppDeviceController.java | 4 +-- .../device/AppDeviceBJQController.java | 4 +-- .../device/AppDeviceHBYController.java | 4 +-- .../LightingCommandTypeConstants.java | 6 ++++ .../global/mqtt/rule/bjq/BjqAlarmRule.java | 32 +++++-------------- .../service/device/DeviceBJQBizService.java} | 20 +++++++++--- .../service/device/DeviceBizService.java} | 11 ++++--- .../status/FunctionAccessBatchStatusRule.java | 8 ++--- .../status/FunctionAccessStatusRule.java | 6 ++-- .../device/status/base/DeviceStatusRule.java | 2 +- .../status/base/RealTimeStatusEngine.java | 2 +- .../status/constants/DeviceTypeConstants.java | 2 +- .../service/impl/WEBDeviceServiceImpl.java | 4 +-- 13 files changed, 52 insertions(+), 53 deletions(-) rename fys-admin/src/main/java/com/fuyuanshen/{app/service/device/AppDeviceBJQBizService.java => web/service/device/DeviceBJQBizService.java} (95%) rename fys-admin/src/main/java/com/fuyuanshen/{app/service/AppDeviceBizService.java => web/service/device/DeviceBizService.java} (98%) rename fys-admin/src/main/java/com/fuyuanshen/{app => web}/service/device/status/FunctionAccessBatchStatusRule.java (90%) rename fys-admin/src/main/java/com/fuyuanshen/{app => web}/service/device/status/FunctionAccessStatusRule.java (91%) rename fys-admin/src/main/java/com/fuyuanshen/{app => web}/service/device/status/base/DeviceStatusRule.java (86%) rename fys-admin/src/main/java/com/fuyuanshen/{app => web}/service/device/status/base/RealTimeStatusEngine.java (90%) rename fys-admin/src/main/java/com/fuyuanshen/{app => web}/service/device/status/constants/DeviceTypeConstants.java (61%) 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 d414cff7..3a4bf257 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 @@ -3,7 +3,6 @@ package com.fuyuanshen.app.controller; import com.fuyuanshen.app.domain.dto.APPReNameDTO; import com.fuyuanshen.app.domain.dto.AppRealTimeStatusDto; import com.fuyuanshen.app.domain.vo.APPDeviceTypeVo; -import com.fuyuanshen.app.service.AppDeviceBizService; import com.fuyuanshen.common.core.domain.R; import com.fuyuanshen.common.mybatis.core.page.PageQuery; import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; @@ -12,6 +11,7 @@ import com.fuyuanshen.equipment.domain.Device; import com.fuyuanshen.equipment.domain.dto.AppDeviceBo; import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria; import com.fuyuanshen.equipment.domain.vo.AppDeviceVo; +import com.fuyuanshen.web.service.device.DeviceBizService; import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -28,7 +28,7 @@ import java.util.Map; @RequestMapping("/app/device") public class AppDeviceController extends BaseController { - private final AppDeviceBizService appDeviceService; + private final DeviceBizService appDeviceService; /** diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceBJQController.java b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceBJQController.java index 7427f8eb..8a26cdd2 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceBJQController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceBJQController.java @@ -4,13 +4,13 @@ import com.fuyuanshen.app.domain.bo.AppPersonnelInfoBo; import com.fuyuanshen.app.domain.dto.AppDeviceLogoUploadDto; import com.fuyuanshen.app.domain.dto.DeviceInstructDto; import com.fuyuanshen.app.domain.vo.AppDeviceDetailVo; -import com.fuyuanshen.app.service.device.AppDeviceBJQBizService; import com.fuyuanshen.common.core.domain.R; import com.fuyuanshen.common.core.validate.AddGroup; import com.fuyuanshen.common.ratelimiter.annotation.FunctionAccessAnnotation; import com.fuyuanshen.common.ratelimiter.annotation.FunctionAccessBatcAnnotation; import com.fuyuanshen.common.web.core.BaseController; import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo; +import com.fuyuanshen.web.service.device.DeviceBJQBizService; import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; @@ -26,7 +26,7 @@ import org.springframework.web.multipart.MultipartFile; @RequestMapping("/app/bjq/device") public class AppDeviceBJQController extends BaseController { - private final AppDeviceBJQBizService appDeviceService; + private final DeviceBJQBizService appDeviceService; /** * 获取设备详细信息 diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceHBYController.java b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceHBYController.java index 93a2204c..9cd3d400 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceHBYController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceHBYController.java @@ -4,11 +4,11 @@ import com.fuyuanshen.app.domain.bo.AppPersonnelInfoBo; import com.fuyuanshen.app.domain.dto.AppDeviceLogoUploadDto; import com.fuyuanshen.app.domain.dto.DeviceInstructDto; import com.fuyuanshen.app.domain.vo.AppDeviceDetailVo; -import com.fuyuanshen.app.service.AppDeviceBizService; import com.fuyuanshen.common.core.domain.R; import com.fuyuanshen.common.core.validate.AddGroup; import com.fuyuanshen.common.web.core.BaseController; import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo; +import com.fuyuanshen.web.service.device.DeviceBizService; import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; @@ -24,7 +24,7 @@ import org.springframework.web.multipart.MultipartFile; @RequestMapping("/app/hby/device") public class AppDeviceHBYController extends BaseController { - private final AppDeviceBizService appDeviceService; + private final DeviceBizService appDeviceService; /** diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/constants/LightingCommandTypeConstants.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/constants/LightingCommandTypeConstants.java index c0f1ee75..de4e6b3f 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/constants/LightingCommandTypeConstants.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/constants/LightingCommandTypeConstants.java @@ -35,6 +35,12 @@ public class LightingCommandTypeConstants { * 设备发送消息 */ public static final String SEND_MESSAGE = "Light_6"; + + + /** + * 报警模式 + */ + public static final String ALARM_MESSAGE = "Light_7"; /** * 定位数据 (Location Data) diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqAlarmRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqAlarmRule.java index 737070b7..759f15b9 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqAlarmRule.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqAlarmRule.java @@ -28,7 +28,7 @@ public class BjqAlarmRule implements MqttMessageRule { @Override public String getCommandType() { - return LightingCommandTypeConstants.LIGHT_MODE; + return LightingCommandTypeConstants.ALARM_MESSAGE; } @Override @@ -37,10 +37,13 @@ public class BjqAlarmRule implements MqttMessageRule { try { Object[] convertArr = context.getConvertArr(); - String mainLightMode = convertArr[1].toString(); - if(StringUtils.isNotBlank(mainLightMode)){ - // 发送设备状态和位置信息到Redis - syncSendDeviceDataToRedisWithFuture(context.getDeviceImei(),mainLightMode); + String convertValue = convertArr[1].toString(); + if(StringUtils.isNotBlank(convertValue)){ + // 将设备状态信息存储到Redis中 + String deviceRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_KEY_PREFIX + context.getDeviceImei() + DEVICE_ALARM_KEY_PREFIX; + + // 存储到Redis + RedisUtils.setCacheObject(deviceRedisKey, convertValue); } RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.OK.getCode(), Duration.ofSeconds(20)); } catch (Exception e) { @@ -49,24 +52,5 @@ public class BjqAlarmRule implements MqttMessageRule { } } - /** - * 发送设备状态信息和位置信息到Redis(使用CompletableFuture) - * - * @param deviceImei 设备IMEI - */ - public void syncSendDeviceDataToRedisWithFuture(String deviceImei,Object convertValue) { - try { - // 将设备状态信息存储到Redis中 - String deviceRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_KEY_PREFIX + deviceImei + DEVICE_ALARM_KEY_PREFIX; - - // 存储到Redis - RedisUtils.setCacheObject(deviceRedisKey, convertValue.toString()); - - } catch (Exception e) { - log.error("异步发送设备信息到Redis时出错: device={}, error={}", deviceImei, e.getMessage(), e); - } - } - - } diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/device/AppDeviceBJQBizService.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java similarity index 95% rename from fys-admin/src/main/java/com/fuyuanshen/app/service/device/AppDeviceBJQBizService.java rename to fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java index c74b558d..888b1fed 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/service/device/AppDeviceBJQBizService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java @@ -1,4 +1,4 @@ -package com.fuyuanshen.app.service.device; +package com.fuyuanshen.web.service.device; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; @@ -14,7 +14,6 @@ import com.fuyuanshen.app.mapper.AppPersonnelInfoMapper; import com.fuyuanshen.common.core.constant.GlobalConstants; import com.fuyuanshen.common.core.exception.ServiceException; import com.fuyuanshen.common.core.utils.*; -import com.fuyuanshen.common.ratelimiter.annotation.FunctionAccessAnnotation; import com.fuyuanshen.common.redis.utils.RedisUtils; import com.fuyuanshen.common.satoken.utils.AppLoginHelper; import com.fuyuanshen.equipment.domain.Device; @@ -39,14 +38,13 @@ import static com.fuyuanshen.common.core.constant.GlobalConstants.GLOBAL_REDIS_K import static com.fuyuanshen.common.core.utils.Bitmap80x12Generator.buildArr; import static com.fuyuanshen.common.core.utils.Bitmap80x12Generator.generateFixedBitmapData; import static com.fuyuanshen.common.core.utils.ImageToCArrayConverter.convertHexToDecimal; -import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_BOOT_LOGO_KEY_PREFIX; -import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.*; @Slf4j @Service @RequiredArgsConstructor -public class AppDeviceBJQBizService { +public class DeviceBJQBizService { private final DeviceMapper deviceMapper; private final AppPersonnelInfoMapper appPersonnelInfoMapper; @@ -97,6 +95,7 @@ public class AppDeviceBJQBizService { deviceMapper.update(updateWrapper); } catch (Exception e) { log.info("发送信息设备发送信息失败:{}" ,deviceId); + throw new ServiceException("发送指令失败"); } } @@ -161,6 +160,11 @@ public class AppDeviceBJQBizService { vo.setAddress((String)jsonObject.get("address")); } + String alarmStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY +DEVICE_KEY_PREFIX+ device.getDeviceImei()+ DEVICE_ALARM_KEY_PREFIX); + if(StringUtils.isNotBlank(alarmStatus)){ + vo.setAlarmStatus(alarmStatus); + } + return vo; } @@ -248,6 +252,7 @@ public class AppDeviceBJQBizService { log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),JSON.toJSONString(map)); } catch (Exception e){ e.printStackTrace(); + throw new ServiceException("发送指令失败"); } } @@ -276,6 +281,7 @@ public class AppDeviceBJQBizService { log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),JSON.toJSONString(map)); } catch (Exception e){ e.printStackTrace(); + throw new ServiceException("发送指令失败"); } } @@ -308,6 +314,7 @@ public class AppDeviceBJQBizService { log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),JSON.toJSONString(map)); } catch (Exception e){ e.printStackTrace(); + throw new ServiceException("发送指令失败"); } } @@ -332,6 +339,7 @@ public class AppDeviceBJQBizService { log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),JSON.toJSONString(map)); } catch (Exception e){ e.printStackTrace(); + throw new ServiceException("发送指令失败"); } } @@ -377,11 +385,13 @@ public class AppDeviceBJQBizService { deviceMapper.update(updateWrapper); } catch (Exception e) { log.info("设备发送信息失败:{}" ,deviceId); + throw new ServiceException("设备发送信息失败"); } } } catch (Exception e){ e.printStackTrace(); + throw new ServiceException("发送指令失败"); } return 1; } diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceBizService.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBizService.java similarity index 98% rename from fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceBizService.java rename to fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBizService.java index b614aec9..6dc6aeae 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceBizService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBizService.java @@ -1,4 +1,4 @@ -package com.fuyuanshen.app.service; +package com.fuyuanshen.web.service.device; import cn.hutool.core.collection.CollectionUtil; import com.alibaba.fastjson2.JSON; @@ -19,8 +19,6 @@ import com.fuyuanshen.app.domain.vo.AppPersonnelInfoVo; import com.fuyuanshen.app.mapper.AppDeviceBindRecordMapper; import com.fuyuanshen.app.mapper.AppPersonnelInfoMapper; import com.fuyuanshen.app.mapper.equipment.APPDeviceMapper; -import com.fuyuanshen.app.service.device.status.base.DeviceStatusRule; -import com.fuyuanshen.app.service.device.status.base.RealTimeStatusEngine; import com.fuyuanshen.common.core.constant.GlobalConstants; import com.fuyuanshen.common.core.exception.ServiceException; import com.fuyuanshen.common.core.utils.*; @@ -36,12 +34,15 @@ import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria; import com.fuyuanshen.equipment.domain.vo.AppDeviceVo; import com.fuyuanshen.equipment.enums.BindingStatusEnum; import com.fuyuanshen.equipment.enums.CommunicationModeEnum; +import com.fuyuanshen.equipment.mapper.DeviceLogMapper; import com.fuyuanshen.equipment.mapper.DeviceMapper; import com.fuyuanshen.equipment.mapper.DeviceTypeMapper; import com.fuyuanshen.equipment.service.DeviceService; import com.fuyuanshen.global.mqtt.config.MqttGateway; import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants; import com.fuyuanshen.global.mqtt.constants.MqttConstants; +import com.fuyuanshen.web.service.device.status.base.DeviceStatusRule; +import com.fuyuanshen.web.service.device.status.base.RealTimeStatusEngine; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.core.io.ClassPathResource; @@ -63,7 +64,7 @@ import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.*; @Slf4j @Service @RequiredArgsConstructor -public class AppDeviceBizService { +public class DeviceBizService { private final APPDeviceMapper appDeviceMapper; private final DeviceMapper deviceMapper; @@ -72,7 +73,7 @@ public class AppDeviceBizService { private final MqttGateway mqttGateway; private final AppDeviceBindRecordMapper appDeviceBindRecordMapper; private final RealTimeStatusEngine realTimeStatusEngine; - private final DeviceService deviceService; + private final DeviceLogMapper deviceLogMapper; diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/FunctionAccessBatchStatusRule.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/status/FunctionAccessBatchStatusRule.java similarity index 90% rename from fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/FunctionAccessBatchStatusRule.java rename to fys-admin/src/main/java/com/fuyuanshen/web/service/device/status/FunctionAccessBatchStatusRule.java index 8127fbb4..116b5c91 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/FunctionAccessBatchStatusRule.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/status/FunctionAccessBatchStatusRule.java @@ -1,13 +1,12 @@ -package com.fuyuanshen.app.service.device.status; +package com.fuyuanshen.web.service.device.status; -import cn.hutool.json.JSONArray; import cn.hutool.json.JSONUtil; import com.fuyuanshen.app.domain.dto.AppRealTimeStatusDto; -import com.fuyuanshen.app.service.device.status.base.DeviceStatusRule; -import com.fuyuanshen.app.service.device.status.constants.DeviceTypeConstants; import com.fuyuanshen.common.core.utils.StringUtils; import com.fuyuanshen.common.redis.utils.RedisUtils; import com.fuyuanshen.global.mqtt.listener.domain.FunctionAccessStatus; +import com.fuyuanshen.web.service.device.status.base.DeviceStatusRule; +import com.fuyuanshen.web.service.device.status.constants.DeviceTypeConstants; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -16,7 +15,6 @@ import java.util.List; import java.util.Map; import static com.fuyuanshen.common.core.constant.GlobalConstants.FUNCTION_ACCESS_KEY; -import static com.fuyuanshen.common.core.constant.GlobalConstants.FUNCTION_ACCESS_TIMEOUT_KEY; @Slf4j diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/FunctionAccessStatusRule.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/status/FunctionAccessStatusRule.java similarity index 91% rename from fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/FunctionAccessStatusRule.java rename to fys-admin/src/main/java/com/fuyuanshen/web/service/device/status/FunctionAccessStatusRule.java index 8f12bcbe..6b6f094d 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/FunctionAccessStatusRule.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/status/FunctionAccessStatusRule.java @@ -1,11 +1,11 @@ -package com.fuyuanshen.app.service.device.status; +package com.fuyuanshen.web.service.device.status; import com.fuyuanshen.app.domain.dto.AppRealTimeStatusDto; -import com.fuyuanshen.app.service.device.status.base.DeviceStatusRule; -import com.fuyuanshen.app.service.device.status.constants.DeviceTypeConstants; import com.fuyuanshen.common.core.utils.StringUtils; import com.fuyuanshen.common.redis.utils.RedisUtils; import com.fuyuanshen.global.mqtt.listener.domain.FunctionAccessStatus; +import com.fuyuanshen.web.service.device.status.base.DeviceStatusRule; +import com.fuyuanshen.web.service.device.status.constants.DeviceTypeConstants; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/base/DeviceStatusRule.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/status/base/DeviceStatusRule.java similarity index 86% rename from fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/base/DeviceStatusRule.java rename to fys-admin/src/main/java/com/fuyuanshen/web/service/device/status/base/DeviceStatusRule.java index 9bc32353..57e1fd8e 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/base/DeviceStatusRule.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/status/base/DeviceStatusRule.java @@ -1,4 +1,4 @@ -package com.fuyuanshen.app.service.device.status.base; +package com.fuyuanshen.web.service.device.status.base; import com.fuyuanshen.app.domain.dto.AppRealTimeStatusDto; diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/base/RealTimeStatusEngine.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/status/base/RealTimeStatusEngine.java similarity index 90% rename from fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/base/RealTimeStatusEngine.java rename to fys-admin/src/main/java/com/fuyuanshen/web/service/device/status/base/RealTimeStatusEngine.java index 4eae5675..d374eb52 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/base/RealTimeStatusEngine.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/status/base/RealTimeStatusEngine.java @@ -1,4 +1,4 @@ -package com.fuyuanshen.app.service.device.status.base; +package com.fuyuanshen.web.service.device.status.base; import org.springframework.stereotype.Component; diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/constants/DeviceTypeConstants.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/status/constants/DeviceTypeConstants.java similarity index 61% rename from fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/constants/DeviceTypeConstants.java rename to fys-admin/src/main/java/com/fuyuanshen/web/service/device/status/constants/DeviceTypeConstants.java index 271f6330..1e0f0ccf 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/service/device/status/constants/DeviceTypeConstants.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/status/constants/DeviceTypeConstants.java @@ -1,4 +1,4 @@ -package com.fuyuanshen.app.service.device.status.constants; +package com.fuyuanshen.web.service.device.status.constants; public class DeviceTypeConstants { public static final String TYPE_BJQ6170 = "BJQ6170"; diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/service/impl/WEBDeviceServiceImpl.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/impl/WEBDeviceServiceImpl.java index 9f8e0416..f38a2e88 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/service/impl/WEBDeviceServiceImpl.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/impl/WEBDeviceServiceImpl.java @@ -1,12 +1,12 @@ package com.fuyuanshen.web.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.fuyuanshen.app.service.AppDeviceBizService; import com.fuyuanshen.equipment.domain.Device; import com.fuyuanshen.equipment.domain.DeviceAssignments; import com.fuyuanshen.equipment.mapper.DeviceAssignmentsMapper; import com.fuyuanshen.equipment.mapper.DeviceMapper; import com.fuyuanshen.web.service.WEBDeviceService; +import com.fuyuanshen.web.service.device.DeviceBizService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -21,7 +21,7 @@ import org.springframework.stereotype.Service; @RequiredArgsConstructor public class WEBDeviceServiceImpl extends ServiceImpl implements WEBDeviceService { - private final AppDeviceBizService appDeviceService; + private final DeviceBizService appDeviceService; private final DeviceAssignmentsMapper deviceAssignmentsMapper; From 3145b494d949a4239088f28fda4fd8cef93920ae Mon Sep 17 00:00:00 2001 From: chenyouting <514333061@qq.com> Date: Thu, 14 Aug 2025 15:56:10 +0800 Subject: [PATCH 19/47] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=91=8A=E8=AD=A6?= =?UTF-8?q?=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=912?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/controller/device/AppDeviceBJQController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceBJQController.java b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceBJQController.java index 8a26cdd2..d6bf411d 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceBJQController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceBJQController.java @@ -98,7 +98,7 @@ public class AppDeviceBJQController extends BaseController { * 灯光亮度设置 * */ - @FunctionAccessAnnotation("lightBrightnessSettings") +// @FunctionAccessAnnotation("lightBrightnessSettings") @PostMapping("/lightBrightnessSettings") public R lightBrightnessSettings(@RequestBody DeviceInstructDto params) { appDeviceService.lightBrightnessSettings(params); From 51741adc69ad5cbc76652f5b1bc875394ab4ce11 Mon Sep 17 00:00:00 2001 From: chenyouting <514333061@qq.com> Date: Thu, 14 Aug 2025 16:25:14 +0800 Subject: [PATCH 20/47] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=91=8A=E8=AD=A6?= =?UTF-8?q?=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=913?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../device/AppDeviceHBYController.java | 112 ------ .../web/service/device/DeviceBizService.java | 365 +----------------- 2 files changed, 5 insertions(+), 472 deletions(-) delete mode 100644 fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceHBYController.java diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceHBYController.java b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceHBYController.java deleted file mode 100644 index 9cd3d400..00000000 --- a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceHBYController.java +++ /dev/null @@ -1,112 +0,0 @@ -package com.fuyuanshen.app.controller.device; - -import com.fuyuanshen.app.domain.bo.AppPersonnelInfoBo; -import com.fuyuanshen.app.domain.dto.AppDeviceLogoUploadDto; -import com.fuyuanshen.app.domain.dto.DeviceInstructDto; -import com.fuyuanshen.app.domain.vo.AppDeviceDetailVo; -import com.fuyuanshen.common.core.domain.R; -import com.fuyuanshen.common.core.validate.AddGroup; -import com.fuyuanshen.common.web.core.BaseController; -import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo; -import com.fuyuanshen.web.service.device.DeviceBizService; -import jakarta.validation.constraints.NotNull; -import lombok.RequiredArgsConstructor; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; - -/** - * HBY210设备控制类 - */ -@Validated -@RequiredArgsConstructor -@RestController -@RequestMapping("/app/hby/device") -public class AppDeviceHBYController extends BaseController { - - private final DeviceBizService appDeviceService; - - - /** - * 获取设备详细信息 - * - * @param id 主键 - */ - @GetMapping("/{id}") - public R getInfo(@NotNull(message = "主键不能为空") - @PathVariable Long id) { - return R.ok(appDeviceService.getInfo(id)); - } - - /** - * 人员信息登记 - */ - @PostMapping(value = "/registerPersonInfo") - public R registerPersonInfo(@Validated(AddGroup.class) @RequestBody AppPersonnelInfoBo bo) { - return toAjax(appDeviceService.registerPersonInfo(bo)); - } - - /** - * 发送信息 - */ - @PostMapping(value = "/sendMessage") - public R sendMessage(@RequestBody AppDeviceSendMsgBo bo) { - return toAjax(appDeviceService.sendMessage(bo)); - } - - /** - * 上传设备logo图片 - */ - @PostMapping("/uploadLogo") - public R upload(@Validated @ModelAttribute AppDeviceLogoUploadDto bo) { - - MultipartFile file = bo.getFile(); - if(file.getSize()>1024*1024*2){ - return R.warn("图片不能大于2M"); - } - appDeviceService.uploadDeviceLogo(bo); - - return R.ok(); - } - - /** - * 灯光模式 - * 0(关灯),1(强光模式),2(弱光模式), 3(爆闪模式), 4(泛光模式) - */ - @PostMapping("/lightModeSettings") - public R lightModeSettings(@RequestBody DeviceInstructDto params) { - // params 转 JSONObject - appDeviceService.lightModeSettings(params); - return R.ok(); - } - - /** - * 灯光亮度设置 - * - */ - @PostMapping("/lightBrightnessSettings") - public R lightBrightnessSettings(@RequestBody DeviceInstructDto params) { - appDeviceService.lightBrightnessSettings(params); - return R.ok(); - } - - /** - * 激光模式设置 - * - */ - @PostMapping("/laserModeSettings") - public R laserModeSettings(@RequestBody DeviceInstructDto params) { - appDeviceService.laserModeSettings(params); - return R.ok(); - } - - /** - * 地图逆解析 - * - */ - @PostMapping("/mapReverseGeocoding") - public R mapReverseGeocoding(@RequestBody DeviceInstructDto params) { - String mapJson = appDeviceService.mapReverseGeocoding(params); - return R.ok(mapJson); - } -} diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBizService.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBizService.java index 6dc6aeae..82a49649 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBizService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBizService.java @@ -1,35 +1,27 @@ package com.fuyuanshen.web.service.device; import cn.hutool.core.collection.CollectionUtil; -import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fuyuanshen.app.domain.AppDeviceBindRecord; -import com.fuyuanshen.app.domain.AppPersonnelInfo; -import com.fuyuanshen.app.domain.bo.AppPersonnelInfoBo; import com.fuyuanshen.app.domain.dto.APPReNameDTO; -import com.fuyuanshen.app.domain.dto.AppDeviceLogoUploadDto; import com.fuyuanshen.app.domain.dto.AppRealTimeStatusDto; import com.fuyuanshen.app.domain.dto.DeviceInstructDto; import com.fuyuanshen.app.domain.vo.APPDeviceTypeVo; -import com.fuyuanshen.app.domain.vo.AppDeviceDetailVo; -import com.fuyuanshen.app.domain.vo.AppPersonnelInfoVo; import com.fuyuanshen.app.mapper.AppDeviceBindRecordMapper; import com.fuyuanshen.app.mapper.AppPersonnelInfoMapper; import com.fuyuanshen.app.mapper.equipment.APPDeviceMapper; -import com.fuyuanshen.common.core.constant.GlobalConstants; import com.fuyuanshen.common.core.exception.ServiceException; -import com.fuyuanshen.common.core.utils.*; +import com.fuyuanshen.common.core.utils.ObjectUtils; +import com.fuyuanshen.common.core.utils.StringUtils; import com.fuyuanshen.common.mybatis.core.page.PageQuery; import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; import com.fuyuanshen.common.redis.utils.RedisUtils; import com.fuyuanshen.common.satoken.utils.AppLoginHelper; import com.fuyuanshen.equipment.domain.Device; -import com.fuyuanshen.equipment.domain.DeviceType; import com.fuyuanshen.equipment.domain.dto.AppDeviceBo; -import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo; import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria; import com.fuyuanshen.equipment.domain.vo.AppDeviceVo; import com.fuyuanshen.equipment.enums.BindingStatusEnum; @@ -37,27 +29,19 @@ import com.fuyuanshen.equipment.enums.CommunicationModeEnum; import com.fuyuanshen.equipment.mapper.DeviceLogMapper; import com.fuyuanshen.equipment.mapper.DeviceMapper; import com.fuyuanshen.equipment.mapper.DeviceTypeMapper; -import com.fuyuanshen.equipment.service.DeviceService; import com.fuyuanshen.global.mqtt.config.MqttGateway; import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants; -import com.fuyuanshen.global.mqtt.constants.MqttConstants; import com.fuyuanshen.web.service.device.status.base.DeviceStatusRule; import com.fuyuanshen.web.service.device.status.base.RealTimeStatusEngine; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.core.io.ClassPathResource; import org.springframework.stereotype.Service; -import org.springframework.web.multipart.MultipartFile; -import java.io.IOException; -import java.io.InputStream; -import java.time.Duration; -import java.util.*; +import java.util.Date; +import java.util.List; +import java.util.Map; import static com.fuyuanshen.common.core.constant.GlobalConstants.GLOBAL_REDIS_KEY; -import static com.fuyuanshen.common.core.utils.Bitmap80x12Generator.buildArr; -import static com.fuyuanshen.common.core.utils.Bitmap80x12Generator.generateFixedBitmapData; -import static com.fuyuanshen.common.core.utils.ImageToCArrayConverter.convertHexToDecimal; import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.*; @@ -68,9 +52,6 @@ public class DeviceBizService { private final APPDeviceMapper appDeviceMapper; private final DeviceMapper deviceMapper; - private final AppPersonnelInfoMapper appPersonnelInfoMapper; - private final DeviceTypeMapper deviceTypeMapper; - private final MqttGateway mqttGateway; private final AppDeviceBindRecordMapper appDeviceBindRecordMapper; private final RealTimeStatusEngine realTimeStatusEngine; private final DeviceLogMapper deviceLogMapper; @@ -91,60 +72,6 @@ public class DeviceBizService { } - public int sendMessage(AppDeviceSendMsgBo bo) { - List deviceIds = bo.getDeviceIds(); - if (deviceIds == null || deviceIds.isEmpty()) { - throw new ServiceException("请选择设备"); - } - for (Long deviceId : deviceIds) { - Device device = deviceMapper.selectById(deviceId); - if (device == null) { - throw new ServiceException("设备不存在" + deviceId); - } - - try { - ClassPathResource resource = new ClassPathResource("image/background.png"); - InputStream inputStream = resource.getInputStream(); - -// String backgroundImagePath = "D:\\background.png"; // 替换为实际背景图片路径 - byte[] largeData = ImageWithTextGenerate.generate160x80ImageWithText2(bo.getSendMsg(), inputStream, 25600); - int[] ints = convertHexToDecimal(largeData); - RedisUtils.setCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DEVICE_SEND_MESSAGE_KEY_PREFIX , Arrays.toString(ints), Duration.ofSeconds(30 * 60L)); - - String data = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DEVICE_SEND_MESSAGE_KEY_PREFIX); - - byte[] arr = ImageToCArrayConverter.convertStringToByteArray(data); - byte[] specificChunk = ImageToCArrayConverter.getChunk(arr, 0, 512); - log.info("发送信息第0块数据大小: {} 字节",specificChunk.length); -// log.info("第0块数据: {}", Arrays.toString(specificChunk)); - - ArrayList intData = new ArrayList<>(); - intData.add(6); - intData.add(1); - ImageToCArrayConverter.buildArr(convertHexToDecimal(specificChunk),intData); - intData.add(0); - intData.add(0); - intData.add(0); - intData.add(0); - Map map = new HashMap<>(); - map.put("instruct", intData); - mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(), 1 , JSON.toJSONString(map)); - log.info("发送信息点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),JSON.toJSONString(map)); - - UpdateWrapper updateWrapper = new UpdateWrapper<>(); - updateWrapper.eq("id", deviceId) - .eq("binding_user_id", AppLoginHelper.getUserId()) - .set("send_msg", bo.getSendMsg()); - deviceMapper.update(updateWrapper); - } catch (Exception e) { - log.info("发送信息设备发送信息失败:{}" ,deviceId); - } - - } - return 1; - } - - public TableDataInfo queryAppDeviceList(DeviceQueryCriteria bo, PageQuery pageQuery) { if (bo.getBindingUserId() == null) { Long userId = AppLoginHelper.getUserId(); @@ -316,247 +243,6 @@ public class DeviceBizService { return 1; } - - public AppDeviceDetailVo getInfo(Long id) { - Device device = deviceMapper.selectById(id); - if (device == null) { - throw new RuntimeException("请先将设备入库!!!"); - } - AppDeviceDetailVo vo = new AppDeviceDetailVo(); - vo.setDeviceId(device.getId()); - vo.setDeviceName(device.getDeviceName()); - vo.setDevicePic(device.getDevicePic()); - vo.setDeviceImei(device.getDeviceImei()); - vo.setDeviceMac(device.getDeviceMac()); - vo.setDeviceStatus(device.getDeviceStatus()); - DeviceType deviceType = deviceTypeMapper.selectById(device.getDeviceType()); - if (deviceType != null) { - vo.setCommunicationMode(Integer.valueOf(deviceType.getCommunicationMode())); - vo.setTypeName(deviceType.getTypeName()); - } - vo.setBluetoothName(device.getBluetoothName()); - - vo.setSendMsg(device.getSendMsg()); - - QueryWrapper qw = new QueryWrapper() - .eq("device_id", device.getId()); - AppPersonnelInfo appPersonnelInfo = appPersonnelInfoMapper.selectOne(qw); - if (appPersonnelInfo != null) { - AppPersonnelInfoVo personnelInfoVo = MapstructUtils.convert(appPersonnelInfo, AppPersonnelInfoVo.class); - vo.setPersonnelInfo(personnelInfoVo); - } - //设备在线状态 - String onlineStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX); - if(StringUtils.isNotBlank(onlineStatus)){ - vo.setOnlineStatus(1); - }else{ - vo.setOnlineStatus(0); - } - String deviceStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX); - // 获取电量 - if(StringUtils.isNotBlank(deviceStatus)){ - JSONObject jsonObject = JSONObject.parseObject(deviceStatus); - vo.setMainLightMode(jsonObject.getString("mainLightMode")); - vo.setLaserLightMode(jsonObject.getString("laserLightMode")); - vo.setBatteryPercentage(jsonObject.getString("batteryPercentage")); - vo.setChargeState(jsonObject.getString("chargeState")); - vo.setBatteryRemainingTime(jsonObject.getString("batteryRemainingTime")); - }else{ - vo.setBatteryPercentage("0"); - } - - // 获取经度纬度 - String locationKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DEVICE_LOCATION_KEY_PREFIX; - String locationInfo = RedisUtils.getCacheObject(locationKey); - if(StringUtils.isNotBlank(locationInfo)){ - JSONObject jsonObject = JSONObject.parseObject(locationInfo); - vo.setLongitude(jsonObject.get("longitude").toString()); - vo.setLatitude(jsonObject.get("latitude").toString()); - vo.setAddress((String)jsonObject.get("address")); - } - - return vo; - } - - - public boolean registerPersonInfo(AppPersonnelInfoBo bo) { - Long deviceId = bo.getDeviceId(); - Device deviceObj = deviceMapper.selectById(deviceId); - if (deviceObj == null) { - throw new RuntimeException("请先将设备入库!!!"); - } - QueryWrapper qw = new QueryWrapper() - .eq("device_id", deviceId); - List appPersonnelInfoVos = appPersonnelInfoMapper.selectVoList(qw); -// unitName,position,name,id - byte[] unitName = generateFixedBitmapData(bo.getUnitName(), 120); - byte[] position = generateFixedBitmapData(bo.getPosition(), 120); - byte[] name = generateFixedBitmapData(bo.getName(), 120); - byte[] id = generateFixedBitmapData(bo.getCode(), 120); - ArrayList intData = new ArrayList<>(); - intData.add(2); - buildArr(convertHexToDecimal(unitName), intData); - buildArr(convertHexToDecimal(position), intData); - buildArr(convertHexToDecimal(name), intData); - buildArr(convertHexToDecimal(id), intData); - intData.add(0); - intData.add(0); - intData.add(0); - intData.add(0); - Map map = new HashMap<>(); - map.put("instruct", intData); - mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY + deviceObj.getDeviceImei(), 1, JSON.toJSONString(map)); - log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY + deviceObj.getDeviceImei(), bo); - - if (ObjectUtils.length(appPersonnelInfoVos) == 0) { - AppPersonnelInfo appPersonnelInfo = MapstructUtils.convert(bo, AppPersonnelInfo.class); - return appPersonnelInfoMapper.insertOrUpdate(appPersonnelInfo); - } else { - UpdateWrapper uw = new UpdateWrapper<>(); - uw.eq("device_id", deviceId) - .set("name", bo.getName()) - .set("position", bo.getPosition()) - .set("unit_name", bo.getUnitName()) - .set("code", bo.getCode()); - return appPersonnelInfoMapper.update(null, uw) > 0; - } - - - } - - public static void main(String[] args) throws IOException { - byte[] largeData = ImageToCArrayConverter.convertImageToCArray("E:\\workspace\\demo.png", 160, 80, 25600); - System.out.println("长度:" + largeData.length); - - System.out.println("原始数据大小: " + largeData.length + " 字节"); - - int[] ints = convertHexToDecimal(largeData); - System.out.println("转换后的数据: " + Arrays.toString(ints)); - } - - public void uploadDeviceLogo(AppDeviceLogoUploadDto bo) { - try { - Device device = deviceMapper.selectById(bo.getDeviceId()); - if (device == null) { - throw new ServiceException("设备不存在"); - } - MultipartFile file = bo.getFile(); - - byte[] largeData = ImageToCArrayConverter.convertImageToCArray(file.getInputStream(), 160, 80, 25600); - log.info("长度:" + largeData.length); - - log.info("原始数据大小: {} 字节", largeData.length); - - int[] ints = convertHexToDecimal(largeData); - RedisUtils.setCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DEVICE_BOOT_LOGO_KEY_PREFIX, Arrays.toString(ints), Duration.ofSeconds(30 * 60L)); - - String data = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DEVICE_BOOT_LOGO_KEY_PREFIX); - - byte[] arr = ImageToCArrayConverter.convertStringToByteArray(data); - byte[] specificChunk = ImageToCArrayConverter.getChunk(arr, 0, 512); - log.info("第0块数据大小: {} 字节", specificChunk.length); -// log.info("第0块数据: {}", Arrays.toString(specificChunk)); - - ArrayList intData = new ArrayList<>(); - intData.add(3); - intData.add(1); - ImageToCArrayConverter.buildArr(convertHexToDecimal(specificChunk),intData); - intData.add(0); - intData.add(0); - intData.add(0); - intData.add(0); - Map map = new HashMap<>(); - map.put("instruct", intData); - mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(), 1 , JSON.toJSONString(map)); - log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),JSON.toJSONString(map)); - } catch (Exception e){ - e.printStackTrace(); - } - } - - /** - * 灯光模式 - * 0(关灯),1(强光模式),2(弱光模式), 3(爆闪模式), 4(泛光模式) - */ - public void lightModeSettings(DeviceInstructDto params) { - try { - Long deviceId = params.getDeviceId(); - Device device = deviceMapper.selectById(deviceId); - if(device == null){ - throw new ServiceException("设备不存在"); - } - Integer instructValue = Integer.parseInt(params.getInstructValue()); - ArrayList intData = new ArrayList<>(); - intData.add(1); - intData.add(instructValue); - intData.add(0); - intData.add(0); - intData.add(0); - Map map = new HashMap<>(); - map.put("instruct", intData); - mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(), 1 , JSON.toJSONString(map)); - log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),JSON.toJSONString(map)); - } catch (Exception e){ - e.printStackTrace(); - } - } - - //灯光亮度设置 - public void lightBrightnessSettings(DeviceInstructDto params) { - try { - Long deviceId = params.getDeviceId(); - Device device = deviceMapper.selectById(deviceId); - if(device == null){ - throw new ServiceException("设备不存在"); - } - String instructValue = params.getInstructValue(); - ArrayList intData = new ArrayList<>(); - intData.add(5); - String[] values = instructValue.split("\\."); - String value1 = values[0]; - String value2 = values[1]; - if(StringUtils.isNoneBlank(value1)){ - intData.add(Integer.parseInt(value1)); - } - if(StringUtils.isNoneBlank(value2)){ - intData.add(Integer.parseInt(value2)); - } - intData.add(0); - intData.add(0); - intData.add(0); - Map map = new HashMap<>(); - map.put("instruct", intData); - mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(), 1 , JSON.toJSONString(map)); - log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),JSON.toJSONString(map)); - } catch (Exception e){ - e.printStackTrace(); - } - } - - //激光模式设置 - public void laserModeSettings(DeviceInstructDto params) { - try { - Long deviceId = params.getDeviceId(); - Device device = deviceMapper.selectById(deviceId); - if(device == null){ - throw new ServiceException("设备不存在"); - } - Integer instructValue = Integer.parseInt(params.getInstructValue()); - ArrayList intData = new ArrayList<>(); - intData.add(4); - intData.add(instructValue); - intData.add(0); - intData.add(0); - intData.add(0); - Map map = new HashMap<>(); - map.put("instruct", intData); - mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(), 1 , JSON.toJSONString(map)); - log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),JSON.toJSONString(map)); - } catch (Exception e){ - e.printStackTrace(); - } - } - public String mapReverseGeocoding(DeviceInstructDto params) { // Long deviceId = params.getDeviceId(); // Device device = deviceMapper.selectById(deviceId); @@ -569,47 +255,6 @@ public class DeviceBizService { return RedisUtils.getCacheObject("device:location:" + devices.get(0).getDeviceImei()); } - public int sendAlarmMessage(AppDeviceSendMsgBo bo) { - try { - List deviceIds = bo.getDeviceIds(); - if (deviceIds == null || deviceIds.isEmpty()) { - throw new ServiceException("请选择设备"); - } - for (Long deviceId : deviceIds) { - Device device = deviceMapper.selectById(deviceId); - if (device == null) { - throw new ServiceException("设备不存在" + deviceId); - } - - try { - ArrayList intData = new ArrayList<>(); - intData.add(7); - intData.add(Integer.parseInt(bo.getInstructValue())); - intData.add(0); - intData.add(0); - intData.add(0); - intData.add(0); - Map map = new HashMap<>(); - map.put("instruct", intData); - mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(), 1 , JSON.toJSONString(map)); - log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),JSON.toJSONString(map)); - - UpdateWrapper updateWrapper = new UpdateWrapper<>(); - updateWrapper.eq("id", deviceId) - .eq("binding_user_id", AppLoginHelper.getUserId()) - .set("send_msg", bo.getSendMsg()); - deviceMapper.update(updateWrapper); - } catch (Exception e) { - log.info("设备发送信息失败:{}" ,deviceId); - } - - } - } catch (Exception e){ - e.printStackTrace(); - } - return 1; - } - public Map getRealTimeStatus(AppRealTimeStatusDto statusDto) { try { String commandType = statusDto.getTypeName()+"_" + statusDto.getFunctionMode(); From 9e24e3daafd149a64e50bae6ec84951ec7d50e2b Mon Sep 17 00:00:00 2001 From: chenyouting <514333061@qq.com> Date: Thu, 14 Aug 2025 17:38:07 +0800 Subject: [PATCH 21/47] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=91=8A=E8=AD=A6?= =?UTF-8?q?=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=914?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mqtt/rule/bjq/BjqLightBrightnessRule.java | 51 +++++++++++++++++++ .../service/device/DeviceBJQBizService.java | 5 ++ .../app/domain/vo/AppDeviceDetailVo.java | 3 ++ 3 files changed, 59 insertions(+) create mode 100644 fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqLightBrightnessRule.java diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqLightBrightnessRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqLightBrightnessRule.java new file mode 100644 index 00000000..0fc6dd8e --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqLightBrightnessRule.java @@ -0,0 +1,51 @@ +package com.fuyuanshen.global.mqtt.rule.bjq; + +import com.fuyuanshen.common.core.constant.GlobalConstants; +import com.fuyuanshen.common.core.utils.StringUtils; +import com.fuyuanshen.common.redis.utils.RedisUtils; +import com.fuyuanshen.global.mqtt.base.MqttMessageRule; +import com.fuyuanshen.global.mqtt.base.MqttRuleContext; +import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants; +import com.fuyuanshen.global.mqtt.constants.LightingCommandTypeConstants; +import com.fuyuanshen.global.mqtt.listener.domain.FunctionAccessStatus; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.time.Duration; + +import static com.fuyuanshen.common.core.constant.GlobalConstants.FUNCTION_ACCESS_KEY; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.*; + +/** + * 灯光模式订阅设备回传消息 + */ +@Component +@RequiredArgsConstructor +@Slf4j +public class BjqLightBrightnessRule implements MqttMessageRule { + + @Override + public String getCommandType() { + return LightingCommandTypeConstants.MAIN_LIGHT_BRIGHTNESS; + } + + @Override + public void execute(MqttRuleContext context) { + String functionAccess = FUNCTION_ACCESS_KEY + context.getDeviceImei(); + try { + Object[] convertArr = context.getConvertArr(); + + String convertValue = convertArr[1].toString(); + // 将设备状态信息存储到Redis中 + String deviceRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_KEY_PREFIX + context.getDeviceImei() + DEVICE_LIGHT_BRIGHTNESS_KEY_PREFIX; + + // 存储到Redis + RedisUtils.setCacheObject(deviceRedisKey, convertValue); + RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.OK.getCode(), Duration.ofSeconds(20)); + } catch (Exception e) { + log.error("处理灯光亮度命令时出错", e); + RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.FAILED.getCode(), Duration.ofSeconds(20)); + } + } +} diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java index 888b1fed..671fe8ef 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java @@ -165,6 +165,11 @@ public class DeviceBJQBizService { vo.setAlarmStatus(alarmStatus); } + String lightBrightness = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY +DEVICE_KEY_PREFIX+ device.getDeviceImei()+ DEVICE_LIGHT_BRIGHTNESS_KEY_PREFIX); + if(StringUtils.isNotBlank(lightBrightness)){ + vo.setLightBrightness(lightBrightness); + } + return vo; } diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceDetailVo.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceDetailVo.java index 230a2c48..c1728092 100644 --- a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceDetailVo.java +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceDetailVo.java @@ -104,4 +104,7 @@ public class AppDeviceDetailVo { * 告警状态(0解除告警,1告警) */ private String alarmStatus; + + // 灯光亮度 + private String lightBrightness; } From f1a3a0325bfb0ce2141503007be2204b5af87413 Mon Sep 17 00:00:00 2001 From: chenyouting <514333061@qq.com> Date: Thu, 14 Aug 2025 18:28:55 +0800 Subject: [PATCH 22/47] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=91=8A=E8=AD=A6?= =?UTF-8?q?=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=916?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/fuyuanshen/app/domain/vo/AppDeviceShareVo.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceShareVo.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceShareVo.java index e5aef582..224ca8ce 100644 --- a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceShareVo.java +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceShareVo.java @@ -71,6 +71,11 @@ public class AppDeviceShareVo implements Serializable { @ExcelDictFormat(readConverterExp = "1=:灯光模式;2:激光模式;3:开机画面;4:人员信息登记;5:发送信息;6:产品信息") private String permission; + /** + * 设备类型 + */ + private String typeName; + /** * 备注 */ From 48e972166fe9ad0e8512f52ba2aa5e699957c208 Mon Sep 17 00:00:00 2001 From: daiyongfei <974332738@qq.com> Date: Thu, 14 Aug 2025 18:55:53 +0800 Subject: [PATCH 23/47] =?UTF-8?q?=E5=9E=8B=E5=8F=B7=E5=AD=97=E5=85=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fuyuanshen/equipment/domain/DeviceType.java | 7 +++++++ .../equipment/domain/form/DeviceTypeForm.java | 13 ++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceType.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceType.java index 76e554ed..4ed83806 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceType.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceType.java @@ -65,4 +65,11 @@ public class DeviceType extends TenantEntity { BeanUtil.copyProperties(source, this, CopyOptions.create().setIgnoreNullValue(true)); } + /** + * 型号字典用于APP页面跳转 + */ + @Schema(name = "型号字典用于APP页面跳转") + private Integer modelDictionary; + + } diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceTypeForm.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceTypeForm.java index d4167180..5a8617a7 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceTypeForm.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceTypeForm.java @@ -1,13 +1,6 @@ package com.fuyuanshen.equipment.domain.form; -import cn.hutool.core.bean.BeanUtil; -import cn.hutool.core.bean.copier.CopyOptions; -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import com.fuyuanshen.common.tenant.core.TenantEntity; import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotBlank; import lombok.Data; /** @@ -36,4 +29,10 @@ public class DeviceTypeForm { @Schema(name = "通讯方式", example = "0:4G;1:蓝牙") private String communicationMode; + /** + * 型号字典用于APP页面跳转 + */ + @Schema(name = "型号字典用于APP页面跳转") + private Integer modelDictionary; + } From c587ef738935bfd0271939d4558bb39ecd9fe03e Mon Sep 17 00:00:00 2001 From: chenyouting <514333061@qq.com> Date: Thu, 14 Aug 2025 18:57:50 +0800 Subject: [PATCH 24/47] =?UTF-8?q?=E8=A7=A3=E7=BB=91=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/service/device/DeviceBizService.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBizService.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBizService.java index 82a49649..4d9a8de0 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBizService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBizService.java @@ -6,12 +6,16 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fuyuanshen.app.domain.AppDeviceBindRecord; +import com.fuyuanshen.app.domain.AppDeviceShare; import com.fuyuanshen.app.domain.dto.APPReNameDTO; import com.fuyuanshen.app.domain.dto.AppRealTimeStatusDto; import com.fuyuanshen.app.domain.dto.DeviceInstructDto; import com.fuyuanshen.app.domain.vo.APPDeviceTypeVo; +import com.fuyuanshen.app.domain.vo.AppUserVo; import com.fuyuanshen.app.mapper.AppDeviceBindRecordMapper; +import com.fuyuanshen.app.mapper.AppDeviceShareMapper; import com.fuyuanshen.app.mapper.AppPersonnelInfoMapper; +import com.fuyuanshen.app.mapper.AppUserMapper; import com.fuyuanshen.app.mapper.equipment.APPDeviceMapper; import com.fuyuanshen.common.core.exception.ServiceException; import com.fuyuanshen.common.core.utils.ObjectUtils; @@ -55,6 +59,8 @@ public class DeviceBizService { private final AppDeviceBindRecordMapper appDeviceBindRecordMapper; private final RealTimeStatusEngine realTimeStatusEngine; private final DeviceLogMapper deviceLogMapper; + private final AppDeviceShareMapper appDeviceShareMapper; + private final AppUserMapper appUserMapper;; @@ -240,6 +246,15 @@ public class DeviceBizService { appDeviceBindRecordMapper.deleteById(appDeviceBindRecord.getId())); } + AppUserVo appUserVo = appUserMapper.selectVoById(userId); + QueryWrapper appDeviceShareQueryWrapper = new QueryWrapper<>(); + appDeviceShareQueryWrapper.eq("device_id", device.getId()); + appDeviceShareQueryWrapper.eq("phonenumber", appUserVo.getPhonenumber()); + List appDeviceShareList = appDeviceShareMapper.selectList(appDeviceShareQueryWrapper); + if (CollectionUtil.isNotEmpty(appDeviceShareList)) { + appDeviceShareList.forEach(appDeviceShare -> + appDeviceShareMapper.deleteById(appDeviceShare.getId())); + } return 1; } From 77542f5e763eae4443a25f5e53ed17d596d1af62 Mon Sep 17 00:00:00 2001 From: chenyouting <514333061@qq.com> Date: Fri, 15 Aug 2025 09:32:54 +0800 Subject: [PATCH 25/47] commit --- .../mqtt/receiver/ReceiverMessageHandler.java | 2 +- .../service/device/DeviceBJQBizService.java | 36 +++++++++++++++++-- 2 files changed, 34 insertions(+), 4 deletions(-) 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 618758f7..811acd54 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 @@ -49,7 +49,7 @@ public class ReceiverMessageHandler implements MessageHandler { if(StringUtils.isNotBlank(deviceImei)){ //在线状态 String deviceOnlineStatusRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ deviceImei + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX ; - RedisUtils.setCacheObject(deviceOnlineStatusRedisKey, "1", Duration.ofSeconds(60*15)); + RedisUtils.setCacheObject(deviceOnlineStatusRedisKey, "1", Duration.ofSeconds(62)); } String state = payloadDict.getStr("state"); diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java index 671fe8ef..7038c8ed 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java @@ -19,6 +19,7 @@ import com.fuyuanshen.common.satoken.utils.AppLoginHelper; import com.fuyuanshen.equipment.domain.Device; import com.fuyuanshen.equipment.domain.DeviceType; import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo; +import com.fuyuanshen.equipment.mapper.DeviceLogMapper; import com.fuyuanshen.equipment.mapper.DeviceMapper; import com.fuyuanshen.equipment.mapper.DeviceTypeMapper; import com.fuyuanshen.global.mqtt.config.MqttGateway; @@ -50,6 +51,7 @@ public class DeviceBJQBizService { private final AppPersonnelInfoMapper appPersonnelInfoMapper; private final DeviceTypeMapper deviceTypeMapper; private final MqttGateway mqttGateway; + private final DeviceLogMapper deviceLogMapper; public int sendMessage(AppDeviceSendMsgBo bo) { List deviceIds = bo.getDeviceIds(); @@ -93,15 +95,43 @@ public class DeviceBJQBizService { .eq("binding_user_id", AppLoginHelper.getUserId()) .set("send_msg", bo.getSendMsg()); deviceMapper.update(updateWrapper); + recordDeviceLog(deviceId, device.getDeviceName(), "发送信息", bo.getSendMsg(), AppLoginHelper.getUserId()); } catch (Exception e) { log.info("发送信息设备发送信息失败:{}" ,deviceId); throw new ServiceException("发送指令失败"); } } + + return 1; } + /** + * 记录设备操作日志 + * @param deviceId 设备ID + * @param content 日志内容 + * @param operator 操作人 + */ + private void recordDeviceLog(Long deviceId,String deviceName, String deviceAction, String content, Long operator) { + try { + // 创建设备日志实体 + com.fuyuanshen.equipment.domain.DeviceLog deviceLog = new com.fuyuanshen.equipment.domain.DeviceLog(); + deviceLog.setDeviceId(deviceId); + deviceLog.setDeviceAction(deviceAction); + deviceLog.setContent(content); + deviceLog.setCreateBy(operator); + deviceLog.setDeviceName(deviceName); + deviceLog.setCreateTime(new Date()); + + // 插入日志记录 + deviceLogMapper.insert(deviceLog); + } catch (Exception e) { + log.error("记录设备操作日志失败: {}", e.getMessage(), e); + } + } + + public AppDeviceDetailVo getInfo(Long id) { Device device = deviceMapper.selectById(id); if (device == null) { @@ -203,7 +233,7 @@ public class DeviceBJQBizService { map.put("instruct", intData); mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY + deviceObj.getDeviceImei(), 1, JSON.toJSONString(map)); log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY + deviceObj.getDeviceImei(), bo); - + recordDeviceLog(deviceId, deviceObj.getDeviceName(), "人员信息登记", JSON.toJSONString(bo), AppLoginHelper.getUserId()); if (ObjectUtils.length(appPersonnelInfoVos) == 0) { AppPersonnelInfo appPersonnelInfo = MapstructUtils.convert(bo, AppPersonnelInfo.class); return appPersonnelInfoMapper.insertOrUpdate(appPersonnelInfo); @@ -216,8 +246,6 @@ public class DeviceBJQBizService { .set("code", bo.getCode()); return appPersonnelInfoMapper.update(null, uw) > 0; } - - } public void uploadDeviceLogo(AppDeviceLogoUploadDto bo) { @@ -255,6 +283,8 @@ public class DeviceBJQBizService { map.put("instruct", intData); mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(), 1 , JSON.toJSONString(map)); log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),JSON.toJSONString(map)); + + recordDeviceLog(device.getId(), device.getDeviceName(), "上传开机画面", "上传开机画面", AppLoginHelper.getUserId()); } catch (Exception e){ e.printStackTrace(); throw new ServiceException("发送指令失败"); From f65a8cdc8c64030c5ee386caafd7df0583f17102 Mon Sep 17 00:00:00 2001 From: daiyongfei <974332738@qq.com> Date: Fri, 15 Aug 2025 09:40:33 +0800 Subject: [PATCH 26/47] =?UTF-8?q?=E5=9E=8B=E5=8F=B7=E5=AD=97=E5=85=B8=20mo?= =?UTF-8?q?delDictionary?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/fuyuanshen/equipment/domain/DeviceType.java | 2 +- .../com/fuyuanshen/equipment/domain/form/DeviceTypeForm.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceType.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceType.java index 4ed83806..32bd32e3 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceType.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceType.java @@ -69,7 +69,7 @@ public class DeviceType extends TenantEntity { * 型号字典用于APP页面跳转 */ @Schema(name = "型号字典用于APP页面跳转") - private Integer modelDictionary; + private String modelDictionary; } diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceTypeForm.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceTypeForm.java index 5a8617a7..7fc8a103 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceTypeForm.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceTypeForm.java @@ -33,6 +33,6 @@ public class DeviceTypeForm { * 型号字典用于APP页面跳转 */ @Schema(name = "型号字典用于APP页面跳转") - private Integer modelDictionary; + private String modelDictionary; } From 33f3cb5989d867fe0c818a1510cd33f7e8cd3a03 Mon Sep 17 00:00:00 2001 From: chenyouting <514333061@qq.com> Date: Fri, 15 Aug 2025 10:14:35 +0800 Subject: [PATCH 27/47] =?UTF-8?q?app=E5=A2=9E=E5=8A=A0=E5=AD=97=E5=85=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/mapper/app/AppDeviceShareMapper.xml | 2 ++ .../java/com/fuyuanshen/equipment/domain/vo/AppDeviceVo.java | 5 +++++ .../src/main/resources/mapper/equipment/DeviceMapper.xml | 2 ++ 3 files changed, 9 insertions(+) diff --git a/fys-modules/fys-app/src/main/resources/mapper/app/AppDeviceShareMapper.xml b/fys-modules/fys-app/src/main/resources/mapper/app/AppDeviceShareMapper.xml index 9b3b29c5..c1d1b751 100644 --- a/fys-modules/fys-app/src/main/resources/mapper/app/AppDeviceShareMapper.xml +++ b/fys-modules/fys-app/src/main/resources/mapper/app/AppDeviceShareMapper.xml @@ -13,6 +13,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" d.device_pic, dt.type_name, dt.communication_mode, + dt.model_dictionary detailPageUrl, d.bluetooth_name, c.binding_time, ad.*,u.user_name otherPhonenumber @@ -34,6 +35,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" dt.type_name, dt.communication_mode, d.bluetooth_name, + dt.model_dictionary detailPageUrl, c.binding_time, ad.*,u.user_name otherPhonenumber from 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 1d0ec238..aafc6fc2 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 @@ -81,4 +81,9 @@ public class AppDeviceVo implements Serializable { * 告警状态(0解除告警,1告警) */ private String alarmStatus; + + /** + * 设备详情页面 + */ + 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 8af7215a..37b01927 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 @@ -148,6 +148,7 @@ dt.type_name, dt.communication_mode, d.bluetooth_name, + dt.model_dictionary detailPageUrl, c.binding_time from device d inner join device_type dt on d.device_type = dt.id @@ -177,6 +178,7 @@ d.device_pic, dt.type_name, dt.communication_mode, + dt.model_dictionary detailPageUrl, d.bluetooth_name from device d inner join device_type dt on d.device_type = dt.id From f8c53451c05ae277c1b4231c31bcc1b32affd3e9 Mon Sep 17 00:00:00 2001 From: chenyouting <514333061@qq.com> Date: Fri, 15 Aug 2025 18:16:37 +0800 Subject: [PATCH 28/47] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=81=AF=E5=85=89?= =?UTF-8?q?=E4=B8=8A=E6=8A=A5=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fuyuanshen/global/mqtt/base/MqttRuleEngine.java | 11 +++++++++-- .../mqtt/rule/bjq/BjqLaserModeSettingsRule.java | 2 +- .../fuyuanshen/global/mqtt/rule/bjq/BjqModeRule.java | 8 ++++++-- fys-admin/src/main/resources/application.yml | 2 +- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttRuleEngine.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttRuleEngine.java index 66ea4dc0..b27d57aa 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttRuleEngine.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttRuleEngine.java @@ -1,5 +1,9 @@ package com.fuyuanshen.global.mqtt.base; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Component; import java.util.Comparator; @@ -11,7 +15,10 @@ import java.util.List; */ @Component public class MqttRuleEngine { - + + @Autowired + @Qualifier("threadPoolTaskExecutor") + private ThreadPoolTaskExecutor threadPoolTaskExecutor; private final LinkedHashMap rulesMap = new LinkedHashMap<>(); public MqttRuleEngine(List rules) { @@ -30,7 +37,7 @@ public class MqttRuleEngine { int commandType = context.getCommandType(); MqttMessageRule mqttMessageRule = rulesMap.get("Light_"+commandType); if (mqttMessageRule != null) { - mqttMessageRule.execute(context); + threadPoolTaskExecutor.execute(() -> mqttMessageRule.execute(context)); return true; } diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqLaserModeSettingsRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqLaserModeSettingsRule.java index f255b107..b2bb3391 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqLaserModeSettingsRule.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqLaserModeSettingsRule.java @@ -49,7 +49,7 @@ public class BjqLaserModeSettingsRule implements MqttMessageRule { RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.OK.getCode(), Duration.ofSeconds(30)); } catch (Exception e) { - log.error("处理灯光模式命令时出错", e); + log.error("处理激光模式命令时出错", e); RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.FAILED.getCode(), Duration.ofSeconds(30)); } } diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqModeRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqModeRule.java index 7c53d20c..f16b77e4 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqModeRule.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/bjq/BjqModeRule.java @@ -16,8 +16,7 @@ import java.time.Duration; import java.util.concurrent.CompletableFuture; import static com.fuyuanshen.common.core.constant.GlobalConstants.FUNCTION_ACCESS_KEY; -import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX; -import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_LIGHT_MODE_KEY_PREFIX; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.*; /** * 灯光模式订阅设备回传消息 @@ -39,6 +38,7 @@ public class BjqModeRule implements MqttMessageRule { Object[] convertArr = context.getConvertArr(); String mainLightMode = convertArr[1].toString(); + String batteryRemainingTime = convertArr[2].toString(); if(StringUtils.isNotBlank(mainLightMode)){ if("0".equals(mainLightMode)){ String deviceOnlineStatusRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ context.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX ; @@ -46,6 +46,10 @@ public class BjqModeRule implements MqttMessageRule { } // 发送设备状态和位置信息到Redis syncSendDeviceDataToRedisWithFuture(context.getDeviceImei(),mainLightMode); + String deviceRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_KEY_PREFIX + context.getDeviceImei() + DEVICE_LIGHT_BRIGHTNESS_KEY_PREFIX; + + // 存储到Redis + RedisUtils.setCacheObject(deviceRedisKey, batteryRemainingTime); } RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.OK.getCode(), Duration.ofSeconds(20)); } catch (Exception e) { diff --git a/fys-admin/src/main/resources/application.yml b/fys-admin/src/main/resources/application.yml index c413dff7..3b4dce13 100644 --- a/fys-admin/src/main/resources/application.yml +++ b/fys-admin/src/main/resources/application.yml @@ -232,7 +232,7 @@ xss: # 如使用JDK21请直接使用虚拟线程 不要开启此配置 thread-pool: # 是否开启线程池 - enabled: false + enabled: true # 队列最大长度 queueCapacity: 128 # 线程池维护线程所允许的空闲时间 From 6d6db190b97fb67ad0307279272cdca41b0fc233 Mon Sep 17 00:00:00 2001 From: chenyouting <514333061@qq.com> Date: Sat, 16 Aug 2025 11:30:06 +0800 Subject: [PATCH 29/47] =?UTF-8?q?=E8=AE=BE=E5=A4=87=E5=88=86=E4=BA=AB2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../device/AppDeviceBJQController.java | 8 +-- .../app/service/AppDeviceShareService.java | 12 ++++ .../service/device/DeviceBJQBizService.java | 24 +++++-- .../app/domain/vo/AppDeviceShareDetailVo.java | 3 + .../equipment/enums/LightModeEnum.java | 72 +++++++++++++++++++ 5 files changed, 110 insertions(+), 9 deletions(-) create mode 100644 fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/enums/LightModeEnum.java diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceBJQController.java b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceBJQController.java index d6bf411d..51fb810e 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceBJQController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceBJQController.java @@ -43,7 +43,7 @@ public class AppDeviceBJQController extends BaseController { * 人员信息登记 */ @PostMapping(value = "/registerPersonInfo") - @FunctionAccessAnnotation("registerPersonInfo") +// @FunctionAccessAnnotation("registerPersonInfo") public R registerPersonInfo(@Validated(AddGroup.class) @RequestBody AppPersonnelInfoBo bo) { return toAjax(appDeviceService.registerPersonInfo(bo)); } @@ -61,7 +61,7 @@ public class AppDeviceBJQController extends BaseController { * 发送报警信息 */ @PostMapping(value = "/sendAlarmMessage") - @FunctionAccessBatcAnnotation("sendAlarmMessage") +// @FunctionAccessBatcAnnotation("sendAlarmMessage") public R sendAlarmMessage(@RequestBody AppDeviceSendMsgBo bo) { return toAjax(appDeviceService.sendAlarmMessage(bo)); } @@ -86,7 +86,7 @@ public class AppDeviceBJQController extends BaseController { * 灯光模式 * 0(关灯),1(强光模式),2(弱光模式), 3(爆闪模式), 4(泛光模式) */ - @FunctionAccessAnnotation("lightModeSettings") +// @FunctionAccessAnnotation("lightModeSettings") @PostMapping("/lightModeSettings") public R lightModeSettings(@RequestBody DeviceInstructDto params) { // params 转 JSONObject @@ -110,7 +110,7 @@ public class AppDeviceBJQController extends BaseController { * */ @PostMapping("/laserModeSettings") - @FunctionAccessAnnotation("laserModeSettings") +// @FunctionAccessAnnotation("laserModeSettings") public R laserModeSettings(@RequestBody DeviceInstructDto params) { appDeviceService.laserModeSettings(params); return R.ok(); diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceShareService.java b/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceShareService.java index be5986c1..1b60ce6a 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceShareService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceShareService.java @@ -161,6 +161,18 @@ public class AppDeviceShareService { shareDetailVo.setLatitude(jsonObject.get("latitude").toString()); shareDetailVo.setAddress((String)jsonObject.get("address")); } + + + String alarmStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY +DEVICE_KEY_PREFIX+ device.getDeviceImei()+ DEVICE_ALARM_KEY_PREFIX); + if(StringUtils.isNotBlank(alarmStatus)){ + shareDetailVo.setAlarmStatus(alarmStatus); + } + + String lightBrightness = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY +DEVICE_KEY_PREFIX+ device.getDeviceImei()+ DEVICE_LIGHT_BRIGHTNESS_KEY_PREFIX); + if(StringUtils.isNotBlank(lightBrightness)){ + shareDetailVo.setLightBrightness(lightBrightness); + } + return shareDetailVo; } /** diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java index 7038c8ed..1488ed5f 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java @@ -19,6 +19,7 @@ import com.fuyuanshen.common.satoken.utils.AppLoginHelper; import com.fuyuanshen.equipment.domain.Device; import com.fuyuanshen.equipment.domain.DeviceType; import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo; +import com.fuyuanshen.equipment.enums.LightModeEnum; import com.fuyuanshen.equipment.mapper.DeviceLogMapper; import com.fuyuanshen.equipment.mapper.DeviceMapper; import com.fuyuanshen.equipment.mapper.DeviceTypeMapper; @@ -69,7 +70,7 @@ public class DeviceBJQBizService { byte[] largeData = ImageWithTextGenerate.generate160x80ImageWithText2(bo.getSendMsg(), inputStream, 25600); int[] ints = convertHexToDecimal(largeData); - RedisUtils.setCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + ":app_send_message_data" , Arrays.toString(ints), Duration.ofSeconds(30 * 60L)); + RedisUtils.setCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + ":app_send_message_data" , Arrays.toString(ints), Duration.ofSeconds(5 * 60L)); String data = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + ":app_send_message_data"); @@ -95,6 +96,7 @@ public class DeviceBJQBizService { .eq("binding_user_id", AppLoginHelper.getUserId()) .set("send_msg", bo.getSendMsg()); deviceMapper.update(updateWrapper); + recordDeviceLog(deviceId, device.getDeviceName(), "发送信息", bo.getSendMsg(), AppLoginHelper.getUserId()); } catch (Exception e) { log.info("发送信息设备发送信息失败:{}" ,deviceId); @@ -211,6 +213,7 @@ public class DeviceBJQBizService { if (deviceObj == null) { throw new RuntimeException("请先将设备入库!!!"); } + QueryWrapper qw = new QueryWrapper() .eq("device_id", deviceId); List appPersonnelInfoVos = appPersonnelInfoMapper.selectVoList(qw); @@ -233,6 +236,7 @@ public class DeviceBJQBizService { map.put("instruct", intData); mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY + deviceObj.getDeviceImei(), 1, JSON.toJSONString(map)); log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY + deviceObj.getDeviceImei(), bo); + recordDeviceLog(deviceId, deviceObj.getDeviceName(), "人员信息登记", JSON.toJSONString(bo), AppLoginHelper.getUserId()); if (ObjectUtils.length(appPersonnelInfoVos) == 0) { AppPersonnelInfo appPersonnelInfo = MapstructUtils.convert(bo, AppPersonnelInfo.class); @@ -262,7 +266,7 @@ public class DeviceBJQBizService { log.info("原始数据大小: {} 字节", largeData.length); int[] ints = convertHexToDecimal(largeData); - RedisUtils.setCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() +DEVICE_BOOT_LOGO_KEY_PREFIX, Arrays.toString(ints), Duration.ofSeconds(30 * 60L)); + RedisUtils.setCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() +DEVICE_BOOT_LOGO_KEY_PREFIX, Arrays.toString(ints), Duration.ofSeconds(5 * 60L)); String data = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() + DEVICE_BOOT_LOGO_KEY_PREFIX); @@ -314,6 +318,8 @@ public class DeviceBJQBizService { map.put("instruct", intData); mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(), 1 , JSON.toJSONString(map)); log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),JSON.toJSONString(map)); + LightModeEnum modeEnum = LightModeEnum.getByCode(instructValue); + recordDeviceLog(device.getId(), device.getDeviceName(), "灯光模式", modeEnum!=null?modeEnum.getName():null, AppLoginHelper.getUserId()); } catch (Exception e){ e.printStackTrace(); throw new ServiceException("发送指令失败"); @@ -347,6 +353,7 @@ public class DeviceBJQBizService { map.put("instruct", intData); mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(), 1 , JSON.toJSONString(map)); log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),JSON.toJSONString(map)); + } catch (Exception e){ e.printStackTrace(); throw new ServiceException("发送指令失败"); @@ -372,6 +379,12 @@ public class DeviceBJQBizService { map.put("instruct", intData); mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(), 1 , JSON.toJSONString(map)); log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),JSON.toJSONString(map)); + // 1代表开启激光灯,此时主灯关闭,主灯控件为关机状态,为0代表关闭激光灯 + if("1".equals(params.getInstructValue())){ + recordDeviceLog(device.getId(), device.getDeviceName(), "激光模式设置", "开启激光灯", AppLoginHelper.getUserId()); + }else{ + recordDeviceLog(device.getId(), device.getDeviceName(), "激光模式设置", "关闭激光灯", AppLoginHelper.getUserId()); + } } catch (Exception e){ e.printStackTrace(); throw new ServiceException("发送指令失败"); @@ -418,15 +431,16 @@ public class DeviceBJQBizService { .eq("binding_user_id", AppLoginHelper.getUserId()) .set("send_msg", bo.getSendMsg()); deviceMapper.update(updateWrapper); + recordDeviceLog(device.getId(), device.getDeviceName(), "发送告警信息", bo.getSendMsg(), AppLoginHelper.getUserId()); } catch (Exception e) { - log.info("设备发送信息失败:{}" ,deviceId); - throw new ServiceException("设备发送信息失败"); + log.info("设备发送告警信息信息失败:{}" ,deviceId); + throw new ServiceException("设备发送告警信息信息失败"); } } } catch (Exception e){ e.printStackTrace(); - throw new ServiceException("发送指令失败"); + throw new ServiceException("发送告警信息指令失败"); } return 1; } diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceShareDetailVo.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceShareDetailVo.java index 89716f64..f9e8483e 100644 --- a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceShareDetailVo.java +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppDeviceShareDetailVo.java @@ -138,4 +138,7 @@ public class AppDeviceShareDetailVo implements Serializable { * 告警状态(0解除告警,1告警) */ private String alarmStatus; + + // 灯光亮度 + private String lightBrightness; } diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/enums/LightModeEnum.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/enums/LightModeEnum.java new file mode 100644 index 00000000..7394a082 --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/enums/LightModeEnum.java @@ -0,0 +1,72 @@ +package com.fuyuanshen.equipment.enums; + +/** + * 灯光模式枚举 + */ +public enum LightModeEnum { + + /** + * 关灯模式 + */ + OFF(0, "关灯"), + + /** + * 强光模式 + */ + HIGH_BEAM(1, "开启强光模式"), + + /** + * 弱光模式 + */ + LOW_BEAM(2, "开启弱光模式"), + + /** + * 爆闪模式 + */ + STROBE(3, "开启爆闪模式"), + + /** + * 泛光模式 + */ + FLOOD(4, "开启泛光模式"); + + private final Integer code; + private final String name; + + LightModeEnum(Integer code, String name) { + this.code = code; + this.name = name; + } + + public Integer getCode() { + return code; + } + + public String getName() { + return name; + } + + /** + * 根据编号获取枚举 + * @param code 编号 + * @return 对应的枚举值 + */ + public static LightModeEnum getByCode(Integer code) { + for (LightModeEnum mode : LightModeEnum.values()) { + if (mode.getCode().equals(code)) { + return mode; + } + } + return null; + } + + /** + * 根据编号获取名称 + * @param code 编号 + * @return 对应的名称 + */ + public static String getNameByCode(Integer code) { + LightModeEnum mode = getByCode(code); + return mode != null ? mode.getName() : null; + } +} From b51e88052fe66074fb1148bb754d85101596ebc5 Mon Sep 17 00:00:00 2001 From: chenyouting <514333061@qq.com> Date: Sat, 16 Aug 2025 16:40:58 +0800 Subject: [PATCH 30/47] =?UTF-8?q?=E8=AE=BE=E5=A4=87=E5=88=86=E4=BA=AB3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AppDeviceShareController.java | 4 +-- .../device/AppDeviceBJQController.java | 4 +-- .../service/DeviceShareService.java} | 12 +++---- .../service/device/DeviceBJQBizService.java | 31 +++++++++++++++++-- .../annotation/FunctionAccessAnnotation.java | 1 + .../FunctionAccessBatcAnnotation.java | 2 ++ .../aspectj/FunctionAccessAspect.java | 3 +- .../aspectj/FunctionAccessBatchAspect.java | 4 +-- 8 files changed, 44 insertions(+), 17 deletions(-) rename fys-admin/src/main/java/com/fuyuanshen/{app/service/AppDeviceShareService.java => web/service/DeviceShareService.java} (95%) 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 4c743206..613bb7ea 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 @@ -5,7 +5,6 @@ import cn.hutool.core.util.RandomUtil; import com.fuyuanshen.app.domain.bo.AppDeviceShareBo; import com.fuyuanshen.app.domain.vo.AppDeviceShareDetailVo; import com.fuyuanshen.app.domain.vo.AppDeviceShareVo; -import com.fuyuanshen.app.service.AppDeviceShareService; import com.fuyuanshen.app.service.IAppDeviceShareService; import com.fuyuanshen.common.core.constant.Constants; import com.fuyuanshen.common.core.domain.R; @@ -16,6 +15,7 @@ import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; import com.fuyuanshen.common.ratelimiter.annotation.RateLimiter; import com.fuyuanshen.common.redis.utils.RedisUtils; import com.fuyuanshen.common.web.core.BaseController; +import com.fuyuanshen.web.service.DeviceShareService; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; @@ -45,7 +45,7 @@ public class AppDeviceShareController extends BaseController { private final IAppDeviceShareService deviceShareService; - private final AppDeviceShareService appDeviceShareService; + private final DeviceShareService appDeviceShareService; /** * 分享管理列表 diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceBJQController.java b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceBJQController.java index 51fb810e..3cc71f8c 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceBJQController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceBJQController.java @@ -52,7 +52,7 @@ public class AppDeviceBJQController extends BaseController { * 发送信息 */ @PostMapping(value = "/sendMessage") - @FunctionAccessBatcAnnotation("sendMessage") + @FunctionAccessBatcAnnotation(value = "sendMessage", timeOut = 30, batchMaxTimeOut = 40) public R sendMessage(@RequestBody AppDeviceSendMsgBo bo) { return toAjax(appDeviceService.sendMessage(bo)); } @@ -61,7 +61,7 @@ public class AppDeviceBJQController extends BaseController { * 发送报警信息 */ @PostMapping(value = "/sendAlarmMessage") -// @FunctionAccessBatcAnnotation("sendAlarmMessage") + @FunctionAccessBatcAnnotation(value = "sendAlarmMessage", timeOut = 5, batchMaxTimeOut = 10) public R sendAlarmMessage(@RequestBody AppDeviceSendMsgBo bo) { return toAjax(appDeviceService.sendAlarmMessage(bo)); } diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceShareService.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/DeviceShareService.java similarity index 95% rename from fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceShareService.java rename to fys-admin/src/main/java/com/fuyuanshen/web/service/DeviceShareService.java index 1b60ce6a..d73eaa7f 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/service/AppDeviceShareService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/DeviceShareService.java @@ -1,8 +1,7 @@ -package com.fuyuanshen.app.service; +package com.fuyuanshen.web.service; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -14,11 +13,8 @@ import com.fuyuanshen.app.domain.vo.AppDeviceShareVo; import com.fuyuanshen.app.domain.vo.AppPersonnelInfoVo; import com.fuyuanshen.app.mapper.AppDeviceShareMapper; import com.fuyuanshen.app.mapper.AppPersonnelInfoMapper; -import com.fuyuanshen.common.core.constant.Constants; import com.fuyuanshen.common.core.constant.GlobalConstants; import com.fuyuanshen.common.core.exception.ServiceException; -import com.fuyuanshen.common.core.exception.user.CaptchaExpireException; -import com.fuyuanshen.common.core.utils.MessageUtils; import com.fuyuanshen.common.core.utils.StringUtils; import com.fuyuanshen.common.mybatis.core.page.PageQuery; import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; @@ -44,7 +40,7 @@ import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.*; @RequiredArgsConstructor @Slf4j @Service -public class AppDeviceShareService { +public class DeviceShareService { private final AppDeviceShareMapper appDeviceShareMapper; @@ -60,7 +56,7 @@ public class AppDeviceShareService { Page page = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize()); Page result = appDeviceShareMapper.selectAppDeviceShareList(bo, page); List records = result.getRecords(); - records.forEach(AppDeviceShareService::buildDeviceStatus); + records.forEach(DeviceShareService::buildDeviceStatus); return TableDataInfo.build(result); } @@ -231,7 +227,7 @@ public class AppDeviceShareService { IPage result = appDeviceShareMapper.otherDeviceShareList(bo, page); List records = result.getRecords(); - records.forEach(AppDeviceShareService::buildDeviceStatus); + records.forEach(DeviceShareService::buildDeviceStatus); return TableDataInfo.build(result); } diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java index 1488ed5f..60c80d70 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java @@ -64,6 +64,9 @@ public class DeviceBJQBizService { if (device == null) { throw new ServiceException("设备不存在" + deviceId); } + if(getDeviceStatus(device.getDeviceImei())){ + throw new ServiceException(device.getDeviceName()+",设备已断开连接"); + } try { ClassPathResource resource = new ClassPathResource("image/background.png"); InputStream inputStream = resource.getInputStream(); @@ -139,6 +142,7 @@ public class DeviceBJQBizService { if (device == null) { throw new RuntimeException("请先将设备入库!!!"); } + AppDeviceDetailVo vo = new AppDeviceDetailVo(); vo.setDeviceId(device.getId()); vo.setDeviceName(device.getDeviceName()); @@ -213,7 +217,9 @@ public class DeviceBJQBizService { if (deviceObj == null) { throw new RuntimeException("请先将设备入库!!!"); } - + if(getDeviceStatus(deviceObj.getDeviceImei())){ + throw new ServiceException(deviceObj.getDeviceName()+",设备已断开连接"); + } QueryWrapper qw = new QueryWrapper() .eq("device_id", deviceId); List appPersonnelInfoVos = appPersonnelInfoMapper.selectVoList(qw); @@ -258,6 +264,9 @@ public class DeviceBJQBizService { if (device == null) { throw new ServiceException("设备不存在"); } + if(getDeviceStatus(device.getDeviceImei())){ + throw new ServiceException(device.getDeviceName()+",设备已断开连接"); + } MultipartFile file = bo.getFile(); byte[] largeData = ImageToCArrayConverter.convertImageToCArray(file.getInputStream(), 160, 80, 25600); @@ -307,6 +316,9 @@ public class DeviceBJQBizService { if(device == null){ throw new ServiceException("设备不存在"); } + if(getDeviceStatus(device.getDeviceImei())){ + throw new ServiceException(device.getDeviceName()+",设备已断开连接"); + } Integer instructValue = Integer.parseInt(params.getInstructValue()); ArrayList intData = new ArrayList<>(); intData.add(1); @@ -334,6 +346,9 @@ public class DeviceBJQBizService { if(device == null){ throw new ServiceException("设备不存在"); } + if(getDeviceStatus(device.getDeviceImei())){ + throw new ServiceException(device.getDeviceName()+",设备已断开连接"); + } String instructValue = params.getInstructValue(); ArrayList intData = new ArrayList<>(); intData.add(5); @@ -368,6 +383,9 @@ public class DeviceBJQBizService { if(device == null){ throw new ServiceException("设备不存在"); } + if(getDeviceStatus(device.getDeviceImei())){ + throw new ServiceException(device.getDeviceName()+",设备已断开连接"); + } Integer instructValue = Integer.parseInt(params.getInstructValue()); ArrayList intData = new ArrayList<>(); intData.add(4); @@ -407,13 +425,17 @@ public class DeviceBJQBizService { if (deviceIds == null || deviceIds.isEmpty()) { throw new ServiceException("请选择设备"); } + for (Long deviceId : deviceIds) { Device device = deviceMapper.selectById(deviceId); if (device == null) { throw new ServiceException("设备不存在" + deviceId); } - + if(getDeviceStatus(device.getDeviceImei())){ + throw new ServiceException(device.getDeviceName()+",设备已断开连接"); + } try { + ArrayList intData = new ArrayList<>(); intData.add(7); intData.add(Integer.parseInt(bo.getInstructValue())); @@ -444,4 +466,9 @@ public class DeviceBJQBizService { } return 1; } + + private boolean getDeviceStatus(String deviceImei) { + String deviceOnlineStatusRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ deviceImei + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX ; + return StringUtils.isBlank(deviceOnlineStatusRedisKey); + } } diff --git a/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/annotation/FunctionAccessAnnotation.java b/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/annotation/FunctionAccessAnnotation.java index 635b5b9f..ab211b22 100644 --- a/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/annotation/FunctionAccessAnnotation.java +++ b/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/annotation/FunctionAccessAnnotation.java @@ -8,4 +8,5 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) public @interface FunctionAccessAnnotation { String value() default ""; + long timeOut() default 30; } diff --git a/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/annotation/FunctionAccessBatcAnnotation.java b/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/annotation/FunctionAccessBatcAnnotation.java index 3f59cd96..ef0934ee 100644 --- a/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/annotation/FunctionAccessBatcAnnotation.java +++ b/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/annotation/FunctionAccessBatcAnnotation.java @@ -8,4 +8,6 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) public @interface FunctionAccessBatcAnnotation { String value() default ""; + long timeOut() default 30; + long batchMaxTimeOut() default 40; } diff --git a/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/aspectj/FunctionAccessAspect.java b/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/aspectj/FunctionAccessAspect.java index 1d884f12..41ecd7ea 100644 --- a/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/aspectj/FunctionAccessAspect.java +++ b/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/aspectj/FunctionAccessAspect.java @@ -28,6 +28,7 @@ public class FunctionAccessAspect { // 获取方法参数,查找设备ID Object[] args = joinPoint.getArgs(); deviceImei = extractDeviceImei(args); + long timeout = functionAccessAnnotation.timeOut(); if (StringUtils.isNotBlank(deviceImei)) { // 生成全局Redis key @@ -37,7 +38,7 @@ public class FunctionAccessAspect { throw new ServiceException("设备已存在访问限制,请稍后再试", 500); } // - RedisUtils.setCacheObject(redisKey, "ACTIVE", Duration.ofSeconds(30)); + RedisUtils.setCacheObject(redisKey, "ACTIVE", Duration.ofSeconds(timeout)); } // 执行原方法 diff --git a/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/aspectj/FunctionAccessBatchAspect.java b/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/aspectj/FunctionAccessBatchAspect.java index c2c571c3..5a901ff8 100644 --- a/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/aspectj/FunctionAccessBatchAspect.java +++ b/fys-common/fys-common-ratelimiter/src/main/java/com/fuyuanshen/common/ratelimiter/aspectj/FunctionAccessBatchAspect.java @@ -41,10 +41,10 @@ public class FunctionAccessBatchAspect { throw new ServiceException("设备已存在访问限制,请稍后再试", 500); } deviceImeiList.forEach(item->{ - RedisUtils.setCacheObject(FUNCTION_ACCESS_KEY + item, "ACTIVE", Duration.ofSeconds(30)); + RedisUtils.setCacheObject(FUNCTION_ACCESS_KEY + item, "ACTIVE", Duration.ofSeconds(functionAccessBatchAspect.timeOut())); }); String deviceImeiListStr = JSONUtil.toJsonStr(deviceImeiList); - RedisUtils.setCacheObject(redisKey, deviceImeiListStr , Duration.ofSeconds(40)); + RedisUtils.setCacheObject(redisKey, deviceImeiListStr , Duration.ofSeconds(functionAccessBatchAspect.batchMaxTimeOut())); } // 执行原方法 From 9a6bf05c4b00c2e9302bcc8749c1b2dcd44f64d0 Mon Sep 17 00:00:00 2001 From: chenyouting <514333061@qq.com> Date: Mon, 18 Aug 2025 11:04:23 +0800 Subject: [PATCH 31/47] =?UTF-8?q?=E6=A0=B9=E6=8D=AEmac=E5=9C=B0=E5=9D=80?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E8=AE=BE=E5=A4=87=E8=AF=A6=E6=83=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/controller/AppDeviceController.java | 2 +- .../web/service/device/DeviceBizService.java | 13 +++++-------- .../equipment/mapper/DeviceMapper.java | 1 + .../resources/mapper/equipment/DeviceMapper.xml | 17 +++++++++++++++++ 4 files changed, 24 insertions(+), 9 deletions(-) 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 3a4bf257..d4b1695e 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 @@ -87,7 +87,7 @@ public class AppDeviceController extends BaseController { * 根据mac查询设备信息 */ @GetMapping("/getDeviceInfoByDeviceMac") - public R getDeviceInfo(String deviceMac) { + public R getDeviceInfo(String deviceMac) { return R.ok(appDeviceService.getDeviceInfo(deviceMac)); } } diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBizService.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBizService.java index 4d9a8de0..3c0d9be8 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBizService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBizService.java @@ -284,13 +284,10 @@ public class DeviceBizService { return null; } - public Device getDeviceInfo(String deviceMac) { - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("device_mac", deviceMac); - List devices = deviceMapper.selectList(queryWrapper); - if(ObjectUtils.length(devices) ==0){ - return null; - } - return devices.get(0); + public AppDeviceVo getDeviceInfo(String deviceMac) { +// QueryWrapper queryWrapper = new QueryWrapper<>(); +// queryWrapper.eq("device_mac", deviceMac); +// List devices = deviceMapper.selectList(queryWrapper); + return deviceMapper.getDeviceInfo(deviceMac); } } diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceMapper.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceMapper.java index d767a998..96bbfcef 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceMapper.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceMapper.java @@ -67,4 +67,5 @@ public interface DeviceMapper extends BaseMapper { */ List findByOriginalDeviceId(Long originalDeviceId); + AppDeviceVo getDeviceInfo(@Param("deviceMac") String deviceMac); } 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 37b01927..615c86a6 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 @@ -212,5 +212,22 @@ FROM device WHERE original_device_id = #{originalDeviceId} + \ No newline at end of file From 34ee4ccecae9f7698832cff3e514c8e0679cd55f Mon Sep 17 00:00:00 2001 From: chenyouting <514333061@qq.com> Date: Tue, 19 Aug 2025 13:58:48 +0800 Subject: [PATCH 32/47] =?UTF-8?q?web=E7=AB=AF=E6=8E=A7=E5=88=B6=E4=B8=AD?= =?UTF-8?q?=E5=BF=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../device/DeviceBJQController.java | 119 ++++++++++++++++++ .../device/WEBDeviceController.java | 80 +++++++++++- .../mapper/equipment/DeviceMapper.xml | 4 +- 3 files changed, 196 insertions(+), 7 deletions(-) create mode 100644 fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceBJQController.java diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceBJQController.java b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceBJQController.java new file mode 100644 index 00000000..d42d5223 --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceBJQController.java @@ -0,0 +1,119 @@ +package com.fuyuanshen.web.controller.device; + +import com.fuyuanshen.app.domain.bo.AppPersonnelInfoBo; +import com.fuyuanshen.app.domain.dto.AppDeviceLogoUploadDto; +import com.fuyuanshen.app.domain.dto.DeviceInstructDto; +import com.fuyuanshen.app.domain.vo.AppDeviceDetailVo; +import com.fuyuanshen.common.core.domain.R; +import com.fuyuanshen.common.core.validate.AddGroup; +import com.fuyuanshen.common.ratelimiter.annotation.FunctionAccessAnnotation; +import com.fuyuanshen.common.ratelimiter.annotation.FunctionAccessBatcAnnotation; +import com.fuyuanshen.common.web.core.BaseController; +import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo; +import com.fuyuanshen.web.service.device.DeviceBJQBizService; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +/** + * BJQ6170设备控制类 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/api/bjq/device") +public class DeviceBJQController extends BaseController { + + private final DeviceBJQBizService appDeviceService; + + /** + * 获取设备详细信息 + * + * @param id 主键 + */ + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(appDeviceService.getInfo(id)); + } + + /** + * 人员信息登记 + */ + @PostMapping(value = "/registerPersonInfo") +// @FunctionAccessAnnotation("registerPersonInfo") + public R registerPersonInfo(@Validated(AddGroup.class) @RequestBody AppPersonnelInfoBo bo) { + return toAjax(appDeviceService.registerPersonInfo(bo)); + } + + /** + * 发送信息 + */ + @PostMapping(value = "/sendMessage") + @FunctionAccessBatcAnnotation(value = "sendMessage", timeOut = 30, batchMaxTimeOut = 40) + public R sendMessage(@RequestBody AppDeviceSendMsgBo bo) { + return toAjax(appDeviceService.sendMessage(bo)); + } + + /** + * 发送报警信息 + */ + @PostMapping(value = "/sendAlarmMessage") + @FunctionAccessBatcAnnotation(value = "sendAlarmMessage", timeOut = 5, batchMaxTimeOut = 10) + public R sendAlarmMessage(@RequestBody AppDeviceSendMsgBo bo) { + return toAjax(appDeviceService.sendAlarmMessage(bo)); + } + + /** + * 上传设备logo图片 + */ + @PostMapping("/uploadLogo") + @FunctionAccessAnnotation("uploadLogo") + public R upload(@Validated @ModelAttribute AppDeviceLogoUploadDto bo) { + + MultipartFile file = bo.getFile(); + if(file.getSize()>1024*1024*2){ + return R.warn("图片不能大于2M"); + } + appDeviceService.uploadDeviceLogo(bo); + + return R.ok(); + } + + /** + * 灯光模式 + * 0(关灯),1(强光模式),2(弱光模式), 3(爆闪模式), 4(泛光模式) + */ +// @FunctionAccessAnnotation("lightModeSettings") + @PostMapping("/lightModeSettings") + public R lightModeSettings(@RequestBody DeviceInstructDto params) { + // params 转 JSONObject + appDeviceService.lightModeSettings(params); + return R.ok(); + } + + /** + * 灯光亮度设置 + * + */ +// @FunctionAccessAnnotation("lightBrightnessSettings") + @PostMapping("/lightBrightnessSettings") + public R lightBrightnessSettings(@RequestBody DeviceInstructDto params) { + appDeviceService.lightBrightnessSettings(params); + return R.ok(); + } + + /** + * 激光模式设置 + * + */ + @PostMapping("/laserModeSettings") +// @FunctionAccessAnnotation("laserModeSettings") + public R laserModeSettings(@RequestBody DeviceInstructDto params) { + appDeviceService.laserModeSettings(params); + return R.ok(); + } + +} diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java index eadb1579..0d196762 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java @@ -1,16 +1,27 @@ package com.fuyuanshen.web.controller.device; +import com.fuyuanshen.app.domain.dto.APPReNameDTO; +import com.fuyuanshen.app.domain.dto.AppRealTimeStatusDto; +import com.fuyuanshen.app.domain.vo.APPDeviceTypeVo; import com.fuyuanshen.common.core.domain.R; +import com.fuyuanshen.common.mybatis.core.page.PageQuery; +import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; import com.fuyuanshen.common.web.core.BaseController; +import com.fuyuanshen.equipment.domain.dto.AppDeviceBo; +import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria; +import com.fuyuanshen.equipment.domain.vo.AppDeviceVo; import com.fuyuanshen.web.service.WEBDeviceService; +import com.fuyuanshen.web.service.device.DeviceBizService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Map; /** * @Description: @@ -25,7 +36,7 @@ import org.springframework.web.bind.annotation.RestController; public class WEBDeviceController extends BaseController { private final WEBDeviceService deviceService; - + private final DeviceBizService appDeviceService; /** * @param id @@ -41,6 +52,67 @@ public class WEBDeviceController extends BaseController { } + + + /** + * 查询设备列表 + */ + @GetMapping("/list") + public TableDataInfo list(DeviceQueryCriteria bo, PageQuery pageQuery) { + return appDeviceService.queryAppDeviceList(bo,pageQuery); + } + + /** + * 绑定设备 + */ + @PostMapping("/bind") + public R bind(@RequestBody AppDeviceBo bo) { + return toAjax(appDeviceService.bindDevice(bo)); + } + + + /** + * 解绑设备 + */ + @DeleteMapping("/unBind") + public R unBind(Long id) { + return toAjax(appDeviceService.unBindDevice(id)); + } + + /** + * 查询设备类型列表 + */ + @GetMapping(value = "/typeList") + public R> getTypeList() { + List typeList = appDeviceService.getTypeList(); + return R.ok(typeList); + } + + /** + * 重命名设备 + * @param reNameDTO + * @return + */ + @PostMapping(value = "/reName") + public R reName(@Validated @RequestBody APPReNameDTO reNameDTO) { + appDeviceService.reName(reNameDTO); + return R.ok("重命名成功!!!"); + } + + + @GetMapping("/realTimeStatus") + public R> getRealTimeStatus(AppRealTimeStatusDto statusDto) { + Map status = appDeviceService.getRealTimeStatus(statusDto); + return R.ok(status); + } + + /** + * 根据mac查询设备信息 + */ + @GetMapping("/getDeviceInfoByDeviceMac") + public R getDeviceInfo(String deviceMac) { + return R.ok(appDeviceService.getDeviceInfo(deviceMac)); + } } 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 615c86a6..e5c95a31 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 @@ -222,11 +222,9 @@ dt.type_name, dt.communication_mode, d.bluetooth_name, - dt.model_dictionary detailPageUrl, - c.binding_time + dt.model_dictionary detailPageUrl from device d inner join device_type dt on d.device_type = dt.id - inner join app_device_bind_record c on d.id = c.device_id where d.device_mac = #{deviceMac} From 7f65ebedc213a0014a02482e3de66fe61bc3496c Mon Sep 17 00:00:00 2001 From: daiyongfei <974332738@qq.com> Date: Wed, 20 Aug 2025 13:31:54 +0800 Subject: [PATCH 33/47] =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=AD=97=E5=85=B8?= =?UTF-8?q?=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/controller/system/SysDictDataController.java | 7 +++++++ .../fuyuanshen/system/service/ISysDictDataService.java | 5 +++++ .../fuyuanshen/system/service/ISysDictTypeService.java | 5 +++++ .../system/service/impl/SysDictDataServiceImpl.java | 9 +++++++++ .../system/service/impl/SysDictTypeServiceImpl.java | 8 ++++++++ 5 files changed, 34 insertions(+) diff --git a/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/controller/system/SysDictDataController.java b/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/controller/system/SysDictDataController.java index ff3b6dcc..4ba67de4 100644 --- a/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/controller/system/SysDictDataController.java +++ b/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/controller/system/SysDictDataController.java @@ -2,6 +2,7 @@ package com.fuyuanshen.system.controller.system; import cn.dev33.satoken.annotation.SaCheckPermission; import cn.hutool.core.util.ObjectUtil; +import com.fuyuanshen.common.core.constant.CacheNames; import com.fuyuanshen.common.log.annotation.Log; import com.fuyuanshen.common.web.core.BaseController; import com.fuyuanshen.common.mybatis.core.page.PageQuery; @@ -14,10 +15,12 @@ import com.fuyuanshen.system.domain.vo.SysDictDataVo; import com.fuyuanshen.system.service.ISysDictDataService; import com.fuyuanshen.system.service.ISysDictTypeService; import lombok.RequiredArgsConstructor; +import org.springframework.cache.annotation.CacheEvict; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import jakarta.servlet.http.HttpServletResponse; + import java.util.ArrayList; import java.util.List; @@ -73,6 +76,8 @@ public class SysDictDataController extends BaseController { */ @GetMapping(value = "/type/{dictType}") public R> dictType(@PathVariable String dictType) { + // 使用时先清除缓存再查询 + dictTypeService.clearDictTypeCache(dictType); List data = dictTypeService.selectDictDataByType(dictType); if (ObjectUtil.isNull(data)) { data = new ArrayList<>(); @@ -94,6 +99,7 @@ public class SysDictDataController extends BaseController { return R.ok(); } + /** * 修改保存字典类型 */ @@ -105,6 +111,7 @@ public class SysDictDataController extends BaseController { return R.fail("修改字典数据'" + dict.getDictValue() + "'失败,字典键值已存在"); } dictDataService.updateDictData(dict); + return R.ok(); } diff --git a/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/service/ISysDictDataService.java b/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/service/ISysDictDataService.java index 1f8fc322..d5f03758 100644 --- a/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/service/ISysDictDataService.java +++ b/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/service/ISysDictDataService.java @@ -73,4 +73,9 @@ public interface ISysDictDataService { */ boolean checkDictDataUnique(SysDictDataBo dict); + /** + * 清空字典缓存 + */ + void clearDictTypeCache(String dictType); + } diff --git a/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/service/ISysDictTypeService.java b/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/service/ISysDictTypeService.java index 004b6e58..183ceb59 100644 --- a/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/service/ISysDictTypeService.java +++ b/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/service/ISysDictTypeService.java @@ -92,4 +92,9 @@ public interface ISysDictTypeService { * @return 结果 */ boolean checkDictTypeUnique(SysDictTypeBo dictType); + + /** + * 清空字典缓存 + */ + void clearDictTypeCache(String dictType); } diff --git a/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/service/impl/SysDictDataServiceImpl.java b/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/service/impl/SysDictDataServiceImpl.java index adcf47d1..19f55440 100644 --- a/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/service/impl/SysDictDataServiceImpl.java +++ b/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/service/impl/SysDictDataServiceImpl.java @@ -18,6 +18,7 @@ import com.fuyuanshen.system.domain.vo.SysDictDataVo; import com.fuyuanshen.system.mapper.SysDictDataMapper; import com.fuyuanshen.system.service.ISysDictDataService; import lombok.RequiredArgsConstructor; +import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CachePut; import org.springframework.stereotype.Service; @@ -154,4 +155,12 @@ public class SysDictDataServiceImpl implements ISysDictDataService { return true; } + + // 清除指定dictType的缓存 + @CacheEvict(cacheNames = CacheNames.SYS_DICT, key = "#dictType") + public void clearDictTypeCache(String dictType) { + // 仅用于清除缓存 + } + + } diff --git a/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/service/impl/SysDictTypeServiceImpl.java b/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/service/impl/SysDictTypeServiceImpl.java index 822a2b87..692675c6 100644 --- a/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/service/impl/SysDictTypeServiceImpl.java +++ b/fys-modules/fys-system/src/main/java/com/fuyuanshen/system/service/impl/SysDictTypeServiceImpl.java @@ -28,6 +28,7 @@ import com.fuyuanshen.system.domain.vo.SysDictTypeVo; import com.fuyuanshen.system.mapper.SysDictDataMapper; import com.fuyuanshen.system.mapper.SysDictTypeMapper; import com.fuyuanshen.system.service.ISysDictTypeService; +import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; @@ -294,4 +295,11 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService return BeanUtil.copyToList(list, DictDataDTO.class); } + + // 清除指定dictType的缓存 + @CacheEvict(cacheNames = CacheNames.SYS_DICT, key = "#dictType") + public void clearDictTypeCache(String dictType) { + // 仅用于清除缓存 + } + } From bb11bc4dfa3824186f72bd6460aa873f261a5ad9 Mon Sep 17 00:00:00 2001 From: daiyongfei <974332738@qq.com> Date: Wed, 20 Aug 2025 15:13:43 +0800 Subject: [PATCH 34/47] =?UTF-8?q?WEB=E7=AB=AF=E8=A7=A3=E7=BB=91=E8=AE=BE?= =?UTF-8?q?=E5=A4=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../device/WEBDeviceController.java | 6 ++--- .../service/impl/WEBDeviceServiceImpl.java | 24 ++++++++++++++++++- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java index 0d196762..71be5103 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java @@ -38,6 +38,7 @@ public class WEBDeviceController extends BaseController { private final WEBDeviceService deviceService; private final DeviceBizService appDeviceService; + /** * @param id * @return @@ -52,14 +53,12 @@ public class WEBDeviceController extends BaseController { } - - /** * 查询设备列表 */ @GetMapping("/list") public TableDataInfo list(DeviceQueryCriteria bo, PageQuery pageQuery) { - return appDeviceService.queryAppDeviceList(bo,pageQuery); + return appDeviceService.queryAppDeviceList(bo, pageQuery); } /** @@ -90,6 +89,7 @@ public class WEBDeviceController extends BaseController { /** * 重命名设备 + * * @param reNameDTO * @return */ diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/service/impl/WEBDeviceServiceImpl.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/impl/WEBDeviceServiceImpl.java index f38a2e88..7e328b8d 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/service/impl/WEBDeviceServiceImpl.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/impl/WEBDeviceServiceImpl.java @@ -1,8 +1,13 @@ package com.fuyuanshen.web.service.impl; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fuyuanshen.app.domain.AppDeviceBindRecord; +import com.fuyuanshen.app.mapper.AppDeviceBindRecordMapper; import com.fuyuanshen.equipment.domain.Device; import com.fuyuanshen.equipment.domain.DeviceAssignments; +import com.fuyuanshen.equipment.enums.BindingStatusEnum; import com.fuyuanshen.equipment.mapper.DeviceAssignmentsMapper; import com.fuyuanshen.equipment.mapper.DeviceMapper; import com.fuyuanshen.web.service.WEBDeviceService; @@ -10,6 +15,7 @@ import com.fuyuanshen.web.service.device.DeviceBizService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; /** * @Description: @@ -25,6 +31,10 @@ public class WEBDeviceServiceImpl extends ServiceImpl impl private final DeviceAssignmentsMapper deviceAssignmentsMapper; + private final AppDeviceBindRecordMapper appDeviceBindRecordMapper; + + private final DeviceMapper deviceMapper; + /** * WEB端解绑设备 @@ -33,6 +43,7 @@ public class WEBDeviceServiceImpl extends ServiceImpl impl * @return */ @Override + @Transactional public int webUnBindDevice(Long id, Long userId) { // 设备端解绑 0:设备端解绑 1:web端解绑 int type = 1; @@ -44,7 +55,18 @@ public class WEBDeviceServiceImpl extends ServiceImpl impl id = deviceAssignments.getDeviceId(); type = 0; } - return appDeviceService.unBindDevice(id, userId, type); + + QueryWrapper deviceId = new QueryWrapper().eq("device_id", id); + + // appDeviceService.unBindDevice(id, userId, type); + UpdateWrapper deviceUpdateWrapper = new UpdateWrapper<>(); + deviceUpdateWrapper.eq("id", id) + .set("binding_user_id", null) + .set("binding_status", BindingStatusEnum.UNBOUND.getCode()) + .set("binding_time", null); + deviceMapper.update(null, deviceUpdateWrapper); + + return appDeviceBindRecordMapper.delete(deviceId); } From 5b6927729fec25386e9cc009ccc16a29918fe55e Mon Sep 17 00:00:00 2001 From: daiyongfei <974332738@qq.com> Date: Thu, 21 Aug 2025 15:17:11 +0800 Subject: [PATCH 35/47] =?UTF-8?q?WebApp=E7=94=A8=E6=88=B7=E4=BF=A1?= =?UTF-8?q?=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{AppUserController.java => WebAppUserController.java} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename fys-modules/fys-app/src/main/java/com/fuyuanshen/app/controller/{AppUserController.java => WebAppUserController.java} (96%) diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/controller/AppUserController.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/controller/WebAppUserController.java similarity index 96% rename from fys-modules/fys-app/src/main/java/com/fuyuanshen/app/controller/AppUserController.java rename to fys-modules/fys-app/src/main/java/com/fuyuanshen/app/controller/WebAppUserController.java index 4c24feb5..34f6c959 100644 --- a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/controller/AppUserController.java +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/controller/WebAppUserController.java @@ -24,7 +24,7 @@ import com.fuyuanshen.app.service.IAppUserService; import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; /** - * APP用户信息 + * WebApp用户信息 * * @author Lion Li * @date 2025-06-27 @@ -32,8 +32,8 @@ import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; @Validated @RequiredArgsConstructor @RestController -@RequestMapping("/app/user") -public class AppUserController extends BaseController { +@RequestMapping("/WebApp/user") +public class WebAppUserController extends BaseController { private final IAppUserService appUserService; From e6d0e883fb0df0b90a9bf048fc5325e5b07a7d94 Mon Sep 17 00:00:00 2001 From: daiyongfei <974332738@qq.com> Date: Thu, 21 Aug 2025 16:51:17 +0800 Subject: [PATCH 36/47] =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=91=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/query/DeviceQueryCriteria.java | 5 +++ .../domain/query/DeviceTypeQueryCriteria.java | 6 ++++ .../service/impl/DeviceServiceImpl.java | 7 +++++ .../service/impl/DeviceTypeServiceImpl.java | 20 +++++++++--- .../mapper/equipment/DeviceMapper.xml | 31 +++++++++++-------- 5 files changed, 52 insertions(+), 17 deletions(-) diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceQueryCriteria.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceQueryCriteria.java index 09f9815f..d8a9505e 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceQueryCriteria.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceQueryCriteria.java @@ -65,4 +65,9 @@ public class DeviceQueryCriteria extends BaseEntity { /* app绑定用户id */ private Long bindingUserId; + + + /* 是否为管理员 */ + private Boolean isAdmin = false; + } diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceTypeQueryCriteria.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceTypeQueryCriteria.java index a2a0ad09..2beea69a 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceTypeQueryCriteria.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceTypeQueryCriteria.java @@ -35,4 +35,10 @@ public class DeviceTypeQueryCriteria extends BaseEntity implements Serializable @Schema(name = "每页数据量", example = "10") private Integer pageSize = 10; + + + /* 是否为管理员 */ + private Boolean isAdmin = false; + + } diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceServiceImpl.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceServiceImpl.java index 92ba94ac..357a82d1 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceServiceImpl.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceServiceImpl.java @@ -106,6 +106,13 @@ public class DeviceServiceImpl extends ServiceImpl impleme criteria.setDeviceType(deviceTypeGrant.getDeviceTypeId()); } } + + // 管理员 + String username = LoginHelper.getUsername(); + if (username.equals("admin")) { + criteria.setIsAdmin(true); + } + IPage devices = deviceMapper.findAll(criteria, page); List records = devices.getRecords(); diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceTypeServiceImpl.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceTypeServiceImpl.java index 8f9d7f7a..c069ddf6 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceTypeServiceImpl.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceTypeServiceImpl.java @@ -53,8 +53,12 @@ public class DeviceTypeServiceImpl extends ServiceImpl queryAll(DeviceTypeQueryCriteria criteria, Page page) { - criteria.setCustomerId(LoginHelper.getUserId()); - // return + // 管理员 + String username = LoginHelper.getUsername(); + if (!username.equals("admin")) { + criteria.setCustomerId(LoginHelper.getUserId()); + } + IPage deviceTypeIPage = deviceTypeMapper.findAll(criteria, page); return new TableDataInfo(deviceTypeIPage.getRecords(), deviceTypeIPage.getTotal()); } @@ -74,8 +78,16 @@ public class DeviceTypeServiceImpl extends ServiceImpl queryDeviceTypes() { DeviceTypeQueryCriteria criteria = new DeviceTypeQueryCriteria(); - Long userId = LoginHelper.getUserId(); - criteria.setCustomerId(userId); + + // 管理员 + String username = LoginHelper.getUsername(); + if (!username.equals("admin")) { + criteria.setCustomerId(LoginHelper.getUserId()); + + Long userId = LoginHelper.getUserId(); + criteria.setCustomerId(userId); + } + return deviceTypeMapper.findAll(criteria); } 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 e5c95a31..3439362f 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 @@ -74,8 +74,11 @@ and da.create_time between #{criteria.params.beginTime} and #{criteria.params.endTime} - AND da.assignee_id = #{criteria.currentOwnerId} - AND dg.customer_id = #{criteria.currentOwnerId} + + + AND da.assignee_id = #{criteria.currentOwnerId} + AND dg.customer_id = #{criteria.currentOwnerId} + ) AS ranked WHERE rn = 1 @@ -213,18 +216,20 @@ WHERE original_device_id = #{originalDeviceId} From f1a19f95f5a83057ae267a7a39f3f38dd483670f Mon Sep 17 00:00:00 2001 From: DragonWenLong <552045633@qq.com> Date: Thu, 21 Aug 2025 17:44:06 +0800 Subject: [PATCH 37/47] =?UTF-8?q?feat(mqtt):=20=E6=96=B0=E5=A2=9E=E6=98=9F?= =?UTF-8?q?=E6=B1=89=E8=AE=BE=E5=A4=87=E6=95=B0=E6=8D=AE=E5=A4=84=E7=90=86?= =?UTF-8?q?=E8=A7=84=E5=88=99=E5=92=8C=E8=A7=A3=E6=9E=90=E9=80=BB=E8=BE=91?= =?UTF-8?q?-=20=E6=B7=BB=E5=8A=A0=20MqttXinghanCommandType=20=E6=9E=9A?= =?UTF-8?q?=E4=B8=BE=E7=B1=BB=EF=BC=8C=E7=94=A8=E4=BA=8E=E8=AF=86=E5=88=AB?= =?UTF-8?q?=E5=92=8C=E5=A4=84=E7=90=86=E6=98=9F=E6=B1=89=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E7=9A=84=E5=91=BD=E4=BB=A4=E7=B1=BB=E5=9E=8B=20-=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=20MqttXinghanJson=20=E7=B1=BB=EF=BC=8C=E7=94=A8?= =?UTF-8?q?=E4=BA=8E=E8=A7=A3=E6=9E=90=E6=98=9F=E6=B1=89=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E7=9A=84=20JSON=20=E6=95=B0=E6=8D=AE=20-=20=E5=9C=A8=20Receive?= =?UTF-8?q?rMessageHandler=20=E4=B8=AD=E9=9B=86=E6=88=90=E6=98=9F=E6=B1=89?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E6=95=B0=E6=8D=AE=E7=9A=84=E5=A4=84=E7=90=86?= =?UTF-8?q?=E9=80=BB=E8=BE=91=20-=20=E6=B7=BB=E5=8A=A0=20XingHanCommandTyp?= =?UTF-8?q?eConstants=20=E5=B8=B8=E9=87=8F=E7=B1=BB=EF=BC=8C=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E6=98=9F=E6=B1=89=E8=AE=BE=E5=A4=87=E7=9A=84=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=E7=B1=BB=E5=9E=8B=E5=B8=B8=E9=87=8F=20-=20=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=20XinghanDeviceDataRule=20=E7=B1=BB=EF=BC=8C=E5=A4=84?= =?UTF-8?q?=E7=90=86=E6=98=9F=E6=B1=89=E8=AE=BE=E5=A4=87=E4=B8=BB=E5=8A=A8?= =?UTF-8?q?=E4=B8=8A=E6=8A=A5=E7=9A=84=E6=95=B0=E6=8D=AE=E5=91=BD=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mqtt/base/MqttXinghanCommandType.java | 56 +++++ .../global/mqtt/base/MqttXinghanJson.java | 65 ++++++ .../XingHanCommandTypeConstants.java | 16 ++ .../mqtt/receiver/ReceiverMessageHandler.java | 15 ++ .../rule/xinghan/XinghanDeviceDataRule.java | 212 ++++++++++++++++++ 5 files changed, 364 insertions(+) create mode 100644 fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttXinghanCommandType.java create mode 100644 fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttXinghanJson.java create mode 100644 fys-admin/src/main/java/com/fuyuanshen/global/mqtt/constants/XingHanCommandTypeConstants.java create mode 100644 fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/xinghan/XinghanDeviceDataRule.java diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttXinghanCommandType.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttXinghanCommandType.java new file mode 100644 index 00000000..6f6a6a81 --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttXinghanCommandType.java @@ -0,0 +1,56 @@ +package com.fuyuanshen.global.mqtt.base; + +import cn.hutool.core.lang.Dict; + +import java.util.Map; +import java.util.LinkedHashMap; +import java.util.Collections; +import org.springframework.stereotype.Component; + + +@Component +public final class MqttXinghanCommandType { + private MqttXinghanCommandType() {} + + public enum XinghanCommandTypeEnum { + GRADE_INFO(101), + PIC_TRANS(102), + TEX_TRANS(103), + BREAK_NEWS(104), + UNKNOWN(0); + + private final int value; + XinghanCommandTypeEnum(int value) { this.value = value; } + public int getValue() { return value; } + } + + private static final Map KEY_TO_TYPE; + static { + LinkedHashMap map = new LinkedHashMap<>(); + map.put("sta_DetectGrade", XinghanCommandTypeEnum.GRADE_INFO); + map.put("sta_PowerTime", XinghanCommandTypeEnum.GRADE_INFO); + map.put("sta_longitude", XinghanCommandTypeEnum.GRADE_INFO); + map.put("sta_latitude", XinghanCommandTypeEnum.GRADE_INFO); + map.put("sta_PicTrans", XinghanCommandTypeEnum.PIC_TRANS); + map.put("sta_TexTrans", XinghanCommandTypeEnum.TEX_TRANS); + map.put("sta_BreakNews", XinghanCommandTypeEnum.BREAK_NEWS); + KEY_TO_TYPE = Collections.unmodifiableMap(map); + } + + public static int computeVirtualCommandType(Dict payloadDict) { + if (payloadDict == null) { + return XinghanCommandTypeEnum.UNKNOWN.getValue(); + } + try { + for (String key : KEY_TO_TYPE.keySet()) { + if (payloadDict.containsKey(key)) { + return KEY_TO_TYPE.get(key).getValue(); + } + } + } catch (Exception ex) { + return XinghanCommandTypeEnum.UNKNOWN.getValue(); + } + + return XinghanCommandTypeEnum.UNKNOWN.getValue(); + } +} diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttXinghanJson.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttXinghanJson.java new file mode 100644 index 00000000..fde03ac9 --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttXinghanJson.java @@ -0,0 +1,65 @@ +package com.fuyuanshen.global.mqtt.base; + +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonProperty; + +@Data +public class MqttXinghanJson { + + /** + * 第一键值对,静电预警档位:3,2,1,0,分别表示高档/中档/低挡/关闭. + */ + @JsonProperty("sta_DetectGrade") + private Integer staDetectGrade; + /** + * 第二键值对,照明档位,2,1,0,分别表示弱光/强光/关闭 + */ + @JsonProperty("sta_LightGrade") + private Integer staLightGrade; + /** + * 第三键值对,SOS档位,2,1,0, 分别表示红蓝模式/爆闪模式/关闭 + */ + @JsonProperty("sta_SOSGrade") + public int staSOSGrade; + /** + * 第四键值对,剩余照明时间,0-5999,单位分钟。 + */ + @JsonProperty("sta_PowerTime") + public int staPowerTime; + /** + * 第五键值对,剩余电量百分比,0-100 + */ + @JsonProperty("sta_PowerPercent") + public int staPowerPercent; + /** + * 第六键值对, 近电预警级别, 0-无预警,1-弱预警,2-中预警,3-强预警,4-非常强预警。 + */ + @JsonProperty("sta_DetectResult") + public int staDetectResult; + /** + * 第七键值对, 静止报警状态,0-未静止报警,1-正在静止报警。 + */ + @JsonProperty("staShakeBit") + public int sta_ShakeBit; + /** + * 第八键值对, 4G信号强度,0-32,数值越大,信号越强。 + */ + @JsonProperty("sta_4gSinal") + public int sta4gSinal; + /** + * 第九键值对,IMIE卡号 + */ + @JsonProperty("sta_imei") + public int staimei; + /** + * 第十键值对,经度 + */ + @JsonProperty("sta_longitude") + public String stalongitude; + /** + * 第十一键值对,纬度 + */ + @JsonProperty("sta_latitude") + public String stalatitude; + +} diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/constants/XingHanCommandTypeConstants.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/constants/XingHanCommandTypeConstants.java new file mode 100644 index 00000000..a7f4ba28 --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/constants/XingHanCommandTypeConstants.java @@ -0,0 +1,16 @@ +package com.fuyuanshen.global.mqtt.constants; + +public class XingHanCommandTypeConstants { + /** + * 星汉设备主动上报数据 (XingHan Device Data) + */ + public static final String XingHan_DEVICE_DATA = "Light_101"; + /** + * 星汉开机LOGO (XingHan Boot Logo) + */ + public static final String XingHan_BOOT_LOGO = "Light_102"; + /** + * 星汉设备发送消息 (XingHan send msg) + */ + public static final String XingHan_ESEND_MSG = "Light_103"; +} 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 811acd54..4259cd18 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 @@ -8,6 +8,7 @@ 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 lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -69,5 +70,19 @@ public class ReceiverMessageHandler implements MessageHandler { 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/rule/xinghan/XinghanDeviceDataRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/xinghan/XinghanDeviceDataRule.java new file mode 100644 index 00000000..e12c0665 --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/xinghan/XinghanDeviceDataRule.java @@ -0,0 +1,212 @@ +package com.fuyuanshen.global.mqtt.rule.xinghan; + +import com.alibaba.fastjson2.JSONObject; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fuyuanshen.common.core.constant.GlobalConstants; +import com.fuyuanshen.common.core.utils.StringUtils; +import com.fuyuanshen.common.json.utils.JsonUtils; +import com.fuyuanshen.common.redis.utils.RedisUtils; +import com.fuyuanshen.equipment.utils.map.GetAddressFromLatUtil; +import com.fuyuanshen.equipment.utils.map.LngLonUtil; +import com.fuyuanshen.global.mqtt.base.MqttMessageRule; +import com.fuyuanshen.global.mqtt.base.MqttRuleContext; +import com.fuyuanshen.global.mqtt.base.MqttXinghanJson; +import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants; +import com.fuyuanshen.global.mqtt.constants.LightingCommandTypeConstants; +import com.fuyuanshen.global.mqtt.constants.XingHanCommandTypeConstants; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.CompletableFuture; + +import static com.fuyuanshen.common.core.constant.GlobalConstants.FUNCTION_ACCESS_KEY; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.*; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX; + +/** + * 主动上报设备数据命令处理 + * 第一键值对,静电预警档位:3,2,1,0,分别表示高档/中档/低挡/关闭. + * 第二键值对,照明档位,2,1,0,分别表示弱光/强光/关闭 + * 第三键值对,SOS档位,2,1,0, 分别表示红蓝模式/爆闪模式/关闭 + * 第四键值对,剩余照明时间,0-5999,单位分钟。 + * 第五键值对, 剩余电量百分比,0-100。 + * 第六键值对, 近电预警级别, 0-无预警,1-弱预警,2-中预警,3-强预警,4-非常强预警。 + * 第七键值对, 静止报警状态,0-未静止报警,1-正在静止报警。 + * 第八键值对, 4G信号强度,0-32,数值越大,信号越强。 + * 第九键值对,IMIE卡号 + * 第十键值对,经度 + * 第十一键值对,纬度 + */ +@Component +@RequiredArgsConstructor +@Slf4j +public class XinghanDeviceDataRule implements MqttMessageRule { + + @Override + public String getCommandType() { + return XingHanCommandTypeConstants.XingHan_DEVICE_DATA; + } + + @Autowired + private ObjectMapper objectMapper; + + @Override + public void execute(MqttRuleContext context) { + try { + // Latitude, longitude + //主灯档位,激光灯档位,电量百分比,充电状态,电池剩余续航时间 + MqttXinghanJson deviceStatus = objectMapper.convertValue(context.getPayloadDict(), MqttXinghanJson.class); + + // 发送设备状态和位置信息到Redis + asyncSendDeviceDataToRedisWithFuture(context.getDeviceImei(),deviceStatus); + } catch (Exception e) { + log.error("处理上报数据命令时出错", e); + } + } + + /** + * 发送设备状态信息和位置信息到Redis + * + * @param deviceImei 设备IMEI + * @param deviceStatus 机器主动上报的状态信息 + */ + public void asyncSendDeviceDataToRedisWithFuture(String deviceImei, MqttXinghanJson deviceStatus) { + CompletableFuture.runAsync(() -> { + try { + + // 将设备状态信息存储到Redis中 + String deviceRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+ DeviceRedisKeyConstants.DEVICE_KEY_PREFIX + deviceImei + DEVICE_STATUS_KEY_PREFIX; + String deviceInfoJson = JsonUtils.toJsonString(deviceStatus); + // 存储到Redis + RedisUtils.setCacheObject(deviceRedisKey, deviceInfoJson); + + log.info("设备状态信息已异步发送到Redis: device={}, deviceInfoJson={}", + deviceImei, deviceInfoJson); + + //设备坐标缓存KEY + String functionAccess = FUNCTION_ACCESS_KEY + deviceImei; + // 异步发送经纬度到Redis + asyncSendLocationToRedisWithFuture(deviceImei, deviceStatus.getStalatitude(), deviceStatus.getStalongitude()); + + } catch (Exception e) { + log.error("异步发送设备信息到Redis时出错: device={}, error={}", deviceImei, e.getMessage(), e); + } + }); + } + + /** + * 异步发送位置信息到Redis(使用CompletableFuture) + * + * @param deviceImei 设备IMEI + * @param latitude 纬度 + * @param longitude 经度 + */ + public void asyncSendLocationToRedisWithFuture(String deviceImei, String latitude, String longitude) { + CompletableFuture.runAsync(() -> { + try { + if(StringUtils.isBlank(latitude) || StringUtils.isBlank(longitude)){ + return; + } + String[] latArr = latitude.split("\\."); + String[] lonArr = longitude.split("\\."); + // 将位置信息存储到Redis中 + String redisKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ deviceImei + DEVICE_LOCATION_KEY_PREFIX; + String redisObj = RedisUtils.getCacheObject(redisKey); + JSONObject jsonOBj = JSONObject.parseObject(redisObj); + if(jsonOBj != null){ + String str1 = latArr[0] +"."+ latArr[1].substring(0,4); + String str2 = lonArr[0] +"."+ lonArr[1].substring(0,4); + + String cacheLatitude = jsonOBj.getString("wgs84_latitude"); + String cacheLongitude = jsonOBj.getString("wgs84_longitude"); + String[] latArr1 = cacheLatitude.split("\\."); + String[] lonArr1 = cacheLongitude.split("\\."); + + String cacheStr1 = latArr1[0] +"."+ latArr1[1].substring(0,4); + String cacheStr2 = lonArr1[0] +"."+ lonArr1[1].substring(0,4); + if(str1.equals(cacheStr1) && str2.equals(cacheStr2)){ + log.info("位置信息未发生变化: device={}, lat={}, lon={}", deviceImei, latitude, longitude); + return; + } + } + + // 构造位置信息对象 + Map locationInfo = new LinkedHashMap<>(); + double[] doubles = LngLonUtil.gps84_To_Gcj02(Double.parseDouble(latitude), Double.parseDouble(longitude)); + locationInfo.put("deviceImei", deviceImei); + locationInfo.put("latitude", doubles[0]); + locationInfo.put("longitude", doubles[1]); + locationInfo.put("wgs84_latitude", latitude); + locationInfo.put("wgs84_longitude", longitude); + String address = GetAddressFromLatUtil.getAdd(String.valueOf(doubles[1]), String.valueOf(doubles[0])); + locationInfo.put("address", address); + locationInfo.put("timestamp", System.currentTimeMillis()); + + + + String locationJson = JsonUtils.toJsonString(locationInfo); + + // 存储到Redis + RedisUtils.setCacheObject(redisKey, locationJson); + + // 存储到一个列表中,保留历史位置信息 +// String locationHistoryKey = GlobalConstants.GLOBAL_REDIS_KEY+DeviceRedisKeyConstants.DEVICE_LOCATION_HISTORY_KEY_PREFIX + deviceImei; +// RedisUtils.addCacheList(locationHistoryKey, locationJson); +// RedisUtils.expire(locationHistoryKey, Duration.ofDays(90)); + storeDeviceTrajectoryWithSortedSet(deviceImei, locationJson); + log.info("位置信息已异步发送到Redis: device={}, lat={}, lon={}", deviceImei, latitude, longitude); + } catch (Exception e) { + log.error("异步发送位置信息到Redis时出错: device={}, error={}", deviceImei, e.getMessage(), e); + } + }); + } + + /** + * 存储设备30天历史轨迹到Redis (使用Sorted Set) + */ + public void storeDeviceTrajectoryWithSortedSet(String deviceImei, String locationJson) { + try { + String trajectoryKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + deviceImei + DeviceRedisKeyConstants.DEVICE_LOCATION_HISTORY_KEY_PREFIX; +// String trajectoryKey = "device:trajectory:zset:" + deviceImei; +// String locationJson = JsonUtils.toJsonString(locationInfo); + long timestamp = System.currentTimeMillis(); + + // 添加到Sorted Set,使用时间戳作为score + RedisUtils.zAdd(trajectoryKey, locationJson, timestamp); + +// // 设置30天过期时间 +// RedisUtils.expire(trajectoryKey, Duration.ofDays(30)); + + // 清理30天前的数据(冗余保护) + long thirtyDaysAgo = System.currentTimeMillis() - (7L * 24 * 60 * 60 * 1000); + RedisUtils.zRemoveRangeByScore(trajectoryKey, 0, thirtyDaysAgo); + } catch (Exception e) { + log.error("存储设备轨迹到Redis(ZSet)失败: device={}, error={}", deviceImei, e.getMessage(), e); + } + } + + private Map buildLocationDataMap(String latitude, String longitude) { + String[] latArr = latitude.split("\\."); + String[] lonArr = longitude.split("\\."); + + ArrayList intData = new ArrayList<>(); + intData.add(11); + intData.add(Integer.parseInt(latArr[0])); + String str1 = latArr[1]; + intData.add(Integer.parseInt(str1.substring(0,4))); + String str2 = lonArr[1]; + intData.add(Integer.parseInt(lonArr[0])); + intData.add(Integer.parseInt(str2.substring(0,4))); + + Map map = new HashMap<>(); + map.put("instruct", intData); + return map; + } + +} From 9dee7ad102de8aebeb45f838499bc7bda42a589a Mon Sep 17 00:00:00 2001 From: daiyongfei <974332738@qq.com> Date: Thu, 21 Aug 2025 17:55:59 +0800 Subject: [PATCH 38/47] =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=91=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../equipment/service/impl/DeviceTypeServiceImpl.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceTypeServiceImpl.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceTypeServiceImpl.java index c069ddf6..cdeaacd4 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceTypeServiceImpl.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/service/impl/DeviceTypeServiceImpl.java @@ -169,8 +169,12 @@ public class DeviceTypeServiceImpl extends ServiceImpl Date: Fri, 22 Aug 2025 09:40:52 +0800 Subject: [PATCH 39/47] =?UTF-8?q?=E8=AE=BE=E5=A4=87=E6=89=80=E5=B1=9E?= =?UTF-8?q?=E5=88=86=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/query/DeviceQueryCriteria.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceQueryCriteria.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceQueryCriteria.java index d8a9505e..e0e51be5 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceQueryCriteria.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceQueryCriteria.java @@ -66,8 +66,22 @@ public class DeviceQueryCriteria extends BaseEntity { /* app绑定用户id */ private Long bindingUserId; - - /* 是否为管理员 */ + /** + * 是否为管理员 + */ + @Schema(name = "是否为管理员") private Boolean isAdmin = false; + /** + * 设备所属分组 + */ + @Schema(name = "设备所属分组") + private Long groupId; + + /** + * 设备地区 + */ + @Schema(name = "设备地区") + private String area; + } From b83be496b61c3295f26b0ce8ffde6f5546e9cdb9 Mon Sep 17 00:00:00 2001 From: daiyongfei <974332738@qq.com> Date: Fri, 22 Aug 2025 09:58:27 +0800 Subject: [PATCH 40/47] =?UTF-8?q?=E5=87=BA=E5=8E=82=E6=97=A5=E6=9C=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fuyuanshen/equipment/domain/Device.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/Device.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/Device.java index ae1a00d3..902874c1 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/Device.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/Device.java @@ -1,9 +1,6 @@ package com.fuyuanshen.equipment.domain; -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.*; import com.fasterxml.jackson.annotation.JsonInclude; import com.fuyuanshen.common.tenant.core.TenantEntity; import io.swagger.v3.oas.annotations.media.Schema; @@ -32,6 +29,13 @@ public class Device extends TenantEntity { @TableField(exist = false) private Long assignId; + /** + * 设备分组 + * group_id + */ + @Schema(name = "设备分组") + private Long groupId; + /** * device_type */ @@ -143,4 +147,11 @@ public class Device extends TenantEntity { */ private String subTopic; + /** + * 出厂日期 + * production_date + */ + @Schema(name = "出厂日期") + private Date productionDate; + } From 2965b454cf534f794f7261aeeb37b17f179c434c Mon Sep 17 00:00:00 2001 From: daiyongfei <974332738@qq.com> Date: Fri, 22 Aug 2025 16:37:58 +0800 Subject: [PATCH 41/47] =?UTF-8?q?web:=E8=AE=BE=E5=A4=87=E5=88=86=E7=BB=84?= =?UTF-8?q?=20=E6=8E=A5=E5=8F=A3=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/controller/device/DeviceGroupController.java | 8 ++++++++ fys-admin/src/main/resources/application.yml | 2 ++ .../com/fuyuanshen/equipment/domain/bo/DeviceGroupBo.java | 3 +++ 3 files changed, 13 insertions(+) diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceGroupController.java b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceGroupController.java index 0f0eafab..28601a1a 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceGroupController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceGroupController.java @@ -3,6 +3,8 @@ package com.fuyuanshen.web.controller.device; import java.util.List; import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.constraints.*; @@ -27,6 +29,7 @@ import com.fuyuanshen.equipment.service.IDeviceGroupService; * @author Lion Li * @date 2025-08-08 */ +@Tag(name = "web:设备分组", description = "web:设备分组") @Validated @RequiredArgsConstructor @RestController @@ -39,6 +42,7 @@ public class DeviceGroupController extends BaseController { /** * 查询设备分组列表 */ + @Operation(summary = "查询设备分组列表") @SaCheckPermission("fys-equipment:group:list") @GetMapping("/list") public R> list(DeviceGroupBo bo) { @@ -64,6 +68,7 @@ public class DeviceGroupController extends BaseController { * * @param id 主键 */ + @Operation(summary = "获取设备分组详细信息") @SaCheckPermission("fys-equipment:group:query") @GetMapping("/{id}") public R getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) { @@ -74,6 +79,7 @@ public class DeviceGroupController extends BaseController { /** * 新增设备分组 */ + @Operation(summary = "新增设备分组") @SaCheckPermission("fys-equipment:group:add") @Log(title = "设备分组", businessType = BusinessType.INSERT) @RepeatSubmit() @@ -86,6 +92,7 @@ public class DeviceGroupController extends BaseController { /** * 修改设备分组 */ + @Operation(summary = "修改设备分组") @SaCheckPermission("fys-equipment:group:edit") @Log(title = "设备分组", businessType = BusinessType.UPDATE) @RepeatSubmit() @@ -99,6 +106,7 @@ public class DeviceGroupController extends BaseController { * * @param ids 主键串 */ + @Operation(summary = "删除设备分组") @SaCheckPermission("fys-equipment:group:remove") @Log(title = "设备分组", businessType = BusinessType.DELETE) @DeleteMapping("/{ids}") diff --git a/fys-admin/src/main/resources/application.yml b/fys-admin/src/main/resources/application.yml index 3b4dce13..21924a61 100644 --- a/fys-admin/src/main/resources/application.yml +++ b/fys-admin/src/main/resources/application.yml @@ -219,6 +219,8 @@ springdoc: packages-to-scan: com.fuyuanshen.customer - group: APP模块 packages-to-scan: com.fuyuanshen.app + - group: 设备分组 + packages-to-scan: com.fuyuanshen.web.controller.device # 防止XSS攻击 xss: diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/bo/DeviceGroupBo.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/bo/DeviceGroupBo.java index 37cff3b9..064c5aa2 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/bo/DeviceGroupBo.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/bo/DeviceGroupBo.java @@ -30,18 +30,21 @@ public class DeviceGroupBo extends BaseEntity { /** * 分组名称 */ + @Schema(name = "分组名称") @NotBlank(message = "分组名称不能为空", groups = { AddGroup.class, EditGroup.class }) private String groupName; /** * 状态:0-禁用,1-正常 */ + @Schema(name = "状态:0-禁用,1-正常") // @NotNull(message = "状态:0-禁用,1-正常不能为空", groups = { AddGroup.class, EditGroup.class }) private Long status; /** * 父分组ID */ + @Schema(name = "父分组ID") private Long parentId; /** From 95aa01e1c253777166836659704963415617abe8 Mon Sep 17 00:00:00 2001 From: DragonWenLong <552045633@qq.com> Date: Fri, 22 Aug 2025 18:09:08 +0800 Subject: [PATCH 42/47] =?UTF-8?q?feat(device):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E6=98=9F=E6=B1=89=E8=AE=BE=E5=A4=87=E6=8E=A7=E5=88=B6=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加星汉设备控制器 AppDeviceXinghanController- 实现星汉设备业务逻辑 DeviceXinghanBizService - 增加开机 LOGO 下发规则 XinghanBootLogoRule - 添加设备发送消息规则 XinghanSendMsgRule - 更新 MQTT 命令类型常量 XingHanCommandTypeConstants - 修改设备状态 JSON 结构 MqttXinghanJson --- .../device/AppDeviceXinghanController.java | 96 +++++++ .../mqtt/base/MqttXinghanCommandType.java | 9 + .../global/mqtt/base/MqttXinghanJson.java | 14 +- .../XingHanCommandTypeConstants.java | 4 + .../rule/xinghan/XinghanBootLogoRule.java | 143 ++++++++++ .../mqtt/rule/xinghan/XinghanSendMsgRule.java | 117 ++++++++ .../device/DeviceXinghanBizService.java | 269 ++++++++++++++++++ 7 files changed, 645 insertions(+), 7 deletions(-) create mode 100644 fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceXinghanController.java create mode 100644 fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/xinghan/XinghanBootLogoRule.java create mode 100644 fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/xinghan/XinghanSendMsgRule.java create mode 100644 fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceXinghanBizService.java diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceXinghanController.java b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceXinghanController.java new file mode 100644 index 00000000..b4f53c51 --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/AppDeviceXinghanController.java @@ -0,0 +1,96 @@ +package com.fuyuanshen.app.controller.device; + +import com.fuyuanshen.app.domain.bo.AppPersonnelInfoBo; +import com.fuyuanshen.app.domain.dto.AppDeviceLogoUploadDto; +import com.fuyuanshen.app.domain.dto.DeviceInstructDto; +import com.fuyuanshen.common.core.domain.R; +import com.fuyuanshen.common.core.validate.AddGroup; +import com.fuyuanshen.common.ratelimiter.annotation.FunctionAccessAnnotation; +import com.fuyuanshen.common.web.core.BaseController; +import com.fuyuanshen.web.service.device.DeviceBJQBizService; +import com.fuyuanshen.web.service.device.DeviceXinghanBizService; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +/** + * HBY670设备控制类 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/app/xinghan/device") +public class AppDeviceXinghanController extends BaseController { + + private final DeviceXinghanBizService appDeviceService; + /** + * 人员信息登记 + */ + @PostMapping(value = "/registerPersonInfo") +// @FunctionAccessAnnotation("registerPersonInfo") + public R registerPersonInfo(@Validated(AddGroup.class) @RequestBody AppPersonnelInfoBo bo) { + return toAjax(appDeviceService.registerPersonInfo(bo)); + } + + /** + * 上传设备logo图片 + */ + @PostMapping("/uploadLogo") + @FunctionAccessAnnotation("uploadLogo") + public R upload(@Validated @ModelAttribute AppDeviceLogoUploadDto bo) { + + MultipartFile file = bo.getFile(); + if(file.getSize()>1024*1024*2){ + return R.warn("图片不能大于2M"); + } + appDeviceService.uploadDeviceLogo(bo); + + return R.ok(); + } + + /** + * 静电预警档位 + * 3,2,1,0,分别表示高档/中档/低挡/关闭 + */ + @PostMapping("/DetectGradeSettings") + public R DetectGradeSettings(@RequestBody DeviceInstructDto params) { + // params 转 JSONObject + appDeviceService.upDetectGradeSettings(params); + return R.ok(); + } + + /** + * 照明档位 + * 照明档位,2,1,0,分别表示弱光/强光/关闭 + */ + @PostMapping("/LightGradeSettings") + public R LightGradeSettings(@RequestBody DeviceInstructDto params) { + // params 转 JSONObject + appDeviceService.upLightGradeSettings(params); + return R.ok(); + } + + /** + * SOS档位 + * SOS档位,2,1,0, 分别表示红蓝模式/爆闪模式/关闭 + */ + @PostMapping("/SOSGradeSettings") + public R SOSGradeSettings(@RequestBody DeviceInstructDto params) { + // params 转 JSONObject + appDeviceService.upSOSGradeSettings(params); + return R.ok(); + } + + /** + * 静止报警状态 + * 静止报警状态,0-未静止报警,1-正在静止报警。 + */ + @PostMapping("/ShakeBitSettings") + public R ShakeBitSettings(@RequestBody DeviceInstructDto params) { + // params 转 JSONObject + appDeviceService.upShakeBitSettings(params); + return R.ok(); + } + +} diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttXinghanCommandType.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttXinghanCommandType.java index 6f6a6a81..99e7bc78 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttXinghanCommandType.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttXinghanCommandType.java @@ -13,8 +13,17 @@ public final class MqttXinghanCommandType { private MqttXinghanCommandType() {} public enum XinghanCommandTypeEnum { + /** + * 星汉设备主动上报数据 + */ GRADE_INFO(101), + /** + * 星汉开机LOGO + */ PIC_TRANS(102), + /** + * 星汉设备发送消息 (XingHan send msg) + */ TEX_TRANS(103), BREAK_NEWS(104), UNKNOWN(0); diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttXinghanJson.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttXinghanJson.java index fde03ac9..2d49b468 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttXinghanJson.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/base/MqttXinghanJson.java @@ -20,37 +20,37 @@ public class MqttXinghanJson { * 第三键值对,SOS档位,2,1,0, 分别表示红蓝模式/爆闪模式/关闭 */ @JsonProperty("sta_SOSGrade") - public int staSOSGrade; + public Integer staSOSGrade; /** * 第四键值对,剩余照明时间,0-5999,单位分钟。 */ @JsonProperty("sta_PowerTime") - public int staPowerTime; + public Integer staPowerTime; /** * 第五键值对,剩余电量百分比,0-100 */ @JsonProperty("sta_PowerPercent") - public int staPowerPercent; + public Integer staPowerPercent; /** * 第六键值对, 近电预警级别, 0-无预警,1-弱预警,2-中预警,3-强预警,4-非常强预警。 */ @JsonProperty("sta_DetectResult") - public int staDetectResult; + public Integer staDetectResult; /** * 第七键值对, 静止报警状态,0-未静止报警,1-正在静止报警。 */ @JsonProperty("staShakeBit") - public int sta_ShakeBit; + public Integer sta_ShakeBit; /** * 第八键值对, 4G信号强度,0-32,数值越大,信号越强。 */ @JsonProperty("sta_4gSinal") - public int sta4gSinal; + public Integer sta4gSinal; /** * 第九键值对,IMIE卡号 */ @JsonProperty("sta_imei") - public int staimei; + public String staimei; /** * 第十键值对,经度 */ diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/constants/XingHanCommandTypeConstants.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/constants/XingHanCommandTypeConstants.java index a7f4ba28..0b6f3d7c 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/constants/XingHanCommandTypeConstants.java +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/constants/XingHanCommandTypeConstants.java @@ -13,4 +13,8 @@ public class XingHanCommandTypeConstants { * 星汉设备发送消息 (XingHan send msg) */ public static final String XingHan_ESEND_MSG = "Light_103"; + /** + * 星汉设备发送紧急通知 (XingHan break news) + */ + public static final String XingHan_BREAK_NEWS = "Light_104"; } diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/xinghan/XinghanBootLogoRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/xinghan/XinghanBootLogoRule.java new file mode 100644 index 00000000..96faf308 --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/xinghan/XinghanBootLogoRule.java @@ -0,0 +1,143 @@ +package com.fuyuanshen.global.mqtt.rule.xinghan; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fuyuanshen.common.core.utils.ImageToCArrayConverter; +import com.fuyuanshen.common.core.utils.StringUtils; +import com.fuyuanshen.common.json.utils.JsonUtils; +import com.fuyuanshen.common.redis.utils.RedisUtils; +import com.fuyuanshen.global.mqtt.base.MqttMessageRule; +import com.fuyuanshen.global.mqtt.base.MqttRuleContext; +import com.fuyuanshen.global.mqtt.config.MqttGateway; +import com.fuyuanshen.global.mqtt.constants.LightingCommandTypeConstants; +import com.fuyuanshen.global.mqtt.constants.MqttConstants; +import com.fuyuanshen.global.mqtt.constants.XingHanCommandTypeConstants; +import com.fuyuanshen.global.mqtt.listener.domain.FunctionAccessStatus; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.time.Duration; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.zip.CRC32; + +import static com.fuyuanshen.common.core.constant.GlobalConstants.FUNCTION_ACCESS_KEY; +import static com.fuyuanshen.common.core.constant.GlobalConstants.GLOBAL_REDIS_KEY; +import static com.fuyuanshen.common.core.utils.ImageToCArrayConverter.convertHexToDecimal; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_BOOT_LOGO_KEY_PREFIX; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX; + +/** + * 星汉设备开机 LOGO 下发规则: + *

+ * 1. 设备上行 sta_PicTarns=great! => 仅标记成功
+ * 2. 设备上行 sta_PicTarns=数字 => 下发第 N 块数据(256B/块,带 CRC32) + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class XinghanBootLogoRule implements MqttMessageRule { + + private final MqttGateway mqttGateway; + private final ObjectMapper objectMapper; + + @Override + public String getCommandType() { + return XingHanCommandTypeConstants.XingHan_BOOT_LOGO; + } + + @Override + public void execute(MqttRuleContext ctx) { + final String functionAccessKey = FUNCTION_ACCESS_KEY + ctx.getDeviceImei(); + try { + MqttXinghanLogoJson payload = objectMapper.convertValue( + ctx.getPayloadDict(), MqttXinghanLogoJson.class); + + String respText = payload.getStaPicTrans(); + log.warn("设备上报LOGO:{}", respText); + + // 1. great! —— 成功标记 + if ("great!".equalsIgnoreCase(respText)) { + RedisUtils.setCacheObject(functionAccessKey, + FunctionAccessStatus.OK.getCode(), Duration.ofSeconds(20)); + log.info("设备 {} 开机 LOGO 写入成功", ctx.getDeviceImei()); + return; + } + + // 2. 数字 —— 下发数据块 + int blockIndex; + try { + blockIndex = Integer.parseInt(respText); + } catch (NumberFormatException ex) { + log.warn("设备 {} LOGO 上报非法块号:{}", ctx.getDeviceImei(), respText); + return; + } + String hexImage = RedisUtils.getCacheObject( + GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX + ctx.getDeviceImei() + DEVICE_BOOT_LOGO_KEY_PREFIX); + if (StringUtils.isEmpty(hexImage)) { + return; + } + + byte[] fullBin = ImageToCArrayConverter.convertStringToByteArray(hexImage); + byte[] chunk = ImageToCArrayConverter.getChunk(fullBin, blockIndex - 1, CHUNK_SIZE); + log.info("设备 {} 第 {} 块数据长度: {} bytes", ctx.getDeviceImei(), blockIndex, chunk.length); + + // 组装下发数据 + ArrayList dataFrame = new ArrayList<>(); + dataFrame.add(blockIndex); // 块号 + ImageToCArrayConverter.buildArr(convertHexToDecimal(chunk), dataFrame); + dataFrame.addAll(crc32AsList(chunk)); // CRC32 + + Map pub = new HashMap<>(); + pub.put("ins_PicTrans", dataFrame); + + String topic = MqttConstants.GLOBAL_PUB_KEY + ctx.getDeviceImei(); + String json = JsonUtils.toJsonString(pub); + mqttGateway.sendMsgToMqtt(topic, 1, json); + + log.info("下发开机 LOGO 数据 => topic:{}, payload:{}", topic, json); + + } catch (Exception e) { + log.error("处理设备 {} 开机 LOGO 失败", ctx.getDeviceImei(), e); + RedisUtils.setCacheObject(functionAccessKey, + FunctionAccessStatus.FAILED.getCode(), Duration.ofSeconds(20)); + } + } + + /* ---------- 内部工具 ---------- */ + + private static final int CHUNK_SIZE = 256; + + private static ArrayList crc32AsList(byte[] data) { + CRC32 crc = new CRC32(); + crc.update(data); + byte[] crcBytes = ByteBuffer.allocate(4) + .order(ByteOrder.BIG_ENDIAN) + .putInt((int) crc.getValue()) + .array(); + ArrayList list = new ArrayList<>(4); + for (byte b : crcBytes) { + list.add(Byte.toUnsignedInt(b)); + } + return list; + } + + /* ---------- DTO ---------- */ + + @Data + private static class MqttXinghanLogoJson { + /** + * 设备上行: + * 数字 -> 请求对应块号 + * great! -> 写入成功 + */ + @JsonProperty("sta_PicTrans") + private String staPicTrans; + } +} diff --git a/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/xinghan/XinghanSendMsgRule.java b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/xinghan/XinghanSendMsgRule.java new file mode 100644 index 00000000..68acb099 --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/global/mqtt/rule/xinghan/XinghanSendMsgRule.java @@ -0,0 +1,117 @@ +package com.fuyuanshen.global.mqtt.rule.xinghan; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fuyuanshen.common.json.utils.JsonUtils; +import com.fuyuanshen.common.redis.utils.RedisUtils; +import com.fuyuanshen.global.mqtt.base.MqttMessageRule; +import com.fuyuanshen.global.mqtt.base.MqttRuleContext; +import com.fuyuanshen.global.mqtt.config.MqttGateway; +import com.fuyuanshen.global.mqtt.constants.MqttConstants; +import com.fuyuanshen.global.mqtt.constants.XingHanCommandTypeConstants; +import com.fuyuanshen.global.mqtt.listener.domain.FunctionAccessStatus; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.nio.charset.Charset; +import java.time.Duration; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static com.fuyuanshen.common.core.constant.GlobalConstants.FUNCTION_ACCESS_KEY; +import static com.fuyuanshen.common.core.constant.GlobalConstants.GLOBAL_REDIS_KEY; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX; + +/** + * 星汉设备发送消息 下发规则: + *

+ * 1. 设备上行 sta_TexTarns=genius! => 仅标记成功
+ * 2. 设备上行 sta_TexTarns=数字 => GBK编码,每行文字为一包,一共4包,第一字节为包序号 + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class XinghanSendMsgRule implements MqttMessageRule { + + private final MqttGateway mqttGateway; + private final ObjectMapper objectMapper; + + @Override + public String getCommandType() { + return XingHanCommandTypeConstants.XingHan_ESEND_MSG; + } + + @Override + public void execute(MqttRuleContext ctx) { + String functionAccess = FUNCTION_ACCESS_KEY + ctx.getDeviceImei(); + try { + XinghanSendMsgRule.MqttXinghanMsgJson payload = objectMapper.convertValue( + ctx.getPayloadDict(), XinghanSendMsgRule.MqttXinghanMsgJson.class); + + String respText = payload.getStaTexTrans(); + log.info("设备上报人员信息: {} ", respText); + + // 1. genius! —— 成功标记 + if ("genius!".equalsIgnoreCase(respText)) { + RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.FAILED.getCode(), Duration.ofSeconds(20)); + log.info("设备 {} 发送消息完成", ctx.getDeviceImei()); + return; + } + // 2. 数字 —— 下发数据块 + int blockIndex; + try { + blockIndex = Integer.parseInt(respText); + } catch (NumberFormatException ex) { + log.warn("设备 {} 消息上报非法块号:{}", ctx.getDeviceImei(), respText); + return; + } + // 将发送的信息原文本以List形式存储在Redis中 + List data = RedisUtils.getCacheList(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + ctx.getDeviceImei() + ":app_send_message_data"); + if (data.isEmpty()) { + return; + } + // + ArrayList intData = new ArrayList<>(); + intData.add(blockIndex); + // 获取块原内容 转成GBK 再转成无符号十进制整数 + String blockTxt = data.get(blockIndex-1); + // 再按 GBK 编码把字符串转成字节数组,并逐个转为无符号十进制整数 + for (byte b : blockTxt.getBytes(GBK)) { + intData.add(b & 0xFF); // b & 0xFF 得到 0~255 的整数 + } + + Map map = new HashMap<>(); + map.put("ins_TexTrans", intData); + + String topic = MqttConstants.GLOBAL_PUB_KEY + ctx.getDeviceImei(); + String json = JsonUtils.toJsonString(map); + mqttGateway.sendMsgToMqtt(topic, 1, json); + log.info("发送设备信息数据到设备消息=>topic:{},payload:{}", + MqttConstants.GLOBAL_PUB_KEY + ctx.getDeviceImei(), + JsonUtils.toJsonString(map)); + + } catch (Exception e) { + log.error("处理发送设备信息时出错", e); + RedisUtils.setCacheObject(functionAccess, FunctionAccessStatus.FAILED.getCode(), Duration.ofSeconds(20)); + } + } + + private static final Charset GBK = Charset.forName("GBK"); + + /* ---------- DTO ---------- */ + + @Data + private static class MqttXinghanMsgJson { + /** + * 设备上行: + * 数字 -> 请求对应块号 + * genius! -> 写入成功 + */ + @JsonProperty("sta_TexTrans") + private String staTexTrans; + } +} diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceXinghanBizService.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceXinghanBizService.java new file mode 100644 index 00000000..40c2d7af --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceXinghanBizService.java @@ -0,0 +1,269 @@ +package com.fuyuanshen.web.service.device; + +import com.alibaba.fastjson2.JSON; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.fuyuanshen.app.domain.AppPersonnelInfo; +import com.fuyuanshen.app.domain.bo.AppPersonnelInfoBo; +import com.fuyuanshen.app.domain.dto.AppDeviceLogoUploadDto; +import com.fuyuanshen.app.domain.dto.DeviceInstructDto; +import com.fuyuanshen.app.domain.vo.AppPersonnelInfoVo; +import com.fuyuanshen.app.mapper.AppPersonnelInfoMapper; +import com.fuyuanshen.common.core.constant.GlobalConstants; +import com.fuyuanshen.common.core.exception.ServiceException; +import com.fuyuanshen.common.core.utils.ImageToCArrayConverter; +import com.fuyuanshen.common.core.utils.MapstructUtils; +import com.fuyuanshen.common.core.utils.ObjectUtils; +import com.fuyuanshen.common.core.utils.StringUtils; +import com.fuyuanshen.common.json.utils.JsonUtils; +import com.fuyuanshen.common.redis.utils.RedisUtils; +import com.fuyuanshen.common.satoken.utils.AppLoginHelper; +import com.fuyuanshen.equipment.domain.Device; +import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo; +import com.fuyuanshen.equipment.enums.LightModeEnum; +import com.fuyuanshen.equipment.mapper.DeviceLogMapper; +import com.fuyuanshen.equipment.mapper.DeviceMapper; +import com.fuyuanshen.equipment.mapper.DeviceTypeMapper; +import com.fuyuanshen.global.mqtt.config.MqttGateway; +import com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants; +import com.fuyuanshen.global.mqtt.constants.MqttConstants; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.time.Duration; +import java.util.*; + +import static com.fuyuanshen.common.core.constant.GlobalConstants.GLOBAL_REDIS_KEY; +import static com.fuyuanshen.common.core.utils.Bitmap80x12Generator.buildArr; +import static com.fuyuanshen.common.core.utils.Bitmap80x12Generator.generateFixedBitmapData; +import static com.fuyuanshen.common.core.utils.ImageToCArrayConverter.convertHexToDecimal; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_BOOT_LOGO_KEY_PREFIX; +import static com.fuyuanshen.global.mqtt.constants.DeviceRedisKeyConstants.DEVICE_KEY_PREFIX; + +@Slf4j +@Service +@RequiredArgsConstructor +public class DeviceXinghanBizService { + + private final DeviceMapper deviceMapper; + private final AppPersonnelInfoMapper appPersonnelInfoMapper; + private final DeviceTypeMapper deviceTypeMapper; + private final MqttGateway mqttGateway; + private final DeviceLogMapper deviceLogMapper; + + /** + * 所有档位的描述表 + * key : 指令类型,如 "ins_DetectGrade"、"ins_LightGrade" …… + * value : Map 值 -> 描述 + */ + private static final Map> GRADE_DESC = Map.of( + "ins_DetectGrade", Map.of(1, "低档", 2, "中档", 3, "高档"), + "ins_LightGrade", Map.of(1, "强光", 2, "弱光"), + "ins_SOSGrade", Map.of(1, "爆闪模式", 2, "红蓝模式"), + "ins_ShakeBit", Map.of(0, "未静止报警", 1, "正在静止报警") + // 再加 4、5、6…… 档,直接往 Map 里塞即可 + ); + + /** + * 根据指令类型和值,返回中文描述 + */ + private static String resolveGradeDesc(String type, int value) { + return GRADE_DESC.getOrDefault(type, Map.of()) + .getOrDefault(value, "关闭"); + } + + /** + * 设置静电预警档位 + */ + public void upDetectGradeSettings(DeviceInstructDto dto) { + sendCommand(dto, "ins_DetectGrade","静电预警档位"); + } + + /** + * 设置照明档位 + */ + public void upLightGradeSettings(DeviceInstructDto dto) { + sendCommand(dto, "ins_LightGrade","照明档位"); + } + + /** + * 设置SOS档位 + */ + public void upSOSGradeSettings(DeviceInstructDto dto) { + sendCommand(dto, "ins_SOSGrade","SOS档位"); + } + + /** + * 设置强制报警 + */ + public void upShakeBitSettings(DeviceInstructDto dto) { + sendCommand(dto, "ins_ShakeBit","强制报警"); + } + + /** + * 上传设备logo + */ + public void uploadDeviceLogo(AppDeviceLogoUploadDto bo) { + try { + Device device = deviceMapper.selectById(bo.getDeviceId()); + if (device == null) { + throw new ServiceException("设备不存在"); + } + if (isDeviceOffline(device.getDeviceImei())) { + throw new ServiceException("设备已断开连接:" + device.getDeviceName()); + } + MultipartFile file = bo.getFile(); + + byte[] largeData = ImageToCArrayConverter.convertImageToCArray(file.getInputStream(), 160, 80, 25600); + log.info("长度:" + largeData.length); + + log.info("原始数据大小: {} 字节", largeData.length); + + int[] ints = convertHexToDecimal(largeData); + RedisUtils.setCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + device.getDeviceImei() +DEVICE_BOOT_LOGO_KEY_PREFIX, Arrays.toString(ints), Duration.ofSeconds(5 * 60L)); + + Map payload = Map.of("ins_PicTrans", + Collections.singletonList(0)); + String topic = MqttConstants.GLOBAL_PUB_KEY + device.getDeviceImei(); + String json = JsonUtils.toJsonString(payload); + + try { + mqttGateway.sendMsgToMqtt(topic, 1, json); + } catch (Exception e) { + log.error("上传开机画面失败, topic={}, payload={}", topic, json, e); + throw new ServiceException("上传LOGO失败:" + e.getMessage()); + } + log.info("发送上传开机画面到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),json); + + recordDeviceLog(device.getId(), device.getDeviceName(), "上传开机画面", "上传开机画面", AppLoginHelper.getUserId()); + } catch (Exception e){ + throw new ServiceException("发送指令失败"); + } + } + + /** + * 人员登记 + * @param bo + */ + public boolean registerPersonInfo(AppPersonnelInfoBo bo) { + Long deviceId = bo.getDeviceId(); + Device deviceObj = deviceMapper.selectById(deviceId); + if (deviceObj == null) { + throw new RuntimeException("请先将设备入库!!!"); + } + if (isDeviceOffline(deviceObj.getDeviceImei())) { + throw new ServiceException("设备已断开连接:" + deviceObj.getDeviceName()); + } + QueryWrapper qw = new QueryWrapper() + .eq("device_id", deviceId); + List appPersonnelInfoVos = appPersonnelInfoMapper.selectVoList(qw); + + List list = new ArrayList<>(); + list.add(bo.getUnitName()); + list.add(bo.getName()); + list.add(bo.getPosition()); + list.add(bo.getCode()); + RedisUtils.setCacheList(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX + deviceObj.getDeviceImei() + ":app_send_message_data", list); + + Map payload = Map.of("ins_TexTrans", + Collections.singletonList(0)); + String topic = MqttConstants.GLOBAL_PUB_KEY + deviceObj.getDeviceImei(); + String json = JsonUtils.toJsonString(payload); + + try { + mqttGateway.sendMsgToMqtt(topic, 1, json); + } catch (Exception e) { + log.error("人员信息登记失败, topic={}, payload={}", topic, json, e); + throw new ServiceException("人员信息登记失败:" + e.getMessage()); + } + log.info("发送人员信息登记到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY + deviceObj.getDeviceImei(), bo); + + recordDeviceLog(deviceId, deviceObj.getDeviceName(), "人员信息登记", JSON.toJSONString(bo), AppLoginHelper.getUserId()); + if (ObjectUtils.length(appPersonnelInfoVos) == 0) { + AppPersonnelInfo appPersonnelInfo = MapstructUtils.convert(bo, AppPersonnelInfo.class); + return appPersonnelInfoMapper.insertOrUpdate(appPersonnelInfo); + } else { + UpdateWrapper uw = new UpdateWrapper<>(); + uw.eq("device_id", deviceId) + .set("name", bo.getName()) + .set("position", bo.getPosition()) + .set("unit_name", bo.getUnitName()) + .set("code", bo.getCode()); + return appPersonnelInfoMapper.update(null, uw) > 0; + } + } + + /* ---------------------------------- 私有通用方法 ---------------------------------- */ + + private void sendCommand(DeviceInstructDto dto, + String payloadKey,String deviceAction) { + long deviceId = dto.getDeviceId(); + Device device = deviceMapper.selectById(deviceId); + if (device == null) { + throw new ServiceException("设备不存在"); + } + if (isDeviceOffline(device.getDeviceImei())) { + throw new ServiceException("设备已断开连接:" + device.getDeviceName()); + } + + Integer value = Integer.parseInt(dto.getInstructValue()); + + Map payload = Map.of(payloadKey, + Collections.singletonList(value)); + + String topic = MqttConstants.GLOBAL_PUB_KEY + device.getDeviceImei(); + String json = JsonUtils.toJsonString(payload); + + try { + mqttGateway.sendMsgToMqtt(topic, 1, json); + } catch (Exception e) { + log.error("发送指令失败, topic={}, payload={}", topic, json, e); + throw new ServiceException("发送指令失败:" + e.getMessage()); + } + + log.info("发送指令成功 => topic:{}, payload:{}", topic, json); + String content = resolveGradeDesc("ins_DetectGrade", value); + recordDeviceLog(device.getId(), + device.getDeviceName(), + deviceAction, + content, + AppLoginHelper.getUserId()); + } + + private boolean isDeviceOffline(String imei) { + // 原方法名语义相反,这里取反,使含义更清晰 + return getDeviceStatus(imei); + } + + /** + * 记录设备操作日志 + * @param deviceId 设备ID + * @param content 日志内容 + * @param operator 操作人 + */ + private void recordDeviceLog(Long deviceId,String deviceName, String deviceAction, String content, Long operator) { + try { + // 创建设备日志实体 + com.fuyuanshen.equipment.domain.DeviceLog deviceLog = new com.fuyuanshen.equipment.domain.DeviceLog(); + deviceLog.setDeviceId(deviceId); + deviceLog.setDeviceAction(deviceAction); + deviceLog.setContent(content); + deviceLog.setCreateBy(operator); + deviceLog.setDeviceName(deviceName); + deviceLog.setCreateTime(new Date()); + + // 插入日志记录 + deviceLogMapper.insert(deviceLog); + } catch (Exception e) { + log.error("记录设备操作日志失败: {}", e.getMessage(), e); + } + } + + private boolean getDeviceStatus(String deviceImei) { + String deviceOnlineStatusRedisKey = GlobalConstants.GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ deviceImei + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX ; + return StringUtils.isBlank(deviceOnlineStatusRedisKey); + } + +} From 8811c30a9730cfe07b0856507436735c5869fec0 Mon Sep 17 00:00:00 2001 From: chenyouting <514333061@qq.com> Date: Sat, 23 Aug 2025 16:39:30 +0800 Subject: [PATCH 43/47] =?UTF-8?q?web=E7=AB=AF=E6=8E=A7=E5=88=B6=E4=B8=AD?= =?UTF-8?q?=E5=BF=832?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/controller/device/TestController.java | 47 ++++ .../domain/dto/AppDeviceLogoUploadDto.java | 1 + .../device/DeviceBJQController.java | 2 +- .../device/DeviceControlCenterController.java | 222 +++++------------- .../device/WEBDeviceController.java | 61 +---- .../service/device/DeviceBJQBizService.java | 63 ++++- .../web/service/device/DeviceBizService.java | 42 ++++ .../core/utils/ImageToCArrayConverter.java | 18 ++ .../AppPersonnelInfoRecordsController.java | 105 +++++++++ .../app/domain/AppPersonnelInfoRecords.java | 66 ++++++ .../domain/bo/AppPersonnelInfoRecordsBo.java | 67 ++++++ .../domain/vo/AppPersonnelInfoRecordsVo.java | 80 +++++++ .../mapper/AppPersonnelInfoRecordsMapper.java | 15 ++ .../IAppPersonnelInfoRecordsService.java | 68 ++++++ .../AppPersonnelInfoRecordsServiceImpl.java | 138 +++++++++++ .../app/AppPersonnelInfoRecordsMapper.xml | 7 + .../domain/query/DeviceQueryCriteria.java | 6 + .../equipment/domain/vo/WebDeviceVo.java | 95 ++++++++ .../equipment/mapper/DeviceMapper.java | 3 + .../mapper/equipment/DeviceMapper.xml | 41 ++++ 20 files changed, 914 insertions(+), 233 deletions(-) create mode 100644 fys-admin/src/main/java/com/fuyuanshen/app/controller/device/TestController.java create mode 100644 fys-modules/fys-app/src/main/java/com/fuyuanshen/app/controller/AppPersonnelInfoRecordsController.java create mode 100644 fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/AppPersonnelInfoRecords.java create mode 100644 fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/bo/AppPersonnelInfoRecordsBo.java create mode 100644 fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppPersonnelInfoRecordsVo.java create mode 100644 fys-modules/fys-app/src/main/java/com/fuyuanshen/app/mapper/AppPersonnelInfoRecordsMapper.java create mode 100644 fys-modules/fys-app/src/main/java/com/fuyuanshen/app/service/IAppPersonnelInfoRecordsService.java create mode 100644 fys-modules/fys-app/src/main/java/com/fuyuanshen/app/service/impl/AppPersonnelInfoRecordsServiceImpl.java create mode 100644 fys-modules/fys-app/src/main/resources/mapper/app/AppPersonnelInfoRecordsMapper.xml create mode 100644 fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/WebDeviceVo.java diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/TestController.java b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/TestController.java new file mode 100644 index 00000000..a9afd170 --- /dev/null +++ b/fys-admin/src/main/java/com/fuyuanshen/app/controller/device/TestController.java @@ -0,0 +1,47 @@ +package com.fuyuanshen.app.controller.device; + +import com.fuyuanshen.app.domain.bo.AppPersonnelInfoBo; +import com.fuyuanshen.app.domain.dto.AppDeviceLogoUploadDto; +import com.fuyuanshen.app.domain.dto.DeviceInstructDto; +import com.fuyuanshen.app.domain.vo.AppDeviceDetailVo; +import com.fuyuanshen.common.core.domain.R; +import com.fuyuanshen.common.core.validate.AddGroup; +import com.fuyuanshen.common.ratelimiter.annotation.FunctionAccessAnnotation; +import com.fuyuanshen.common.ratelimiter.annotation.FunctionAccessBatcAnnotation; +import com.fuyuanshen.common.web.core.BaseController; +import com.fuyuanshen.equipment.domain.dto.AppDeviceSendMsgBo; +import com.fuyuanshen.web.service.device.DeviceBJQBizService; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +/** + * BJQ6170设备控制类 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/test") +public class TestController extends BaseController { + + private final DeviceBJQBizService appDeviceService; + + /** + * 上传设备logo图片 + */ + @PostMapping("/uploadLogo") + @FunctionAccessAnnotation("uploadLogo") + public R upload(@Validated @ModelAttribute AppDeviceLogoUploadDto bo) { + + MultipartFile file = bo.getFile(); + if(file.getSize()>1024*1024*2){ + return R.warn("图片不能大于2M"); + } + appDeviceService.uploadDeviceLogo2(bo); + + return R.ok(); + } + +} diff --git a/fys-admin/src/main/java/com/fuyuanshen/app/domain/dto/AppDeviceLogoUploadDto.java b/fys-admin/src/main/java/com/fuyuanshen/app/domain/dto/AppDeviceLogoUploadDto.java index 26db3c16..1841dadb 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/app/domain/dto/AppDeviceLogoUploadDto.java +++ b/fys-admin/src/main/java/com/fuyuanshen/app/domain/dto/AppDeviceLogoUploadDto.java @@ -14,4 +14,5 @@ public class AppDeviceLogoUploadDto { */ private MultipartFile file; + private Integer chunkSize; } diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceBJQController.java b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceBJQController.java index d42d5223..e0536306 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceBJQController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceBJQController.java @@ -18,7 +18,7 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; /** - * BJQ6170设备控制类 + * web后台:设备控制类 */ @Validated @RequiredArgsConstructor diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceControlCenterController.java b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceControlCenterController.java index 13b34712..76e39357 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceControlCenterController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/DeviceControlCenterController.java @@ -1,9 +1,22 @@ package com.fuyuanshen.web.controller.device; +import com.fuyuanshen.app.domain.dto.APPReNameDTO; +import com.fuyuanshen.app.domain.dto.AppRealTimeStatusDto; +import com.fuyuanshen.app.domain.vo.APPDeviceTypeVo; +import com.fuyuanshen.common.core.domain.R; +import com.fuyuanshen.common.mybatis.core.page.PageQuery; +import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; +import com.fuyuanshen.common.web.core.BaseController; +import com.fuyuanshen.equipment.domain.dto.AppDeviceBo; +import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria; +import com.fuyuanshen.equipment.domain.vo.AppDeviceVo; +import com.fuyuanshen.equipment.domain.vo.WebDeviceVo; +import com.fuyuanshen.web.service.device.DeviceBizService; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.util.Date; @@ -12,199 +25,74 @@ import java.util.List; import java.util.Map; /** - * @author: 默苍璃 - * @date: 2025-08-0810:40 + * web后台:设备控制中心 */ @Slf4j -@Tag(name = "web后台:设备控制中心", description = "web后台:设备控制中心") @RestController @RequiredArgsConstructor @RequestMapping("/api/device/controlCenter") -public class DeviceControlCenterController { +public class DeviceControlCenterController extends BaseController { + private final DeviceBizService appDeviceService; /** - * 获取设备基本信息 - * @param deviceId 设备ID - * @return 设备基本信息 + * 查询设备列表 */ - @GetMapping("/info/{deviceId}") - public ResponseEntity> getDeviceInfo(@PathVariable String deviceId) { - // 实际应用中这里会从数据库查询设备信息 - Map deviceInfo = new HashMap<>(); - deviceInfo.put("deviceName", "6170零零一"); - deviceInfo.put("deviceModel", "BJQ6170"); - deviceInfo.put("deviceId", deviceId); - deviceInfo.put("status", "在线"); - deviceInfo.put("batteryLevel", 85); - - return ResponseEntity.ok(deviceInfo); + @GetMapping("/list") + public TableDataInfo list(DeviceQueryCriteria bo, PageQuery pageQuery) { + return appDeviceService.queryWebDeviceList(bo, pageQuery); } /** - * 设置灯光模式 - * @param lightModeRequest 灯光模式请求 - * @return 操作结果 + * 绑定设备 */ - @PostMapping("/light-mode") - public ResponseEntity> setLightMode(@RequestBody LightModeRequest lightModeRequest) { - // 实际应用中这里会控制设备灯光 - Map response = new HashMap<>(); - response.put("code", 200); - // response.put("message", "灯光模式已设置为: " + lightModeRequest.getMode()); - // response.put("deviceId", lightModeRequest.getDeviceId()); - // response.put("mode", lightModeRequest.getMode()); + @PostMapping("/bind") + public R bind(@RequestBody AppDeviceBo bo) { + return toAjax(appDeviceService.bindDevice(bo)); + } - return ResponseEntity.ok(response); + + /** + * 解绑设备 + */ + @DeleteMapping("/unBind") + public R unBind(Long id) { + return toAjax(appDeviceService.unBindDevice(id)); } /** - * 更新人员信息 - * @param personInfo 人员信息 - * @return 操作结果 + * 查询设备类型列表 */ - @PostMapping("/person-info") - public ResponseEntity> updatePersonInfo(@RequestBody PersonInfo personInfo) { - // 实际应用中这里会更新数据库 - Map response = new HashMap<>(); - response.put("code", 200); - response.put("message", "人员信息已更新"); - // response.put("unit", personInfo.getUnit()); - // response.put("position", personInfo.getPosition()); - - return ResponseEntity.ok(response); + @GetMapping(value = "/typeList") + public R> getTypeList() { + List typeList = appDeviceService.getTypeList(); + return R.ok(typeList); } /** - * 管理开机画面内容 - * @param bootScreenRequest 开机画面请求 - * @return 操作结果 + * 重命名设备 + * + * @param reNameDTO + * @return */ - @PostMapping("/boot-screen") - public ResponseEntity> manageBootScreen(@RequestBody BootScreenRequest bootScreenRequest) { - // 实际应用中这里会更新设备开机画面 - Map response = new HashMap<>(); - response.put("code", 200); - response.put("message", "开机画面内容已更新"); - // response.put("deviceId", bootScreenRequest.getDeviceId()); - // response.put("screens", bootScreenRequest.getScreens()); + @PostMapping(value = "/reName") + public R reName(@Validated @RequestBody APPReNameDTO reNameDTO) { + appDeviceService.reName(reNameDTO); + return R.ok("重命名成功!!!"); + } - return ResponseEntity.ok(response); + + @GetMapping("/realTimeStatus") + public R> getRealTimeStatus(AppRealTimeStatusDto statusDto) { + Map status = appDeviceService.getRealTimeStatus(statusDto); + return R.ok(status); } /** - * 设置灯光亮度 - * @param brightnessRequest 亮度请求 - * @return 操作结果 + * 根据mac查询设备信息 */ - @PostMapping("/brightness") - public ResponseEntity> setBrightness(@RequestBody BrightnessRequest brightnessRequest) { - // 实际应用中这里会控制设备亮度 - Map response = new HashMap<>(); - response.put("code", 200); - // response.put("message", "灯光亮度已设置为: " + brightnessRequest.getBrightness() + "%"); - // response.put("deviceId", brightnessRequest.getDeviceId()); - // response.put("brightness", brightnessRequest.getBrightness()); - // response.put("forceAlarm", brightnessRequest.isForceAlarm()); - - return ResponseEntity.ok(response); - } - - /** - * 获取设备位置信息 - * @param deviceId 设备ID - * @return 位置信息 - */ - @GetMapping("/location/{deviceId}") - public ResponseEntity> getLocation(@PathVariable String deviceId) { - // 实际应用中这里会从设备获取实时位置 - Map locationInfo = new HashMap<>(); - locationInfo.put("deviceId", deviceId); - locationInfo.put("longitude", "114°7'E"); - locationInfo.put("latitude", "30'28'N"); - locationInfo.put("address", "湖北省武汉市洪山区光谷大道国际企业中心"); - locationInfo.put("timestamp", new Date()); - - return ResponseEntity.ok(locationInfo); - } - - /** - * 发送紧急消息 - * @param messageRequest 消息请求 - * @return 操作结果 - */ - @PostMapping("/send-message") - public ResponseEntity> sendMessage(@RequestBody MessageRequest messageRequest) { - // 实际应用中这里会向设备发送消息 - Map response = new HashMap<>(); - response.put("code", 200); - response.put("message", "消息已发送"); - // response.put("deviceId", messageRequest.getDeviceId()); - // response.put("content", messageRequest.getContent()); - response.put("timestamp", new Date()); - - return ResponseEntity.ok(response); - } - - /** - * 管理操作视频 - * @param videoRequest 视频请求 - * @return 操作结果 - */ - @PostMapping("/operation-video") - public ResponseEntity> manageOperationVideo(@RequestBody VideoRequest videoRequest) { - // 实际应用中这里会更新设备操作视频 - Map response = new HashMap<>(); - response.put("code", 200); - response.put("message", "操作视频已更新"); - // response.put("deviceId", videoRequest.getDeviceId()); - // response.put("videoUrl", videoRequest.getVideoUrl()); - - return ResponseEntity.ok(response); - } - - // 请求对象类定义 - public static class LightModeRequest { - private String deviceId; - private String mode; // 强光、弱光、爆闪、泛光、激光 - - // Getters and Setters - } - - public static class PersonInfo { - private String deviceId; - private String unit; // 单位 - private String position; // 职位 - - // Getters and Setters - } - - public static class BootScreenRequest { - private String deviceId; - private List screens; // 产品参数、操作说明等 - - // Getters and Setters - } - - public static class BrightnessRequest { - private String deviceId; - private int brightness; // 0-100 - private boolean forceAlarm; // 强制报警 - - // Getters and Setters - } - - public static class MessageRequest { - private String deviceId; - private String content; // 消息内容 - - // Getters and Setters - } - - public static class VideoRequest { - private String deviceId; - private String videoUrl; // 视频链接 - - // Getters and Setters + @GetMapping("/getDeviceInfoByDeviceMac") + public R getDeviceInfo(String deviceMac) { + return R.ok(appDeviceService.getDeviceInfo(deviceMac)); } } diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java index 71be5103..4519b2e7 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java @@ -36,7 +36,7 @@ import java.util.Map; public class WEBDeviceController extends BaseController { private final WEBDeviceService deviceService; - private final DeviceBizService appDeviceService; + /** @@ -53,66 +53,7 @@ public class WEBDeviceController extends BaseController { } - /** - * 查询设备列表 - */ - @GetMapping("/list") - public TableDataInfo list(DeviceQueryCriteria bo, PageQuery pageQuery) { - return appDeviceService.queryAppDeviceList(bo, pageQuery); - } - /** - * 绑定设备 - */ - @PostMapping("/bind") - public R bind(@RequestBody AppDeviceBo bo) { - return toAjax(appDeviceService.bindDevice(bo)); - } - - - /** - * 解绑设备 - */ - @DeleteMapping("/unBind") - public R unBind(Long id) { - return toAjax(appDeviceService.unBindDevice(id)); - } - - /** - * 查询设备类型列表 - */ - @GetMapping(value = "/typeList") - public R> getTypeList() { - List typeList = appDeviceService.getTypeList(); - return R.ok(typeList); - } - - /** - * 重命名设备 - * - * @param reNameDTO - * @return - */ - @PostMapping(value = "/reName") - public R reName(@Validated @RequestBody APPReNameDTO reNameDTO) { - appDeviceService.reName(reNameDTO); - return R.ok("重命名成功!!!"); - } - - - @GetMapping("/realTimeStatus") - public R> getRealTimeStatus(AppRealTimeStatusDto statusDto) { - Map status = appDeviceService.getRealTimeStatus(statusDto); - return R.ok(status); - } - - /** - * 根据mac查询设备信息 - */ - @GetMapping("/getDeviceInfoByDeviceMac") - public R getDeviceInfo(String deviceMac) { - return R.ok(appDeviceService.getDeviceInfo(deviceMac)); - } } diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java index 60c80d70..9ee8236e 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBJQBizService.java @@ -1,16 +1,19 @@ package com.fuyuanshen.web.service.device; +import cn.hutool.core.bean.BeanUtil; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.fuyuanshen.app.domain.AppPersonnelInfo; +import com.fuyuanshen.app.domain.AppPersonnelInfoRecords; import com.fuyuanshen.app.domain.bo.AppPersonnelInfoBo; import com.fuyuanshen.app.domain.dto.AppDeviceLogoUploadDto; import com.fuyuanshen.app.domain.dto.DeviceInstructDto; import com.fuyuanshen.app.domain.vo.AppDeviceDetailVo; import com.fuyuanshen.app.domain.vo.AppPersonnelInfoVo; import com.fuyuanshen.app.mapper.AppPersonnelInfoMapper; +import com.fuyuanshen.app.mapper.AppPersonnelInfoRecordsMapper; import com.fuyuanshen.common.core.constant.GlobalConstants; import com.fuyuanshen.common.core.exception.ServiceException; import com.fuyuanshen.common.core.utils.*; @@ -50,6 +53,7 @@ public class DeviceBJQBizService { private final DeviceMapper deviceMapper; private final AppPersonnelInfoMapper appPersonnelInfoMapper; + private final AppPersonnelInfoRecordsMapper appPersonnelInfoRecordsMapper; private final DeviceTypeMapper deviceTypeMapper; private final MqttGateway mqttGateway; private final DeviceLogMapper deviceLogMapper; @@ -242,11 +246,18 @@ public class DeviceBJQBizService { map.put("instruct", intData); mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY + deviceObj.getDeviceImei(), 1, JSON.toJSONString(map)); log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY + deviceObj.getDeviceImei(), bo); - - recordDeviceLog(deviceId, deviceObj.getDeviceName(), "人员信息登记", JSON.toJSONString(bo), AppLoginHelper.getUserId()); + String logContent = "单位:"+bo.getUnitName()+",职位:"+bo.getPosition()+",姓名:"+bo.getName()+",ID:"+bo.getCode(); + recordDeviceLog(deviceId, deviceObj.getDeviceName(), "人员信息登记", logContent, AppLoginHelper.getUserId()); if (ObjectUtils.length(appPersonnelInfoVos) == 0) { AppPersonnelInfo appPersonnelInfo = MapstructUtils.convert(bo, AppPersonnelInfo.class); - return appPersonnelInfoMapper.insertOrUpdate(appPersonnelInfo); + appPersonnelInfoMapper.insertOrUpdate(appPersonnelInfo); + + AppPersonnelInfoRecords appPersonnelInfoRecords = new AppPersonnelInfoRecords(); + BeanUtil.copyProperties(appPersonnelInfo, appPersonnelInfoRecords); + appPersonnelInfoRecords.setId(null); + appPersonnelInfoRecords.setPersonnelId(appPersonnelInfo.getId()); + + appPersonnelInfoRecordsMapper.insert(appPersonnelInfoRecords); } else { UpdateWrapper uw = new UpdateWrapper<>(); uw.eq("device_id", deviceId) @@ -254,10 +265,52 @@ public class DeviceBJQBizService { .set("position", bo.getPosition()) .set("unit_name", bo.getUnitName()) .set("code", bo.getCode()); - return appPersonnelInfoMapper.update(null, uw) > 0; + appPersonnelInfoMapper.update(null, uw); + + AppPersonnelInfoVo personnelInfoVo = appPersonnelInfoVos.get(0); + AppPersonnelInfo appPersonnelInfo = MapstructUtils.convert(bo, AppPersonnelInfo.class); + AppPersonnelInfoRecords appPersonnelInfoRecords = new AppPersonnelInfoRecords(); + BeanUtil.copyProperties(appPersonnelInfo, appPersonnelInfoRecords); + appPersonnelInfoRecords.setId(null); + appPersonnelInfoRecords.setPersonnelId(personnelInfoVo.getId()); + appPersonnelInfoRecordsMapper.insert(appPersonnelInfoRecords); + } + return true; + } + public void uploadDeviceLogo2(AppDeviceLogoUploadDto bo) { + try { + Device device = deviceMapper.selectById(bo.getDeviceId()); + if (device == null) { + throw new ServiceException("设备不存在"); + } + MultipartFile file = bo.getFile(); + + byte[] largeData = ImageToCArrayConverter.convertImageToCArray(file.getInputStream(), 160, 80, 25600); + + log.info("长度:" + largeData.length); + // 在获取 largeData 后,将其与前缀合并 + byte[] prefix = new byte[]{0x50, 0x49, 0x43, 0x54, 0x55, 0x52, 0x45}; // "PICTURE" + byte[] combinedData = new byte[prefix.length + largeData.length]; + System.arraycopy(prefix, 0, combinedData, 0, prefix.length); + System.arraycopy(largeData, 0, combinedData, prefix.length, largeData.length); + + // 将 combinedData 转换为十六进制表示 + String[] hexArray = new String[combinedData.length]; + for (int i = 0; i < combinedData.length; i++) { + hexArray[i] = String.format("0x%02X", combinedData[i]); + } +// Map map = new HashMap<>(); +// map.put("instruct", combinedData); + String[] specificChunk = ImageToCArrayConverter.getChunk2(hexArray, 0, bo.getChunkSize()); + mqttGateway.sendMsgToMqtt(MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(), 1 , Arrays.toString(specificChunk)); + log.info("发送点阵数据到设备消息=>topic:{},payload:{}", MqttConstants.GLOBAL_PUB_KEY+device.getDeviceImei(),Arrays.toString(specificChunk)); + + recordDeviceLog(device.getId(), device.getDeviceName(), "上传开机画面", "上传开机画面", AppLoginHelper.getUserId()); + } catch (Exception e){ + e.printStackTrace(); + throw new ServiceException("发送指令失败"); } } - public void uploadDeviceLogo(AppDeviceLogoUploadDto bo) { try { Device device = deviceMapper.selectById(bo.getDeviceId()); diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBizService.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBizService.java index 3c0d9be8..90114467 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBizService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/device/DeviceBizService.java @@ -28,6 +28,7 @@ import com.fuyuanshen.equipment.domain.Device; import com.fuyuanshen.equipment.domain.dto.AppDeviceBo; import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria; import com.fuyuanshen.equipment.domain.vo.AppDeviceVo; +import com.fuyuanshen.equipment.domain.vo.WebDeviceVo; import com.fuyuanshen.equipment.enums.BindingStatusEnum; import com.fuyuanshen.equipment.enums.CommunicationModeEnum; import com.fuyuanshen.equipment.mapper.DeviceLogMapper; @@ -123,6 +124,47 @@ public class DeviceBizService { return TableDataInfo.build(result); } + public TableDataInfo queryWebDeviceList(DeviceQueryCriteria bo, PageQuery pageQuery) { + Page result = deviceMapper.queryWebDeviceList(pageQuery.build(), bo); + List records = result.getRecords(); + if(records != null && !records.isEmpty()){ + records.forEach(item -> { + if(item.getCommunicationMode()!=null && item.getCommunicationMode() == 0){ + + //设备在线状态 + String onlineStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY+ DEVICE_KEY_PREFIX+ item.getDeviceImei() + DeviceRedisKeyConstants.DEVICE_ONLINE_STATUS_KEY_PREFIX); + if(StringUtils.isNotBlank(onlineStatus)){ + + item.setOnlineStatus(1); + }else{ + item.setOnlineStatus(0); + } + String deviceStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY + DEVICE_KEY_PREFIX+ item.getDeviceImei() + DEVICE_STATUS_KEY_PREFIX); + // 获取电量 + if(StringUtils.isNotBlank(deviceStatus)){ + JSONObject jsonObject = JSONObject.parseObject(deviceStatus); + item.setBattery(jsonObject.getString("batteryPercentage")); + }else{ + item.setBattery("0"); + } + + String location = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY +DEVICE_KEY_PREFIX+ item.getDeviceImei()+ DEVICE_LOCATION_KEY_PREFIX); + if(StringUtils.isNotBlank(location)){ + JSONObject jsonObject = JSONObject.parseObject(location); + item.setLatitude(jsonObject.getString("latitude")); + item.setLongitude(jsonObject.getString("longitude")); + } + + String alarmStatus = RedisUtils.getCacheObject(GLOBAL_REDIS_KEY +DEVICE_KEY_PREFIX+ item.getDeviceImei()+ DEVICE_ALARM_KEY_PREFIX); + if(StringUtils.isNotBlank(alarmStatus)){ + item.setAlarmStatus(alarmStatus); + } + } + }); + } + return TableDataInfo.build(result); + } + public int bindDevice(AppDeviceBo bo) { Integer mode = bo.getCommunicationMode(); Long userId = AppLoginHelper.getUserId(); diff --git a/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/utils/ImageToCArrayConverter.java b/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/utils/ImageToCArrayConverter.java index 8823ad08..eedfead6 100644 --- a/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/utils/ImageToCArrayConverter.java +++ b/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/utils/ImageToCArrayConverter.java @@ -88,6 +88,24 @@ public class ImageToCArrayConverter { return chunk; } + public static String[] getChunk2(String[] data, int chunkIndex, int chunkSize) { + if (data == null || chunkSize <= 0 || chunkIndex < 0) { + return new String[0]; + } + + int start = chunkIndex * chunkSize; + if (start >= data.length) { + return new String[0]; // 索引超出范围 + } + + int end = Math.min(start + chunkSize, data.length); + int length = end - start; + + String[] chunk = new String[length]; + System.arraycopy(data, start, chunk, 0, length); + return chunk; + } + public static void buildArr(int[] data,List intData){ for (int datum : data) { intData.add(datum); diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/controller/AppPersonnelInfoRecordsController.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/controller/AppPersonnelInfoRecordsController.java new file mode 100644 index 00000000..b7f9dd62 --- /dev/null +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/controller/AppPersonnelInfoRecordsController.java @@ -0,0 +1,105 @@ +package com.fuyuanshen.app.controller; + +import java.util.List; + +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import com.fuyuanshen.common.idempotent.annotation.RepeatSubmit; +import com.fuyuanshen.common.log.annotation.Log; +import com.fuyuanshen.common.web.core.BaseController; +import com.fuyuanshen.common.mybatis.core.page.PageQuery; +import com.fuyuanshen.common.core.domain.R; +import com.fuyuanshen.common.core.validate.AddGroup; +import com.fuyuanshen.common.core.validate.EditGroup; +import com.fuyuanshen.common.log.enums.BusinessType; +import com.fuyuanshen.common.excel.utils.ExcelUtil; +import com.fuyuanshen.app.domain.vo.AppPersonnelInfoRecordsVo; +import com.fuyuanshen.app.domain.bo.AppPersonnelInfoRecordsBo; +import com.fuyuanshen.app.service.IAppPersonnelInfoRecordsService; +import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; + +/** + * 人员信息登记记录 + * + * @author CYT + * @date 2025-08-22 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/app/personnelInfoRecords") +public class AppPersonnelInfoRecordsController extends BaseController { + + private final IAppPersonnelInfoRecordsService appPersonnelInfoRecordsService; + + /** + * 查询人员信息登记记录列表 + */ + @SaCheckPermission("app:personnelInfoRecords:list") + @GetMapping("/list") + public TableDataInfo list(AppPersonnelInfoRecordsBo bo, PageQuery pageQuery) { + return appPersonnelInfoRecordsService.queryPageList(bo, pageQuery); + } + + /** + * 导出人员信息登记记录列表 + */ + @SaCheckPermission("app:personnelInfoRecords:export") + @Log(title = "人员信息登记记录", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(AppPersonnelInfoRecordsBo bo, HttpServletResponse response) { + List list = appPersonnelInfoRecordsService.queryList(bo); + ExcelUtil.exportExcel(list, "人员信息登记记录", AppPersonnelInfoRecordsVo.class, response); + } + + /** + * 获取人员信息登记记录详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("app:personnelInfoRecords:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(appPersonnelInfoRecordsService.queryById(id)); + } + + /** + * 新增人员信息登记记录 + */ + @SaCheckPermission("app:personnelInfoRecords:add") + @Log(title = "人员信息登记记录", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody AppPersonnelInfoRecordsBo bo) { + return toAjax(appPersonnelInfoRecordsService.insertByBo(bo)); + } + + /** + * 修改人员信息登记记录 + */ + @SaCheckPermission("app:personnelInfoRecords:edit") + @Log(title = "人员信息登记记录", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody AppPersonnelInfoRecordsBo bo) { + return toAjax(appPersonnelInfoRecordsService.updateByBo(bo)); + } + + /** + * 删除人员信息登记记录 + * + * @param ids 主键串 + */ + @SaCheckPermission("app:personnelInfoRecords:remove") + @Log(title = "人员信息登记记录", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(appPersonnelInfoRecordsService.deleteWithValidByIds(List.of(ids), true)); + } +} diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/AppPersonnelInfoRecords.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/AppPersonnelInfoRecords.java new file mode 100644 index 00000000..848bd37e --- /dev/null +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/AppPersonnelInfoRecords.java @@ -0,0 +1,66 @@ +package com.fuyuanshen.app.domain; + +import com.fuyuanshen.common.tenant.core.TenantEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; + +/** + * 人员信息登记记录对象 app_personnel_info_records + * + * @author CYT + * @date 2025-08-22 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("app_personnel_info_records") +public class AppPersonnelInfoRecords extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId(value = "id") + private Long id; + + /** + * 设备id + */ + private Long deviceId; + + /** + * 主键 + */ + private Long personnelId; + + /** + * 人员姓名 + */ + private String name; + + /** + * 职位 + */ + private String position; + + /** + * 单位名称 + */ + private String unitName; + + /** + * ID号 + */ + private String code; + + /** + * 发送信息 + */ + private String sendMsg; + + +} diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/bo/AppPersonnelInfoRecordsBo.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/bo/AppPersonnelInfoRecordsBo.java new file mode 100644 index 00000000..70e24269 --- /dev/null +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/bo/AppPersonnelInfoRecordsBo.java @@ -0,0 +1,67 @@ +package com.fuyuanshen.app.domain.bo; + +import com.fuyuanshen.app.domain.AppPersonnelInfoRecords; +import com.fuyuanshen.common.core.validate.AddGroup; +import com.fuyuanshen.common.core.validate.EditGroup; +import com.fuyuanshen.common.mybatis.core.domain.BaseEntity; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; + +/** + * 人员信息登记记录业务对象 app_personnel_info_records + * + * @author CYT + * @date 2025-08-22 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = AppPersonnelInfoRecords.class, reverseConvertGenerate = false) +public class AppPersonnelInfoRecordsBo extends BaseEntity { + + /** + * 主键 + */ + @NotNull(message = "主键不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * 设备id + */ + @NotNull(message = "设备id不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long deviceId; + + /** + * 主键 + */ + @NotNull(message = "主键不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long personnelId; + + /** + * 人员姓名 + */ + private String name; + + /** + * 职位 + */ + private String position; + + /** + * 单位名称 + */ + private String unitName; + + /** + * ID号 + */ + private String code; + + /** + * 发送信息 + */ + private String sendMsg; + + +} diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppPersonnelInfoRecordsVo.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppPersonnelInfoRecordsVo.java new file mode 100644 index 00000000..1d05a0ce --- /dev/null +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/domain/vo/AppPersonnelInfoRecordsVo.java @@ -0,0 +1,80 @@ +package com.fuyuanshen.app.domain.vo; + +import com.fuyuanshen.app.domain.AppPersonnelInfoRecords; +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import com.fuyuanshen.common.excel.annotation.ExcelDictFormat; +import com.fuyuanshen.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + + +/** + * 人员信息登记记录视图对象 app_personnel_info_records + * + * @author CYT + * @date 2025-08-22 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = AppPersonnelInfoRecords.class) +public class AppPersonnelInfoRecordsVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @ExcelProperty(value = "主键") + private Long id; + + /** + * 设备id + */ + @ExcelProperty(value = "设备id") + private Long deviceId; + + /** + * 主键 + */ + @ExcelProperty(value = "主键") + private Long personnelId; + + /** + * 人员姓名 + */ + @ExcelProperty(value = "人员姓名") + private String name; + + /** + * 职位 + */ + @ExcelProperty(value = "职位") + private String position; + + /** + * 单位名称 + */ + @ExcelProperty(value = "单位名称") + private String unitName; + + /** + * ID号 + */ + @ExcelProperty(value = "ID号") + private String code; + + /** + * 发送信息 + */ + @ExcelProperty(value = "发送信息") + private String sendMsg; + + +} diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/mapper/AppPersonnelInfoRecordsMapper.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/mapper/AppPersonnelInfoRecordsMapper.java new file mode 100644 index 00000000..bffca130 --- /dev/null +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/mapper/AppPersonnelInfoRecordsMapper.java @@ -0,0 +1,15 @@ +package com.fuyuanshen.app.mapper; + +import com.fuyuanshen.app.domain.AppPersonnelInfoRecords; +import com.fuyuanshen.app.domain.vo.AppPersonnelInfoRecordsVo; +import com.fuyuanshen.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 人员信息登记记录Mapper接口 + * + * @author CYT + * @date 2025-08-22 + */ +public interface AppPersonnelInfoRecordsMapper extends BaseMapperPlus { + +} diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/service/IAppPersonnelInfoRecordsService.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/service/IAppPersonnelInfoRecordsService.java new file mode 100644 index 00000000..a845a858 --- /dev/null +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/service/IAppPersonnelInfoRecordsService.java @@ -0,0 +1,68 @@ +package com.fuyuanshen.app.service; + +import com.fuyuanshen.app.domain.vo.AppPersonnelInfoRecordsVo; +import com.fuyuanshen.app.domain.bo.AppPersonnelInfoRecordsBo; +import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; +import com.fuyuanshen.common.mybatis.core.page.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 人员信息登记记录Service接口 + * + * @author CYT + * @date 2025-08-22 + */ +public interface IAppPersonnelInfoRecordsService { + + /** + * 查询人员信息登记记录 + * + * @param id 主键 + * @return 人员信息登记记录 + */ + AppPersonnelInfoRecordsVo queryById(Long id); + + /** + * 分页查询人员信息登记记录列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 人员信息登记记录分页列表 + */ + TableDataInfo queryPageList(AppPersonnelInfoRecordsBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的人员信息登记记录列表 + * + * @param bo 查询条件 + * @return 人员信息登记记录列表 + */ + List queryList(AppPersonnelInfoRecordsBo bo); + + /** + * 新增人员信息登记记录 + * + * @param bo 人员信息登记记录 + * @return 是否新增成功 + */ + Boolean insertByBo(AppPersonnelInfoRecordsBo bo); + + /** + * 修改人员信息登记记录 + * + * @param bo 人员信息登记记录 + * @return 是否修改成功 + */ + Boolean updateByBo(AppPersonnelInfoRecordsBo bo); + + /** + * 校验并批量删除人员信息登记记录信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/service/impl/AppPersonnelInfoRecordsServiceImpl.java b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/service/impl/AppPersonnelInfoRecordsServiceImpl.java new file mode 100644 index 00000000..b330ded9 --- /dev/null +++ b/fys-modules/fys-app/src/main/java/com/fuyuanshen/app/service/impl/AppPersonnelInfoRecordsServiceImpl.java @@ -0,0 +1,138 @@ +package com.fuyuanshen.app.service.impl; + +import com.fuyuanshen.common.core.utils.MapstructUtils; +import com.fuyuanshen.common.core.utils.StringUtils; +import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; +import com.fuyuanshen.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import com.fuyuanshen.app.domain.bo.AppPersonnelInfoRecordsBo; +import com.fuyuanshen.app.domain.vo.AppPersonnelInfoRecordsVo; +import com.fuyuanshen.app.domain.AppPersonnelInfoRecords; +import com.fuyuanshen.app.mapper.AppPersonnelInfoRecordsMapper; +import com.fuyuanshen.app.service.IAppPersonnelInfoRecordsService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 人员信息登记记录Service业务层处理 + * + * @author CYT + * @date 2025-08-22 + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class AppPersonnelInfoRecordsServiceImpl implements IAppPersonnelInfoRecordsService { + + private final AppPersonnelInfoRecordsMapper baseMapper; + + /** + * 查询人员信息登记记录 + * + * @param id 主键 + * @return 人员信息登记记录 + */ + @Override + public AppPersonnelInfoRecordsVo queryById(Long id){ + return baseMapper.selectVoById(id); + } + + /** + * 分页查询人员信息登记记录列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 人员信息登记记录分页列表 + */ + @Override + public TableDataInfo queryPageList(AppPersonnelInfoRecordsBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的人员信息登记记录列表 + * + * @param bo 查询条件 + * @return 人员信息登记记录列表 + */ + @Override + public List queryList(AppPersonnelInfoRecordsBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(AppPersonnelInfoRecordsBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.orderByAsc(AppPersonnelInfoRecords::getId); + lqw.eq(bo.getDeviceId() != null, AppPersonnelInfoRecords::getDeviceId, bo.getDeviceId()); + lqw.eq(bo.getPersonnelId() != null, AppPersonnelInfoRecords::getPersonnelId, bo.getPersonnelId()); + lqw.like(StringUtils.isNotBlank(bo.getName()), AppPersonnelInfoRecords::getName, bo.getName()); + lqw.eq(StringUtils.isNotBlank(bo.getPosition()), AppPersonnelInfoRecords::getPosition, bo.getPosition()); + lqw.like(StringUtils.isNotBlank(bo.getUnitName()), AppPersonnelInfoRecords::getUnitName, bo.getUnitName()); + lqw.eq(StringUtils.isNotBlank(bo.getCode()), AppPersonnelInfoRecords::getCode, bo.getCode()); + lqw.eq(StringUtils.isNotBlank(bo.getSendMsg()), AppPersonnelInfoRecords::getSendMsg, bo.getSendMsg()); + return lqw; + } + + /** + * 新增人员信息登记记录 + * + * @param bo 人员信息登记记录 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(AppPersonnelInfoRecordsBo bo) { + AppPersonnelInfoRecords add = MapstructUtils.convert(bo, AppPersonnelInfoRecords.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改人员信息登记记录 + * + * @param bo 人员信息登记记录 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(AppPersonnelInfoRecordsBo bo) { + AppPersonnelInfoRecords update = MapstructUtils.convert(bo, AppPersonnelInfoRecords.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(AppPersonnelInfoRecords entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除人员信息登记记录信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } +} diff --git a/fys-modules/fys-app/src/main/resources/mapper/app/AppPersonnelInfoRecordsMapper.xml b/fys-modules/fys-app/src/main/resources/mapper/app/AppPersonnelInfoRecordsMapper.xml new file mode 100644 index 00000000..28b50d97 --- /dev/null +++ b/fys-modules/fys-app/src/main/resources/mapper/app/AppPersonnelInfoRecordsMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceQueryCriteria.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceQueryCriteria.java index d8a9505e..caafe10f 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceQueryCriteria.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceQueryCriteria.java @@ -66,8 +66,14 @@ public class DeviceQueryCriteria extends BaseEntity { /* app绑定用户id */ private Long bindingUserId; + /** + * 使用人员 + */ + private String personnelBy; /* 是否为管理员 */ private Boolean isAdmin = false; + + } diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/WebDeviceVo.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/WebDeviceVo.java new file mode 100644 index 00000000..bcbc71a5 --- /dev/null +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/WebDeviceVo.java @@ -0,0 +1,95 @@ +package com.fuyuanshen.equipment.domain.vo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +@Data +public class WebDeviceVo implements Serializable { + + private Long id; + + /** + * 设备名称 + */ + private String deviceName; + + /** + * 设备IMEI + */ + private String deviceImei; + + /** + * 设备MAC + */ + private String deviceMac; + + /** + * 通讯方式 0:4G;1:蓝牙 + */ + private Integer communicationMode; + + /** + * 设备图片 + */ + private String devicePic; + + /** + * 设备类型 + */ + private String typeName; + + /** + * 蓝牙名称 + */ + private String bluetoothName; + + /** + * 使用人员 + */ + private String personnelBy; + + /** + * 设备状态 + * 0 失效 + * 1 正常 + */ + private Integer deviceStatus; + + /** + * 绑定时间 + */ + private Date bindingTime; + + /** + * 在线状态(0离线,1在线) + */ + private Integer onlineStatus; + + /** + * 电量 百分比 + */ + private String battery; + + /** + * 纬度 + */ + private String latitude; + + /** + * 经度 + */ + private String longitude; + + /** + * 告警状态(0解除告警,1告警) + */ + private String alarmStatus; + + /** + * 设备详情页面 + */ + private String detailPageUrl; + +} diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceMapper.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceMapper.java index 96bbfcef..39896531 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceMapper.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/mapper/DeviceMapper.java @@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fuyuanshen.equipment.domain.Device; import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria; import com.fuyuanshen.equipment.domain.vo.AppDeviceVo; +import com.fuyuanshen.equipment.domain.vo.WebDeviceVo; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -68,4 +69,6 @@ public interface DeviceMapper extends BaseMapper { List findByOriginalDeviceId(Long originalDeviceId); AppDeviceVo getDeviceInfo(@Param("deviceMac") String deviceMac); + + Page queryWebDeviceList(Page build, DeviceQueryCriteria bo); } 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 3439362f..51f0a638 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 @@ -232,5 +232,46 @@ inner join device_type dt on d.device_type = dt.id where d.device_mac = #{deviceMac} + \ No newline at end of file From 1246ac5cf70e51fbaf8ed332d4bcedf83bf5dc09 Mon Sep 17 00:00:00 2001 From: daiyongfei <974332738@qq.com> Date: Sat, 23 Aug 2025 17:33:35 +0800 Subject: [PATCH 44/47] @Schema(title = "ID", hidden = true) --- .../fuyuanshen/equipment/domain/Device.java | 46 +++++++++---------- .../equipment/domain/DeviceType.java | 22 ++++----- .../equipment/domain/bo/DeviceGroupBo.java | 10 ++-- .../equipment/domain/form/DeviceForm.java | 2 +- .../equipment/domain/form/DeviceTypeForm.java | 14 +++--- .../domain/query/DeviceTypeQueryCriteria.java | 14 +++--- .../equipment/domain/vo/CustomerVo.java | 4 +- 7 files changed, 56 insertions(+), 56 deletions(-) diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/Device.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/Device.java index 902874c1..d166aacb 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/Device.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/Device.java @@ -22,10 +22,10 @@ public class Device extends TenantEntity { * id */ @TableId(value = "id", type = IdType.AUTO) - @Schema(name = "ID") + @Schema(title = "ID") private Long id; - @Schema(name = "设备记录ID") + @Schema(title = "设备记录ID") @TableField(exist = false) private Long assignId; @@ -33,76 +33,76 @@ public class Device extends TenantEntity { * 设备分组 * group_id */ - @Schema(name = "设备分组") + @Schema(title = "设备分组") private Long groupId; /** * device_type */ - @Schema(name = "设备类型") + @Schema(title = "设备类型") private Long deviceType; - @Schema(name = "设备类型名称") + @Schema(title = "设备类型名称") private String typeName; - @Schema(name = "客户号") + @Schema(title = "客户号") private Long customerId; - @Schema(name = "所属客户") + @Schema(title = "所属客户") private String customerName; /** * 当前所有者 * current_owner_id */ - @Schema(name = "当前所有者") + @Schema(title = "当前所有者") private Long currentOwnerId; /** * 原始所有者(创建者) * original_owner_id */ - @Schema(name = "原始所有者(创建者)") + @Schema(title = "原始所有者(创建者)") private Long originalOwnerId; /** * 原始设备 */ - @Schema(name = "原始设备") + @Schema(title = "原始设备") private Long originalDeviceId; - @Schema(name = "设备编号") + @Schema(title = "设备编号") private String deviceNo; - @Schema(name = "设备名称") + @Schema(title = "设备名称") private String deviceName; - @Schema(name = "设备图片") + @Schema(title = "设备图片") private String devicePic; - @Schema(name = "设备MAC") + @Schema(title = "设备MAC") private String deviceMac; - @Schema(name = "蓝牙名称") + @Schema(title = "蓝牙名称") private String bluetoothName; /** * 设备IMEI * device_imei */ - @Schema(name = "设备IMEI") + @Schema(title = "设备IMEI") private String deviceImei; - @Schema(name = "设备SN") + @Schema(title = "设备SN") private String deviceSn; - @Schema(name = "经度") + @Schema(title = "经度") private String longitude; - @Schema(name = "纬度") + @Schema(title = "纬度") private String latitude; - @Schema(name = "备注") + @Schema(title = "备注") private String remark; /** @@ -110,7 +110,7 @@ public class Device extends TenantEntity { * 0 失效 * 1 正常 */ - @Schema(name = "设备状态") + @Schema(title = "设备状态") private Integer deviceStatus; /** @@ -118,7 +118,7 @@ public class Device extends TenantEntity { * 0 未绑定 * 1 已绑定 */ - @Schema(name = "绑定状态") + @Schema(title = "绑定状态") private Integer bindingStatus; /** @@ -151,7 +151,7 @@ public class Device extends TenantEntity { * 出厂日期 * production_date */ - @Schema(name = "出厂日期") + @Schema(title = "出厂日期") private Date productionDate; } diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceType.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceType.java index 32bd32e3..fe1db44a 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceType.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceType.java @@ -18,42 +18,42 @@ import lombok.Data; public class DeviceType extends TenantEntity { @TableId(value = "id", type = IdType.AUTO) - @Schema(name = "ID", hidden = true) + @Schema(title = "ID", hidden = true) private Long id; - @Schema(name = "客户号") + @Schema(title = "客户号") private Long customerId; - @Schema(name = "创建该类型的客户") + @Schema(title = "创建该类型的客户") private Long ownerCustomerId; /** * 原始所有者(创建者) * original_owner_id */ - @Schema(name = "原始所有者(创建者)") + @Schema(title = "原始所有者(创建者)") private Long originalOwnerId; /** * 原始设备 */ - @Schema(name = "原始设备类型") + @Schema(title = "原始设备类型") private Long originalDeviceId; @NotBlank(message = "设备类型名称不能为空") - @Schema(name = "类型名称", required = true) + @Schema(title = "类型名称", required = true) private String typeName; - @Schema(name = "是否支持蓝牙") + @Schema(title = "是否支持蓝牙") private Boolean isSupportBle; - @Schema(name = "定位方式", example = "0:无;1:GPS;2:基站;3:wifi;4:北斗") + @Schema(title = "定位方式", example = "0:无;1:GPS;2:基站;3:wifi;4:北斗") private String locateMode; - @Schema(name = "联网方式", example = "0:无;1:4G;2:WIFI") + @Schema(title = "联网方式", example = "0:无;1:4G;2:WIFI") private String networkWay; - @Schema(name = "通讯方式", example = "0:4G;1:蓝牙") + @Schema(title = "通讯方式", example = "0:4G;1:蓝牙") private String communicationMode; /** @@ -68,7 +68,7 @@ public class DeviceType extends TenantEntity { /** * 型号字典用于APP页面跳转 */ - @Schema(name = "型号字典用于APP页面跳转") + @Schema(title = "型号字典用于APP页面跳转") private String modelDictionary; diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/bo/DeviceGroupBo.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/bo/DeviceGroupBo.java index 064c5aa2..e0ac783e 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/bo/DeviceGroupBo.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/bo/DeviceGroupBo.java @@ -30,21 +30,21 @@ public class DeviceGroupBo extends BaseEntity { /** * 分组名称 */ - @Schema(name = "分组名称") + @Schema(title = "分组名称") @NotBlank(message = "分组名称不能为空", groups = { AddGroup.class, EditGroup.class }) private String groupName; /** * 状态:0-禁用,1-正常 */ - @Schema(name = "状态:0-禁用,1-正常") + @Schema(title = "状态:0-禁用,1-正常") // @NotNull(message = "状态:0-禁用,1-正常不能为空", groups = { AddGroup.class, EditGroup.class }) private Long status; /** * 父分组ID */ - @Schema(name = "父分组ID") + @Schema(title = "父分组ID") private Long parentId; /** @@ -59,10 +59,10 @@ public class DeviceGroupBo extends BaseEntity { private Long isDeleted; - @Schema(name = "页码", example = "1") + @Schema(title = "页码", example = "1") private Integer pageNum = 1; - @Schema(name = "每页数据量", example = "10") + @Schema(title = "每页数据量", example = "10") private Integer pageSize = 10; } diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceForm.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceForm.java index 2de4ca34..a51e13bd 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceForm.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceForm.java @@ -40,7 +40,7 @@ public class DeviceForm { @Schema(title = "设备MAC") private String deviceMac; - @Schema(name = "蓝牙名称") + @Schema(title = "蓝牙名称") private String bluetoothName; diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceTypeForm.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceTypeForm.java index 7fc8a103..d5e1df70 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceTypeForm.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/form/DeviceTypeForm.java @@ -11,28 +11,28 @@ import lombok.Data; @Data public class DeviceTypeForm { - @Schema(name = "ID", hidden = true) + @Schema(title = "ID", hidden = true) private Long id; - @Schema(name = "类型名称", required = true) + @Schema(title = "类型名称", required = true) private String typeName; - @Schema(name = "是否支持蓝牙") + @Schema(title = "是否支持蓝牙") private Boolean isSupportBle; - @Schema(name = "定位方式", example = "0:无;1:GPS;2:基站;3:wifi;4:北斗") + @Schema(title = "定位方式", example = "0:无;1:GPS;2:基站;3:wifi;4:北斗") private String locateMode; - @Schema(name = "联网方式", example = "0:无;1:4G;2:WIFI") + @Schema(title = "联网方式", example = "0:无;1:4G;2:WIFI") private String networkWay; - @Schema(name = "通讯方式", example = "0:4G;1:蓝牙") + @Schema(title = "通讯方式", example = "0:4G;1:蓝牙") private String communicationMode; /** * 型号字典用于APP页面跳转 */ - @Schema(name = "型号字典用于APP页面跳转") + @Schema(title = "型号字典用于APP页面跳转") private String modelDictionary; } diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceTypeQueryCriteria.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceTypeQueryCriteria.java index 2beea69a..5080edc6 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceTypeQueryCriteria.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/query/DeviceTypeQueryCriteria.java @@ -15,25 +15,25 @@ import java.util.Set; @Data public class DeviceTypeQueryCriteria extends BaseEntity implements Serializable { - @Schema(name = "设备类型id") + @Schema(title = "设备类型id") private Long deviceTypeId; - @Schema(name = "型号名称") + @Schema(title = "型号名称") private String typeName; - @Schema(name = "所属客户") + @Schema(title = "所属客户") private Set customerIds; - @Schema(name = "所属客户") + @Schema(title = "所属客户") private Long customerId; - @Schema(name = "com.fuyuanshen") + @Schema(title = "com.fuyuanshen") private Long tenantId; - @Schema(name = "页码", example = "1") + @Schema(title = "页码", example = "1") private Integer pageNum = 1; - @Schema(name = "每页数据量", example = "10") + @Schema(title = "每页数据量", example = "10") private Integer pageSize = 10; diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/CustomerVo.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/CustomerVo.java index b2ff0481..3debd670 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/CustomerVo.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/CustomerVo.java @@ -16,11 +16,11 @@ import java.util.List; @Validated public class CustomerVo { - @Schema(name = "客户ID") + @Schema(title = "客户ID") @NotNull(message = "客户ID不能为空") private Long customerId; - @Schema(name = "设备ID") + @Schema(title = "设备ID") @NotNull(message = "设备ID不能为空") private List deviceIds; From d962c6ead51d913c1223cba1f813d1b748893eee Mon Sep 17 00:00:00 2001 From: daiyongfei <974332738@qq.com> Date: Mon, 25 Aug 2025 10:19:57 +0800 Subject: [PATCH 45/47] =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E5=88=86=E4=BA=AB?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../device/WEBDeviceController.java | 16 +++++++++- .../web/service/WEBDeviceService.java | 9 ++++++ .../service/impl/WEBDeviceServiceImpl.java | 29 +++++++++++++++++-- .../equipment/domain/vo/WebDeviceVo.java | 5 ++++ 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java index 4519b2e7..700ff0d9 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java @@ -8,9 +8,11 @@ import com.fuyuanshen.common.core.domain.R; import com.fuyuanshen.common.mybatis.core.page.PageQuery; import com.fuyuanshen.common.mybatis.core.page.TableDataInfo; import com.fuyuanshen.common.web.core.BaseController; +import com.fuyuanshen.equipment.domain.Device; import com.fuyuanshen.equipment.domain.dto.AppDeviceBo; import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria; import com.fuyuanshen.equipment.domain.vo.AppDeviceVo; +import com.fuyuanshen.equipment.domain.vo.WebDeviceVo; import com.fuyuanshen.web.service.WEBDeviceService; import com.fuyuanshen.web.service.device.DeviceBizService; import io.swagger.v3.oas.annotations.Operation; @@ -38,7 +40,6 @@ public class WEBDeviceController extends BaseController { private final WEBDeviceService deviceService; - /** * @param id * @return @@ -53,6 +54,19 @@ public class WEBDeviceController extends BaseController { } + /** + * 设备详情 + * + * @param id + * @return + */ + @Operation(summary = "设备详情") + @GetMapping(value = "/detail/{id}") + public R getDevice(@PathVariable Long id) { + WebDeviceVo device = deviceService.getDevice(id); + return R.ok(device); + } + } diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/service/WEBDeviceService.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/WEBDeviceService.java index 02747174..fe84f3b9 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/service/WEBDeviceService.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/WEBDeviceService.java @@ -10,6 +10,7 @@ import com.fuyuanshen.equipment.domain.form.DeviceForm; import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria; import com.fuyuanshen.equipment.domain.vo.AppDeviceVo; import com.fuyuanshen.equipment.domain.vo.CustomerVo; +import com.fuyuanshen.equipment.domain.vo.WebDeviceVo; import java.io.IOException; import java.util.List; @@ -29,4 +30,12 @@ public interface WEBDeviceService extends IService { */ int webUnBindDevice(Long id, Long userId); + /** + * WEB端设备详情 + * + * @param id + * @return + */ + WebDeviceVo getDevice(Long id); + } diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/service/impl/WEBDeviceServiceImpl.java b/fys-admin/src/main/java/com/fuyuanshen/web/service/impl/WEBDeviceServiceImpl.java index 7e328b8d..0d5097c1 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/service/impl/WEBDeviceServiceImpl.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/service/impl/WEBDeviceServiceImpl.java @@ -1,12 +1,17 @@ package com.fuyuanshen.web.service.impl; +import cn.hutool.core.bean.BeanUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.fuyuanshen.app.domain.AppDeviceBindRecord; +import com.fuyuanshen.app.domain.AppDeviceShare; +import com.fuyuanshen.app.domain.vo.AppDeviceShareVo; import com.fuyuanshen.app.mapper.AppDeviceBindRecordMapper; +import com.fuyuanshen.app.mapper.AppDeviceShareMapper; import com.fuyuanshen.equipment.domain.Device; import com.fuyuanshen.equipment.domain.DeviceAssignments; +import com.fuyuanshen.equipment.domain.vo.WebDeviceVo; import com.fuyuanshen.equipment.enums.BindingStatusEnum; import com.fuyuanshen.equipment.mapper.DeviceAssignmentsMapper; import com.fuyuanshen.equipment.mapper.DeviceMapper; @@ -27,13 +32,12 @@ import org.springframework.transaction.annotation.Transactional; @RequiredArgsConstructor public class WEBDeviceServiceImpl extends ServiceImpl implements WEBDeviceService { - private final DeviceBizService appDeviceService; - private final DeviceAssignmentsMapper deviceAssignmentsMapper; private final AppDeviceBindRecordMapper appDeviceBindRecordMapper; private final DeviceMapper deviceMapper; + private final AppDeviceShareMapper appDeviceShareMapper; /** @@ -70,4 +74,25 @@ public class WEBDeviceServiceImpl extends ServiceImpl impl } + /** + * WEB端设备详情 + * + * @param id + * @return + */ + @Override + public WebDeviceVo getDevice(Long id) { + Device device = deviceMapper.selectById(id); + if (device != null) { + WebDeviceVo webDeviceVo = new WebDeviceVo(); + BeanUtil.copyProperties(device, webDeviceVo); + // 查询分享用户数 + Long count = appDeviceShareMapper.selectCount(new QueryWrapper().eq("device_id", id)); + webDeviceVo.setShareUsersNumber(Math.toIntExact(count)); + return webDeviceVo; + } + return null; + } + + } diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/WebDeviceVo.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/WebDeviceVo.java index bcbc71a5..94b20e80 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/WebDeviceVo.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/vo/WebDeviceVo.java @@ -92,4 +92,9 @@ public class WebDeviceVo implements Serializable { */ private String detailPageUrl; + /** + * 分享用户数量 + */ + private Integer shareUsersNumber; + } From 9b476e98ba7903c55f610db10332c3414e1ccc30 Mon Sep 17 00:00:00 2001 From: daiyongfei <974332738@qq.com> Date: Mon, 25 Aug 2025 11:40:59 +0800 Subject: [PATCH 46/47] =?UTF-8?q?=E5=9E=8B=E5=8F=B7=E5=AD=97=E5=85=B8?= =?UTF-8?q?=E7=94=A8=E4=BA=8EPC=E9=A1=B5=E9=9D=A2=E8=B7=B3=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fuyuanshen/equipment/domain/DeviceType.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceType.java b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceType.java index fe1db44a..d0ab5b0f 100644 --- a/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceType.java +++ b/fys-modules/fys-equipment/src/main/java/com/fuyuanshen/equipment/domain/DeviceType.java @@ -67,9 +67,17 @@ public class DeviceType extends TenantEntity { /** * 型号字典用于APP页面跳转 + * app_model_dictionary */ @Schema(title = "型号字典用于APP页面跳转") - private String modelDictionary; + private String appModelDictionary; + + /** + * 型号字典用于PC页面跳转 + * pc_model_dictionary + */ + @Schema(title = "型号字典用于PC页面跳转") + private String pcModelDictionary; } From 74cefe9cc3bc538c92021de2f2e8adac97faebb0 Mon Sep 17 00:00:00 2001 From: daiyongfei <974332738@qq.com> Date: Mon, 25 Aug 2025 13:42:24 +0800 Subject: [PATCH 47/47] =?UTF-8?q?=E8=AE=BE=E5=A4=87=E8=AF=A6=E6=83=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fuyuanshen/web/controller/device/WEBDeviceController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java index 700ff0d9..86ec7ed6 100644 --- a/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java +++ b/fys-admin/src/main/java/com/fuyuanshen/web/controller/device/WEBDeviceController.java @@ -61,7 +61,7 @@ public class WEBDeviceController extends BaseController { * @return */ @Operation(summary = "设备详情") - @GetMapping(value = "/detail/{id}") + @GetMapping(value = "/pc/detail/{id}") public R getDevice(@PathVariable Long id) { WebDeviceVo device = deviceService.getDevice(id); return R.ok(device);