Merge remote-tracking branch 'origin/main'

This commit is contained in:
attiya 2025-10-30 10:46:59 +08:00
commit 357c09c1ea
14 changed files with 262 additions and 90 deletions

View File

@ -133,11 +133,13 @@
<artifactId>okhttp</artifactId>
<version>${okhttp.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>${fastjson.version}</version>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- for test only -->
<dependency>
<groupId>org.springframework.boot</groupId>

View File

@ -1,8 +1,10 @@
package com.cdzy.payment.controller;
import com.alibaba.fastjson2.JSONObject;
import com.cdzy.payment.model.vo.EbikeWxHandleNotifyVo;
import com.cdzy.payment.service.EbikeWxPayService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@ -25,6 +27,9 @@ public class EbikeWxPayNotifyController {
@Resource
private EbikeWxPayService wxPayService;
@Resource
private ObjectMapper objectMapper;
/**
* 支付回调通知
*
@ -37,16 +42,10 @@ public class EbikeWxPayNotifyController {
EbikeWxHandleNotifyVo r = wxPayService.handlePayNotify(request);
if (!r.isSuccess()) {
response.setStatus(500);
JSONObject jsonObject = new JSONObject();
jsonObject.put("code", "SYSTEM_ERROR");
jsonObject.put("message", r.getMessage());
return jsonObject.toJSONString();
return createErrorResponse(r.getMessage());
}
response.setStatus(200);
JSONObject jsonObject = new JSONObject();
jsonObject.put("code", "SUCCESS");
jsonObject.put("message", "OK");
return jsonObject.toJSONString();
return createSuccessResponse();
}
/**
@ -61,16 +60,39 @@ public class EbikeWxPayNotifyController {
EbikeWxHandleNotifyVo r = wxPayService.handleRefundNotify(request);
if (!r.isSuccess()) {
response.setStatus(500);
JSONObject jsonObject = new JSONObject();
jsonObject.put("code", "SYSTEM_ERROR");
jsonObject.put("message", r.getMessage());
return jsonObject.toJSONString();
return createErrorResponse(r.getMessage());
}
response.setStatus(200);
JSONObject jsonObject = new JSONObject();
jsonObject.put("code", "SUCCESS");
jsonObject.put("message", "OK");
return jsonObject.toJSONString();
return createSuccessResponse();
}
}
/**
* 创建成功响应
*/
private String createSuccessResponse() {
try {
ObjectNode jsonObject = objectMapper.createObjectNode();
jsonObject.put("code", "SUCCESS");
jsonObject.put("message", "OK");
return objectMapper.writeValueAsString(jsonObject);
} catch (JsonProcessingException e) {
// 如果JSON序列化失败返回简单的成功响应
return "{\"code\":\"SUCCESS\",\"message\":\"OK\"}";
}
}
/**
* 创建错误响应
*/
private String createErrorResponse(String message) {
try {
ObjectNode jsonObject = objectMapper.createObjectNode();
jsonObject.put("code", "SYSTEM_ERROR");
jsonObject.put("message", message);
return objectMapper.writeValueAsString(jsonObject);
} catch (JsonProcessingException e) {
// 如果JSON序列化失败返回简单的错误响应
return "{\"code\":\"SYSTEM_ERROR\",\"message\":\"" + message + "\"}";
}
}
}

View File

@ -1,12 +1,12 @@
package com.cdzy.payment.controller;
import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson2.JSONObject;
import com.cdzy.common.model.response.JsonResult;
import com.cdzy.payment.model.dto.*;
import com.cdzy.payment.model.vo.*;
import com.cdzy.payment.service.EbikeRefundService;
import com.cdzy.payment.service.EbikeWxPayService;
import com.fasterxml.jackson.databind.JsonNode;
import com.mybatisflex.core.paginate.Page;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.refund.model.Refund;
@ -40,7 +40,7 @@ public class EbikeWxPaymentController {
*/
@GetMapping("/prepay")
public JsonResult<?> prepay(@RequestParam(name = "orderId") Long orderId) {
JSONObject r = wxPayService.prepay(orderId);
JsonNode r = wxPayService.prepay(orderId);
return JsonResult.success(r);
}

View File

@ -1,7 +1,8 @@
package com.cdzy.payment.model.vo;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wechat.pay.java.core.cipher.SignatureResult;
import com.wechat.pay.java.core.cipher.Signer;
import lombok.Data;
@ -37,7 +38,7 @@ public class EbikeWxJsapiPromptVo {
/**
* 订单详情扩展提交格式如prepay_id=***
*/
@JSONField(name = "package")
@JsonProperty("package")
private String extension;
/**
@ -50,17 +51,43 @@ public class EbikeWxJsapiPromptVo {
*/
private String paySign;
public JSONObject toJson(Signer rsaSigner) {
/**
* 转换为JSON字符串
* @param rsaSigner 签名器
* @return JSON字符串
*/
public String toJsonString(Signer rsaSigner) {
try {
// 计算签名
String signMsg = appId + "\n" + timeStamp + "\n" + nonceStr + "\n" + extension + "\n";
SignatureResult sign = rsaSigner.sign(signMsg);
this.paySign = sign.getSign();
//result.put("package", result.remove("extension"));
return JSONObject.parseObject(JSONObject.toJSONString(this));
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.writeValueAsString(this);
} catch (Exception e) {
log.error("计算签名失败", e);
throw new RuntimeException("计算签名失败", e);
log.error("计算签名或生成JSON失败", e);
throw new RuntimeException("计算签名或生成JSON失败", e);
}
}
}
/**
* 转换为JSON对象如果需要返回JsonNode而不是字符串
* @param rsaSigner 签名器
* @return JsonNode对象
*/
public com.fasterxml.jackson.databind.JsonNode toJsonNode(Signer rsaSigner) {
try {
// 计算签名
String signMsg = appId + "\n" + timeStamp + "\n" + nonceStr + "\n" + extension + "\n";
SignatureResult sign = rsaSigner.sign(signMsg);
this.paySign = sign.getSign();
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.valueToTree(this);
} catch (Exception e) {
log.error("计算签名或生成JSON失败", e);
throw new RuntimeException("计算签名或生成JSON失败", e);
}
}
}

View File

@ -1,6 +1,5 @@
package com.cdzy.payment.service;
import com.alibaba.fastjson2.JSONObject;
import com.cdzy.payment.model.dto.EbikeRefundDto;
import com.cdzy.payment.model.dto.EbikeRefundProcessDto;
import com.cdzy.payment.model.dto.EbikeRefundQueryDto;
@ -8,6 +7,7 @@ import com.cdzy.payment.model.vo.EbikeRefundApplyOrderInfoVo;
import com.cdzy.payment.model.vo.EbikeRefundOrderDetailVo;
import com.cdzy.payment.model.vo.EbikeRefundUserDetailInfoVo;
import com.cdzy.payment.model.vo.EbikeWxHandleNotifyVo;
import com.fasterxml.jackson.databind.JsonNode;
import com.mybatisflex.core.paginate.Page;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.refund.model.Refund;
@ -37,7 +37,7 @@ public interface EbikeWxPayService {
* @param orderId 订单id
* @return 下单成功返回wx支付请求参数否则返回null
*/
JSONObject prepay(Long orderId);
JsonNode prepay(Long orderId);
/**
@ -77,7 +77,7 @@ public interface EbikeWxPayService {
* 退款申请
*
* @param orderId 商户(骑行)订单号
* @param reason 退款原因
* @param reason 退款原因
* @return 退款信息id
*/
Long refundApply(Long orderId, String reason);

View File

@ -1,7 +1,9 @@
package com.cdzy.payment.service.impl;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.type.TypeReference;
import com.cdzy.common.enums.Code;
import com.cdzy.common.enums.GlobalConstants;
import com.cdzy.common.model.response.JsonResult;
@ -26,6 +28,7 @@ import com.ebike.feign.model.dto.FeignEbikeSiteQueryDto;
import com.ebike.feign.model.dto.FeignLocationDto;
import com.ebike.feign.model.vo.FeignEbikeBikeBaseInfoVo;
import com.ebike.feign.model.vo.FeignEbikeSiteInfoVo;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.mybatisflex.core.paginate.Page;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.cipher.Signer;
@ -98,6 +101,9 @@ public class EbikeWxPayServiceImpl implements EbikeWxPayService {
@Resource
private OperationsFeignClient operationsFeignClient;
@Resource
private ObjectMapper objectMapper;
@Override
public boolean closeOrder(String outTradeNo) {
try {
@ -115,8 +121,8 @@ public class EbikeWxPayServiceImpl implements EbikeWxPayService {
@Override
public JSONObject prepay(Long orderId) {
JSONObject r = new JSONObject();
public JsonNode prepay(Long orderId) {
ObjectNode r = objectMapper.createObjectNode();
// 首先检查订单是否正在付中或者已经支付成功
// 关闭了的订单重新发起请求
EbikePayment ebikePayment = ebikePaymentService.getByOrderId(orderId);
@ -185,8 +191,8 @@ public class EbikeWxPayServiceImpl implements EbikeWxPayService {
* @param ebikePayment 原始支付记录
* @return 下单成功返回wx支付请求参数否则返回null
*/
private JSONObject prepay(EbikePaymentVo paymentVo, EbikePayment ebikePayment) {
JSONObject r = new JSONObject();
private JsonNode prepay(EbikePaymentVo paymentVo, EbikePayment ebikePayment) {
ObjectNode r = objectMapper.createObjectNode();
String outTradeNo = String.valueOf(paymentVo.getOrderId());
String description = paymentVo.getDescription();
String goodsTag = String.valueOf(paymentVo.getOrderType());
@ -285,7 +291,8 @@ public class EbikeWxPayServiceImpl implements EbikeWxPayService {
wxJsapiPromptDto.setTimeStamp(String.valueOf(Instant.now().getEpochSecond()));
wxJsapiPromptDto.setNonceStr(NonceUtil.createNonce(32));
wxJsapiPromptDto.setExtension("prepay_id=" + response.getPrepayId());
return wxJsapiPromptDto.toJson(wxRsaSigner);
String jsonString = wxJsapiPromptDto.toJsonString(wxRsaSigner);
return objectMapper.readTree(jsonString);
}
log.error("微信支付下单prepay失败订单号{}", outTradeNo);
@ -528,8 +535,12 @@ public class EbikeWxPayServiceImpl implements EbikeWxPayService {
} catch (Exception e) {
String err = logError("退款refund", e);
try {
JSONObject json = JSON.parseObject(err);
notifyVo.setMessage(json.getString("message"));
JsonNode jsonNode = objectMapper.readTree(err);
if (jsonNode.has("message")) {
notifyVo.setMessage(jsonNode.get("message").asText());
} else {
notifyVo.setMessage(err);
}
} catch (Exception ex) {
notifyVo.setMessage(err);
}
@ -908,8 +919,10 @@ public class EbikeWxPayServiceImpl implements EbikeWxPayService {
location.setLatitude(latitude);
JsonResult<?> result = operationsFeignClient.locationAddressDetails(location);
if (result.getCode() == Code.SUCCESS) {
JSONObject address = JSON.parseObject(JSONObject.toJSONString(result.getData()), JSONObject.class);
return address != null ? address.getString("district") : null;
// 使用Jackson进行对象转换
String jsonString = objectMapper.writeValueAsString(result.getData());
JsonNode addressNode = objectMapper.readTree(jsonString);
return addressNode.has("district") ? addressNode.get("district").asText() : null;
}
} catch (Exception e) {
log.error("获取区域信息失败,坐标: [{}, {}]", longitude, latitude, e);
@ -930,7 +943,9 @@ public class EbikeWxPayServiceImpl implements EbikeWxPayService {
siteQuery.setAreaId(bike.getReginId());
JsonResult<?> siteInfo = operationsFeignClient.querySite(siteQuery);
if (siteInfo.getCode() == Code.SUCCESS) {
FeignEbikeSiteInfoVo site = JSON.parseObject(JSONObject.toJSONString(siteInfo.getData()), FeignEbikeSiteInfoVo.class);
// 使用Jackson进行对象转换
String jsonString = objectMapper.writeValueAsString(siteInfo.getData());
FeignEbikeSiteInfoVo site = objectMapper.readValue(jsonString, FeignEbikeSiteInfoVo.class);
return site != null ? site.getSiteName() : null;
}
}
@ -950,8 +965,10 @@ public class EbikeWxPayServiceImpl implements EbikeWxPayService {
location.setLatitude(latitude);
JsonResult<?> result = operationsFeignClient.locationAddressDetails(location);
if (result.getCode() == Code.SUCCESS) {
JSONObject address = JSON.parseObject(JSONObject.toJSONString(result.getData()), JSONObject.class);
return address != null ? address.getString("detail") : null;
// 使用Jackson进行对象转换
String jsonString = objectMapper.writeValueAsString(result.getData());
JsonNode addressNode = objectMapper.readTree(jsonString);
return addressNode.has("detail") ? addressNode.get("detail").asText() : null;
}
} catch (Exception e) {
log.error("获取详细地址失败,坐标: [{}, {}]", longitude, latitude, e);
@ -966,7 +983,9 @@ public class EbikeWxPayServiceImpl implements EbikeWxPayService {
try {
JsonResult<?> bikeInfo = operationsFeignClient.getBikeBaseInfoByCode(bikeCode);
if (bikeInfo.getCode() == Code.SUCCESS) {
return JSON.parseObject(JSONObject.toJSONString(bikeInfo.getData()), FeignEbikeBikeBaseInfoVo.class);
// 使用Jackson进行对象转换
String jsonString = objectMapper.writeValueAsString(bikeInfo.getData());
return objectMapper.readValue(jsonString, FeignEbikeBikeBaseInfoVo.class);
}
} catch (Exception e) {
log.error("获取车辆基本信息失败,车辆编码: {}", bikeCode, e);

View File

@ -124,9 +124,9 @@
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>${fastjson.version}</version>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- 数据宝实名认证加密 -->

View File

@ -0,0 +1,50 @@
package com.cdzy.user.component;
import org.springframework.stereotype.Component;
import java.util.concurrent.*;
/**
* @author attiya
* @since 2025-03-18
*/
@Component
public class EbikeCoreHandler {
private final ConcurrentMap<String, CompletableFuture<String>> pendingRequests = new ConcurrentHashMap<>();
private final ScheduledExecutorService timeoutScheduler = Executors.newScheduledThreadPool(1);
/**
* 下发命令
*
* @param ebikeEcuInfo 中控信息
* @return 一致性返回
*/
// public CompletableFuture<String> executeCommand(FeignEbikeEcuInfo ebikeEcuInfo, String cmdCode, Long bikeId, String userId) {
// CompletableFuture<String> future = new CompletableFuture<>();
// CMDMsg cmdMsg = new CMDMsg();
// cmdMsg.setDeviceId(ebikeEcuInfo.getEcuSn());
// cmdMsg.setGroup(ebikeEcuInfo.getOperatorCode());
// String tid = UUID.randomUUID().toString().replace("-", "");
// String command = getCommand(cmdCode, tid);
// cmdMsg.setCommand(command);
// // 注册响应监听
// pendingRequests.put(tid, future);
// String string = JSONObject.toJSONString(cmdMsg);
// producer.send("command", string);
//
//
// // 设置超时任务30秒未响应则超时
// timeoutScheduler.schedule(() -> {
// CompletableFuture<String> timedOutFuture = pendingRequests.remove(tid);
// if (timedOutFuture != null) {
// timedOutFuture.completeExceptionally(new TimeoutException("超时未响应"));
// }
// }, 5, TimeUnit.SECONDS);
// return future;
// }
}

View File

@ -1,6 +1,5 @@
package com.cdzy.user.controller;
import com.alibaba.fastjson2.JSONObject;
import com.cdzy.common.model.response.JsonResult;
import com.cdzy.user.model.dto.EbikeUserPageDto;
import com.cdzy.user.model.dto.UserValidateDto;
@ -11,6 +10,9 @@ import com.cdzy.user.model.vo.EbikeUserVo;
import com.cdzy.user.service.EbikeOrderService;
import com.cdzy.user.service.EbikeUserService;
import com.cdzy.user.utils.VerifyUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mybatisflex.core.paginate.Page;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*;
@ -35,6 +37,9 @@ public class EbikeUserController {
@Resource
private EbikeOrderService ebikeOrderTransactionService;
@Resource
private ObjectMapper objectMapper;
/**
* 用户微信无感登录
*
@ -42,14 +47,14 @@ public class EbikeUserController {
*/
@RequestMapping("login")
public JsonResult<?> silentLogin(@RequestParam(name = "js_code") String code) {
JSONObject result = verifyUtil.wechatAuthority(code);
JsonNode result = verifyUtil.wechatAuthority(code);
if (result == null) {
return JsonResult.failed("微信登录失败");
}
if (result.containsKey("errcode")) {
return JsonResult.failed(String.format("微信登录失败 %s", result.getString("errmsg")));
if (result.has("errcode")) {
return JsonResult.failed(String.format("微信登录失败 %s", result.get("errmsg").asText()));
}
return JsonResult.success("微信登录成功", result.getString("openid"));
return JsonResult.success("微信登录成功", result.get("openid").asText());
}
/**
@ -59,19 +64,29 @@ public class EbikeUserController {
*/
@PostMapping("getEncryptInfo")
public JsonResult<?> getEncryptInfo(@RequestBody WechatInfoDto wechatInfoDto) {
JSONObject result = verifyUtil.wechatAuthority(wechatInfoDto.getJsCode());
JsonNode result = verifyUtil.wechatAuthority(wechatInfoDto.getJsCode());
if (result == null) {
return JsonResult.failed("解密失败");
}
if (result.containsKey("errcode")) {
return JsonResult.failed(String.format("解密失败 %s", result.getString("errmsg")));
if (result.has("errcode")) {
return JsonResult.failed(String.format("解密失败 %s", result.get("errmsg").asText()));
}
String decryptedData = verifyUtil.decryptData(wechatInfoDto.getEncryptedData(), result.getString("session_key"), wechatInfoDto.getIv());
String decryptedData = verifyUtil.decryptData(wechatInfoDto.getEncryptedData(), result.get("session_key").asText(), wechatInfoDto.getIv());
if (decryptedData == null || decryptedData.isEmpty()) {
return JsonResult.failed("解密失败");
}
JSONObject jsonObject = JSONObject.parseObject(decryptedData);
return JsonResult.success("解密成功", jsonObject.getString("phoneNumber"));
try {
// 使用 Jackson 解析解密后的数据
JsonNode jsonNode = objectMapper.readTree(decryptedData);
if (jsonNode.has("phoneNumber")) {
return JsonResult.success("解密成功", jsonNode.get("phoneNumber").asText());
} else {
return JsonResult.failed("解密数据中未找到手机号");
}
} catch (JsonProcessingException e) {
return JsonResult.failed("解密数据解析失败");
}
}
/**
@ -186,4 +201,4 @@ public class EbikeUserController {
Page<EbikeUserVo> list = ebikeUserService.queryPage(userPageDto);
return JsonResult.success(list);
}
}
}

View File

@ -1,8 +1,11 @@
package com.cdzy.user.model.dto;
import com.cdzy.user.handler.PGpointDeserializer;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.postgresql.geometric.PGpoint;
/**
* 用户骑行信息(用户id及自行车编号)
@ -25,4 +28,10 @@ public class EbikeUserCyclingDto {
*/
@NotBlank(message = "车辆编号不能为空")
private String bikeCode;
/**
* 骑行起始点
*/
@JsonDeserialize(using = PGpointDeserializer.class)
private PGpoint startPoint;
}

View File

@ -1,7 +1,12 @@
package com.cdzy.user.service.impl;
import com.cdzy.common.enums.BikeUsageStatus;
import com.cdzy.common.enums.Code;
import com.cdzy.common.model.dto.ResGPSDto;
import com.cdzy.common.model.response.JsonResult;
import com.cdzy.user.enums.EbikeRegionInOperation;
import com.cdzy.user.enums.OrderStatus;
import com.cdzy.user.enums.OrderType;
import com.cdzy.user.mapper.EbikeOrderMapper;
import com.cdzy.user.model.dto.EbikeUserCyclingDto;
import com.cdzy.user.model.entity.EbikeOrder;
@ -10,11 +15,18 @@ import com.cdzy.user.utils.RedisUtil;
import com.ebike.feign.clients.OperationsFeignClient;
import com.ebike.feign.model.dto.FeignOrderPaymentDto;
import com.ebike.feign.model.vo.FeignEbikeBikeInfoVo;
import com.ebike.feign.model.vo.FeignEbikeConfigurationVo;
import com.ebike.feign.model.vo.FeignEbikeEcuInfoVo;
import com.ebike.feign.model.vo.FeignEbikeRegionVo;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import static com.cdzy.user.model.entity.table.EbikeOrderTableDef.EBIKE_ORDER;
@ -31,8 +43,8 @@ public class EbikeOrderImpl extends ServiceImpl<EbikeOrderMapper, EbikeOrder> im
@Resource
private RedisUtil redisUtil;
// @Resource
// private EbikeCoreHandler ebikeCoreHandler;
//@Resource
//private EbikeCoreHandler ebikeCoreHandler;
@Resource
private EbikeOrderMapper ebikeOrderTransactionMapper;
@ -96,8 +108,7 @@ public class EbikeOrderImpl extends ServiceImpl<EbikeOrderMapper, EbikeOrder> im
// //改变骑行状态-骑行中
// operationsFeignClient.riding(bikeInfoDto.getBikeId());
// userOrders.setBikeId(bikeInfoDto.getBikeId());
// String stringBuilder = resGpsDto.getLongitude() + "," + resGpsDto.getLatitude();
// userOrders.setStartLocation(stringBuilder);
// userOrders.setStartLocation(orderDto.getStartPoint());
// ebikeOrderTransactionMapper.insert(userOrders);
// //处理车辆
// return userOrders.getOrderId();

View File

@ -1,7 +1,5 @@
package com.cdzy.user.utils;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.cdp.product.security.context.SecurityContext;
import com.cdp.product.security.exception.DecryptFailureException;
import com.cdp.product.security.exception.EncryptFailureException;
@ -18,6 +16,9 @@ import com.cdzy.user.model.entity.EbikeUser;
import com.cdzy.user.model.entity.EbikeUserRealInfo;
import com.cdzy.user.service.EbikeUserRealInfoService;
import com.cdzy.user.service.EbikeUserService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
@ -69,6 +70,9 @@ public class VerifyUtil {
@Resource
private EbikeUserRealInfoService ebikeUserRealInfoService;
@Resource
private ObjectMapper objectMapper;
//暂时硬编码后续放到redis或者config中本地数据加密解密
private SecureComponent secureComponent;
private static final String PRIVATE_KEY = "f8209a2ebe6691e41e1f2b667bfe71f0b511716cc0f7c4452502fc12ec3957e4";
@ -95,7 +99,7 @@ public class VerifyUtil {
* @param code 微信登录返回的code
* @return openId
*/
public JSONObject wechatAuthority(String code) {
public JsonNode wechatAuthority(String code) {
Map<String, String> params = new HashMap<>();
params.put("appid", wechatConfig.getAppId());
params.put("secret", wechatConfig.getAppSecret());
@ -160,25 +164,28 @@ public class VerifyUtil {
params.put("key", realNameVerifyConfig.getApiKey());
// 2. 验证用户实名
JSONObject result = httpPost("验证用户实名", REALNAME_VERIFY_URL, params, null);
JsonNode result = httpPost("验证用户实名", REALNAME_VERIFY_URL, params, null);
log.info("验证用户实名结果:{}", result);
if (result == null) {
log.error("验证用户实名失败");
return JsonResult.failed("验证用户实名失败");
}
if ("10000".equals(result.getString("code"))) {
if (result.has("code") && "10000".equals(result.get("code").asText())) {
// 3. 解密结果
String data = securityContext.decrypt(result.getString("data"), realNameVerifyConfig.getClientPrivateKey());
JSONObject jsonData = JSON.parseObject(data);
if ("1".equals(jsonData.getString("result"))) {
String data = securityContext.decrypt(result.get("data").asText(), realNameVerifyConfig.getClientPrivateKey());
JsonNode jsonData = objectMapper.readTree(data);
if (jsonData.has("result") && "1".equals(jsonData.get("result").asText())) {
// 4. 更新用户实名信息
updateRealNameInfo(userValidateDto, true);
return JsonResult.success("验证用户实名成功");
}
}
updateRealNameInfo(userValidateDto, false);
log.error("验证用户实名失败,{} {}", result.getString("code"), result.getString("message"));
return JsonResult.failed(result.getString("code") + ", " + result.getString("message"));
String errorCode = result.has("code") ? result.get("code").asText() : "未知错误";
String errorMessage = result.has("message") ? result.get("message").asText() : "验证失败";
log.error("验证用户实名失败,{} {}", errorCode, errorMessage);
return JsonResult.failed(errorCode + ", " + errorMessage);
} catch (EncryptFailureException e) {
log.error("加密失败", e);
return JsonResult.failed("加密失败");
@ -188,6 +195,9 @@ public class VerifyUtil {
} catch (DecryptFailureException e) {
log.error("结果解密失败", e);
return JsonResult.failed("结果解密失败");
} catch (JsonProcessingException e) {
log.error("JSON解析失败", e);
return JsonResult.failed("数据解析失败");
}
}
@ -226,7 +236,7 @@ public class VerifyUtil {
* @param params 请求参数
* @return 响应结果
*/
private JSONObject httpGet(String func_, String url, Map<String, String> params) {
private JsonNode httpGet(String func_, String url, Map<String, String> params) {
StringJoiner paramJoiner = new StringJoiner("&");
for (Map.Entry<String, String> entry : params.entrySet()) {
paramJoiner.add(entry.getKey() + "=" + entry.getValue());
@ -239,7 +249,8 @@ public class VerifyUtil {
try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful()) {
if (response.body() != null) {
return JSON.parseObject(response.body().string());
String responseBody = response.body().string();
return objectMapper.readTree(responseBody);
}
log.error("{}, 请求{}无返回结果", func_, url);
return null;
@ -264,7 +275,7 @@ public class VerifyUtil {
* @param params 请求参数
* @return 响应结果
*/
private JSONObject httpPost(String func_, String url, Map<String, String> params, Map<String, Object> body) {
private JsonNode httpPost(String func_, String url, Map<String, String> params, Map<String, Object> body) {
StringJoiner paramJoiner = new StringJoiner("&");
for (Map.Entry<String, String> entry : params.entrySet()) {
paramJoiner.add(entry.getKey() + "=" + entry.getValue());
@ -276,8 +287,14 @@ public class VerifyUtil {
.url(requestUrl);
if (body != null) {
MediaType typeJson = MediaType.parse("application/json; charset=utf-8");
RequestBody requestBody = RequestBody.create(JSON.toJSONString(body), typeJson);
builder.post(requestBody);
try {
String jsonBody = objectMapper.writeValueAsString(body);
RequestBody requestBody = RequestBody.create(jsonBody, typeJson);
builder.post(requestBody);
} catch (JsonProcessingException e) {
log.error("{}, 请求体序列化失败", func_, e);
return null;
}
} else {
builder.post(RequestBody.create(null, new byte[0]));
}
@ -285,7 +302,8 @@ public class VerifyUtil {
try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful()) {
if (response.body() != null) {
return JSON.parseObject(response.body().string());
String responseBody = response.body().string();
return objectMapper.readTree(responseBody);
}
log.error("{}, 请求{}无返回结果", func_, url);
return null;
@ -317,4 +335,4 @@ public class VerifyUtil {
public String decryptRealName(String name) throws DecryptFailureException {
return securityContext.decrypt(name, PRIVATE_KEY);
}
}
}

View File

@ -218,7 +218,7 @@ COMMENT ON TABLE "public"."ebike_order" IS '用户订单表';
DROP TABLE IF EXISTS "public"."ebike_order_detail";
CREATE TABLE "public"."ebike_order_detail" (
"detail_id" int8 NOT NULL DEFAULT nextval('ebike_order_detail_detail_id_seq'::regclass),
"order_id" varchar(64) COLLATE "pg_catalog"."default" NOT NULL,
"order_id" int8 NOT NULL,
"operator_id" int8 NOT NULL,
"detail_type" int2 NOT NULL,
"detail_name" varchar(50) COLLATE "pg_catalog"."default",
@ -253,7 +253,7 @@ DROP TABLE IF EXISTS "public"."ebike_payment";
CREATE TABLE "public"."ebike_payment" (
"payment_id" int8 NOT NULL DEFAULT nextval('ebike_payment_payment_id_seq'::regclass),
"user_id" int8 NOT NULL,
"order_id" varchar(64) COLLATE "pg_catalog"."default" NOT NULL,
"order_id" int8 NOT NULL,
"operator_id" int8 NOT NULL,
"trade_id" varchar(64) COLLATE "pg_catalog"."default" NOT NULL,
"transaction_id" varchar(64) COLLATE "pg_catalog"."default",
@ -295,7 +295,7 @@ DROP TABLE IF EXISTS "public"."ebike_refund";
CREATE TABLE "public"."ebike_refund" (
"refund_id" int8 NOT NULL DEFAULT nextval('ebike_refund_refund_id_seq'::regclass),
"refund_order_id" varchar(64) COLLATE "pg_catalog"."default",
"order_id" varchar(64) COLLATE "pg_catalog"."default",
"order_id" int8 NOT NULL,
"operator_id" int8 NOT NULL,
"transaction_id" varchar(64) COLLATE "pg_catalog"."default",
"refund_time" timestamp(6),

View File

@ -39,7 +39,6 @@
<HikariCP.version>5.0.1</HikariCP.version>
<okhttp.version>4.12.0</okhttp.version>
<minio.version>8.5.7</minio.version>
<fastjson.version>2.0.50</fastjson.version>
</properties>
<dependencyManagement>
<dependencies>