代码优化
This commit is contained in:
@@ -59,7 +59,6 @@
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-spring-boot4-starter</artifactId>
|
||||
@@ -94,6 +93,19 @@
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- JSON 解析器和生成器 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.fastjson2</groupId>
|
||||
<artifactId>fastjson2</artifactId>
|
||||
<version>2.0.23</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Hutool工具包 -->
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>5.8.40</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<String> 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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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<String, String> 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<String, String> 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<String, String> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<CarInfo> {
|
||||
|
||||
List<CarInfo> selectCarInfoList(CarInfo car);
|
||||
|
||||
}
|
||||
|
||||
@@ -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<CarParkItem> {
|
||||
|
||||
@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);
|
||||
}
|
||||
@@ -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<CarParkRecord> {
|
||||
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package org.dromara.mica.mqtt.server.pojo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class User<T> {
|
||||
private String name;
|
||||
private T girlfriend;
|
||||
|
||||
public static User newUser(){
|
||||
User<User> user1 = new User();
|
||||
user1.setName("name1");
|
||||
|
||||
User<User> user2 = new User();
|
||||
user2.setName("name2");
|
||||
user2.setGirlfriend(user1);
|
||||
return user2;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
}
|
||||
@@ -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> {
|
||||
|
||||
CarInfo selectCarInfoBySn(String sn);
|
||||
|
||||
List<CarInfo> selectCarInfoList(CarInfo car);
|
||||
}
|
||||
|
||||
@@ -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> {
|
||||
|
||||
CarParkItem selectBySn(String sn);
|
||||
}
|
||||
@@ -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<CarParkRecord> {
|
||||
|
||||
int updateByClientId(CarParkRecord carParkRecord);
|
||||
|
||||
void delByClientId(CarParkRecord carParkRecord);
|
||||
}
|
||||
@@ -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<CarInfoMapper, CarInfo> implements ICarInfoService {
|
||||
|
||||
@@ -20,4 +22,9 @@ public class CarInfoServiceImpl extends ServiceImpl<CarInfoMapper, CarInfo> impl
|
||||
|
||||
return new CarInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CarInfo> selectCarInfoList(CarInfo car) {
|
||||
return carInfoMapper.selectCarInfoList(car);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<CarParkItemMapper, CarParkItem> implements ICarParkItemService {
|
||||
|
||||
@Autowired
|
||||
CarParkItemMapper carParkItemMapper;
|
||||
|
||||
@Override
|
||||
public CarParkItem selectBySn(String sn) {
|
||||
return carParkItemMapper.selectBySn(sn);
|
||||
}
|
||||
}
|
||||
@@ -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<CarParkRecordMapper, CarParkRecord> implements ICarParkRecordService {
|
||||
|
||||
@Autowired
|
||||
CarParkRecordMapper carParkRecordMapper;
|
||||
|
||||
@Override
|
||||
public int updateByClientId(CarParkRecord carParkRecord) {
|
||||
int id = carParkRecordMapper.update(carParkRecord, new QueryWrapper<CarParkRecord>().eq("client_id", carParkRecord.getClientId()));
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delByClientId(CarParkRecord carParkRecord) {
|
||||
carParkRecordMapper.delete(new QueryWrapper<CarParkRecord>().eq("client_id", carParkRecord.getClientId()));
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.util.List;
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class HeartbeatOnLine {
|
||||
public class HeartbeatOnLineTask {
|
||||
|
||||
@Autowired
|
||||
RedisService redisService;
|
||||
@@ -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<CarInfo> 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<CarInfo> carInfos = carInfoService.selectCarInfoList(carDel);
|
||||
if (CollUtil.isNotEmpty(carInfos)) {
|
||||
//需要下发的设备
|
||||
List<String> snList = carInfos.stream().map(CarInfo::getSn).distinct().toList();
|
||||
for (String sn : snList) {
|
||||
if (!redisService.hasKey(CacheConstants.EQUIPMENT_HEARTBEAT + sn)) {
|
||||
log.error("删除车牌,设备:{},无心跳", sn);
|
||||
continue;
|
||||
}
|
||||
|
||||
//车辆授权列表
|
||||
List<CarParkRecord> 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<String> 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<String> 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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("-", "");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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:
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
<result property="delFlag" column="del_flag" />
|
||||
<result property="sync" column="sync" />
|
||||
<result property="overclockCard" column="overclock_card" />
|
||||
<result property="sn" column="sequence" />
|
||||
<result property="carParkRecordId" column="carParkRecordId" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectCarInfoVo">
|
||||
@@ -33,7 +35,33 @@
|
||||
</sql>
|
||||
|
||||
<select id="selectCarInfoList" parameterType="org.dromara.mica.mqtt.server.entity.CarInfo" resultMap="CarInfoResult">
|
||||
<include refid="selectCarInfoVo"/>
|
||||
SELECT
|
||||
ci.customer_id,
|
||||
ci.enable_time,
|
||||
ci.overdue_time,
|
||||
ci.`enable`,
|
||||
ci.plate,
|
||||
ci.time_seg_enable,
|
||||
ci.seg_time,
|
||||
ci.need_alarm,
|
||||
ci.vehicle_code,
|
||||
ci.vehicle_comment,
|
||||
ci.people_id,
|
||||
ci.del_flag,
|
||||
ci.sync,
|
||||
ci.remark,
|
||||
ci.create_by,
|
||||
ci.create_time,
|
||||
ci.update_by,
|
||||
ci.update_time,
|
||||
ci.overclock_card,
|
||||
se.sequence,
|
||||
cpr.id as carParkRecordId
|
||||
FROM car_info ci
|
||||
LEFT JOIN car_park cp ON ci.park_id = cp.id
|
||||
LEFT JOIN sys_people p ON ci.people_id = p.id
|
||||
LEFT JOIN car_park_record cpr ON cpr.customer_id = ci.customer_id
|
||||
LEFT JOIN sys_equipment se ON cpr.equipment_id = se.id
|
||||
<where>
|
||||
<if test="enableTime != null "> and ci.enable_time = #{enableTime}</if>
|
||||
<if test="overdueTime != null "> and ci.overdue_time = #{overdueTime}</if>
|
||||
|
||||
Reference in New Issue
Block a user