1. 微信服务添加用户相关接口
2. 微信服务添加云平台中订单相关接口 3. 云平台服务完善优化MQTT启动相关流程 4. 云平台服务开启多线程处理MQTT业务消息 5. 云平台服务添加换电新流程中请求订单的处理逻辑 6. 云平台服务换电新流程添加 MQTT消息测试
This commit is contained in:
parent
7011024e46
commit
dda394c898
@ -71,4 +71,17 @@ public interface HDConstant {
|
||||
String HD_STATION_SECRET_KEY_AES_PREFIX = "hd:station:secretKey:aes:";
|
||||
|
||||
|
||||
/**
|
||||
* 微信服务请求头中权限验证字段
|
||||
*/
|
||||
String WECHAT_SERVER_AUTHORIZATION_KEY = "WXUID";
|
||||
|
||||
/**
|
||||
* 微信登录缓存数据前缀
|
||||
*/
|
||||
String openidPrefix = "hd:wechat:login:openid:";
|
||||
String unionidPrefix = "hd:wechat:login:unionid:";
|
||||
String sessionKeyPrefix = "hd:wechat:login:sessionKey:";
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package com.evotech.hd.wechat.dao;
|
||||
package com.evotech.hd.common.core.dao.wechat;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.evotech.hd.wechat.entity.WechatUser;
|
||||
import com.evotech.hd.common.core.entity.wechat.WechatUser;
|
||||
|
||||
/**
|
||||
* @author zrb
|
||||
@ -12,6 +12,8 @@ import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.media.Schema.RequiredMode;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
@ -30,30 +32,34 @@ public class OrderSwapBatteryPre implements Serializable {
|
||||
private Integer pkId;
|
||||
|
||||
@Schema(description = "来源:1-小程序,2-云端,3-站端", requiredMode = RequiredMode.REQUIRED)
|
||||
private Integer from;
|
||||
@NotNull
|
||||
private Integer source;
|
||||
|
||||
@Schema(description = "来源是站端时,记录发送Id,其他来源不需要", hidden = true)
|
||||
private String sourceId;
|
||||
|
||||
@Schema(description = "预约人编码")
|
||||
@Schema(description = "预约人编码", requiredMode = RequiredMode.REQUIRED)
|
||||
private String ucode;
|
||||
|
||||
@Schema(description = "预约人姓名")
|
||||
@Schema(description = "预约人姓名", requiredMode = RequiredMode.REQUIRED)
|
||||
private String uname;
|
||||
|
||||
@Schema(description = "手机号码")
|
||||
@Schema(description = "手机号码", requiredMode = RequiredMode.REQUIRED)
|
||||
private String phone;
|
||||
|
||||
@Schema(description = "车牌号")
|
||||
@Schema(description = "车牌号", requiredMode = RequiredMode.REQUIRED)
|
||||
@NotBlank
|
||||
private String plateNum;
|
||||
|
||||
@Schema(description = "换电站编码")
|
||||
@Schema(description = "换电站编码", requiredMode = RequiredMode.REQUIRED)
|
||||
@NotBlank
|
||||
private String stationCode;
|
||||
|
||||
@Schema(description = "换电站名称")
|
||||
@Schema(description = "换电站名称", requiredMode = RequiredMode.REQUIRED)
|
||||
@NotBlank
|
||||
private String stationName;
|
||||
|
||||
@Schema(description = "预约时间", hidden = true)
|
||||
@Schema(description = "预约时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
|
||||
private Date reservationTime;
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.evotech.hd.cloud.entity.request;
|
||||
package com.evotech.hd.common.core.entity.cloud;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@ -23,6 +23,9 @@ public class PageListSwapOrderRequest extends BasePageRequest {
|
||||
|
||||
@Schema(description = "车牌号")
|
||||
private String plateNum;
|
||||
|
||||
@Schema(description = "多车牌号")
|
||||
private String plateNums;
|
||||
|
||||
@Schema(description = "订单时间开始", example = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@ -1,4 +1,4 @@
|
||||
package com.evotech.hd.wechat.entity;
|
||||
package com.evotech.hd.common.core.entity.wechat;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@ -20,13 +20,14 @@ import lombok.Setter;
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("yt_t_wechat_user")
|
||||
@Schema(name = "WechatUser", description = "小程序用户信息")
|
||||
@TableName("hd_wechat.yt_t_wechat_user")
|
||||
@Schema(name = "小程序用户信息")
|
||||
public class WechatUser implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value = "pk_id", type = IdType.AUTO)
|
||||
@Schema(description = "id", hidden = true)
|
||||
private Integer pkId;
|
||||
|
||||
@Schema(description = "微信用户id")
|
||||
@ -46,9 +47,21 @@ public class WechatUser implements Serializable {
|
||||
|
||||
@Schema(description = "用户头像")
|
||||
private String avatarUrl;
|
||||
|
||||
@Schema(description = "名称")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "用户性别:1-男;2-女")
|
||||
private Boolean gender;
|
||||
private Integer gender;
|
||||
|
||||
@Schema(description = "类型:1-独立账户,2-公司员工子账户")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "父账户编码")
|
||||
private String pcode;
|
||||
|
||||
@Schema(description = "父账户名称")
|
||||
private String pname;
|
||||
|
||||
@Schema(description = "创建人", hidden = true)
|
||||
private String creater;
|
||||
@ -0,0 +1,52 @@
|
||||
package com.evotech.hd.cloud.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springdoc.core.annotations.ParameterObject;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.evotech.hd.cloud.entity.request.PageListWechatUserRequest;
|
||||
import com.evotech.hd.cloud.service.WechatUserService;
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.evotech.hd.common.core.entity.wechat.WechatUser;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
@Tag(name = "微信用户")
|
||||
@RestController
|
||||
@RequestMapping("/wechat/user")
|
||||
@ApiSupport(order = 11)
|
||||
public class WechatUserController {
|
||||
|
||||
@Resource
|
||||
private WechatUserService wechatUserService;
|
||||
|
||||
|
||||
@Operation(summary = "查询")
|
||||
@GetMapping("/list")
|
||||
public Result<List<WechatUser>> list(@ParameterObject PageListWechatUserRequest plwur) {
|
||||
return wechatUserService.list(plwur);
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "更新手机号/名称")
|
||||
@PostMapping("/alterphone")
|
||||
public Result<Integer> alterPhone(String wuid, String phone, String name) {
|
||||
return wechatUserService.alterPhone(wuid, phone, name);
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "关联公司")
|
||||
@PostMapping("/companyrelation")
|
||||
public Result<Integer> companyRelation(String wuid, String pcode, String pname) {
|
||||
return wechatUserService.companyRelation(wuid, pcode, pname);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -21,7 +21,7 @@ import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
|
||||
@Tag(name = "交易详情")
|
||||
@Tag(name = "充值订单")
|
||||
@ApiSupport(order = 25)
|
||||
@RestController
|
||||
@RequestMapping("/order/recharge")
|
||||
|
||||
@ -8,12 +8,12 @@ import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.evotech.hd.cloud.entity.request.PageListSwapOrderRequest;
|
||||
import com.evotech.hd.cloud.service.OrderSwapBatteryService;
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryStep;
|
||||
import com.evotech.hd.common.core.entity.cloud.PageListSwapOrderRequest;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
|
||||
@ -51,8 +51,8 @@ public class OrderSwapBatteryController {
|
||||
@Operation(summary = "查询预约")
|
||||
@GetMapping("/pre/list")
|
||||
@ApiOperationSupport(order = 3)
|
||||
public Result<List<OrderSwapBatteryPre>> listPre(String plateNum, Integer status, String userId) {
|
||||
return orderSwapBatteryService.listPre(plateNum, status, userId);
|
||||
public Result<List<OrderSwapBatteryPre>> listPre(String plateNum, Integer status, String ucode, String stationCode) {
|
||||
return orderSwapBatteryService.listPre(plateNum, status, ucode, stationCode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,81 @@
|
||||
package com.evotech.hd.cloud.controller.test;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.springdoc.core.annotations.ParameterObject;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.evotech.hd.cloud.controller.test.service.MqttTestUtil;
|
||||
import com.evotech.hd.cloud.mqtt.enums.MqttMessageTypeEnum;
|
||||
import com.evotech.hd.cloud.mqtt.enums.RequestFunctionTypesEnum;
|
||||
import com.evotech.hd.cloud.mqtt.enums.StateFunctionTypesEnum;
|
||||
import com.evotech.hd.cloud.mqtt.message.MqttMessageHeader;
|
||||
import com.evotech.hd.cloud.mqtt.message.dto.newer.req.order.OrderByPlateNumReq;
|
||||
import com.evotech.hd.cloud.mqtt.message.dto.newer.state.OrderStatus;
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
@Tag(name = "Mqtt消息测试")
|
||||
@ApiSupport(order = 700)
|
||||
@RestController
|
||||
@RequestMapping("/test/mqtt")
|
||||
public class MqttMessageTestController {
|
||||
|
||||
public static String topicPrefix = "ZZHD/{}/S2M/{}";
|
||||
|
||||
@Resource
|
||||
private MqttTestUtil mqttTestUtil;
|
||||
|
||||
|
||||
@Operation(summary = "车牌号生成订单")
|
||||
@PostMapping("/orderByPlateNum")
|
||||
@ApiOperationSupport(order = 1)
|
||||
public Result<String> orderByPlateNum(String plateNum, String stationCode) {
|
||||
|
||||
OrderByPlateNumReq req = new OrderByPlateNumReq();
|
||||
req.setOrderRequestId("O" + DateUtil.format(new Date(), DatePattern.PURE_DATETIME_MS_FORMATTER));
|
||||
req.setPlateNum(plateNum);
|
||||
req.setStationCode(stationCode);
|
||||
JSONObject jo = JSONUtil.parseObj(req);
|
||||
|
||||
String topic = mqttTestUtil.getTopic(stationCode, MqttMessageTypeEnum.REQUEST.getType());
|
||||
MqttMessageHeader header = mqttTestUtil.getHeader(RequestFunctionTypesEnum.FUN_ORDERBYPLATENUM.getFunction());
|
||||
|
||||
mqttTestUtil.publishMessage(stationCode, jo, topic, header);
|
||||
|
||||
return new Result<String>().success("OK");
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "反馈订单状态")
|
||||
@PostMapping("/orderStatus")
|
||||
@ApiOperationSupport(order = 2)
|
||||
public Result<String> orderStatus(@ParameterObject OrderStatus orderStatus, String stationCode) {
|
||||
|
||||
JSONObject jo = JSONUtil.parseObj(orderStatus);
|
||||
|
||||
String topic = mqttTestUtil.getTopic(stationCode, MqttMessageTypeEnum.STATE.getType());
|
||||
MqttMessageHeader header = mqttTestUtil.getHeader(StateFunctionTypesEnum.FUN_ORDERSTATUS.getFunction());
|
||||
|
||||
mqttTestUtil.publishMessage(stationCode, jo, topic, header);
|
||||
|
||||
return new Result<String>().success("OK");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -1,9 +1,7 @@
|
||||
package com.evotech.hd.cloud.mqtt.config;
|
||||
package com.evotech.hd.cloud.controller.test.service;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Date;
|
||||
|
||||
import org.eclipse.paho.client.mqttv3.MqttClient;
|
||||
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
|
||||
import org.eclipse.paho.client.mqttv3.MqttDeliveryToken;
|
||||
@ -11,34 +9,25 @@ import org.eclipse.paho.client.mqttv3.MqttException;
|
||||
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
||||
import org.eclipse.paho.client.mqttv3.MqttTopic;
|
||||
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Configuration
|
||||
@Service
|
||||
@Slf4j
|
||||
public class MqttConfig {
|
||||
|
||||
@Resource
|
||||
private Environment env;
|
||||
|
||||
private MqttClient cloudClient;
|
||||
public class MqttConfigService {
|
||||
|
||||
@Bean
|
||||
MqttProperties mpProperties() {
|
||||
return new MqttProperties();
|
||||
}
|
||||
public static String mqttUrl = "tcp://192.168.5.210:1883";
|
||||
|
||||
@Resource
|
||||
private MqttTestCallback mqttTestCallback;
|
||||
|
||||
|
||||
/**
|
||||
* 客户端连接服务端
|
||||
*/
|
||||
public void connect() {
|
||||
int port = env.getProperty("server.port", Integer.class) == null?8080:env.getProperty("server.port", Integer.class);
|
||||
public MqttClient connect() {
|
||||
String address = "127.0.0.1";
|
||||
try {
|
||||
address = InetAddress.getLocalHost().getHostAddress();
|
||||
@ -46,14 +35,15 @@ public class MqttConfig {
|
||||
address = "192.168.5.213";
|
||||
e.printStackTrace();
|
||||
}
|
||||
String clientId = address + "-" + port + "-" + DateUtil.format(new Date(), DatePattern.PURE_DATETIME_FORMATTER);
|
||||
String clientId = "testClient" + "-" + address;
|
||||
try {
|
||||
cloudClient = new MqttClient(mpProperties().getUrl(), clientId, new MemoryPersistence());
|
||||
MqttClient testClient = new MqttClient(mqttUrl, clientId, new MemoryPersistence());
|
||||
//连接设置
|
||||
MqttConnectOptions options = connectOptions();
|
||||
//设置回调
|
||||
cloudClient.setCallback(new MyMqttCallback());
|
||||
cloudClient.connect(options);
|
||||
testClient.setCallback(mqttTestCallback);
|
||||
testClient.connect(options);
|
||||
return testClient;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("连接MQTT服务出错:" + e.getMessage());
|
||||
@ -74,20 +64,20 @@ public class MqttConfig {
|
||||
*/
|
||||
options.setCleanSession(true);
|
||||
//设置连接用户名
|
||||
options.setUserName(mpProperties().getUsername());
|
||||
options.setUserName("test");
|
||||
//设置连接密码
|
||||
options.setPassword(mpProperties().getPassword().toCharArray());
|
||||
options.setPassword("test1234".toCharArray());
|
||||
//设置超时时间,单位为秒
|
||||
options.setConnectionTimeout(mpProperties().getConnectionTimeout());
|
||||
options.setConnectionTimeout(30);
|
||||
//设置心跳时间 单位为秒,
|
||||
options.setKeepAliveInterval(mpProperties().getKeepAliveInterval());
|
||||
options.setKeepAliveInterval(60);
|
||||
//设置遗嘱消息的话题,若客户端和服务器之间的连接意外断开,服务器将发布客户端的遗嘱信息
|
||||
// options.setWill("willTopic", (clientId + "与服务器断开连接").getBytes(), 0, false);
|
||||
return options;
|
||||
}
|
||||
|
||||
|
||||
public void publish(String message, String topic) {
|
||||
public void publish(MqttClient testClient, String message, String topic) {
|
||||
MqttMessage mqttMessage = new MqttMessage();
|
||||
/**
|
||||
* Qos 0 : 这个消息最多发送一次,不能被持久化到磁盘,不能通过网络被传递,一般内部消息转换
|
||||
@ -100,7 +90,7 @@ public class MqttConfig {
|
||||
// 消息内容
|
||||
mqttMessage.setPayload(message.getBytes());
|
||||
// 主题的目的地,用于发布/订阅信息
|
||||
MqttTopic mqttTopic = cloudClient.getTopic(topic);
|
||||
MqttTopic mqttTopic = testClient.getTopic(topic);
|
||||
// 提供一种机制来跟踪消息的传递进度
|
||||
// 用于在以非阻塞方式(在后台运行)执行发布是跟踪消息的传递进度
|
||||
MqttDeliveryToken token;
|
||||
@ -112,6 +102,8 @@ public class MqttConfig {
|
||||
} catch (MqttException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -119,13 +111,13 @@ public class MqttConfig {
|
||||
* 订阅主题
|
||||
*/
|
||||
public void subscribe(String topic) {
|
||||
try {
|
||||
cloudClient.subscribe(topic, mpProperties().getQos());
|
||||
log.info("\r\n=====>>>MQTT订阅主题 {} 成功...", topic);
|
||||
} catch (MqttException e) {
|
||||
e.printStackTrace();
|
||||
log.error("\r\n=====>>>MQTT订阅主题 {} 失败。。。", topic);
|
||||
}
|
||||
// try {
|
||||
// cloudClient.subscribe(topic, mpProperties().getQos());
|
||||
// log.info("\r\n=====>>>MQTT订阅主题 {} 成功...", topic);
|
||||
// } catch (MqttException e) {
|
||||
// e.printStackTrace();
|
||||
// log.error("\r\n=====>>>MQTT订阅主题 {} 失败。。。", topic);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,52 @@
|
||||
package com.evotech.hd.cloud.controller.test.service;
|
||||
|
||||
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
|
||||
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
|
||||
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MqttTestCallback implements MqttCallbackExtended {
|
||||
|
||||
/**
|
||||
* 建立连接后
|
||||
*/
|
||||
@Override
|
||||
public void connectComplete(boolean reconnect, String serverURI) {
|
||||
log.info("\r\n=====>>>MQTT测试客户端连接成功:{}", serverURI);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 与服务器断开的回调
|
||||
*/
|
||||
@Override
|
||||
public void connectionLost(Throwable cause) {
|
||||
log.error("\r\n=====>>>MQTT与服务器断开连接:{}", cause.getMessage());
|
||||
cause.printStackTrace();
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息到达的回调
|
||||
*/
|
||||
@Override
|
||||
public void messageArrived(String topic, MqttMessage message) throws Exception {
|
||||
log.info("\r\n=====>>>MQTT接收到消息主题:{}---{}", topic, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息发布成功的回调
|
||||
*/
|
||||
@Override
|
||||
public void deliveryComplete(IMqttDeliveryToken token) {
|
||||
log.info("\r\n=====>>>MQTT消息发送成功,id:{}", token.getMessageId());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,79 @@
|
||||
package com.evotech.hd.cloud.controller.test.service;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.eclipse.paho.client.mqttv3.MqttClient;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.evotech.hd.cloud.mqtt.message.MessageTopic;
|
||||
import com.evotech.hd.cloud.mqtt.message.MqttMessageHeader;
|
||||
import com.evotech.hd.cloud.mqtt.message.MyMqttMessage;
|
||||
import com.evotech.hd.cloud.mqtt.message.handle.MessageUtilService;
|
||||
import com.evotech.hd.common.core.utils.SnowflakeUtil;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.crypto.Mode;
|
||||
import cn.hutool.crypto.Padding;
|
||||
import cn.hutool.crypto.symmetric.AES;
|
||||
import cn.hutool.crypto.symmetric.SymmetricCrypto;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
@Component
|
||||
public class MqttTestUtil {
|
||||
|
||||
|
||||
@Resource
|
||||
private MqttConfigService mqttService;
|
||||
@Resource
|
||||
private MessageUtilService messageUtilService;
|
||||
|
||||
|
||||
|
||||
public void publishMessage(String stationCode, JSONObject jo, String topic, MqttMessageHeader header) {
|
||||
// 1. 获取AES
|
||||
JSONObject aesJo = messageUtilService.getAESKey(stationCode);
|
||||
SymmetricCrypto aes = new AES(Mode.CBC, Padding.PKCS5Padding, aesJo.getStr("aesSecretKey").getBytes(), aesJo.getStr("aesIv").getBytes());
|
||||
// 2. 数据
|
||||
MyMqttMessage message = new MyMqttMessage();
|
||||
message.setHeader(header);
|
||||
message.setDataBody(jo);
|
||||
String encrypt = aes.encryptBase64(JSONUtil.toJsonStr(message));
|
||||
// 3. 发送MQTT消息
|
||||
MqttClient testClient = mqttService.connect();
|
||||
mqttService.publish(testClient, encrypt, topic);
|
||||
|
||||
// 4. 断开连接
|
||||
try {
|
||||
testClient.disconnect(1000L);
|
||||
testClient.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public MqttMessageHeader getHeader(String funType) {
|
||||
MqttMessageHeader header = new MqttMessageHeader();
|
||||
header.setVersion("V1");
|
||||
header.setIndex(SnowflakeUtil.getIdStr());
|
||||
header.setTimeStamp(DateUtil.format(new Date(), DatePattern.NORM_DATETIME_FORMATTER));
|
||||
header.setFunction(funType);
|
||||
return header;
|
||||
}
|
||||
|
||||
|
||||
public String getTopic(String stationCode, String messageType) {
|
||||
MessageTopic topic = new MessageTopic();
|
||||
topic.setDataDirection("S2M");
|
||||
topic.setStationCode(stationCode);
|
||||
topic.setMessageType(messageType);
|
||||
return topic.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
package com.evotech.hd.cloud.entity.request;
|
||||
|
||||
import com.evotech.hd.common.core.entity.BasePageRequest;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
|
||||
@Data
|
||||
@Schema(name = "查询微信用户请求参数", hidden = true)
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
public class PageListWechatUserRequest extends BasePageRequest {
|
||||
|
||||
@Schema(description = "微信用户id")
|
||||
private String wuid;
|
||||
|
||||
@Schema(description = "手机号")
|
||||
private String phoneNumber;
|
||||
|
||||
@Schema(description = "用户昵称")
|
||||
private String nickName;
|
||||
|
||||
@Schema(description = "用户性别:1-男;2-女")
|
||||
private Integer gender;
|
||||
|
||||
@Schema(description = "名称")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "类型:1-独立账户,2-公司员工子账户")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "父账户编码")
|
||||
private String pcode;
|
||||
|
||||
}
|
||||
@ -1,54 +0,0 @@
|
||||
package com.evotech.hd.cloud.mqtt;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.evotech.hd.cloud.dao.BatteryStationDao;
|
||||
import com.evotech.hd.cloud.mqtt.config.MqttConfig;
|
||||
import com.evotech.hd.common.core.entity.cloud.BatteryStation;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
@Component
|
||||
@Order(value = 20)
|
||||
public class MqttInit implements ApplicationRunner {
|
||||
|
||||
|
||||
@Resource
|
||||
private MqttConfig mqttConfig;
|
||||
@Resource
|
||||
private BatteryStationDao batteryStationDao;
|
||||
|
||||
|
||||
private String[] mqttMessageTypeArr = {"state", "event", "request", "response", "keepalive", "encryptKeyReq"};
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
// 连接mqtt
|
||||
mqttConfig.connect();
|
||||
// 订阅主题
|
||||
List<BatteryStation> stationList = batteryStationDao.selectList(new QueryWrapper<BatteryStation>().eq("del_flag", 0));
|
||||
if (stationList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<String> stationCodeList = stationList.stream().map(i -> i.getCode()).toList();
|
||||
for (int i = 0; i < stationCodeList.size(); i++) {
|
||||
String stationCode = stationCodeList.get(i);
|
||||
String topic = "ZZHD/" + stationCode + "/S2M/";
|
||||
for (int j = 0; j < mqttMessageTypeArr.length; j++) {
|
||||
mqttConfig.subscribe(topic + mqttMessageTypeArr[j]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,117 @@
|
||||
package com.evotech.hd.cloud.mqtt.config;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.eclipse.paho.client.mqttv3.MqttClient;
|
||||
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
|
||||
import org.eclipse.paho.client.mqttv3.MqttException;
|
||||
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
|
||||
@Component
|
||||
@Order(value = 20)
|
||||
@Slf4j
|
||||
public class MqttConnectInit implements ApplicationRunner {
|
||||
|
||||
// 用来存放客户端, ConcurrentMap是线程安全的
|
||||
static ConcurrentHashMap<String, MqttClient> mqttClientMap = new ConcurrentHashMap<>();
|
||||
|
||||
@Resource
|
||||
private MyMqttCallback mqttCallback;
|
||||
@Resource
|
||||
private MqttProperties mpProperties;
|
||||
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
connect();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 客户端连接服务端
|
||||
*/
|
||||
public MqttClient connect() {
|
||||
String address = "127.0.0.1";
|
||||
try {
|
||||
address = InetAddress.getLocalHost().getHostAddress();
|
||||
} catch (UnknownHostException e) {
|
||||
address = "192.168.5.213";
|
||||
e.printStackTrace();
|
||||
}
|
||||
// String clientId = address + "-" + port + "-" + DateUtil.format(new Date(), DatePattern.PURE_DATETIME_FORMATTER);
|
||||
String clientId = "cloudClient" + "-" + address + "-" + DateUtil.format(new Date(), DatePattern.PURE_DATETIME_FORMATTER);;
|
||||
try {
|
||||
MqttClient cloudClient = new MqttClient(mpProperties.getUrl(), clientId, new MemoryPersistence());
|
||||
//连接设置
|
||||
MqttConnectOptions options = connectOptions();
|
||||
//设置回调
|
||||
cloudClient.setCallback(mqttCallback);
|
||||
cloudClient.connect(options);
|
||||
mqttClientMap.put("cloudClient", cloudClient);
|
||||
return cloudClient;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("连接MQTT服务出错:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private MqttConnectOptions connectOptions() {
|
||||
MqttConnectOptions options = new MqttConnectOptions();
|
||||
/**
|
||||
* 1. 这个类是代理类,其实是MqttAsyncClient干活。它
|
||||
* 使用无阻塞运行在后台的轻量级链接server。基于Tcp,包含了ssl;
|
||||
* 2. 为了确保消息通过网络被送达和重启客户端带有质量标志的消息要求被保存直到重新被送达。
|
||||
* mqtt提供了一种自己持久化机制来保存这些消息。MqttDefaultFilePersistence是默认方式,
|
||||
* 如果为null则为瞬时消息保存在内存中。MqttClientPersistence可以自己现实接口;
|
||||
* 3. 如果在connecting中MqttConnectOptions.setCleanSession(boolean)这个flag,
|
||||
* 为true也就说,如果client掉线disconnect,下次重连,将清空内存persistence消息,
|
||||
* 如果为false,就会使用持久化机制去重传
|
||||
*/
|
||||
options.setCleanSession(true);
|
||||
//设置连接用户名
|
||||
options.setUserName(mpProperties.getUsername());
|
||||
//设置连接密码
|
||||
options.setPassword(mpProperties.getPassword().toCharArray());
|
||||
//设置超时时间,单位为秒
|
||||
options.setConnectionTimeout(mpProperties.getConnectionTimeout());
|
||||
//设置心跳时间 单位为秒,
|
||||
options.setKeepAliveInterval(mpProperties.getKeepAliveInterval());
|
||||
//设置遗嘱消息的话题,若客户端和服务器之间的连接意外断开,服务器将发布客户端的遗嘱信息
|
||||
// options.setWill("willTopic", (clientId + "与服务器断开连接").getBytes(), 0, false);
|
||||
// 自动重连
|
||||
options.setAutomaticReconnect(true);
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
|
||||
@PreDestroy
|
||||
public void PreDestroyComplete() {
|
||||
log.info("===>>>程序要关闭了...");
|
||||
MqttClient cloudClient = MqttConnectInit.mqttClientMap.get("cloudClient");
|
||||
try {
|
||||
cloudClient.disconnect();
|
||||
cloudClient.close();
|
||||
log.info("=====>>>关闭了MQTT");
|
||||
} catch (MqttException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
package com.evotech.hd.cloud.mqtt.config;
|
||||
|
||||
import org.eclipse.paho.client.mqttv3.MqttClient;
|
||||
import org.eclipse.paho.client.mqttv3.MqttDeliveryToken;
|
||||
import org.eclipse.paho.client.mqttv3.MqttException;
|
||||
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
||||
import org.eclipse.paho.client.mqttv3.MqttTopic;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class MqttPublishMessage {
|
||||
|
||||
public void publish(String message, String topic) {
|
||||
MqttClient cloudClient = MqttConnectInit.mqttClientMap.get("cloudClient");
|
||||
MqttMessage mqttMessage = new MqttMessage();
|
||||
/**
|
||||
* Qos 0 : 这个消息最多发送一次,不能被持久化到磁盘,不能通过网络被传递,一般内部消息转换
|
||||
* Qos 1 : 这个消息至少发送一次,能被重传,能持久化,能通过网络传递,需要实现MqttConnectOptions中的持久化,否则,挂了以后,不能重传。
|
||||
* Qos 2 : 这个消息精准只发一次,能持久化,能通过网络传递,客户端和服务器都会收到消息确认
|
||||
*/
|
||||
mqttMessage.setQos(2);
|
||||
// 是否保留最后一条消息
|
||||
mqttMessage.setRetained(false);
|
||||
// 消息内容
|
||||
mqttMessage.setPayload(message.getBytes());
|
||||
// 主题的目的地,用于发布/订阅信息
|
||||
MqttTopic mqttTopic = cloudClient.getTopic(topic);
|
||||
// 提供一种机制来跟踪消息的传递进度
|
||||
// 用于在以非阻塞方式(在后台运行)执行发布是跟踪消息的传递进度
|
||||
MqttDeliveryToken token;
|
||||
try {
|
||||
// 将指定消息发布到主题,但不等待消息传递完成,返回的token可用于跟踪消息的传递状态
|
||||
// 一旦此方法干净地返回,消息就已被客户端接受发布,当连接可用,将在后台完成消息传递。
|
||||
token = mqttTopic.publish(mqttMessage);
|
||||
token.waitForCompletion();
|
||||
} catch (MqttException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
package com.evotech.hd.cloud.mqtt.config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.paho.client.mqttv3.MqttClient;
|
||||
import org.eclipse.paho.client.mqttv3.MqttException;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.evotech.hd.cloud.dao.BatteryStationDao;
|
||||
import com.evotech.hd.common.core.entity.cloud.BatteryStation;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Service
|
||||
@EnableAsync
|
||||
@Slf4j
|
||||
public class MqttSubscribeService {
|
||||
|
||||
static String[] mqttMessageTypeArr = {"state", "event", "request", "response", "keepalive", "encryptKeyReq"};
|
||||
|
||||
@Resource
|
||||
private BatteryStationDao batteryStationDao;
|
||||
@Resource
|
||||
private MqttProperties mpProperties;
|
||||
|
||||
|
||||
@Async("taskExecutor")
|
||||
public void subscribe(MqttClient cloudClient) {
|
||||
log.info("\r\n=====>>>MQTT开始订阅主题>>>");
|
||||
// 订阅主题
|
||||
List<BatteryStation> stationList = batteryStationDao.selectList(new QueryWrapper<BatteryStation>().eq("del_flag", 0));
|
||||
if (stationList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<String> stationCodeList = stationList.stream().map(i -> i.getCode()).toList();
|
||||
for (int i = 0; i < stationCodeList.size(); i++) {
|
||||
String stationCode = stationCodeList.get(i);
|
||||
String topicPrefix = "YTHD/" + stationCode + "/S2M/";
|
||||
for (int j = 0; j < mqttMessageTypeArr.length; j++) {
|
||||
String topic = topicPrefix + mqttMessageTypeArr[j];
|
||||
try {
|
||||
cloudClient.subscribe(topic, mpProperties.getQos());
|
||||
log.info("\r\n=====>>>MQTT订阅主题 {} 成功...", topic);
|
||||
} catch (MqttException e) {
|
||||
e.printStackTrace();
|
||||
log.error("\r\n=====>>>MQTT订阅主题 {} 失败。。。", topic);
|
||||
}
|
||||
}
|
||||
}
|
||||
log.info("\r\n=====>>>MQTT订阅完成<<<===");
|
||||
}
|
||||
}
|
||||
@ -2,12 +2,12 @@ package com.evotech.hd.cloud.mqtt.config;
|
||||
|
||||
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
|
||||
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
|
||||
import org.eclipse.paho.client.mqttv3.MqttClient;
|
||||
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.evotech.hd.cloud.mqtt.message.MessageTopic;
|
||||
import com.evotech.hd.cloud.mqtt.message.handle.MqttMessageHandle;
|
||||
|
||||
import com.evotech.hd.cloud.mqtt.message.handle.MqttMessageHandleService;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@ -16,10 +16,13 @@ import lombok.extern.slf4j.Slf4j;
|
||||
public class MyMqttCallback implements MqttCallbackExtended {
|
||||
|
||||
@Resource
|
||||
private MqttMessageHandle messageHandle;
|
||||
private MqttMessageHandleService messageService;
|
||||
@Resource
|
||||
private MqttSubscribeService mqttSubscribeService;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@ -28,7 +31,14 @@ public class MyMqttCallback implements MqttCallbackExtended {
|
||||
@Override
|
||||
public void connectComplete(boolean reconnect, String serverURI) {
|
||||
log.info("\r\n=====>>>MQTT连接成功:{}", serverURI);
|
||||
|
||||
// 在回调中订阅,这样自动重连后,还会自动订阅
|
||||
try {
|
||||
Thread.sleep(1000L);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
MqttClient cloudClient = MqttConnectInit.mqttClientMap.get("cloudClient");
|
||||
mqttSubscribeService.subscribe(cloudClient);
|
||||
}
|
||||
|
||||
|
||||
@ -48,12 +58,12 @@ public class MyMqttCallback implements MqttCallbackExtended {
|
||||
public void messageArrived(String topic, MqttMessage message) throws Exception {
|
||||
log.info("\r\n=====>>>MQTT接收到消息主题:{}---{}", topic, message);
|
||||
String[] topicArr = topic.split("/");
|
||||
if ("ZZHD".equals(topicArr[0]) && topicArr.length == 4) {
|
||||
if ("YTHD".equals(topicArr[0]) && topicArr.length == 4) {
|
||||
MessageTopic mt = new MessageTopic();
|
||||
mt.setDataDirection(topicArr[2]);
|
||||
mt.setMessageType(topicArr[3]);
|
||||
mt.setStationCode(topicArr[1]);
|
||||
messageHandle.handle(mt, message);
|
||||
messageService.handle(mt, message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ public class MessageTopic implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 7238663818955151985L;
|
||||
|
||||
private String businessType = "ZZHD";
|
||||
private String businessType = "YTHD";
|
||||
|
||||
private String stationCode;
|
||||
|
||||
|
||||
@ -2,6 +2,8 @@ package com.evotech.hd.cloud.mqtt.message.dto.newer.state;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
@ -14,6 +16,7 @@ public class OrderStatus {
|
||||
|
||||
private Integer status;
|
||||
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date statusTime;
|
||||
|
||||
private OrderStatusData statusDate;
|
||||
|
||||
@ -5,7 +5,7 @@ import java.util.Date;
|
||||
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.evotech.hd.cloud.mqtt.config.MqttConfig;
|
||||
import com.evotech.hd.cloud.mqtt.config.MqttPublishMessage;
|
||||
import com.evotech.hd.cloud.mqtt.message.MessageTopic;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
@ -20,14 +20,14 @@ public class KeepaliveMessageService {
|
||||
|
||||
|
||||
@Resource
|
||||
private MqttConfig mqttConfig;
|
||||
private MqttPublishMessage publishMessage;
|
||||
|
||||
|
||||
|
||||
public void keepAlive(MessageTopic topic, MqttMessage message) {
|
||||
String msg = DateUtil.formatDateTime(new Date());
|
||||
String tp = topic.toString().replace("S2M", "M2S");
|
||||
mqttConfig.publish(msg, tp);
|
||||
publishMessage.publish(msg, tp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.evotech.hd.cloud.dao.BatteryStationSecretKeyDao;
|
||||
import com.evotech.hd.cloud.entity.BatteryStationSecretKey;
|
||||
import com.evotech.hd.cloud.entity.MessageMqtt;
|
||||
import com.evotech.hd.cloud.mqtt.config.MqttConfig;
|
||||
import com.evotech.hd.cloud.mqtt.config.MqttPublishMessage;
|
||||
import com.evotech.hd.cloud.mqtt.message.MessageTopic;
|
||||
import com.evotech.hd.cloud.mqtt.message.MqttMessageHeader;
|
||||
import com.evotech.hd.cloud.mqtt.message.MyMqttMessage;
|
||||
@ -47,7 +47,7 @@ public class MessageUtilService {
|
||||
@Resource
|
||||
private BatteryStationSecretKeyDao batteryStationSecretKeyDao;
|
||||
@Resource
|
||||
private MqttConfig mqttConfig;
|
||||
private MqttPublishMessage publishMessage;
|
||||
|
||||
|
||||
|
||||
@ -83,7 +83,7 @@ public class MessageUtilService {
|
||||
public void publishRSAMessage(MessageTopic topic, String msg, String publicKey) {
|
||||
RSA rsa = SecureUtil.rsa(null, publicKey);
|
||||
String encrypt = rsa.encryptBase64(msg, KeyType.PublicKey);
|
||||
mqttConfig.publish(encrypt, topic.toString());
|
||||
publishMessage.publish(encrypt, topic.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -102,7 +102,7 @@ public class MessageUtilService {
|
||||
message.setDataBody(dataBody);
|
||||
String encrypt = aes.encryptBase64(JSONUtil.toJsonStr(message));
|
||||
// 3. 发送MQTT消息
|
||||
mqttConfig.publish(encrypt, topic.toString());
|
||||
publishMessage.publish(encrypt, topic.toString());
|
||||
}
|
||||
|
||||
|
||||
@ -131,9 +131,9 @@ public class MessageUtilService {
|
||||
public JSONObject decryptAesMessage(MessageTopic topic, MqttMessage message) {
|
||||
JSONObject aesJo = getAESKey(topic.getStationCode());
|
||||
SymmetricCrypto aes = new AES(Mode.CBC, Padding.PKCS5Padding, aesJo.getStr("aesSecretKey").getBytes(), aesJo.getStr("aesIv").getBytes());
|
||||
byte[] decrypt = aes.decrypt(message.getPayload());
|
||||
String decrypt = aes.decryptStr(new String(message.getPayload()));
|
||||
|
||||
return JSONUtil.parseObj(new String(decrypt));
|
||||
return JSONUtil.parseObj(decrypt);
|
||||
}
|
||||
|
||||
|
||||
@ -171,7 +171,7 @@ public class MessageUtilService {
|
||||
public JSONObject setAesKey(String stationCode) {
|
||||
SecretKey key = KeyUtil.generateKey(SymmetricAlgorithm.AES.getValue());
|
||||
String base64KeyStr = Base64.getEncoder().encodeToString(key.getEncoded());
|
||||
String iv = RandomUtil.randomString(12);
|
||||
String iv = RandomUtil.randomString(16);
|
||||
batteryStationSecretKeyDao.delete(new QueryWrapper<BatteryStationSecretKey>().eq("type", 2).eq("station_code", stationCode));
|
||||
BatteryStationSecretKey bssk = new BatteryStationSecretKey();
|
||||
bssk.setStationCode(stationCode);
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package com.evotech.hd.cloud.mqtt.message.handle;
|
||||
|
||||
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.evotech.hd.cloud.mqtt.enums.MqttMessageTypeEnum;
|
||||
import com.evotech.hd.cloud.mqtt.message.MessageTopic;
|
||||
@ -13,8 +13,8 @@ import jakarta.annotation.Resource;
|
||||
/**
|
||||
* Mqtt消息处理
|
||||
*/
|
||||
@Component
|
||||
public class MqttMessageHandle {
|
||||
@Service
|
||||
public class MqttMessageHandleService {
|
||||
|
||||
@Resource
|
||||
private EncryptKeyReqMessageService encryptKeyReqService;
|
||||
@ -51,7 +51,7 @@ public class MqttMessageHandle {
|
||||
// 3.2 分类处理
|
||||
// 3.2.1 state
|
||||
if (MqttMessageTypeEnum.STATE.getType().equals(topic.getMessageType())) {
|
||||
// 多线程处理
|
||||
|
||||
stateMessageService.state(topic, header, dataBody);
|
||||
return;
|
||||
}
|
||||
@ -5,19 +5,32 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.evotech.hd.cloud.dao.BatteryStationDcDao;
|
||||
import com.evotech.hd.cloud.dao.OrderSwapBatteryDao;
|
||||
import com.evotech.hd.cloud.dao.OrderSwapBatteryPreDao;
|
||||
import com.evotech.hd.cloud.dao.VehicleWechatUserRelationDao;
|
||||
import com.evotech.hd.cloud.mqtt.enums.MqttMessageTypeEnum;
|
||||
import com.evotech.hd.cloud.mqtt.enums.RequestFunctionTypesEnum;
|
||||
import com.evotech.hd.cloud.mqtt.message.MessageTopic;
|
||||
import com.evotech.hd.cloud.mqtt.message.MqttMessageHeader;
|
||||
import com.evotech.hd.cloud.mqtt.message.dto.newer.req.battery.BatteryInfoReq;
|
||||
import com.evotech.hd.cloud.mqtt.message.dto.newer.req.carinfo.CarInfoReq;
|
||||
import com.evotech.hd.cloud.mqtt.message.dto.newer.req.carinfo.CarInfoResponse;
|
||||
import com.evotech.hd.cloud.mqtt.message.dto.newer.req.carinfo.VehicleData;
|
||||
import com.evotech.hd.cloud.mqtt.message.dto.newer.req.order.OrderByPlateNumReq;
|
||||
import com.evotech.hd.cloud.mqtt.message.dto.newer.req.order.OrderByPlateNumResponse;
|
||||
import com.evotech.hd.cloud.mqtt.message.dto.newer.req.order.OrderData;
|
||||
import com.evotech.hd.cloud.service.OrderSwapBatteryService;
|
||||
import com.evotech.hd.cloud.utils.CommonUtil;
|
||||
import com.evotech.hd.common.core.entity.cloud.BatteryStationDc;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre;
|
||||
import com.evotech.hd.common.core.entity.cloud.VehicleWechatUserRelation;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
@ -36,8 +49,16 @@ public class RequestMessageService {
|
||||
private VehicleWechatUserRelationDao vehicleWechatUserRelationDao;
|
||||
@Resource
|
||||
private MessageUtilService messageUtilService;
|
||||
@Resource
|
||||
private BatteryStationDcDao batteryStationDcDao;
|
||||
@Resource
|
||||
private OrderSwapBatteryDao orderSwapBatteryDao;
|
||||
@Resource
|
||||
private OrderSwapBatteryPreDao orderSwapBatteryPreDao;
|
||||
@Resource
|
||||
private OrderSwapBatteryService orderSwapBatteryService;
|
||||
|
||||
|
||||
@Async("taskExecutor")
|
||||
public void request(MessageTopic topic, MqttMessageHeader header, JSONObject dataBody) {
|
||||
switch (RequestFunctionTypesEnum.getFunctionType(header.getFunction())) {
|
||||
case FUN_CARINFO:
|
||||
@ -45,16 +66,16 @@ public class RequestMessageService {
|
||||
handleCarInfo(topic, header, carInfoReq);
|
||||
break;
|
||||
case FUN_BATTERYINFO:
|
||||
|
||||
|
||||
BatteryInfoReq batteryInfoReq = JSONUtil.toBean(dataBody, BatteryInfoReq.class);
|
||||
handleBatteryInfo(topic, header, batteryInfoReq);
|
||||
break;
|
||||
case FUN_PREORDER:
|
||||
|
||||
|
||||
break;
|
||||
case FUN_ORDERBYPLATENUM:
|
||||
|
||||
|
||||
OrderByPlateNumReq orderByPlateNumReq = JSONUtil.toBean(dataBody, OrderByPlateNumReq.class);
|
||||
handleOrderByPlateNum(topic, header, orderByPlateNumReq);
|
||||
break;
|
||||
case FUN_CANCELORDER:
|
||||
|
||||
@ -67,6 +88,86 @@ public class RequestMessageService {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* OrderByPlateNum请求处理
|
||||
* @param topic
|
||||
* @param header
|
||||
* @param orderByPlateNumReq
|
||||
*/
|
||||
private void handleOrderByPlateNum(MessageTopic topic, MqttMessageHeader header, OrderByPlateNumReq orderByPlateNumReq) {
|
||||
OrderByPlateNumResponse response = new OrderByPlateNumResponse();
|
||||
Date d = new Date();
|
||||
// 查预约
|
||||
OrderSwapBatteryPre osbp = orderSwapBatteryPreDao.selectOne(new QueryWrapper<OrderSwapBatteryPre>()
|
||||
.eq("plate_num", orderByPlateNumReq.getPlateNum())
|
||||
.eq("station_code", orderByPlateNumReq.getStationCode())
|
||||
.last("limit 1"));
|
||||
if (osbp == null) {
|
||||
response.setOrderRequestId(orderByPlateNumReq.getOrderRequestId());
|
||||
response.setCode(0);
|
||||
response.setMsg("车辆未预约,请扫码进入");
|
||||
} else {
|
||||
OrderSwapBattery osb = orderSwapBatteryDao.selectOne(new QueryWrapper<OrderSwapBattery>()
|
||||
.eq("plate_num", orderByPlateNumReq.getPlateNum())
|
||||
.eq("station_code", orderByPlateNumReq.getStationCode())
|
||||
.eq("order_pre_id", osbp.getPkId())
|
||||
.eq("status", 1));
|
||||
if (osb == null) {
|
||||
// 生成订单
|
||||
osb = new OrderSwapBattery();
|
||||
osb.setOrderNo(CommonUtil.swapBatteryOrderNo(orderByPlateNumReq.getStationCode()));
|
||||
osb.setOrderPreId(osbp.getPkId());
|
||||
osb.setOrderPrePhone(osbp.getPhone());
|
||||
osb.setOrderPreUid(osbp.getUcode());
|
||||
osb.setOrderPreUname(osbp.getUname());
|
||||
osb.setPlateNum(osbp.getPlateNum());
|
||||
osb.setOrderTime(d);
|
||||
osb.setOrderType(1);
|
||||
osb.setStatus(1);
|
||||
osb.setStationCode(osbp.getStationCode());
|
||||
osb.setStationName(osbp.getStationName());
|
||||
orderSwapBatteryService.add(osb);
|
||||
}
|
||||
// 返回数据
|
||||
OrderData od = new OrderData();
|
||||
BeanUtils.copyProperties(osb, od);
|
||||
response.setOrderRequestId(orderByPlateNumReq.getOrderRequestId());
|
||||
response.setCode(1);
|
||||
response.setMsg("OK");
|
||||
response.setOrderData(od);
|
||||
}
|
||||
// 发送
|
||||
topic.setDataDirection("M2S");
|
||||
topic.setMessageType(MqttMessageTypeEnum.RESPONSE.getType());
|
||||
header.setFunction(RequestFunctionTypesEnum.FUN_ORDERBYPLATENUM.getReFunction());
|
||||
header.setTimeStamp(DateUtil.format(d, DatePattern.NORM_DATETIME_FORMATTER));
|
||||
messageUtilService.publishAESMessage(topic, header, JSONUtil.parseObj(response));
|
||||
}
|
||||
|
||||
/**
|
||||
* BatteryInfo请求处理
|
||||
* @param topic
|
||||
* @param header
|
||||
* @param batteryInfoReq
|
||||
*/
|
||||
private void handleBatteryInfo(MessageTopic topic, MqttMessageHeader header, BatteryInfoReq batteryInfoReq) {
|
||||
String batCode = batteryInfoReq.getBatCode();
|
||||
int pageNo = 0;
|
||||
int pageSize = 500;
|
||||
Page<BatteryStationDc> page = new Page<BatteryStationDc>(pageNo, pageSize);
|
||||
do {
|
||||
pageNo += 1;
|
||||
page = new Page<BatteryStationDc>(pageNo, pageSize);
|
||||
page = batteryStationDcDao.selectPage(page, new QueryWrapper<BatteryStationDc>().eq(StringUtils.hasText(batCode), "bat_code", batCode));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} while (page.getCurrent() < page.getPages());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* CarInfo请求处理
|
||||
@ -81,7 +182,7 @@ public class RequestMessageService {
|
||||
Page<VehicleWechatUserRelation> page = new Page<VehicleWechatUserRelation>(pageNo, pageSize);
|
||||
do {
|
||||
pageNo += 1;
|
||||
page = new Page<VehicleWechatUserRelation>(pageNo, 500);
|
||||
page = new Page<VehicleWechatUserRelation>(pageNo, pageSize);
|
||||
page = vehicleWechatUserRelationDao.selectPage(page, new QueryWrapper<VehicleWechatUserRelation>()
|
||||
.eq(StringUtils.hasText(plateNum), "plate_num", plateNum));
|
||||
CarInfoResponse response = new CarInfoResponse();
|
||||
|
||||
@ -1,11 +1,27 @@
|
||||
package com.evotech.hd.cloud.mqtt.message.handle;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.evotech.hd.cloud.dao.OrderSwapBatteryDao;
|
||||
import com.evotech.hd.cloud.dao.OrderSwapBatteryPreDao;
|
||||
import com.evotech.hd.cloud.dao.OrderSwapBatteryStepDao;
|
||||
import com.evotech.hd.cloud.mqtt.enums.StateFunctionTypesEnum;
|
||||
import com.evotech.hd.cloud.mqtt.message.MessageTopic;
|
||||
import com.evotech.hd.cloud.mqtt.message.MqttMessageHeader;
|
||||
import com.evotech.hd.cloud.mqtt.message.dto.newer.state.OrderStatus;
|
||||
import com.evotech.hd.cloud.mqtt.message.dto.newer.state.OrderStatusData;
|
||||
import com.evotech.hd.cloud.mqtt.message.dto.newer.state.SwapStep;
|
||||
import com.evotech.hd.cloud.service.BatteryStationDcService;
|
||||
import com.evotech.hd.common.core.entity.cloud.BatteryTrace;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryStep;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import jakarta.annotation.Resource;
|
||||
@ -19,16 +35,32 @@ public class StateMessageService {
|
||||
|
||||
@Resource
|
||||
private MessageUtilService messageUtilService;
|
||||
@Resource
|
||||
private OrderSwapBatteryDao orderSwapBatteryDao;
|
||||
@Resource
|
||||
private OrderSwapBatteryPreDao orderSwapBatteryPreDao;
|
||||
@Resource
|
||||
private OrderSwapBatteryStepDao orderSwapBatteryStepDao;
|
||||
@Resource
|
||||
private BatteryStationDcService batteryStationDcService;
|
||||
|
||||
@Async("taskExecutor")
|
||||
public void state(MessageTopic topic, MqttMessageHeader header, JSONObject dataBody) {
|
||||
switch (StateFunctionTypesEnum.getFunctionType(header.getFunction())) {
|
||||
case FUN_ORDERSTATUS:
|
||||
OrderStatus orderStatus = JSONUtil.toBean(dataBody, OrderStatus.class);
|
||||
handleOrderStatus(orderStatus);
|
||||
OrderStatusData statusData = JSONUtil.toBean(dataBody.getJSONObject("statusDate"), OrderStatusData.class);
|
||||
handleOrderStatus(orderStatus, statusData);
|
||||
|
||||
break;
|
||||
case FUN_SWAPSTEP:
|
||||
SwapStep swapStep = JSONUtil.toBean(dataBody, SwapStep.class);
|
||||
// 记录换电步骤
|
||||
OrderSwapBatteryStep step = new OrderSwapBatteryStep();
|
||||
BeanUtils.copyProperties(swapStep, step);
|
||||
step.setCtime(new Date());
|
||||
step.setCreater("SYS");
|
||||
orderSwapBatteryStepDao.insert(step);
|
||||
|
||||
break;
|
||||
default:
|
||||
@ -38,31 +70,98 @@ public class StateMessageService {
|
||||
|
||||
}
|
||||
|
||||
private void handleOrderStatus(OrderStatus orderStatus) {
|
||||
/**
|
||||
* 订单状态更新处理
|
||||
* @param orderStatus
|
||||
* @param statusData
|
||||
*/
|
||||
private void handleOrderStatus(OrderStatus orderStatus, OrderStatusData statusData) {
|
||||
switch (orderStatus.getStatus()) {
|
||||
case 2:
|
||||
// 修改订单状态
|
||||
|
||||
// 添加换电步骤1-车辆进站
|
||||
|
||||
orderStatus2(orderStatus);
|
||||
break;
|
||||
case 3:
|
||||
// 修改订单状态和数据
|
||||
OrderSwapBattery osb = alterOrderStatus(orderStatus, statusData);
|
||||
// 换电步骤添加最后一条 TODO
|
||||
|
||||
|
||||
// 添加2块电池的溯源记录
|
||||
addBatteryTrace(orderStatus, statusData, osb);
|
||||
break;
|
||||
case 4:
|
||||
// 修改订单状态
|
||||
|
||||
alterOrderStatus(orderStatus, null);
|
||||
break;
|
||||
case 5:
|
||||
// 修改订单状态和数据
|
||||
|
||||
alterOrderStatus(orderStatus, statusData);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加电池轨迹记录
|
||||
* @param orderStatus
|
||||
* @param statusData
|
||||
* @param osb
|
||||
*/
|
||||
private void addBatteryTrace(OrderStatus orderStatus, OrderStatusData statusData, OrderSwapBattery osb) {
|
||||
BatteryTrace bt1 = new BatteryTrace();
|
||||
bt1.setBatCode(statusData.getRentBatCode());
|
||||
bt1.setBeginTime(orderStatus.getStatusTime());
|
||||
bt1.setPointType(2);
|
||||
bt1.setPointCode(osb.getPlateNum());
|
||||
bt1.setCreater("SYS");
|
||||
BatteryTrace bt2 = new BatteryTrace();
|
||||
BeanUtils.copyProperties(bt1, bt2);
|
||||
bt2.setBatCode(statusData.getReturnBatCode());
|
||||
bt2.setPointType(1);
|
||||
bt2.setPointCode(osb.getStationCode());
|
||||
bt2.setPointName(osb.getStationName());
|
||||
batteryStationDcService.addTrace(bt1);
|
||||
batteryStationDcService.addTrace(bt2);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 换电开始时的处理
|
||||
* @param orderStatus
|
||||
*/
|
||||
private void orderStatus2(OrderStatus orderStatus) {
|
||||
// 修改订单状态
|
||||
OrderSwapBattery osb = alterOrderStatus(orderStatus, null);
|
||||
// 添加换电步骤1-车辆进站
|
||||
OrderSwapBatteryStep osbs = new OrderSwapBatteryStep();
|
||||
osbs.setOrderNo(orderStatus.getOrderNo());
|
||||
osbs.setStep(1);
|
||||
osbs.setStepTime(orderStatus.getStatusTime());
|
||||
osbs.setCtime(new Date());
|
||||
osbs.setCreater("SYS");
|
||||
orderSwapBatteryStepDao.insert(osbs);
|
||||
// 修改预约订单为完成
|
||||
OrderSwapBatteryPre osbp = new OrderSwapBatteryPre();
|
||||
osbp.setStatus(2);
|
||||
osbp.setPkId(osb.getOrderPreId());
|
||||
orderSwapBatteryPreDao.updateById(osbp);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改订单状态方法
|
||||
* @param orderStatus
|
||||
* @param statusData
|
||||
* @return
|
||||
*/
|
||||
private OrderSwapBattery alterOrderStatus(OrderStatus orderStatus, OrderStatusData statusData) {
|
||||
OrderSwapBattery osb = orderSwapBatteryDao.selectOne(new QueryWrapper<OrderSwapBattery>().eq("order_no", orderStatus.getOrderNo()));
|
||||
osb.setStatus(orderStatus.getStatus());
|
||||
if (orderStatus.getStatus() == 3 || orderStatus.getStatus() == 5) {
|
||||
BeanUtils.copyProperties(statusData, osb);
|
||||
}
|
||||
orderSwapBatteryDao.updateById(osb);
|
||||
return osb;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -2,11 +2,11 @@ package com.evotech.hd.cloud.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.evotech.hd.cloud.entity.request.PageListSwapOrderRequest;
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryStep;
|
||||
import com.evotech.hd.common.core.entity.cloud.PageListSwapOrderRequest;
|
||||
|
||||
public interface OrderSwapBatteryService {
|
||||
|
||||
@ -14,7 +14,7 @@ public interface OrderSwapBatteryService {
|
||||
|
||||
public Result<Integer> cancelPre(Integer id, Integer status);
|
||||
|
||||
public Result<List<OrderSwapBatteryPre>> listPre(String plateNum, Integer status, String userId);
|
||||
public Result<List<OrderSwapBatteryPre>> listPre(String plateNum, Integer status, String ucode, String stationCode);
|
||||
|
||||
public Result<Integer> add(OrderSwapBattery osb);
|
||||
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
package com.evotech.hd.cloud.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.evotech.hd.cloud.entity.request.PageListWechatUserRequest;
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.evotech.hd.common.core.entity.wechat.WechatUser;
|
||||
|
||||
public interface WechatUserService {
|
||||
|
||||
public Result<List<WechatUser>> list(PageListWechatUserRequest plwur);
|
||||
|
||||
public Result<Integer> alterPhone(String wuid, String phone, String name);
|
||||
|
||||
public Result<Integer> companyRelation(String wuid, String pcode, String pname);
|
||||
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package com.evotech.hd.cloud.service.impl;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@ -11,12 +12,12 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.evotech.hd.cloud.dao.OrderSwapBatteryDao;
|
||||
import com.evotech.hd.cloud.dao.OrderSwapBatteryPreDao;
|
||||
import com.evotech.hd.cloud.dao.OrderSwapBatteryStepDao;
|
||||
import com.evotech.hd.cloud.entity.request.PageListSwapOrderRequest;
|
||||
import com.evotech.hd.cloud.service.OrderSwapBatteryService;
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryStep;
|
||||
import com.evotech.hd.common.core.entity.cloud.PageListSwapOrderRequest;
|
||||
import com.evotech.hd.common.core.enums.CodeMsg;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
@ -39,6 +40,10 @@ public class OrderSwapBatteryServiceImpl implements OrderSwapBatteryService {
|
||||
// 2. 检查预约人
|
||||
|
||||
// 3. 添加预约
|
||||
Date d = new Date();
|
||||
osbp.setStatus(1);
|
||||
osbp.setReservationTime(osbp.getReservationTime() == null ? d : osbp.getReservationTime());
|
||||
osbp.setCtime(d);
|
||||
int n = orderSwapBatteryPreDao.insert(osbp);
|
||||
if (n == 1) {
|
||||
return new Result<Integer>().success(n);
|
||||
@ -50,7 +55,7 @@ public class OrderSwapBatteryServiceImpl implements OrderSwapBatteryService {
|
||||
public Result<Integer> cancelPre(Integer id, Integer status) {
|
||||
OrderSwapBatteryPre osbp = new OrderSwapBatteryPre();
|
||||
osbp.setPkId(id);
|
||||
osbp.setStatus(status != null? status : 2);
|
||||
osbp.setStatus(status != null? status : 3);
|
||||
int n = orderSwapBatteryPreDao.updateById(osbp);
|
||||
if (n == 1) {
|
||||
return new Result<Integer>().success(n);
|
||||
@ -59,11 +64,12 @@ public class OrderSwapBatteryServiceImpl implements OrderSwapBatteryService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<OrderSwapBatteryPre>> listPre(String plateNum, Integer status, String userId) {
|
||||
public Result<List<OrderSwapBatteryPre>> listPre(String plateNum, Integer status, String ucode, String stationCode) {
|
||||
List<OrderSwapBatteryPre> list = orderSwapBatteryPreDao.selectList(new QueryWrapper<OrderSwapBatteryPre>()
|
||||
.eq(StringUtils.hasText(userId), "user_id", userId)
|
||||
.eq(StringUtils.hasText(ucode), "ucode", ucode)
|
||||
.eq(status != null, "status", status)
|
||||
.eq(StringUtils.hasText(plateNum), "plate_num", plateNum)
|
||||
.eq(StringUtils.hasText(stationCode), "station_code", stationCode)
|
||||
.orderByDesc("pk_id"));
|
||||
if (list.isEmpty()) {
|
||||
return new Result<List<OrderSwapBatteryPre>>().error(CodeMsg.DATABASE_RESULT_NULL);
|
||||
@ -108,7 +114,8 @@ public class OrderSwapBatteryServiceImpl implements OrderSwapBatteryService {
|
||||
|
||||
page = orderSwapBatteryDao.selectPage(page, new QueryWrapper<OrderSwapBattery>()
|
||||
.eq(StringUtils.hasText(plsor.getOrderNo()), "order_no", plsor.getOrderNo())
|
||||
.like(StringUtils.hasText(plsor.getPlateNum()), "plate_num", plsor.getPlateNum())
|
||||
.eq(StringUtils.hasText(plsor.getPlateNum()), "plate_num", plsor.getPlateNum())
|
||||
.in(StringUtils.hasText(plsor.getPlateNums()), "plate_num", Arrays.asList(plsor.getPlateNums().split(",")))
|
||||
.ge(plsor.getOrderTimeBegin() != null, "order_time", plsor.getOrderTimeBegin())
|
||||
.le(plsor.getOrderTimeEnd() != null, "order_time", plsor.getOrderTimeEnd())
|
||||
.eq(StringUtils.hasText(plsor.getStationCode()), "station_code", plsor.getStationCode())
|
||||
|
||||
@ -0,0 +1,80 @@
|
||||
package com.evotech.hd.cloud.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.evotech.hd.cloud.entity.request.PageListWechatUserRequest;
|
||||
import com.evotech.hd.cloud.service.WechatUserService;
|
||||
import com.evotech.hd.common.core.dao.wechat.WechatUserDao;
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.evotech.hd.common.core.entity.wechat.WechatUser;
|
||||
import com.evotech.hd.common.core.enums.CodeMsg;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
|
||||
@Service
|
||||
public class WechatUserServiceImpl implements WechatUserService {
|
||||
|
||||
@Resource
|
||||
private WechatUserDao wechatUserDao;
|
||||
|
||||
@Override
|
||||
public Result<List<WechatUser>> list(PageListWechatUserRequest plwur) {
|
||||
Page<WechatUser> page = new Page<WechatUser>(plwur.getPageNo(), plwur.getPageSize());
|
||||
|
||||
page = wechatUserDao.selectPage(page, new QueryWrapper<WechatUser>()
|
||||
.eq(StringUtils.hasText(plwur.getWuid()), "wuid", plwur.getWuid())
|
||||
.like(StringUtils.hasText(plwur.getPhoneNumber()), "phone_number", plwur.getPhoneNumber())
|
||||
.eq(plwur.getGender() != null, "gender", plwur.getGender())
|
||||
.eq(plwur.getType() != null, "type", plwur.getType())
|
||||
.eq(StringUtils.hasText(plwur.getNickName()), "nick_name", plwur.getNickName())
|
||||
.eq(StringUtils.hasText(plwur.getName()), "name", plwur.getName())
|
||||
.eq(StringUtils.hasText(plwur.getPcode()), "pcode", plwur.getPcode())
|
||||
.orderByDesc("pk_id"));
|
||||
if (page.getRecords().isEmpty()) {
|
||||
return new Result<List<WechatUser>>().error(CodeMsg.DATABASE_RESULT_NULL);
|
||||
}
|
||||
return new Result<List<WechatUser>>().success(page);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Integer> alterPhone(String wuid, String phone, String name) {
|
||||
if (!(StringUtils.hasText(phone) || StringUtils.hasText(name))) {
|
||||
return new Result<Integer>().error(CodeMsg.PARAM_IS_NULL);
|
||||
}
|
||||
WechatUser user = new WechatUser();
|
||||
user.setPhoneNumber(phone);
|
||||
user.setName(name);
|
||||
int n = wechatUserDao.update(user, new QueryWrapper<WechatUser>().eq("wuid", wuid));
|
||||
if (n == 1) {
|
||||
return new Result<Integer>().success(n);
|
||||
}
|
||||
|
||||
return new Result<Integer>().error("修改微信用户信息出错!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Integer> companyRelation(String wuid, String pcode, String pname) {
|
||||
if (!(StringUtils.hasText(pcode) && StringUtils.hasText(pname))) {
|
||||
return new Result<Integer>().error(CodeMsg.PARAM_IS_NULL);
|
||||
}
|
||||
WechatUser user = new WechatUser();
|
||||
user.setPcode(pcode);
|
||||
user.setPname(pname);
|
||||
int n = wechatUserDao.update(user, new QueryWrapper<WechatUser>().eq("wuid", wuid));
|
||||
if (n == 1) {
|
||||
return new Result<Integer>().success(n);
|
||||
}
|
||||
|
||||
return new Result<Integer>().error("关联公司信息出错!");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package com.evotech.hd.cloud.utils;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
|
||||
public class CommonUtil {
|
||||
|
||||
public static String swapBatteryOrderNo(String stationCode) {
|
||||
String orderNoPrefix = "YTSO";
|
||||
String orderNoMiddle1 = stationCode.length() <= 8?stationCode : stationCode.substring(stationCode.length() - 8);
|
||||
String orderNoMiddle2 = DateUtil.format(new Date(), DatePattern.PURE_DATETIME_MS_FORMATTER);
|
||||
String orderNoSuffix = RandomUtil.randomNumbers(2) + RandomUtil.randomChar("ABC");
|
||||
return orderNoPrefix + orderNoMiddle1 + orderNoMiddle2 + orderNoSuffix;
|
||||
}
|
||||
|
||||
}
|
||||
@ -48,14 +48,20 @@ public class AuthorizationManager implements ReactiveAuthorizationManager<Author
|
||||
}
|
||||
ServerHttpRequest request = authorizationContext.getExchange().getRequest();
|
||||
String uri = request.getURI().toString();
|
||||
// 微信服务先放行,后面再加验证规则
|
||||
if (uri.contains("/gateway/wechat/")) {
|
||||
return Mono.just(new AuthorizationDecision(true));
|
||||
}
|
||||
|
||||
// 1. 对应跨域的预检请求直接放行
|
||||
if (request.getMethod() == HttpMethod.OPTIONS) {
|
||||
return Mono.just(new AuthorizationDecision(true));
|
||||
}
|
||||
// 微信服务将UID放入请求头,验证一下
|
||||
if (uri.contains("/gateway/wechat/")) {
|
||||
String wuid = request.getHeaders().getFirst(HDConstant.WECHAT_SERVER_AUTHORIZATION_KEY);
|
||||
if (redisUtil.hasKey(HDConstant.sessionKeyPrefix + wuid) ) {
|
||||
return Mono.just(new AuthorizationDecision(true));
|
||||
} else {
|
||||
throw new OAuth2AuthorizationException(new OAuth2Error(CodeMsg.TOKEN_INVALID.getCode(), CodeMsg.TOKEN_INVALID.getMsg(), uri));
|
||||
}
|
||||
}
|
||||
// 2. token验证
|
||||
/**
|
||||
* 这个类主要是处理权限(Authorization)的,对于身份(authentication)
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
package com.evotech.hd.gateway.oauth2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@ConfigurationProperties(prefix = "security.oauth2", ignoreUnknownFields = true)
|
||||
@Data
|
||||
@Component
|
||||
public class ResourceIgnoreUri {
|
||||
|
||||
private List<String> ignoreUris = new ArrayList<String>();
|
||||
|
||||
}
|
||||
@ -4,8 +4,6 @@ import java.security.KeyFactory;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.Base64;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.Customizer;
|
||||
@ -17,6 +15,8 @@ import org.springframework.security.oauth2.jwt.JwtValidators;
|
||||
import org.springframework.security.oauth2.jwt.NimbusReactiveJwtDecoder;
|
||||
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
|
||||
import org.springframework.security.web.server.SecurityWebFilterChain;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
|
||||
@ -24,8 +24,8 @@ import jakarta.annotation.Resource;
|
||||
@Configuration
|
||||
public class ResourceServerConfig {
|
||||
|
||||
@Value("${security.oauth2.ignore_uri:{}}")
|
||||
private String[] ignoreUriArr;
|
||||
@Resource
|
||||
private ResourceIgnoreUri ignoreUri;
|
||||
|
||||
@Resource
|
||||
private AuthorizationManager authorizationManager;
|
||||
@ -63,7 +63,7 @@ public class ResourceServerConfig {
|
||||
|
||||
http.authorizeExchange(exchange ->
|
||||
exchange
|
||||
.pathMatchers(ignoreUriArr).permitAll()
|
||||
.pathMatchers(Convert.toStrArray(ignoreUri.getIgnoreUris())).permitAll()
|
||||
.pathMatchers(ignoreFixedUris()).permitAll()
|
||||
// .anyExchange().authenticated()
|
||||
// 其他走自定义逻辑
|
||||
|
||||
@ -34,6 +34,12 @@
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- openfein -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.wechatpay-apiv3</groupId>
|
||||
<artifactId>wechatpay-java</artifactId>
|
||||
|
||||
@ -4,12 +4,14 @@ import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableDiscoveryClient
|
||||
@ComponentScan("com.evotech.hd.**")
|
||||
@MapperScan({"com.evotech.hd.wechat.dao.**", "com.evotech.hd.common.core.dao.**"})
|
||||
@EnableFeignClients
|
||||
public class WechatServerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
@ -0,0 +1,72 @@
|
||||
package com.evotech.hd.wechat.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springdoc.core.annotations.ParameterObject;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryStep;
|
||||
import com.evotech.hd.common.core.entity.cloud.PageListSwapOrderRequest;
|
||||
import com.evotech.hd.wechat.service.CloudService;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
@Tag(name = "云平台API")
|
||||
@ApiSupport(order = 13)
|
||||
@RestController
|
||||
@RequestMapping("/cloud")
|
||||
public class CloudServeController {
|
||||
|
||||
@Resource
|
||||
private CloudService cloudService;
|
||||
|
||||
|
||||
@Operation(summary = "增加预约")
|
||||
@PostMapping("/order/swap/pre/add")
|
||||
@ApiOperationSupport(order = 1)
|
||||
public Result<Integer> addPre(@Valid @ParameterObject OrderSwapBatteryPre osbp) {
|
||||
return cloudService.addPre(osbp);
|
||||
}
|
||||
|
||||
@Operation(summary = "取消预约")
|
||||
@PostMapping("/order/swap/pre/cancel")
|
||||
@ApiOperationSupport(order = 2)
|
||||
public Result<Integer> cancelPre(@NotNull Integer id) {
|
||||
return cloudService.cancelPre(id, null);
|
||||
}
|
||||
|
||||
@Operation(summary = "查询预约")
|
||||
@GetMapping("/order/swap/pre/list")
|
||||
@ApiOperationSupport(order = 3)
|
||||
public Result<List<OrderSwapBatteryPre>> listPre(String plateNum, Integer status, String ucode, String stationCode) {
|
||||
return cloudService.listPre(plateNum, status, ucode, stationCode);
|
||||
}
|
||||
|
||||
@Operation(summary = "查询订单")
|
||||
@GetMapping("/order/swap/list")
|
||||
@ApiOperationSupport(order = 7)
|
||||
public Result<List<OrderSwapBattery>> list(@ParameterObject PageListSwapOrderRequest plsor) {
|
||||
return cloudService.list(plsor);
|
||||
}
|
||||
|
||||
@Operation(summary = "查询换电步骤")
|
||||
@GetMapping("/order/swap/step/list")
|
||||
@ApiOperationSupport(order = 8)
|
||||
public Result<List<OrderSwapBatteryStep>> listStep(@NotBlank String orderNo) {
|
||||
return cloudService.listStep(orderNo);
|
||||
}
|
||||
|
||||
}
|
||||
@ -6,6 +6,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.evotech.hd.wechat.service.LoginService;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@ -15,6 +16,7 @@ import jakarta.annotation.Resource;
|
||||
@Tag(name = "登陆")
|
||||
@RestController
|
||||
@RequestMapping("/login")
|
||||
@ApiSupport(order = 10)
|
||||
public class LoginController {
|
||||
|
||||
@Resource
|
||||
|
||||
@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.evotech.hd.wechat.service.WechatPayService;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import com.wechat.pay.java.service.payments.jsapi.model.Detail;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Hidden;
|
||||
@ -23,6 +24,7 @@ import jakarta.validation.constraints.NotBlank;
|
||||
@Tag(name = "微信支付")
|
||||
@RestController
|
||||
@RequestMapping("/wechatpay")
|
||||
@ApiSupport(order = 12)
|
||||
public class WechatPayController {
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
package com.evotech.hd.wechat.controller;
|
||||
|
||||
import org.springdoc.core.annotations.ParameterObject;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.evotech.hd.common.core.entity.wechat.WechatUser;
|
||||
import com.evotech.hd.wechat.service.WechatUserService;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
@Tag(name = "微信用户")
|
||||
@RestController
|
||||
@RequestMapping("/wechat/user")
|
||||
@ApiSupport(order = 11)
|
||||
public class WechatUserController {
|
||||
|
||||
@Resource
|
||||
private WechatUserService wechatUserService;
|
||||
|
||||
|
||||
@Operation(summary = "修改")
|
||||
@PostMapping("/update")
|
||||
public Result<String> update(@ParameterObject WechatUser wuser) {
|
||||
return wechatUserService.update(wuser);
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "查询")
|
||||
@PostMapping("/userbyuid")
|
||||
public Result<WechatUser> userByUid(String wuid) {
|
||||
return wechatUserService.userByUid(wuid);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
package com.evotech.hd.wechat.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre;
|
||||
import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryStep;
|
||||
import com.evotech.hd.common.core.entity.cloud.PageListSwapOrderRequest;
|
||||
|
||||
@FeignClient(value = "cloud-server")
|
||||
public interface CloudService {
|
||||
|
||||
@PostMapping(value = "/cloud/order/swap/pre/add",
|
||||
consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
|
||||
public Result<Integer> addPre(OrderSwapBatteryPre osbp);
|
||||
|
||||
@PostMapping(value = "/cloud/order/swap/pre/cancel",
|
||||
consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
|
||||
public Result<Integer> cancelPre(@RequestParam Integer id, @RequestParam Integer status);
|
||||
|
||||
@GetMapping(value = "/cloud/order/swap/pre/list",
|
||||
consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
|
||||
public Result<List<OrderSwapBatteryPre>> listPre(@RequestParam String plateNum, @RequestParam Integer status, @RequestParam String userId, @RequestParam String stationCode);
|
||||
|
||||
@GetMapping(value = "/cloud/order/swap/list",
|
||||
consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
|
||||
public Result<List<OrderSwapBattery>> list(PageListSwapOrderRequest plsor);
|
||||
|
||||
@GetMapping(value = "/cloud/order/swap/step/list",
|
||||
consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
|
||||
public Result<List<OrderSwapBatteryStep>> listStep(String orderNo);
|
||||
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.evotech.hd.wechat.service;
|
||||
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.evotech.hd.common.core.entity.wechat.WechatUser;
|
||||
|
||||
public interface WechatUserService {
|
||||
|
||||
public Result<String> update(WechatUser wuser);
|
||||
|
||||
public Result<WechatUser> userByUid(String wuid);
|
||||
|
||||
}
|
||||
@ -6,13 +6,13 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.evotech.hd.common.core.constant.HDConstant;
|
||||
import com.evotech.hd.common.core.dao.wechat.WechatUserDao;
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.evotech.hd.common.core.entity.wechat.WechatUser;
|
||||
import com.evotech.hd.common.core.enums.CodeMsg;
|
||||
import com.evotech.hd.common.redis.utils.RedisUtil;
|
||||
import com.evotech.hd.wechat.config.XcxProperties;
|
||||
import com.evotech.hd.wechat.dao.WechatUserDao;
|
||||
import com.evotech.hd.wechat.entity.WechatUser;
|
||||
import com.evotech.hd.wechat.service.AccessTokenService;
|
||||
import com.evotech.hd.wechat.service.LoginService;
|
||||
import com.evotech.hd.wechat.utils.xcx.LoginUtil;
|
||||
@ -29,10 +29,6 @@ import jakarta.annotation.Resource;
|
||||
@Service
|
||||
public class LoginServiceImpl implements LoginService {
|
||||
|
||||
public static String openidPrefix = "hd:wechat:login:openid:";
|
||||
public static String unionidPrefix = "hd:wechat:login:unionid:";
|
||||
public static String sessionKeyPrefix = "hd:wechat:login:sessionKey:";
|
||||
|
||||
@Resource
|
||||
private XcxProperties xcxProperties;
|
||||
@Resource
|
||||
@ -55,7 +51,7 @@ public class LoginServiceImpl implements LoginService {
|
||||
// 是否登陆过
|
||||
WechatUser wuser = wechatUserDao.selectOne(new QueryWrapper<WechatUser>().eq("openid", openid));
|
||||
if (wuser == null) {
|
||||
String wuid = MD5.create().digestHex(xcxProperties.getAppid() + openid);
|
||||
String wuid = MD5.create().digestHex(xcxProperties.getAppid() + openid + "HBYT");
|
||||
wuser = new WechatUser();
|
||||
wuser.setAppid(xcxProperties.getAppid());
|
||||
wuser.setCtime(new Date());
|
||||
@ -65,20 +61,20 @@ public class LoginServiceImpl implements LoginService {
|
||||
wechatUserDao.insert(wuser);
|
||||
}
|
||||
// 缓存数据
|
||||
redisUtil.set(openidPrefix + wuser.getWuid(), openid);
|
||||
redisUtil.set(unionidPrefix + wuser.getWuid(), unionid);
|
||||
redisUtil.set(sessionKeyPrefix + wuser.getWuid(), sessionKey);
|
||||
redisUtil.set(HDConstant.openidPrefix + wuser.getWuid(), openid);
|
||||
redisUtil.set(HDConstant.unionidPrefix + wuser.getWuid(), unionid);
|
||||
redisUtil.set(HDConstant.sessionKeyPrefix + wuser.getWuid(), sessionKey);
|
||||
|
||||
return new Result<String>().success(wuser.getWuid());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Boolean> checkSessionKey(String wuid) {
|
||||
if (!redisUtil.hasKey(openidPrefix + wuid) || !redisUtil.hasKey(sessionKeyPrefix + wuid)) {
|
||||
if (!redisUtil.hasKey(HDConstant.openidPrefix + wuid) || !redisUtil.hasKey(HDConstant.sessionKeyPrefix + wuid)) {
|
||||
return new Result<Boolean>().error(CodeMsg.WECHAT_SERRION_ERROR);
|
||||
}
|
||||
String openid = redisUtil.get(openidPrefix + wuid).toString();
|
||||
String sessionKey = redisUtil.get(sessionKeyPrefix + wuid).toString();
|
||||
String openid = redisUtil.get(HDConstant.openidPrefix + wuid).toString();
|
||||
String sessionKey = redisUtil.get(HDConstant.sessionKeyPrefix + wuid).toString();
|
||||
HMac hmac = DigestUtil.hmac(HmacAlgorithm.HmacSHA256, sessionKey.getBytes());
|
||||
String res = LoginUtil.code2Session(xcxProperties.getAppid(), openid, hmac.digestHex(""));
|
||||
JSONObject jo = JSONUtil.parseObj(res);
|
||||
@ -94,18 +90,19 @@ public class LoginServiceImpl implements LoginService {
|
||||
if (StringUtils.hasText(wuser.getPhoneNumber())) {
|
||||
return new Result<String>().success("ok", wuser.getPhoneNumber());
|
||||
}
|
||||
if (!redisUtil.hasKey(openidPrefix + wuid)) {
|
||||
if (!redisUtil.hasKey(HDConstant.openidPrefix + wuid)) {
|
||||
return new Result<String>().error(CodeMsg.WECHAT_SERRION_ERROR);
|
||||
}
|
||||
String openid = redisUtil.get(openidPrefix + wuid).toString();
|
||||
String res = PhoneNumberUtil.getPhoneNumber(accessTokenService.getAccessToken(), openid, code);
|
||||
// String openid = redisUtil.get(HDConstant.openidPrefix + wuid).toString();
|
||||
String res = PhoneNumberUtil.getPhoneNumber(accessTokenService.getAccessToken(), code);
|
||||
JSONObject jo = JSONUtil.parseObj(res);
|
||||
if (jo.getInt("errcode") == 0) {
|
||||
String phoneNumber = jo.getJSONObject("phone_info").getStr("phoneNumber");
|
||||
WechatUser wu = new WechatUser();
|
||||
wu.setWuid(wuid);
|
||||
wechatUserDao.update(wu, new UpdateWrapper<WechatUser>().set("phone_number", phoneNumber));
|
||||
}
|
||||
wu.setPhoneNumber(phoneNumber);
|
||||
wechatUserDao.update(wu, new QueryWrapper<WechatUser>().eq("wuid", wuid));
|
||||
return new Result<String>().success(phoneNumber);
|
||||
}
|
||||
return new Result<String>().error(CodeMsg.WECHAT_API_ERROR, jo);
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
package com.evotech.hd.wechat.service.impl;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.evotech.hd.common.core.dao.wechat.WechatUserDao;
|
||||
import com.evotech.hd.common.core.entity.Result;
|
||||
import com.evotech.hd.common.core.entity.wechat.WechatUser;
|
||||
import com.evotech.hd.common.core.enums.CodeMsg;
|
||||
import com.evotech.hd.wechat.service.WechatUserService;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
|
||||
@Service
|
||||
public class WechatUserServiceImpl implements WechatUserService {
|
||||
|
||||
@Resource
|
||||
private WechatUserDao wechatUserDao;
|
||||
|
||||
|
||||
@Override
|
||||
public Result<String> update(WechatUser wuser) {
|
||||
int n = wechatUserDao.update(wuser, new QueryWrapper<WechatUser>().eq("wuid", wuser.getWuid()));
|
||||
if (n == 1) {
|
||||
return new Result<String>().success(1);
|
||||
}
|
||||
return new Result<String>().error("修改微信用户信息出错");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<WechatUser> userByUid(String wuid) {
|
||||
WechatUser user = wechatUserDao.selectOne(new QueryWrapper<WechatUser>().eq("wuid", wuid));
|
||||
if (user == null) {
|
||||
return new Result<WechatUser>().error(CodeMsg.DATABASE_RESULT_NULL);
|
||||
}
|
||||
return new Result<WechatUser>().success(user);
|
||||
}
|
||||
|
||||
}
|
||||
@ -3,7 +3,8 @@ package com.evotech.hd.wechat.utils.xcx;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
|
||||
/**
|
||||
* 小程序手机号
|
||||
@ -20,11 +21,15 @@ private static String getPhoneNumberUrl = "https://api.weixin.qq.com/wxa/busines
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
public static String getPhoneNumber(String access_token, String openid, String code) {
|
||||
public static String getPhoneNumber(String access_token, String code) {
|
||||
Map<String, Object> m = new HashMap<String, Object>();
|
||||
m.put("openid", openid);
|
||||
m.put("code", code);
|
||||
String res = HttpUtil.post(getPhoneNumberUrl + access_token, m);
|
||||
String body = JSONUtil.toJsonStr(m);
|
||||
String res = HttpRequest.post(getPhoneNumberUrl + access_token)
|
||||
.header("Content-Type", "application/json")
|
||||
.body(body)
|
||||
.execute()
|
||||
.body();
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user