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 @@