From a01da7c9ddd035e24ebdddd6a5a668e8e75c627a Mon Sep 17 00:00:00 2001 From: zc Date: Thu, 11 Dec 2025 21:39:02 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pom.xml | 14 +- .../server/controller/ServerController.java | 24 +- .../mica/mqtt/server/entity/CarInfo.java | 15 +- .../mica/mqtt/server/entity/CarParkItem.java | 47 ++++ .../mqtt/server/entity/CarParkRecord.java | 49 ++++ .../mqtt/server/entity/CarPassRecord.java | 87 +++++++ .../server/listener/CarMessageListener.java | 177 ++++++++++++-- .../mqtt/server/mapper/CarInfoMapper.java | 5 + .../mqtt/server/mapper/CarParkItemMapper.java | 17 ++ .../server/mapper/CarParkRecordMapper.java | 10 + .../dromara/mica/mqtt/server/pojo/User.java | 19 -- .../mqtt/server/pojo/WhiteListOperatorPO.java | 47 ++++ .../mqtt/server/service/ICarInfoService.java | 4 + .../server/service/ICarParkItemService.java | 9 + .../server/service/ICarParkRecordService.java | 11 + .../service/impl/CarInfoServiceImpl.java | 7 + .../service/impl/CarParkItemServiceImpl.java | 21 ++ .../impl/CarParkRecordServiceImpl.java | 27 +++ .../server/service/impl/ServerService.java | 28 ++- ...atOnLine.java => HeartbeatOnLineTask.java} | 2 +- .../mqtt/server/task/PlatePublishTask.java | 186 +++++++++++++++ .../mica/mqtt/server/task/PublishAllTask.java | 25 -- .../mica/mqtt/server/utils/AESUtil.java | 217 ++++++++++++++++++ .../mica/mqtt/server/utils/UuidUtil.java | 40 ++++ .../src/main/resources/application-dev.yml | 2 +- .../main/resources/mapper/CarInfoMapper.xml | 30 ++- 26 files changed, 1050 insertions(+), 70 deletions(-) create mode 100644 example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/entity/CarParkItem.java create mode 100644 example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/entity/CarParkRecord.java create mode 100644 example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/entity/CarPassRecord.java create mode 100644 example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/mapper/CarParkItemMapper.java create mode 100644 example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/mapper/CarParkRecordMapper.java delete mode 100644 example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/pojo/User.java create mode 100644 example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/pojo/WhiteListOperatorPO.java create mode 100644 example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/ICarParkItemService.java create mode 100644 example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/ICarParkRecordService.java create mode 100644 example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/impl/CarParkItemServiceImpl.java create mode 100644 example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/impl/CarParkRecordServiceImpl.java rename example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/task/{HeartbeatOnLine.java => HeartbeatOnLineTask.java} (98%) create mode 100644 example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/task/PlatePublishTask.java delete mode 100644 example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/task/PublishAllTask.java create mode 100644 example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/utils/AESUtil.java create mode 100644 example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/utils/UuidUtil.java diff --git a/example/mica-mqtt-server-spring-boot-example/pom.xml b/example/mica-mqtt-server-spring-boot-example/pom.xml index b1ecd8f..083cdac 100644 --- a/example/mica-mqtt-server-spring-boot-example/pom.xml +++ b/example/mica-mqtt-server-spring-boot-example/pom.xml @@ -59,7 +59,6 @@ provided - com.baomidou mybatis-plus-spring-boot4-starter @@ -94,6 +93,19 @@ jackson-databind + + + com.alibaba.fastjson2 + fastjson2 + 2.0.23 + + + + + cn.hutool + hutool-all + 5.8.40 + diff --git a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/controller/ServerController.java b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/controller/ServerController.java index 5dc5f96..b2f30a9 100644 --- a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/controller/ServerController.java +++ b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/controller/ServerController.java @@ -1,7 +1,5 @@ package org.dromara.mica.mqtt.server.controller; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; import org.dromara.mica.mqtt.server.service.impl.ServerService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; @@ -9,17 +7,35 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -@Tag(name = "Mqtt::服务端") @RequestMapping("/mqtt/server") @RestController public class ServerController { @Autowired private ServerService service; - @Operation(summary = "publish") @PostMapping("publish") public boolean publish(@RequestBody String body) { return service.publish(body); } + @PostMapping("open") + public boolean open(@RequestBody String body) { + return service.open(body); + } + + @PostMapping("open2") + public boolean open2(@RequestBody String body) { + return service.open2(body); + } + + @PostMapping("check_offline_record") + public boolean check_offline_record(@RequestBody String body) { + return service.check_offline_record(body); + } + + @PostMapping("offline_record") + public boolean offline_record(@RequestBody String body) { + return service.offline_record(body); + } + } diff --git a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/entity/CarInfo.java b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/entity/CarInfo.java index ffb989f..917e7ca 100644 --- a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/entity/CarInfo.java +++ b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/entity/CarInfo.java @@ -7,6 +7,7 @@ import lombok.Data; import java.io.Serial; import java.io.Serializable; import java.util.Date; +import java.util.List; @Data @TableName("car_info") @@ -31,12 +32,21 @@ public class CarInfo implements Serializable { /** 车牌号 */ private String plate; + /** 车牌号 */ + private List plateList; + /** 是否启用时间段 */ private String timeSegEnable; /** 时间段 */ private String segTime; + /** 时间段 */ + private String segTimeStart = "00:00:00"; + + /** 时间段 */ + private String segTimeEnd = "00:00:00"; + /** 是否需要报警 */ private String needAlarm; @@ -57,8 +67,9 @@ public class CarInfo implements Serializable { private String sn;//设备序列号 - private int num; - /** 超频设备识别标签 */ private String overclockCard; + + /** car_park_record表的主键id */ + private Long carParkRecordId; } diff --git a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/entity/CarParkItem.java b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/entity/CarParkItem.java new file mode 100644 index 0000000..1237010 --- /dev/null +++ b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/entity/CarParkItem.java @@ -0,0 +1,47 @@ +package org.dromara.mica.mqtt.server.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + +/** + * 车场设备实体 + * + */ +@Data +@TableName("car_park_item") +public class CarParkItem implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * id + */ + private Long id; + + /** + * 设备id + */ + private String equipmentId; + + /** + * 停车场id + */ + private String parkId; + + /** + * 过车行驶方向 0 入场过车 1出场过车 + */ + private String way; + + /** + * 区域 + */ + private String area; + +} diff --git a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/entity/CarParkRecord.java b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/entity/CarParkRecord.java new file mode 100644 index 0000000..efbdafe --- /dev/null +++ b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/entity/CarParkRecord.java @@ -0,0 +1,49 @@ +package org.dromara.mica.mqtt.server.entity; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 车辆授权对象 car_park_record + * + */ +@Data +public class CarParkRecord implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + + /** + * id + */ + private Long id; + + /** + * 设备id + */ + + private Long equipmentId; + + /** + * 车场id + */ + + private Long parkId; + + /** + * 车辆id + */ + private Long customerId; + + /** + * 是否下发(0未下发1已下发) + */ + private String sync; + + /** + * 摄像头mqtt协议的报文id + */ + private String clientId; + +} diff --git a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/entity/CarPassRecord.java b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/entity/CarPassRecord.java new file mode 100644 index 0000000..9158868 --- /dev/null +++ b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/entity/CarPassRecord.java @@ -0,0 +1,87 @@ +package org.dromara.mica.mqtt.server.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + +/** + * 通行记录对象 car_pass_record + * + */ +@Data +@TableName("car_pass_record") +public class CarPassRecord implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * id + */ + private Long id; + + /** + * 停车场id + */ + private String parkId; + + /** + * 过车信息唯一标识 + */ + private String uniqueNo; + + /** + * 过车行驶方向 0 入场过车 1出场过车 + */ + private String direction; + + /** + * 车牌号码 + */ + private String license; + + /** + * 通行时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd") + private Date passTime; + + /** + * 触发类型 + */ + private String triggerType; + + /** + * 车牌颜色 + */ + private String colorType; + + /** + * 车辆颜色 + */ + private String carColor; + + /** + * 车牌图片数据 + */ + private String url; + + /** + * 数据类型 0 实时数据 1历史数据 + */ + private String dataType; + + /** + * 设备序列号 + */ + private String sn; + + private String type; + +} diff --git a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/listener/CarMessageListener.java b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/listener/CarMessageListener.java index 66e19d9..9b1191c 100644 --- a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/listener/CarMessageListener.java +++ b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/listener/CarMessageListener.java @@ -1,19 +1,28 @@ package org.dromara.mica.mqtt.server.listener; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; import lombok.extern.slf4j.Slf4j; -import org.dromara.mica.mqtt.codec.message.MqttPublishMessage; -import org.dromara.mica.mqtt.server.constant.CacheConstants; -import org.dromara.mica.mqtt.server.enums.FlagEnums; -import org.dromara.mica.mqtt.server.pojo.User; import org.dromara.mica.mqtt.core.annotation.MqttServerFunction; +import org.dromara.mica.mqtt.server.constant.CacheConstants; +import org.dromara.mica.mqtt.server.entity.CarParkItem; +import org.dromara.mica.mqtt.server.entity.CarParkRecord; +import org.dromara.mica.mqtt.server.entity.CarPassRecord; +import org.dromara.mica.mqtt.server.entity.Equipment; +import org.dromara.mica.mqtt.server.enums.FlagEnums; +import org.dromara.mica.mqtt.server.pojo.WhiteListOperatorPO; import org.dromara.mica.mqtt.server.redis.RedisService; +import org.dromara.mica.mqtt.server.service.ICarParkItemService; +import org.dromara.mica.mqtt.server.service.ICarParkRecordService; +import org.dromara.mica.mqtt.server.service.IEquipmentService; +import org.dromara.mica.mqtt.server.utils.AESUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestParam; -import org.tio.core.ChannelContext; -import org.tio.core.Node; +import org.springframework.transaction.annotation.Transactional; +import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; +import java.util.Base64; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -29,6 +38,23 @@ public class CarMessageListener { @Autowired RedisService redisService; + @Autowired + ICarParkRecordService carParkRecordService; + + @Autowired + IEquipmentService equipmentService; + + @Autowired + ICarParkItemService carParkItemService; + + private static String key = "1234567898765432"; + + /** + * 心跳 + * @param topic + * @param topicVars + * @param message + */ @MqttServerFunction("device/${sn}/message/up/keep_alive") public void onKeepAliveMessage(String topic, Map topicVars, byte[] message) { String sn = topicVars.get("sn"); @@ -38,13 +64,136 @@ public class CarMessageListener { redisService.setCacheObject(CacheConstants.EQUIPMENT_HEARTBEAT + sn, FlagEnums.ONLINE.getCode(), CacheConstants.OFFLINE_THRESHOLD, TimeUnit.MILLISECONDS); } + /** + * 车牌下发结果监听 + * + * @param topic + * @param message + */ @MqttServerFunction("device/${sn}/message/down/white_list_operator/reply") - public void white_list_operator_reply(String topic, byte[] payload) { - log.info("接收到消息 -> Topic: {}, Payload: {}", topic, new String(payload)); - // 在这里添加您的业务逻辑,例如: - // 1. 解析 payload - // 2. 更新设备在线状态 - // 3. 回复心跳响应等 + @Transactional(rollbackFor = Exception.class) + public void white_list_operator_reply(String topic, byte[] message) { + log.info("接收到车牌下发消息 -> Topic: {}, message: {}", topic, new String(message)); + String data = new String(message, StandardCharsets.UTF_8); + WhiteListOperatorPO whiteListOperatorPO = JSONObject.parseObject(data, WhiteListOperatorPO.class); + if (null == whiteListOperatorPO || 200 != whiteListOperatorPO.getCode()) { + log.error("white_list_operator发布失败:{}", data); + return; + } + + CarParkRecord carParkRecord = new CarParkRecord(); + carParkRecord.setClientId(whiteListOperatorPO.getId()); + //新增修改和删除车牌得回执信息一致,通过id区分 + if (whiteListOperatorPO.getId().contains("del_")) { + carParkRecord.setSync("2"); + } else { + carParkRecord.setSync("1"); + } + carParkRecordService.updateByClientId(carParkRecord); + } + + /** + * 车牌入场出场识别监听 + * + * @param topic + * @param message + */ + @MqttServerFunction("device/${sn}/message/up/ivs_result") + public void ivs_result(String topic, Map topicVars, byte[] message) throws Exception { + String sn = topicVars.get("sn"); + log.info("接收到车辆识别消息 -> Topic: {}, message: {}", topic, new String(message)); + String data = new String(message, StandardCharsets.UTF_8); + JSONObject jsonObject = JSONObject.parseObject(data); + JSONObject payload = jsonObject.getJSONObject("payload"); + JSONObject alarmInfoPlate = payload.getJSONObject("AlarmInfoPlate"); + JSONObject result = alarmInfoPlate.getJSONObject("result"); + JSONObject plateResult = result.getJSONObject("PlateResult"); + String license = plateResult.getString("license"); + String colorType = plateResult.getString("colorType"); + String str = ""; + if ("5".equals(colorType)) { + str = AESUtil.decrptyAES_ECB(license, key).substring(0, 20); + } else { + str = AESUtil.decrptyAES_ECB(license, key).substring(0, 18); + } + + license = AESUtil.UTF8decode(str); + log.info("解密前车牌:{},解谜后的车牌:{}", plateResult.getString("license"), license); + } + + /** + * 车辆离线识别监听 + * + * @param topic + * @param message + */ + @MqttServerFunction("device/${sn}/message/up/ivs_result_offline") + public void ivs_result_offline(String topic, Map topicVars, byte[] message) throws Exception { + String sn = topicVars.get("sn"); + log.info("接收到车辆离线识别消息 -> Topic: {}, message: {}", topic, new String(message)); + String data = new String(message, StandardCharsets.UTF_8); + log.info("车牌离线识别监听:{}", data); + JSONObject jsonObject = JSONObject.parseObject(data); + JSONObject payload = jsonObject.getJSONObject("payload"); + JSONObject alarmInfoPlate = payload.getJSONObject("AlarmInfoPlate"); + JSONObject result = alarmInfoPlate.getJSONObject("result"); + JSONObject plateResult = result.getJSONObject("PlateResult"); + String license = plateResult.getString("license"); + String colorType = plateResult.getString("colorType"); + String str = ""; + if ("5".equals(colorType)) { + str = AESUtil.decrptyAES_ECB(license, key).substring(0, 20); + } else { + str = AESUtil.decrptyAES_ECB(license, key).substring(0, 18); + } + + license = AESUtil.UTF8decode(str); + log.info("离线-解密前车牌:{},解谜后的车牌:{}", plateResult.getString("license"), license); + CarParkItem carParkItem = carParkItemService.selectBySn(sn); + CarPassRecord carPassRecord = new CarPassRecord(); + carPassRecord.setSn(sn); + carPassRecord.setParkId(carParkItem.getParkId()); + + + } + + /** + * IO输出事件监听 + * + * @param topic + * @param message + */ + @MqttServerFunction("device/${sn}/message/down/gpio_out/reply") + public void gpio_out(String topic, byte[] message) { + log.info("IO输出事件监听消息 -> Topic: {}, message: {}", topic, new String(message)); + String data = new String(message, StandardCharsets.UTF_8); + + log.info("IO输出事件监听:{}", data); + } + + /** + * IO锁定事件监听 + * + * @param topic + * @param message + */ + @MqttServerFunction("device/${sn}/message/down/set_io_lock_status/reply") + public void set_io_lock_status(String topic, byte[] message) { + log.info("IO锁定事件监听消息 -> Topic: {}, message: {}", topic, new String(message)); + String data = new String(message, StandardCharsets.UTF_8); + log.info("IO锁定事件监听:{}", data); + } + + /** + * 订阅离线数据数量 + * + * @param topic + * @param message + */ + @MqttServerFunction("device/${sn}/message/up/offline_record") + public void offline_record(String topic, byte[] message) { + log.info("订阅离线数据数量 -> Topic: {}, message: {}", topic, new String(message)); + String data = new String(message, StandardCharsets.UTF_8); } } diff --git a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/mapper/CarInfoMapper.java b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/mapper/CarInfoMapper.java index feab25d..10ce42c 100644 --- a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/mapper/CarInfoMapper.java +++ b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/mapper/CarInfoMapper.java @@ -4,6 +4,11 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; import org.dromara.mica.mqtt.server.entity.CarInfo; +import java.util.List; + @Mapper public interface CarInfoMapper extends BaseMapper { + + List selectCarInfoList(CarInfo car); + } diff --git a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/mapper/CarParkItemMapper.java b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/mapper/CarParkItemMapper.java new file mode 100644 index 0000000..04d5c14 --- /dev/null +++ b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/mapper/CarParkItemMapper.java @@ -0,0 +1,17 @@ +package org.dromara.mica.mqtt.server.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.dromara.mica.mqtt.server.entity.CarInfo; +import org.dromara.mica.mqtt.server.entity.CarParkItem; + +import java.util.List; + +@Mapper +public interface CarParkItemMapper extends BaseMapper { + + @Select("SELECT p.id,p.park_id parkId,p.way,p.equipment_id equipmentId,p.area FROM car_park_item p left join sys_equipment e on p.equipment_id = e.id where e.sequence = #{sn} and e.product_id = 4 limit 1") + CarParkItem selectBySn(@Param("sn") String sn); +} diff --git a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/mapper/CarParkRecordMapper.java b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/mapper/CarParkRecordMapper.java new file mode 100644 index 0000000..35e7d99 --- /dev/null +++ b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/mapper/CarParkRecordMapper.java @@ -0,0 +1,10 @@ +package org.dromara.mica.mqtt.server.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.dromara.mica.mqtt.server.entity.CarParkRecord; + +@Mapper +public interface CarParkRecordMapper extends BaseMapper { + +} diff --git a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/pojo/User.java b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/pojo/User.java deleted file mode 100644 index ab94704..0000000 --- a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/pojo/User.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.dromara.mica.mqtt.server.pojo; - -import lombok.Data; - -@Data -public class User { - private String name; - private T girlfriend; - - public static User newUser(){ - User user1 = new User(); - user1.setName("name1"); - - User user2 = new User(); - user2.setName("name2"); - user2.setGirlfriend(user1); - return user2; - } -} diff --git a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/pojo/WhiteListOperatorPO.java b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/pojo/WhiteListOperatorPO.java new file mode 100644 index 0000000..2b17951 --- /dev/null +++ b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/pojo/WhiteListOperatorPO.java @@ -0,0 +1,47 @@ +package org.dromara.mica.mqtt.server.pojo; +import com.alibaba.fastjson2.JSONObject; +import lombok.Data; + +/** + * 设备报文数据实体 + */ +@Data +public class WhiteListOperatorPO { + + /** + * id + */ + private String id; + + /** + * 回执的code + */ + private Integer code; + + /** + * 设备编码 + */ + private String sn; + + /** + * 报文名称 + */ + private String name; + + /** + * 版本 + */ + private String version = "1.0"; + + /** + * 内容 + */ + private JSONObject payload; + + /** + * 时间戳(精确到秒) + */ + private Long timestamp = System.currentTimeMillis() / 1000; + + +} diff --git a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/ICarInfoService.java b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/ICarInfoService.java index 34399de..f9eeded 100644 --- a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/ICarInfoService.java +++ b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/ICarInfoService.java @@ -3,7 +3,11 @@ package org.dromara.mica.mqtt.server.service; import com.baomidou.mybatisplus.extension.service.IService; import org.dromara.mica.mqtt.server.entity.CarInfo; +import java.util.List; + public interface ICarInfoService extends IService { CarInfo selectCarInfoBySn(String sn); + + List selectCarInfoList(CarInfo car); } diff --git a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/ICarParkItemService.java b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/ICarParkItemService.java new file mode 100644 index 0000000..bb3c419 --- /dev/null +++ b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/ICarParkItemService.java @@ -0,0 +1,9 @@ +package org.dromara.mica.mqtt.server.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.dromara.mica.mqtt.server.entity.CarParkItem; + +public interface ICarParkItemService extends IService { + + CarParkItem selectBySn(String sn); +} diff --git a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/ICarParkRecordService.java b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/ICarParkRecordService.java new file mode 100644 index 0000000..0d48072 --- /dev/null +++ b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/ICarParkRecordService.java @@ -0,0 +1,11 @@ +package org.dromara.mica.mqtt.server.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.dromara.mica.mqtt.server.entity.CarParkRecord; + +public interface ICarParkRecordService extends IService { + + int updateByClientId(CarParkRecord carParkRecord); + + void delByClientId(CarParkRecord carParkRecord); +} diff --git a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/impl/CarInfoServiceImpl.java b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/impl/CarInfoServiceImpl.java index 4d7fec1..bc3d4cf 100644 --- a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/impl/CarInfoServiceImpl.java +++ b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/impl/CarInfoServiceImpl.java @@ -8,6 +8,8 @@ import org.dromara.mica.mqtt.server.service.ICarInfoService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.List; + @Service public class CarInfoServiceImpl extends ServiceImpl implements ICarInfoService { @@ -20,4 +22,9 @@ public class CarInfoServiceImpl extends ServiceImpl impl return new CarInfo(); } + + @Override + public List selectCarInfoList(CarInfo car) { + return carInfoMapper.selectCarInfoList(car); + } } diff --git a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/impl/CarParkItemServiceImpl.java b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/impl/CarParkItemServiceImpl.java new file mode 100644 index 0000000..97bb4c0 --- /dev/null +++ b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/impl/CarParkItemServiceImpl.java @@ -0,0 +1,21 @@ +package org.dromara.mica.mqtt.server.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.dromara.mica.mqtt.server.entity.CarParkItem; +import org.dromara.mica.mqtt.server.mapper.CarParkItemMapper; +import org.dromara.mica.mqtt.server.service.ICarParkItemService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class CarParkItemServiceImpl extends ServiceImpl implements ICarParkItemService { + + @Autowired + CarParkItemMapper carParkItemMapper; + + @Override + public CarParkItem selectBySn(String sn) { + return carParkItemMapper.selectBySn(sn); + } +} diff --git a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/impl/CarParkRecordServiceImpl.java b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/impl/CarParkRecordServiceImpl.java new file mode 100644 index 0000000..394ce15 --- /dev/null +++ b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/impl/CarParkRecordServiceImpl.java @@ -0,0 +1,27 @@ +package org.dromara.mica.mqtt.server.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.dromara.mica.mqtt.server.entity.CarParkRecord; +import org.dromara.mica.mqtt.server.mapper.CarParkRecordMapper; +import org.dromara.mica.mqtt.server.service.ICarParkRecordService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class CarParkRecordServiceImpl extends ServiceImpl implements ICarParkRecordService { + + @Autowired + CarParkRecordMapper carParkRecordMapper; + + @Override + public int updateByClientId(CarParkRecord carParkRecord) { + int id = carParkRecordMapper.update(carParkRecord, new QueryWrapper().eq("client_id", carParkRecord.getClientId())); + return id; + } + + @Override + public void delByClientId(CarParkRecord carParkRecord) { + carParkRecordMapper.delete(new QueryWrapper().eq("client_id", carParkRecord.getClientId())); + } +} diff --git a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/impl/ServerService.java b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/impl/ServerService.java index 5f9059b..3bf66a7 100644 --- a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/impl/ServerService.java +++ b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/service/impl/ServerService.java @@ -17,8 +17,32 @@ public class ServerService { private MqttServerTemplate server; public boolean publish(String body) { - boolean result = server.publishAll("/test/123", body.getBytes(StandardCharsets.UTF_8)); - log.info("Mqtt publishAll result:{}", result); + boolean result = server.publish("61e70b04-8e68be6a","device/61e70b04-8e68be6a/message/down/white_list_operator", body.getBytes(StandardCharsets.UTF_8)); + log.info("测试body:{},result:{}", body, result); + return result; + } + + public boolean open(String body) { + boolean result = server.publish("61e70b04-8e68be6a","device/61e70b04-8e68be6a/message/down/gpio_out", body.getBytes(StandardCharsets.UTF_8)); + log.info("IO输出测试body:{},result:{}", body, result); + return result; + } + + public boolean open2(String body) { + boolean result = server.publish("61e70b04-8e68be6a","device/61e70b04-8e68be6a/message/down/set_io_lock_status", body.getBytes(StandardCharsets.UTF_8)); + log.info("IO锁定测试body:{},result:{}", body, result); + return result; + } + + public boolean check_offline_record(String body) { + boolean result = server.publish("61e70b04-8e68be6a","device/61e70b04-8e68be6a/message/down/check_offline_record", body.getBytes(StandardCharsets.UTF_8)); + log.info("发布离线记录推送body:{},result:{}", body, result); + return result; + } + + public boolean offline_record(String body) { + boolean result = server.publish("61e70b04-8e68be6a","device/61e70b04-8e68be6a/message/up/offline_record", body.getBytes(StandardCharsets.UTF_8)); + log.info("发布离线数据数量body:{},result:{}", body, result); return result; } } diff --git a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/task/HeartbeatOnLine.java b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/task/HeartbeatOnLineTask.java similarity index 98% rename from example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/task/HeartbeatOnLine.java rename to example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/task/HeartbeatOnLineTask.java index ea72595..bf71f82 100644 --- a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/task/HeartbeatOnLine.java +++ b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/task/HeartbeatOnLineTask.java @@ -20,7 +20,7 @@ import java.util.List; */ @Slf4j @Service -public class HeartbeatOnLine { +public class HeartbeatOnLineTask { @Autowired RedisService redisService; diff --git a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/task/PlatePublishTask.java b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/task/PlatePublishTask.java new file mode 100644 index 0000000..2917fe9 --- /dev/null +++ b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/task/PlatePublishTask.java @@ -0,0 +1,186 @@ +package org.dromara.mica.mqtt.server.task; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.dromara.mica.mqtt.core.server.MqttServer; +import org.dromara.mica.mqtt.server.constant.CacheConstants; +import org.dromara.mica.mqtt.server.entity.CarInfo; +import org.dromara.mica.mqtt.server.entity.CarParkRecord; +import org.dromara.mica.mqtt.server.pojo.WhiteListOperatorPO; +import org.dromara.mica.mqtt.server.redis.RedisService; +import org.dromara.mica.mqtt.server.service.ICarInfoService; +import org.dromara.mica.mqtt.server.service.ICarParkRecordService; +import org.dromara.mica.mqtt.server.utils.UuidUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; +import org.tio.utils.hutool.CollUtil; +import org.tio.utils.hutool.StrUtil; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * 车牌下发设备定时任务 + */ +@Slf4j +@Service +public class PlatePublishTask { + + @Autowired + private MqttServer mqttServer; + + @Autowired + ICarInfoService carInfoService; + + @Autowired + ICarParkRecordService carParkRecordService; + + @Autowired + RedisService redisService; + + + /** + * 定时查询数据库需要下发的车辆进行下发 + */ + @Scheduled(fixedDelay = 8 * 1000) + public void run() { + String whiteUrl = "device/%s/message/down/white_list_operator"; + + //新增&编辑车牌 + CarInfo carInfo = new CarInfo(); + carInfo.setDelFlag("0"); + carInfo.setSync("0"); + List carInfoList = carInfoService.selectCarInfoList(carInfo); + if (CollUtil.isNotEmpty(carInfoList)) { + //向设备下发车辆信息 + for (CarInfo car : carInfoList) { + //如果该设备没有心跳,不下发车牌信息 + if (!redisService.hasKey(CacheConstants.EQUIPMENT_HEARTBEAT + car.getSn())) { + continue; + } + + String topic = String.format(whiteUrl, car.getSn()); + WhiteListOperatorPO po = new WhiteListOperatorPO(); + String uuid = "add_" + UuidUtil.getUuid(); + po.setId(uuid); + po.setSn(car.getSn()); + po.setName("white_list_operator"); + + //构造数据 + if (StrUtil.equals(car.getSn(), car.getSn())) { + po.setPayload(buildPayload(car)); + } + + //更新car_park_record表的clientId,用于回执消息更新下发状态 + //必须在发送前更新,不然会导致发送后,还没更新完数据库,回执已经收到,无法更新数据,导致持续下发车牌 + CarParkRecord carParkRecord = new CarParkRecord(); + carParkRecord.setId(car.getCarParkRecordId()); + carParkRecord.setClientId(uuid); + carParkRecordService.updateById(carParkRecord); + + //发布车牌到设备(协议只能单条发布) + boolean publish = mqttServer.publish(car.getSn(), topic, JSON.toJSONString(po).getBytes(StandardCharsets.UTF_8)); + log.info("定时任务下发车牌topic:{},报文数据:{},发送结果:{}", topic, JSON.toJSONString(po), publish); + } + } + + //删除车牌 + CarInfo carDel = new CarInfo(); + carDel.setDelFlag("2"); + carDel.setSync("1"); + List carInfos = carInfoService.selectCarInfoList(carDel); + if (CollUtil.isNotEmpty(carInfos)) { + //需要下发的设备 + List snList = carInfos.stream().map(CarInfo::getSn).distinct().toList(); + for (String sn : snList) { + if (!redisService.hasKey(CacheConstants.EQUIPMENT_HEARTBEAT + sn)) { + log.error("删除车牌,设备:{},无心跳", sn); + continue; + } + + //车辆授权列表 + List carParkRecords = new ArrayList<>(); + + String topic = String.format(whiteUrl, sn); + WhiteListOperatorPO po = new WhiteListOperatorPO(); + String uuid = "del_" + UuidUtil.getUuid(); + po.setId(uuid); + po.setSn(sn); + po.setName("white_list_operator"); + + + //构造内层数据 + List plates = new ArrayList<>(); + for (CarInfo car : carInfos) { + if (StrUtil.equals(car.getSn(), car.getSn())) { + plates.add(car.getPlate()); + + CarParkRecord carParkRecord = new CarParkRecord(); + carParkRecord.setClientId(uuid); + carParkRecord.setId(car.getCarParkRecordId()); + carParkRecords.add(carParkRecord); + } + } + po.setPayload(buildPayloadDel(plates)); + + //更新车辆授权信息 + if (CollUtil.isNotEmpty(carParkRecords)) { + carParkRecordService.saveOrUpdateBatch(carParkRecords); + } + //发布车牌到设备 + boolean publish = mqttServer.publish(sn, topic, JSON.toJSONString(po).getBytes(StandardCharsets.UTF_8)); + log.info("定时任务删除车牌topic:{},报文数据:{},发送结果:{}", topic, JSON.toJSONString(po), publish); + + } + } + + } + + + private JSONObject buildPayload(CarInfo carInfo) { + //新增&更新车牌 + if (StrUtil.isNotBlank(carInfo.getSegTime())) { + String[] split = carInfo.getSegTime().split("-"); + carInfo.setSegTimeStart(split[0]); + carInfo.setSegTimeEnd(split[1]); + } + + JSONObject dldbRec = new JSONObject(); + dldbRec.put("create_time", DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN)); + dldbRec.put("enable_time", DateUtil.format(carInfo.getEnableTime(), DatePattern.NORM_DATETIME_PATTERN)); + dldbRec.put("overdue_time", DateUtil.format(carInfo.getOverdueTime(), DatePattern.NORM_DATETIME_PATTERN)); + dldbRec.put("enable", Integer.parseInt(carInfo.getEnable())); + dldbRec.put("plate", carInfo.getPlate()); + dldbRec.put("time_seg_enable", Integer.parseInt(carInfo.getTimeSegEnable())); + dldbRec.put("seg_time_start", carInfo.getSegTimeStart() == null ? "00:00:00" : carInfo.getSegTimeStart()); + dldbRec.put("seg_time_end", carInfo.getSegTimeEnd() == null ? "00:00:00" : carInfo.getSegTimeEnd()); + dldbRec.put("need_alarm", Integer.parseInt(carInfo.getNeedAlarm())); + + JSONObject body = new JSONObject(); + body.put("operator_type", "update_or_add"); + body.put("dldb_rec", dldbRec); + + + JSONObject payload = new JSONObject(); + payload.put("type", "white_list_operator"); + payload.put("body", body); + return payload; + } + + private JSONObject buildPayloadDel(List plates) { + JSONObject body = new JSONObject(); + body.put("operator_type", "delete"); + body.put("plate", plates); + JSONObject payload = new JSONObject(); + payload.put("type", "white_list_operator"); + payload.put("body", body); + return payload; + } + +} diff --git a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/task/PublishAllTask.java b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/task/PublishAllTask.java deleted file mode 100644 index b53f783..0000000 --- a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/task/PublishAllTask.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.dromara.mica.mqtt.server.task; - -import org.dromara.mica.mqtt.core.server.MqttServer; -import org.dromara.mica.mqtt.server.pojo.User; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Service; - -import java.nio.charset.StandardCharsets; - -/** - * @author wsq - */ -@Service -public class PublishAllTask { - @Autowired - private MqttServer mqttServer; - -// @Scheduled(fixedDelay = 1000) -// public void run() { -// mqttServer.publishAll("/test/123", "mica最牛皮".getBytes(StandardCharsets.UTF_8)); -// mqttServer.publishAll("/test/object", User.newUser()); -// } - -} diff --git a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/utils/AESUtil.java b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/utils/AESUtil.java new file mode 100644 index 0000000..32d7355 --- /dev/null +++ b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/utils/AESUtil.java @@ -0,0 +1,217 @@ +package org.dromara.mica.mqtt.server.utils; + + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.Random; + +/** + * AES加密工具类 + */ +public class AESUtil { + + + /** + * 加密Key 需要16位 可用数字与字母组成 + */ + private static String key = "1234567898765432"; + /** + * 偏移量 需要16位 + */ + private static String iv = "4w2Df1xSj5ff662d"; + + private static Logger log = LoggerFactory.getLogger(AESUtil.class); + + private static Base64.Decoder decoder; + + private static Base64.Encoder encoder; + + + + static { + decoder = Base64.getDecoder(); + encoder = Base64.getEncoder(); + } + + + + public static String getSixteenBitString(){ + StringBuffer sb = new StringBuffer(); + String[] chars = new String[]{ + "1","2","3","4","5","6","7","8","9","a","b", + "c","d","e","f","g","h","i","j","k","l","m", + "n","o","p","q","r","s","t","u","v","w","x", + "y","z","A","B","C","D","E","F","G","H","I", + "J","K","L","M","N","O","P","Q","R","S","T", + "U","V","W","X","Y","Z", + }; + int len = chars.length; + Random random = new Random(); + for (int i = 0; i < 16; i++) { + sb.append(chars[random.nextInt(len-1)]); + } + return sb.toString(); + + } + + + + /** + * AES加密 + * @param data + * @param key + * @param iv + * @return + * @throws Exception + */ + public static String encryptAES_CBC(String data,String key,String iv) { + Cipher cipher = null; + try { + cipher = Cipher.getInstance("AES/CBC/NoPadding"); + + int blockSize = cipher.getBlockSize(); + byte[] dataBytes = data.getBytes(); + int dataLength = dataBytes.length; + if (dataLength % blockSize != 0) { + dataLength = dataLength + (blockSize - (dataLength % blockSize)); + } + byte[] plaintext = new byte[dataLength]; + System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length); + SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "AES"); + IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes()); + cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec); + byte[] bytes = cipher.doFinal(plaintext); + return encoder.encodeToString(bytes); + + }catch (Exception e) { + log.error("AES加密失败"); + log.error(e.getMessage()); + + } + + return null; + + } + /** + * AES解密 + * @param data + * @param key + * @param iv + * @return + * @throws Exception + */ + public static String decrptyAES_CBC(String data,String key,String iv){ + try { + byte[] bytes = decoder.decode(data); + Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); + SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "AES"); + IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes()); + cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec); + byte[] plainByte = cipher.doFinal(bytes); + return new String(plainByte).trim(); + }catch (Exception e){ + log.error("AES解密失败"); + log.error(e.getMessage()); + } + + return null; + } + + + /** + * AES加密 + * @param data + * @return + * @throws Exception + */ + public static String encryptAES_ECB(String data,String key) throws Exception{ + Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding"); + int blockSize = cipher.getBlockSize(); + byte[] dataBytes = data.getBytes(); + int dataLength = dataBytes.length; + if(dataLength % blockSize != 0){ + dataLength = dataLength + (blockSize - (dataLength % blockSize)); + } + byte [] plaintext = new byte[dataLength]; + System.arraycopy(dataBytes,0,plaintext,0,dataBytes.length); + SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(),"AES"); + cipher.init(Cipher.ENCRYPT_MODE,secretKey); + byte[] bytes = cipher.doFinal(plaintext); + return encoder.encodeToString(bytes); + + + } + + /** + * AES解密 + * @param data + * @return + * @throws Exception + */ + public static String decrptyAES_ECB(String data,String key) throws Exception{ + // byte[] bytes = decoder.decode(data); + byte[] bytes =Base64.getDecoder().decode(data); + Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding"); + SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(),"AES"); + cipher.init(Cipher.DECRYPT_MODE,secretKey); + byte[] plainByte = cipher.doFinal(bytes); + return bytesToHex(plainByte); + } + private static String bytesToHex(byte[] bytes) { + StringBuilder hexString = new StringBuilder(); + for (byte b : bytes) { + String hex = Integer.toHexString(0xff & b); + if (hex.length() == 1) hexString.append('0'); + hexString.append(hex); + } + return hexString.toString(); + } + + + /** + * gb2312编码 + */ + public static String gb2312decode( String string) throws UnsupportedEncodingException{ + byte[] bytes = new byte[string.length() / 2]; + for(int i = 0; i < bytes.length; i ++){ + byte high = Byte.parseByte(string.substring(i * 2, i * 2 + 1), 16); + byte low = Byte.parseByte(string.substring(i * 2 + 1, i * 2 + 2), 16); + bytes[i] = (byte) (high << 4 | low); + } + return new String(bytes, "gb2312"); + } + + + /** + * UTF8编码 + */ + public static String UTF8decode( String string) throws UnsupportedEncodingException{ + byte[] bytes = new byte[string.length() / 2]; + for(int i = 0; i < bytes.length; i ++){ + byte high = Byte.parseByte(string.substring(i * 2, i * 2 + 1), 16); + byte low = Byte.parseByte(string.substring(i * 2 + 1, i * 2 + 2), 16); + bytes[i] = (byte) (high << 4 | low); + } + return new String(bytes, StandardCharsets.UTF_8); + } + + + public static void main(String[] args) throws Exception{ + String encrypt = "IcDSUR8fdtJ8gLYlZX9qLw=="; + String str = decrptyAES_ECB(encrypt, key); +// String str1 = str.substring(0, 16); + String license = AESUtil.UTF8decode(str); +// System.out.println(gb2312decode(str1)); + System.out.println(license); + } + + + +} diff --git a/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/utils/UuidUtil.java b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/utils/UuidUtil.java new file mode 100644 index 0000000..251b57f --- /dev/null +++ b/example/mica-mqtt-server-spring-boot-example/src/main/java/org/dromara/mica/mqtt/server/utils/UuidUtil.java @@ -0,0 +1,40 @@ +package org.dromara.mica.mqtt.server.utils; + +import java.util.UUID; + +public class UuidUtil { + + public static String[] chars = new String[] { "a", "b", "c", "d", "e", "f", + "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", + "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", + "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", + "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", + "W", "X", "Y", "Z" }; + + + /** + * 获取短UUID + * @return + */ + public static String getShortUuid() { + StringBuffer shortBuffer = new StringBuffer(); + String uuid = UuidUtil.getUuid(); + for (int i = 0; i < 8; i++) { + String str = uuid.substring(i * 4, i * 4 + 4); + int x = Integer.parseInt(str, 16); + shortBuffer.append(chars[x % 0x3E]); // 对62取余 + } + return shortBuffer.toString(); + + } + + /** + * 获得32位UUID + */ + public static String getUuid(){ + String uuid = UUID.randomUUID().toString(); + //去掉“-”符号 + return uuid.replaceAll("-", ""); + } + +} diff --git a/example/mica-mqtt-server-spring-boot-example/src/main/resources/application-dev.yml b/example/mica-mqtt-server-spring-boot-example/src/main/resources/application-dev.yml index 09ea6f8..9c971ba 100644 --- a/example/mica-mqtt-server-spring-boot-example/src/main/resources/application-dev.yml +++ b/example/mica-mqtt-server-spring-boot-example/src/main/resources/application-dev.yml @@ -1,7 +1,7 @@ spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://127.0.0.1:3306/xa_cloud?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true + url: jdbc:mysql://127.0.0.1:3306/xa_cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: root password: root data: diff --git a/example/mica-mqtt-server-spring-boot-example/src/main/resources/mapper/CarInfoMapper.xml b/example/mica-mqtt-server-spring-boot-example/src/main/resources/mapper/CarInfoMapper.xml index 0992191..635265f 100644 --- a/example/mica-mqtt-server-spring-boot-example/src/main/resources/mapper/CarInfoMapper.xml +++ b/example/mica-mqtt-server-spring-boot-example/src/main/resources/mapper/CarInfoMapper.xml @@ -19,6 +19,8 @@ + + @@ -33,7 +35,33 @@