1. 添加换电站 计费模式 字段,生成订单时使用站的计费模式

2. 添加mqtt中车辆信息的回复内容
3. 预约订单分页查询
4. 联调站端AES加密流程
5. 修正swich-case中五枚举结果的报错情况
6. 车辆信息 添加查询、删除关联用户功能
7. 调整内部部分rpc请求,参数格式
8. 调整其他bug
This commit is contained in:
Administrator 2025-03-22 17:28:49 +08:00
parent d095c7d457
commit 2180323915
34 changed files with 261 additions and 90 deletions

View File

@ -50,6 +50,9 @@ public class BatteryStation implements Serializable {
@Schema(description = "站点类型ID")
private Integer type;
@Schema(description = "换电计费方式1-按充电量2-按SOC3-按行驶公里数")
private Integer feeType;
@Schema(description = "地址")
private String address;

View File

@ -0,0 +1,37 @@
package com.evotech.hd.common.core.entity.cloud.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 PageListSwapOrderPreRequest extends BasePageRequest {
@Schema(description = "用户编码")
private String ucode;
@Schema(description = "车牌号")
private String plateNum;
@Schema(description = "预约换电日期开始", example = "yyyyMMdd")
private String swapDayBegin;
@Schema(description = "预约换电日期结束")
private String swapDayEnd;
@Schema(description = "换电站编码")
private String stationCode;
@Schema(description = "订单状态1-预约成功2-到店使用3-取消4-过期")
private Integer status;
}

View File

@ -1,4 +1,4 @@
package com.evotech.hd.common.core.entity.cloud;
package com.evotech.hd.common.core.entity.cloud.request;
import java.util.Date;

View File

@ -64,16 +64,23 @@ public class VehicleController {
return vehicleService.list(plvr);
}
@Operation(summary = "公司关联")
@Operation(summary = "关联公司")
@PostMapping("/company/relation")
@ApiOperationSupport(order = 5)
public Result<Integer> companyRelation(String plateNum, String ccode, String cname) {
return vehicleService.companyRelation(plateNum, ccode, cname);
}
@Operation(summary = "删除关联公司")
@PostMapping("/company/relation/del")
@ApiOperationSupport(order = 6)
public Result<Integer> delCompanyRelation(String plateNum) {
return vehicleService.delCompanyRelation(plateNum);
}
@Operation(summary = "微信用户关联")
@PostMapping("/wechatuser/relation/add")
@ApiOperationSupport(order = 6)
@ApiOperationSupport(order = 7)
public Result<Integer> addWechatUserRelation(@Valid @ParameterObject VehicleWechatUserRelation relation) {
return vehicleService.addWechatUserRelation(relation);
}
@ -81,7 +88,7 @@ public class VehicleController {
@Operation(summary = "删除微信用户关联")
@PostMapping("/wechatuser/relation/del")
@ApiOperationSupport(order = 7)
@ApiOperationSupport(order = 8)
public Result<Integer> deleteWechatUserRelation(Integer id) {
return vehicleService.deleteWechatUserRelation(id);
}
@ -89,11 +96,18 @@ public class VehicleController {
@Operation(summary = "查询微信用户车辆")
@GetMapping("/wechatuser/relation/list")
@ApiOperationSupport(order = 8)
@ApiOperationSupport(order = 9)
public Result<List<VehicleInfo>> listWechatUserRelation(@NotBlank @RequestParam String wuid) {
return vehicleService.listWechatUserRelation(wuid, null);
}
@Operation(summary = "查询车辆的关联用户")
@GetMapping("/relationuser/list")
@ApiOperationSupport(order = 10)
public Result<List<VehicleWechatUserRelation>> listRelationUser(@NotBlank @RequestParam String PlantNo) {
return vehicleService.listRelationUser(PlantNo);
}

View File

@ -16,7 +16,8 @@ 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.entity.cloud.request.PageListSwapOrderPreRequest;
import com.evotech.hd.common.core.entity.cloud.request.PageListSwapOrderRequest;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
@ -55,8 +56,8 @@ public class OrderSwapBatteryController {
@Operation(summary = "查询预约")
@GetMapping("/pre/list")
@ApiOperationSupport(order = 3)
public Result<List<OrderSwapBatteryPre>> listPre(String plateNum, Integer status, String ucode, String stationCode) {
return orderSwapBatteryService.listPre(plateNum, status, ucode, stationCode);
public Result<List<OrderSwapBatteryPre>> listPre(@ParameterObject PageListSwapOrderPreRequest plsopr) {
return orderSwapBatteryService.listPre(plsopr);
}
@ -125,7 +126,8 @@ public class OrderSwapBatteryController {
@PostMapping({"/companywallet/pay"})
@ApiOperationSupport(order = 11)
public Result<String> companyWalletPay(@RequestParam String orderNo, String wuid, String uname) {
return orderSwapBatteryService.calculateCost(orderNo);
// TODO
return null;
}

View File

@ -34,7 +34,7 @@ import jakarta.annotation.Resource;
@RequestMapping("/test/mqtt")
public class MqttMessageTestController {
public static String topicPrefix = "ZZHD/{}/S2M/{}";
public static String topicPrefix = "YTHD/{}/S2M/{}";
@Resource
private MqttTestUtil mqttTestUtil;
@ -89,7 +89,6 @@ public class MqttMessageTestController {
return new Result<String>().success("OK");
}

View File

@ -13,9 +13,6 @@ 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;
@ -34,9 +31,7 @@ public class MqttTestUtil {
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. 数据
SymmetricCrypto aes = messageUtilService.getAes(stationCode);
MyMqttMessage message = new MyMqttMessage();
message.setHeader(header);
message.setDataBody(jo);

View File

@ -38,5 +38,8 @@ public class PageListVehicleRequest extends BasePageRequest {
@Schema(description = "引擎号")
private String engineNo;
@Schema(description = "公司编码")
private String ccode;
}

View File

@ -21,7 +21,7 @@ import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
//@Component
@Component
@Order(value = 20)
@Slf4j
public class MqttConnectInit implements ApplicationRunner {

View File

@ -10,7 +10,8 @@ public enum StateFunctionTypesEnum {
// 新交互请求
FUN_ORDERSTATUS("orderStatus", "", "站端反馈订单状态"),
FUN_SWAPSTEP("swapStep", "", "站端反馈换电步骤"),
FUN_BATTERYSTATUS("batteryStatus", "", "站端反馈电池状态");
FUN_BATTERYSTATUS("batteryStatus", "", "站端反馈电池状态"),
FUN_TEST("test", "", "没用的占位");
String function;
String reFunction;
@ -42,7 +43,7 @@ public enum StateFunctionTypesEnum {
}
return Arrays.stream(StateFunctionTypesEnum.values())
.filter(i -> i.function.equals(function))
.findFirst().orElse(null);
.findFirst().orElse(FUN_TEST);
}
}

View File

@ -17,6 +17,8 @@ public class BatteryInfoResponse {
private Integer isOver;
private String msg;
private List<BatteryData> batteryData;
}

View File

@ -20,6 +20,8 @@ public class CarInfoResponse {
private Integer isOver;
private String msg;
private List<VehicleData> vehicleData;
}

View File

@ -26,7 +26,13 @@ public class EncryptKeyReqMessageService {
public void encryptKeyReq(MessageTopic topic, MqttMessage message) {
// 1. 解密
JSONObject jo = messageUtilService.decryptEncryptKeyReqMessage(topic, message);
JSONObject jo = new JSONObject();
try {
jo = messageUtilService.decryptEncryptKeyReqMessage(topic, message);
} catch (Exception e) {
e.printStackTrace();
return;
}
String clientPublicKey = jo.getStr("publicKey");
// 2. 保存MQTT消息
MessageMqtt mm = new MessageMqtt();

View File

@ -80,8 +80,8 @@ public class MessageUtilService {
* @param msg
* @param publicKey
*/
public void publishRSAMessage(MessageTopic topic, String msg, String publicKey) {
RSA rsa = SecureUtil.rsa(null, publicKey);
public void publishRSAMessage(MessageTopic topic, String msg, String stationPublicKey) {
RSA rsa = SecureUtil.rsa(null, stationPublicKey);
String encrypt = rsa.encryptBase64(msg, KeyType.PublicKey);
publishMessage.publish(encrypt, topic.toString());
}
@ -94,8 +94,7 @@ public class MessageUtilService {
*/
public void publishAESMessage(MessageTopic topic, MqttMessageHeader header, JSONObject dataBody) {
// 1. 获取AES
JSONObject aesJo = getAESKey(topic.getStationCode());
SymmetricCrypto aes = new AES(Mode.CBC, Padding.PKCS5Padding, aesJo.getStr("aesSecretKey").getBytes(), aesJo.getStr("aesIv").getBytes());
SymmetricCrypto aes = getAes(topic.getStationCode());
// 2. 数据
MyMqttMessage message = new MyMqttMessage();
message.setHeader(header);
@ -104,6 +103,9 @@ public class MessageUtilService {
// 3. 发送MQTT消息
publishMessage.publish(encrypt, topic.toString());
}
@ -117,8 +119,7 @@ public class MessageUtilService {
byte[] payload = message.getPayload();
String privateKey = getRSAPrivateKey(topic.getStationCode());
RSA rsa = SecureUtil.rsa(privateKey, null);
byte[] decrypt = rsa.decrypt(payload, KeyType.PrivateKey);
byte[] decrypt = rsa.decrypt(new String(payload), KeyType.PrivateKey);
return JSONUtil.parseObj(new String(decrypt));
}
@ -129,13 +130,20 @@ public class MessageUtilService {
* @return
*/
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());
SymmetricCrypto aes = getAes(topic.getStationCode());
String decrypt = aes.decryptStr(new String(message.getPayload()));
return JSONUtil.parseObj(decrypt);
}
public SymmetricCrypto getAes(String stationCode) {
JSONObject aesJo = getAESKey(stationCode);
String aesSecretKey = aesJo.getStr("encryptKey");
String aesIv = aesJo.getStr("encryptVector");
SymmetricCrypto aes = new AES(Mode.CBC, Padding.PKCS5Padding, Base64.getDecoder().decode(aesSecretKey), aesIv.getBytes());
return aes;
}
/**
* 获取AES秘钥和IV
@ -148,29 +156,32 @@ public class MessageUtilService {
try {
o1 = redisUtil.get(HDConstant.HD_STATION_SECRET_KEY_AES_PREFIX + stationCode + ":key");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Object o2 = null;
try {
o2 = redisUtil.get(HDConstant.HD_STATION_SECRET_KEY_AES_PREFIX + stationCode + ":iv");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (!ObjectUtil.isEmpty(o1) && !ObjectUtil.isEmpty(o2)) {
jo.set("aesSecretKey", o1.toString());
jo.set("aesIv", o2.toString());
// jo.set("aesSecretKey", o1.toString());
// jo.set("aesIv", o2.toString());
jo.set("encryptKey", o1.toString());
jo.set("encryptVector", o2.toString());
return jo;
}
BatteryStationSecretKey bssk = batteryStationSecretKeyDao.selectOne(new QueryWrapper<BatteryStationSecretKey>().eq("type", 2).eq("station_code", stationCode));
if (bssk == null) {
return setAesKey(stationCode);
throw new RuntimeException("AES秘钥未获取到请站端重新登陆");
// return setAesKey(stationCode);
}
redisUtil.set(HDConstant.HD_STATION_SECRET_KEY_AES_PREFIX + stationCode + ":key", bssk.getPublicKey());
redisUtil.set(HDConstant.HD_STATION_SECRET_KEY_AES_PREFIX + stationCode + ":iv", bssk.getPrivateKey());
jo.set("aesSecretKey", o1.toString());
jo.set("aesIv", o2.toString());
// jo.set("aesSecretKey", o1.toString());
// jo.set("aesIv", o2.toString());
jo.set("encryptKey", o1.toString());
jo.set("encryptVector", o2.toString());
return jo;
}
@ -195,8 +206,10 @@ public class MessageUtilService {
redisUtil.set(HDConstant.HD_STATION_SECRET_KEY_AES_PREFIX + stationCode + ":key", bssk.getPublicKey());
redisUtil.set(HDConstant.HD_STATION_SECRET_KEY_AES_PREFIX + stationCode + ":iv", bssk.getPrivateKey());
JSONObject jo = new JSONObject();
jo.set("aesSecretKey", base64KeyStr);
jo.set("aesIv", iv);
// jo.set("aesSecretKey", base64KeyStr);
// jo.set("aesIv", iv);
jo.set("encryptKey", base64KeyStr);
jo.set("encryptVector", iv);
return jo;
}

View File

@ -44,7 +44,13 @@ public class MqttMessageHandleService {
// 3. 其他 AES加密
// 3.1 保存数据
// 3.1.1 解密
JSONObject jo = messageUtilService.decryptAesMessage(topic, message);
JSONObject jo = new JSONObject();
try {
jo = messageUtilService.decryptAesMessage(topic, message);
} catch (Exception e) {
e.printStackTrace();
return;
}
// 3.1.2 保存MQTT消息
MqttMessageHeader header = messageUtilService.addMqttMessage(topic, message.getId()+"", message.getQos(), jo);
JSONObject dataBody = jo.getJSONObject("dataBody");

View File

@ -18,7 +18,9 @@ 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.BatteryData;
import com.evotech.hd.cloud.mqtt.message.dto.newer.req.battery.BatteryInfoReq;
import com.evotech.hd.cloud.mqtt.message.dto.newer.req.battery.BatteryInfoResponse;
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;
@ -34,6 +36,7 @@ import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre;
import com.evotech.hd.common.core.entity.cloud.VehicleWechatUserRelation;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import jakarta.annotation.Resource;
@ -102,6 +105,7 @@ public class RequestMessageService {
.eq("plate_num", orderByPlateNumReq.getPlateNum())
.eq("station_code", orderByPlateNumReq.getStationCode())
.eq("status", 1)
.eq("swap_day", DateUtil.format(d, DatePattern.PURE_DATE_FORMATTER))
.last("limit 1"));
if (osbp == null) {
response.setOrderRequestId(orderByPlateNumReq.getOrderRequestId());
@ -127,6 +131,9 @@ public class RequestMessageService {
osb.setStatus(1);
osb.setStationCode(osbp.getStationCode());
osb.setStationName(osbp.getStationName());
// TODO 查询换电站信息拿到计费方式放到订单信息中
// // 加上费用标准 - 移到订单服务中了
// osb = orderBasicFeeComponent.orderBasicFee(osb);
@ -145,7 +152,8 @@ public class RequestMessageService {
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));
messageUtilService.publishAESMessage(topic, header, JSONUtil.parseObj(response, new JSONConfig().setDateFormat(DatePattern.NORM_DATETIME_PATTERN)));
}
/**
@ -163,11 +171,27 @@ public class RequestMessageService {
pageNo += 1;
page = new Page<BatteryStationDc>(pageNo, pageSize);
page = batteryStationDcDao.selectPage(page, new QueryWrapper<BatteryStationDc>().eq(StringUtils.hasText(batCode), "bat_code", batCode));
BatteryInfoResponse response = new BatteryInfoResponse();
response.setBatteryInfoRequestId(batteryInfoReq.getBatteryInfoRequestId());
response.setPageNo(Integer.valueOf(page.getCurrent() + ""));
response.setPageSize(Integer.valueOf(page.getSize() + ""));
response.setTotal(Integer.valueOf(page.getTotal() + ""));
response.setIsOver(page.getCurrent() < page.getPages()? 0 : 1);
List<BatteryData> list = new ArrayList<BatteryData>();
if (page.getCurrent() > 0) {
list = page.getRecords().stream().map(i -> {
BatteryData bd = new BatteryData();
BeanUtils.copyProperties(i, bd);
return bd;
}).toList();
response.setBatteryData(list);
}
topic.setDataDirection("M2S");
topic.setMessageType(MqttMessageTypeEnum.RESPONSE.getType());
header.setFunction(RequestFunctionTypesEnum.FUN_BATTERYINFO.getReFunction());
header.setTimeStamp(DateUtil.format(new Date(), DatePattern.NORM_DATETIME_FORMATTER));
messageUtilService.publishAESMessage(topic, header, JSONUtil.parseObj(response, new JSONConfig().setDateFormat(DatePattern.NORM_DATETIME_PATTERN)));
} while (page.getCurrent() < page.getPages());
}
@ -207,7 +231,8 @@ public class RequestMessageService {
topic.setMessageType(MqttMessageTypeEnum.RESPONSE.getType());
header.setFunction(RequestFunctionTypesEnum.FUN_CARINFO.getReFunction());
header.setTimeStamp(DateUtil.format(new Date(), DatePattern.NORM_DATETIME_FORMATTER));
messageUtilService.publishAESMessage(topic, header, JSONUtil.parseObj(response));
messageUtilService.publishAESMessage(topic, header, JSONUtil.parseObj(response, new JSONConfig().setDateFormat(DatePattern.NORM_DATETIME_PATTERN)));
} while (page.getCurrent() < page.getPages());
}

View File

@ -65,6 +65,7 @@ public class StateMessageService {
OrderStatus orderStatus = JSONUtil.toBean(dataBody, OrderStatus.class);
OrderStatusData statusData = JSONUtil.toBean(dataBody.getJSONObject("statusData"), OrderStatusData.class);
handleOrderStatus(orderStatus, statusData);
// TODO 回复一下收到了
break;
case FUN_SWAPSTEP:
@ -77,6 +78,8 @@ public class StateMessageService {
step.setStepName(hdStepDictComponent.hdStepDictName(step.getStep()));
orderSwapBatteryStepDao.insert(step);
break;
case FUN_TEST:
break;
default:
break;

View File

@ -7,7 +7,8 @@ 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.entity.cloud.request.PageListSwapOrderPreRequest;
import com.evotech.hd.common.core.entity.cloud.request.PageListSwapOrderRequest;
public interface OrderSwapBatteryService {
@ -15,7 +16,7 @@ public interface OrderSwapBatteryService {
public Result<Integer> cancelPre(Integer id, Integer status);
public Result<List<OrderSwapBatteryPre>> listPre(String plateNum, Integer status, String ucode, String stationCode);
public Result<List<OrderSwapBatteryPre>> listPre(PageListSwapOrderPreRequest plsopr);
public Result<Integer> add(OrderSwapBattery osb);

View File

@ -19,9 +19,13 @@ public interface VehicleService {
public Result<Integer> companyRelation(String plateNum, String ccode, String cname);
public Result<Integer> delCompanyRelation(String plateNum);
public Result<Integer> addWechatUserRelation(VehicleWechatUserRelation relation);
public Result<Integer> deleteWechatUserRelation(Integer id);
public Result<List<VehicleInfo>> listWechatUserRelation(String openid, String plateNum);
public Result<List<VehicleWechatUserRelation>> listRelationUser(String PlantNo);
}

View File

@ -33,7 +33,7 @@ public class MessageMqttServiceImpl implements MessageMqttService {
.eq(StringUtils.hasText(plmmr.getDirection()), "direction", plmmr.getDirection())
.eq(StringUtils.hasText(plmmr.getType()), "type", plmmr.getType())
.eq(StringUtils.hasText(plmmr.getMessageFunction()), "message_function", plmmr.getMessageFunction())
.orderByDesc("message_id"));
.orderByDesc("pk_id"));
if (page.getRecords().isEmpty()) {
return new Result<List<MessageMqtt>>().error(CodeMsg.DATABASE_RESULT_NULL);
}

View File

@ -30,11 +30,12 @@ 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.entity.cloud.TradeDetail;
import com.evotech.hd.common.core.entity.cloud.VehicleInfo;
import com.evotech.hd.common.core.entity.cloud.WalletAccount;
import com.evotech.hd.common.core.entity.cloud.WalletAccountDetail;
import com.evotech.hd.common.core.entity.cloud.request.PageListSwapOrderPreRequest;
import com.evotech.hd.common.core.entity.cloud.request.PageListSwapOrderRequest;
import com.evotech.hd.common.core.entity.wechat.WechatUser;
import com.evotech.hd.common.core.enums.CodeMsg;
import com.evotech.hd.common.core.enums.OrderStatusEnums;
@ -101,7 +102,6 @@ public class OrderSwapBatteryServiceImpl implements OrderSwapBatteryService {
int n = orderSwapBatteryPreDao.insert(osbp);
if (n == 1) {
// 发送服务号消息没有消息队列先用接口吧
osbp.setCtime(null);
templateMessageService.preOrderMessageSend(osbp);
return new Result<Integer>().success(n);
}
@ -122,17 +122,20 @@ public class OrderSwapBatteryServiceImpl implements OrderSwapBatteryService {
}
@Override
public Result<List<OrderSwapBatteryPre>> listPre(String plateNum, Integer status, String ucode, String stationCode) {
List<OrderSwapBatteryPre> list = orderSwapBatteryPreDao.selectList(new QueryWrapper<OrderSwapBatteryPre>()
.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)
public Result<List<OrderSwapBatteryPre>> listPre(PageListSwapOrderPreRequest plsopr) {
Page<OrderSwapBatteryPre> page = new Page<OrderSwapBatteryPre>(plsopr.getPageNo(), plsopr.getPageSize());
page = orderSwapBatteryPreDao.selectPage(page, new QueryWrapper<OrderSwapBatteryPre>()
.eq(StringUtils.hasText(plsopr.getUcode()), "ucode", plsopr.getUcode())
.eq(plsopr.getStatus() != null, "status", plsopr.getStatus())
.eq(StringUtils.hasText(plsopr.getPlateNum()), "plate_num", plsopr.getPlateNum())
.eq(StringUtils.hasText(plsopr.getStationCode()), "station_code", plsopr.getStationCode())
.ge(StringUtils.hasText(plsopr.getSwapDayBegin()), "swap_day", plsopr.getSwapDayBegin())
.le(StringUtils.hasText(plsopr.getSwapDayEnd()), "swap_day", plsopr.getSwapDayEnd())
.orderByDesc("pk_id"));
if (list.isEmpty()) {
if (page.getRecords().isEmpty()) {
return new Result<List<OrderSwapBatteryPre>>().error(CodeMsg.DATABASE_RESULT_NULL);
}
return new Result<List<OrderSwapBatteryPre>>().success(list);
return new Result<List<OrderSwapBatteryPre>>().success(page);
}
@Override
@ -286,11 +289,21 @@ public class OrderSwapBatteryServiceImpl implements OrderSwapBatteryService {
}
}
// 3. 选择费用计算方式 计算费用
// 先按电量计算
if (order.getElectAmount() == null) {
return new Result<String>().error("充电订单 充电量 异常!");
BigDecimal fee = BigDecimal.ZERO;
if (order.getFeeType() == 3) {
// 先按电量计算
if (order.getElectAmount() == null) {
return new Result<String>().error("充电订单 充电量 异常!");
}
fee = order.getServiceFee().add(order.getBasicFee().multiply(order.getElectAmount())).setScale(0, RoundingMode.HALF_UP);
} else if (order.getFeeType() == 2) {
// TODO 按SOC
} else if (order.getFeeType() == 1) {
// TODO 按里程
} else {
}
BigDecimal fee = order.getServiceFee().add(order.getBasicFee().multiply(order.getElectAmount())).setScale(0, RoundingMode.HALF_UP);
// 4. 修改订单
order.setAmount(fee.intValue());
order.setStatus(6);

View File

@ -71,6 +71,7 @@ public class VehicleServiceImpl implements VehicleService {
.eq(StringUtils.hasText(plvr.getEngineNo()), "engine_no", plvr.getEngineNo())
.eq(StringUtils.hasText(plvr.getFrameworkNo()), "framework_no", plvr.getFrameworkNo())
.eq(StringUtils.hasText(plvr.getPhone()), "phone", plvr.getPhone())
.eq(StringUtils.hasText(plvr.getCcode()), "ccode", plvr.getCcode())
.ne("del_flag", 1)
.orderByAsc("plate_num"));
if (page.getRecords().isEmpty()) {
@ -84,12 +85,26 @@ public class VehicleServiceImpl implements VehicleService {
VehicleInfo vi = new VehicleInfo();
vi.setCcode(ccode);
vi.setCname(cname);
vi.setOwnerType(2);
int n = vehicleInfoDao.update(vi, new QueryWrapper<VehicleInfo>().eq("plate_num", plateNum));
if (n == 1) {
return new Result<Integer>().success(n);
}
return new Result<Integer>().error("关联公司失败!");
}
@Override
public Result<Integer> delCompanyRelation(String plateNum) {
VehicleInfo vi = new VehicleInfo();
vi.setCcode("");
vi.setCname("");
vi.setOwnerType(1);
int n = vehicleInfoDao.update(vi, new QueryWrapper<VehicleInfo>().eq("plate_num", plateNum));
if (n == 1) {
return new Result<Integer>().success(n);
}
return new Result<Integer>().error("删除关联公司失败!");
}
@Override
public Result<Integer> addWechatUserRelation(VehicleWechatUserRelation relation) {
@ -124,6 +139,16 @@ public class VehicleServiceImpl implements VehicleService {
return new Result<List<VehicleInfo>>().success(list);
}
@Override
public Result<List<VehicleWechatUserRelation>> listRelationUser(String PlantNo) {
List<VehicleWechatUserRelation> list = vehicleWechatUserRelationDao.selectList(new QueryWrapper<VehicleWechatUserRelation>().eq("plate_num", PlantNo));
if (list.isEmpty()) {
return new Result<List<VehicleWechatUserRelation>>().error(CodeMsg.DATABASE_RESULT_NULL);
}
list.stream().forEach(i -> i.setOpenid(null));
return new Result<List<VehicleWechatUserRelation>>().success(list);
}
}

View File

@ -1,5 +1,6 @@
package com.evotech.hd.cloud.service.newthread;
import java.util.Date;
import java.util.List;
import org.springframework.stereotype.Service;
@ -66,6 +67,7 @@ public class WechatPayNotifyHandleService {
wad.setTradeType(tradeDetail.getTradeType());
wad.setTradeNo(tradeDetail.getOutTradeNo());
wad.setCtime(new Date());
walletAccountDetailDao.insert(wad);
// 改余额
wallet.setTotalAmount(wad.getAfterTotalAmount());

View File

@ -28,7 +28,7 @@ public interface WechatService {
@PostMapping(value = "/wechat/gzh/msg/send/preorder2",
consumes = {MediaType.APPLICATION_JSON_VALUE})
public Result<String> preOrderMessage(OrderSwapBatteryPre osbp);
public Result<String> preOrderMessage(@RequestBody OrderSwapBatteryPre osbp);
@PostMapping(value = "/wechat/gzh/msg/send/order",
consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
@ -39,8 +39,8 @@ public interface WechatService {
public Result<String> orderMessage2(@RequestParam Integer id, @RequestParam Integer templateType);
@PostMapping(value = "/wechat/gzh/msg/send/recharge",
consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
public Result<String> rechargeMessage(@ParameterObject TradeDetail trade, @RequestParam Integer money);
consumes = {MediaType.APPLICATION_JSON_VALUE})
public Result<String> rechargeMessage(@RequestBody TradeDetail trade, @RequestParam Integer money);
@PostMapping(value = "/wechat/wechatpay/native/prepay",
consumes = {MediaType.APPLICATION_JSON_VALUE})

View File

@ -1,5 +1,6 @@
package com.evotech.hd.cloud.task;
import java.util.Date;
import java.util.List;
import org.springframework.scheduling.annotation.Scheduled;
@ -12,11 +13,12 @@ import com.evotech.hd.common.core.entity.Result;
import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery;
import com.evotech.hd.common.core.enums.CodeMsg;
import cn.hutool.core.date.DateUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
//@Component
@Component
@Slf4j
public class OrderCostCalculateTask {
@ -37,7 +39,9 @@ public class OrderCostCalculateTask {
int n = 0;
while (flag) {
List<OrderSwapBattery> list = orderSwapBatteryDao.selectList(new QueryWrapper<OrderSwapBattery>()
.eq("status", 5).ne("del_flag", 1).last("limit 20"));
.eq("status", 5).ne("del_flag", 1)
.ge("order_time", DateUtil.beginOfYear(new Date()))
.last("limit 20"));
if (!list.isEmpty()) {
n = orderCalculate(n, list);
} else {

View File

@ -27,7 +27,7 @@ spring:
username: nacos
password: nacos
discovery:
register-enabled: false
register-enabled: true
#server-addr: 10.10.1.6:8848
#ip: 10.10.1.2
# 因添加了context-pathadmin-server要想发现正确路径需要加这个

View File

@ -13,7 +13,8 @@ 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.entity.cloud.request.PageListSwapOrderPreRequest;
import com.evotech.hd.common.core.entity.cloud.request.PageListSwapOrderRequest;
import com.evotech.hd.wechat.service.OrderService;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
@ -52,8 +53,8 @@ public class SwapOrderController {
@Operation(summary = "查询预约")
@GetMapping("/pre/list")
@ApiOperationSupport(order = 3)
public Result<List<OrderSwapBatteryPre>> listPre(@RequestParam(required = false) String plateNum, @RequestParam(required = false) Integer status, @RequestParam(required = false) String ucode, @RequestParam(required = false) String stationCode) {
return orderService.listPre(plateNum, status, ucode, stationCode);
public Result<List<OrderSwapBatteryPre>> listPre(@ParameterObject PageListSwapOrderPreRequest plsopr) {
return orderService.listPre(plsopr);
}
@Operation(summary = "查询订单")

View File

@ -64,7 +64,7 @@ public class GZHMessageSendController {
@Operation(summary = "充值成功推送公众号消息")
@PostMapping("/recharge")
@ApiOperationSupport(order = 4)
public Result<String> sendTemplateMessageRecharge(@ParameterObject TradeDetail trade, @RequestParam Integer money) {
public Result<String> sendTemplateMessageRecharge(@RequestBody TradeDetail trade, @RequestParam Integer money) {
return gzhMessageTemplateService.sendTemplateMessageRecharge(trade, money);
}

View File

@ -6,7 +6,8 @@ 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.entity.cloud.request.PageListSwapOrderPreRequest;
import com.evotech.hd.common.core.entity.cloud.request.PageListSwapOrderRequest;
public interface OrderService {
@ -14,7 +15,7 @@ public interface OrderService {
public Result<Integer> cancelPre(Integer id);
public Result<List<OrderSwapBatteryPre>> listPre(String plateNum, Integer status, String ucode, String stationCode);
public Result<List<OrderSwapBatteryPre>> listPre(PageListSwapOrderPreRequest plsopr);
public Result<List<OrderSwapBattery>> list(PageListSwapOrderRequest plsor);

View File

@ -1,5 +1,7 @@
package com.evotech.hd.wechat.service.gzh;
import java.math.BigDecimal;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
@ -63,6 +65,7 @@ public class GZHMessageTemplateService {
if (wuser == null) {
return null;
}
if (!StringUtils.hasText(wuser.getGzhOpenid())) {
return new Result<String>().error("未关注公众号!");
}
@ -83,12 +86,14 @@ public class GZHMessageTemplateService {
data.setThing5(osbp.getUname());
data.setPhone_number4(osbp.getPhone());
sendData.setData(JSONUtil.parseObj(data));
String res = TemplateMessageUtil.templateMessageSend(gzhAccessTokenService.gzhAccessToken(), sendData);
JSONObject jo = JSONUtil.parseObj(res);
if (jo.getInt("errcode") == 0) {
return new Result<String>().success(jo);
}
} else {
System.out.println(jo);
}
return new Result<String>().error(CodeMsg.WECHAT_API_ERROR, jo);
}
@ -188,7 +193,6 @@ public class GZHMessageTemplateService {
if (!StringUtils.hasText(wuser.getGzhOpenid())) {
return new Result<String>().error("未关注公众号!");
}
MessageTemplateSendData sendData = new MessageTemplateSendData();
sendData.setTouser(wuser.getGzhOpenid());
String templateId = gzhProperties.getWalletRechargeTemplateId();
@ -201,11 +205,10 @@ public class GZHMessageTemplateService {
WalletRechargeTemplateData data = new WalletRechargeTemplateData();
data.setThing3(trade.getTrader());
data.setAmount1(trade.getTradeAmount()/100 + "");
data.setTime4(DateUtil.format(trade.getPayTime(), DatePattern.CHINESE_DATE_TIME_PATTERN));
data.setAmount5(money/100 + "");
data.setAmount1(new BigDecimal(trade.getTradeAmount()).divide(new BigDecimal(100)).setScale(2) + "");
data.setTime4(DateUtil.format(trade.getPayTime(), DatePattern.NORM_DATETIME_FORMATTER));
data.setAmount5(new BigDecimal(money).divide(new BigDecimal(100)).setScale(2) + "");
sendData.setData(JSONUtil.parseObj(data));
String res = TemplateMessageUtil.templateMessageSend(gzhAccessTokenService.gzhAccessToken(), sendData);
JSONObject jo = JSONUtil.parseObj(res);
if (jo.getInt("errcode") == 0) {

View File

@ -1,6 +1,7 @@
package com.evotech.hd.wechat.service.impl;
import java.util.List;
import java.util.Optional;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
@ -10,7 +11,8 @@ 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.entity.cloud.request.PageListSwapOrderPreRequest;
import com.evotech.hd.common.core.entity.cloud.request.PageListSwapOrderRequest;
import com.evotech.hd.wechat.service.OrderService;
import com.evotech.hd.wechat.service.rpc.CloudService;
@ -38,9 +40,12 @@ public class OrderServiceImpl implements OrderService {
}
@Override
public Result<List<OrderSwapBatteryPre>> listPre(String plateNum, Integer status, String ucode,
String stationCode) {
return cloudService.listPre(plateNum, status, ucode, stationCode);
public Result<List<OrderSwapBatteryPre>> listPre(PageListSwapOrderPreRequest plsopr) {
if (Optional.ofNullable(plsopr.getUcode()).isPresent()) {
return cloudService.listPre(plsopr);
} else {
return new Result<List<OrderSwapBatteryPre>>().error("用户编码不能为空!");
}
}
@Override

View File

@ -53,7 +53,7 @@ public class WechatUserServiceImpl implements WechatUserService {
return new Result<WechatUser>().error(CodeMsg.DATABASE_RESULT_NULL);
}
user.setOpenid(DesensitizedUtil.idCardNum(user.getOpenid(), 5, 6));
user.setPhoneNumber(DesensitizedUtil.mobilePhone(user.getPhoneNumber()));
// user.setPhoneNumber(DesensitizedUtil.mobilePhone(user.getPhoneNumber()));
return new Result<WechatUser>().success(user);
}

View File

@ -14,11 +14,12 @@ 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.entity.cloud.TradeDetail;
import com.evotech.hd.common.core.entity.cloud.VehicleInfo;
import com.evotech.hd.common.core.entity.cloud.WalletAccount;
import com.evotech.hd.common.core.entity.cloud.WalletAccountDetail;
import com.evotech.hd.common.core.entity.cloud.request.PageListSwapOrderPreRequest;
import com.evotech.hd.common.core.entity.cloud.request.PageListSwapOrderRequest;
import com.evotech.hd.common.core.entity.cloud.request.PageListWalletRequest;
import com.evotech.hd.common.core.entity.cloud.vo.BatteryStationVO;
@ -35,7 +36,7 @@ public interface CloudService {
@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);
public Result<List<OrderSwapBatteryPre>> listPre(@SpringQueryMap PageListSwapOrderPreRequest plsopr);
@GetMapping(value = "/cloud/order/swap/list",
consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})

View File

@ -72,7 +72,7 @@ hbyt:
app-secret: 84a6065165ec82862c5e03a010a6dc6c
token: r7YASMj3S9vCeeyJPpKeFPR9drhFaSDt
encodingAESKey: W3zDuKYFMUlYUXpT4AhRSPkqMS7CgcmnEVQ3enVcTtf
pre_order_template_id: 4eknqqZhEqW7_3xSYLskvPUX193irbalhdHjOSY88-g
pre_order_template_id: xmymFQ7DgEHh-rz-6i77-RIcgSzv2RDlEy0E8s0vwFA
order_start_template_id: L_AsG7s7DOyyz4dXLb8gIi7h4Sy__ifEAL1Mo8gAw4E
order_swap_end_template_id: wGll5W3NSHXkHjcEprjUbd1shigGOqywGX7A0BVnzUs
order_to_pay_template_id: IE0_RGuN5ufU4GFrCgM9JeUfvlWfbneEuUMDsn0RBQs