小程序接口开发:缴费逻辑修改
This commit is contained in:
parent
c4b778a452
commit
901b4a16eb
|
|
@ -0,0 +1,57 @@
|
||||||
|
package com.ruoyi.business.util.aspect;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.DesensitizedUtil;
|
||||||
|
import cn.hutool.core.util.ReflectUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
|
import org.aspectj.lang.annotation.Around;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class responseAspect {
|
||||||
|
|
||||||
|
@Around("execution(* com.ruoyi.database.controller.SmallProgramController.*(..))")
|
||||||
|
public TableDataInfo<Object> around(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||||
|
Object proceed = joinPoint.proceed();
|
||||||
|
TableDataInfo<Object> tableDataInfo = (TableDataInfo<Object>) proceed;
|
||||||
|
List list = (List) tableDataInfo.getRows();
|
||||||
|
|
||||||
|
for (Object o : list) {
|
||||||
|
// 获取list表中类的类型
|
||||||
|
Class<?> aClass = o.getClass();
|
||||||
|
|
||||||
|
// 遍历实体类的字段
|
||||||
|
for (Field field : aClass.getDeclaredFields()) {
|
||||||
|
String fieldName = field.getName();
|
||||||
|
// 判断字段是否为电话号码或身份证号码,并对其进行脱敏
|
||||||
|
if (StrUtil.containsIgnoreCase(fieldName, "idcard")) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
String value = String.valueOf(field.get(o));
|
||||||
|
try {
|
||||||
|
ReflectUtil.setFieldValue(o, fieldName, DesensitizedUtil.idCardNum(value, 4, 4));
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StrUtil.containsIgnoreCase(fieldName, "phone")) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
String value = String.valueOf(field.get(o));
|
||||||
|
try {
|
||||||
|
ReflectUtil.setFieldValue(o, fieldName, DesensitizedUtil.mobilePhone(value));
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tableDataInfo.setRows(list);
|
||||||
|
return tableDataInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,7 +4,7 @@ import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public class AlipayConfig {
|
public class AlipayRYConfig {
|
||||||
|
|
||||||
@Value("${alipay.appId}")
|
@Value("${alipay.appId}")
|
||||||
public String appId;
|
public String appId;
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package com.ruoyi.database.controller;
|
package com.ruoyi.database.controller;
|
||||||
|
|
||||||
import com.alipay.api.internal.util.AlipaySignature;
|
import com.alipay.api.internal.util.AlipaySignature;
|
||||||
import com.ruoyi.config.AlipayConfig;
|
import com.ruoyi.config.AlipayRYConfig;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
@ -12,11 +12,11 @@ import java.util.Map;
|
||||||
@RequestMapping("/alipay")
|
@RequestMapping("/alipay")
|
||||||
public class AlipayNotifyController {
|
public class AlipayNotifyController {
|
||||||
|
|
||||||
private final AlipayConfig alipayConfig;
|
private final AlipayRYConfig alipayConfig;
|
||||||
// 假设你有一个处理订单业务的服务
|
// 假设你有一个处理订单业务的服务
|
||||||
// private final OrderService orderService;
|
// private final OrderService orderService;
|
||||||
|
|
||||||
public AlipayNotifyController(AlipayConfig alipayConfig) {
|
public AlipayNotifyController(AlipayRYConfig alipayConfig) {
|
||||||
this.alipayConfig = alipayConfig;
|
this.alipayConfig = alipayConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.ruoyi.database.controller;
|
package com.ruoyi.database.controller;
|
||||||
|
|
||||||
import com.ruoyi.database.domain.Order;
|
import com.ruoyi.database.domain.Order;
|
||||||
|
import com.ruoyi.database.domain.PayFees;
|
||||||
import com.ruoyi.database.service.OrderService;
|
import com.ruoyi.database.service.OrderService;
|
||||||
import com.ruoyi.database.service.WechatMiniProgramPayService;
|
import com.ruoyi.database.service.WechatMiniProgramPayService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
@ -23,76 +24,31 @@ public class PaymentController {
|
||||||
* 创建支付订单
|
* 创建支付订单
|
||||||
*/
|
*/
|
||||||
@PostMapping("/create")
|
@PostMapping("/create")
|
||||||
public Map<String, Object> createPayment(@RequestParam String openid,
|
public Map<String, Object> createPayment(@RequestBody PayFees payFees,
|
||||||
@RequestParam String orderId,
|
|
||||||
@RequestParam Integer amount,
|
|
||||||
@RequestParam String description,
|
|
||||||
HttpServletRequest request) {
|
HttpServletRequest request) {
|
||||||
try {
|
try {
|
||||||
System.out.println("收到创建支付订单请求: openid=" + openid +
|
|
||||||
", orderId=" + orderId + ", amount=" + amount);
|
|
||||||
|
|
||||||
// 1. 创建业务订单
|
// 1. 创建业务订单
|
||||||
orderService.createOrder(orderId, amount, description, openid);
|
orderService.createOrder(payFees);
|
||||||
|
|
||||||
// 2. 获取客户端IP
|
// 2. 获取客户端IP
|
||||||
String clientIp = wechatPayService.getClientIpAddress(request);
|
String clientIp = wechatPayService.getClientIpAddress(request);
|
||||||
|
|
||||||
// 3. 创建支付订单
|
// 3. 创建支付订单
|
||||||
Map<String, Object> result = wechatPayService.createJsapiOrder(
|
// Map<String, Object> result = wechatPayService.createJsapiOrder(
|
||||||
openid, orderId, amount, description, clientIp);
|
// openid, orderId, amount, description, clientIp);
|
||||||
|
|
||||||
|
// return result;
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.err.println("创建支付订单异常: " + e.getMessage());
|
// System.err.println("创建支付订单异常: " + e.getMessage());
|
||||||
e.printStackTrace();
|
// e.printStackTrace();
|
||||||
|
//
|
||||||
Map<String, Object> result = new HashMap<>();
|
// Map<String, Object> result = new HashMap<>();
|
||||||
result.put("success", false);
|
// result.put("success", false);
|
||||||
result.put("message", "系统异常: " + e.getMessage());
|
// result.put("message", "系统异常: " + e.getMessage());
|
||||||
return result;
|
// return result;
|
||||||
}
|
}
|
||||||
}
|
return null;
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询订单状态
|
|
||||||
*/
|
|
||||||
@GetMapping("/status/{orderId}")
|
|
||||||
public Map<String, Object> getOrderStatus(@PathVariable String orderId) {
|
|
||||||
try {
|
|
||||||
System.out.println("查询订单状态: " + orderId);
|
|
||||||
|
|
||||||
Order order = orderService.getOrder(orderId);
|
|
||||||
Map<String, Object> result = new HashMap<>();
|
|
||||||
|
|
||||||
if (order != null) {
|
|
||||||
result.put("success", true);
|
|
||||||
result.put("orderId", order.getOrderId());
|
|
||||||
result.put("status", order.getStatus().name());
|
|
||||||
result.put("amount", order.getAmount());
|
|
||||||
result.put("description", order.getDescription());
|
|
||||||
result.put("createTime", order.getCreateTime());
|
|
||||||
if (order.getPayTime() != null) {
|
|
||||||
result.put("payTime", order.getPayTime());
|
|
||||||
}
|
|
||||||
if (order.getTransactionId() != null) {
|
|
||||||
result.put("transactionId", order.getTransactionId());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result.put("success", false);
|
|
||||||
result.put("message", "订单不存在");
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
System.err.println("查询订单状态异常: " + e.getMessage());
|
|
||||||
|
|
||||||
Map<String, Object> result = new HashMap<>();
|
|
||||||
result.put("success", false);
|
|
||||||
result.put("message", "查询失败: " + e.getMessage());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,8 @@ public class SmallProgramController extends BaseController {
|
||||||
private final HaiKangApiUtils haiKangApiUtils;
|
private final HaiKangApiUtils haiKangApiUtils;
|
||||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("/getOrder")
|
@GetMapping("/getOrder")
|
||||||
@ApiOperation("根据车牌号查询缴费订单")
|
@ApiOperation("根据车牌号查询缴费订单")
|
||||||
public AjaxResult getOrder(String plateNo) {
|
public AjaxResult getOrder(String plateNo) {
|
||||||
|
|
@ -153,4 +155,13 @@ public class SmallProgramController extends BaseController {
|
||||||
return AjaxResult.success(customerPlateNoInfo);
|
return AjaxResult.success(customerPlateNoInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("/payFees")
|
||||||
|
@ApiOperation("缴费")
|
||||||
|
public AjaxResult payFees(@RequestBody PayFees payFees,HttpServletRequest request){
|
||||||
|
LoginUserByPhone loginUserByPhone = tokenService.getLoginUserByPhone(request);
|
||||||
|
return AjaxResult.success();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,14 +12,12 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/wxpay")
|
@RequestMapping("/wxpay")
|
||||||
public class WxPayNotifyController {
|
public class WxPayNotifyController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private WechatMiniProgramPayService wechatPayService;
|
private WechatMiniProgramPayService wechatPayService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private OrderService orderService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信支付结果通知回调
|
* 微信支付结果通知回调
|
||||||
|
|
@ -46,20 +44,20 @@ public class WxPayNotifyController {
|
||||||
System.out.println("解析通知数据: orderId=" + orderId +
|
System.out.println("解析通知数据: orderId=" + orderId +
|
||||||
", transactionId=" + transactionId + ", totalFee=" + totalFee);
|
", transactionId=" + transactionId + ", totalFee=" + totalFee);
|
||||||
|
|
||||||
// 4. 幂等性处理:检查订单是否已处理
|
// // 4. 幂等性处理:检查订单是否已处理
|
||||||
if (orderService.isOrderPaid(orderId)) {
|
// if (orderService.isOrderPaid(orderId)) {
|
||||||
System.out.println("订单已处理,直接返回成功");
|
// System.out.println("订单已处理,直接返回成功");
|
||||||
return WxPayNotifyResponse.success("OK");
|
// return WxPayNotifyResponse.success("OK");
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// 5. 校验订单金额(重要!防止资金损失)
|
// // 5. 校验订单金额(重要!防止资金损失)
|
||||||
if (!orderService.verifyOrderAmount(orderId, totalFee)) {
|
// if (!orderService.verifyOrderAmount(orderId, totalFee)) {
|
||||||
System.out.println("订单金额校验失败");
|
// System.out.println("订单金额校验失败");
|
||||||
return WxPayNotifyResponse.fail("订单金额不一致");
|
// return WxPayNotifyResponse.fail("订单金额不一致");
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// 6. 处理业务逻辑(更新订单状态等)
|
// // 6. 处理业务逻辑(更新订单状态等)
|
||||||
orderService.updateOrderToPaid(orderId, transactionId);
|
// orderService.updateOrderToPaid(orderId, transactionId);
|
||||||
|
|
||||||
System.out.println("支付通知处理成功");
|
System.out.println("支付通知处理成功");
|
||||||
System.out.println("========== 支付通知处理完成 ==========");
|
System.out.println("========== 支付通知处理完成 ==========");
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ import javax.validation.constraints.NotBlank;
|
||||||
@Data
|
@Data
|
||||||
public class BindTheVehicle {
|
public class BindTheVehicle {
|
||||||
|
|
||||||
|
@ApiModelProperty("车牌号")
|
||||||
@NotBlank(message = "不能为空")
|
@NotBlank(message = "车牌号不能为空")
|
||||||
private String plateNo;
|
private String plateNo;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,8 @@ public class ParkingBillInfo {
|
||||||
@ApiModelProperty("入场时间戳(毫秒)")
|
@ApiModelProperty("入场时间戳(毫秒)")
|
||||||
@Excel(name = "入场时间戳(毫秒)")
|
@Excel(name = "入场时间戳(毫秒)")
|
||||||
private Long enterTime;
|
private Long enterTime;
|
||||||
|
@TableField(exist = false)
|
||||||
|
private String enterTimeCn;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 离场时间戳(毫秒)
|
* 离场时间戳(毫秒)
|
||||||
|
|
@ -85,6 +87,8 @@ public class ParkingBillInfo {
|
||||||
@ApiModelProperty("离场时间戳(毫秒)")
|
@ApiModelProperty("离场时间戳(毫秒)")
|
||||||
@Excel(name = "离场时间戳(毫秒)")
|
@Excel(name = "离场时间戳(毫秒)")
|
||||||
private Long costTime;
|
private Long costTime;
|
||||||
|
@TableField(exist = false)
|
||||||
|
private String costTimeCn;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 停车时长(分钟)
|
* 停车时长(分钟)
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -100,6 +101,8 @@ public class ParkingBillPaymentInfo {
|
||||||
@ApiModelProperty("支付状态")
|
@ApiModelProperty("支付状态")
|
||||||
@Excel(name = "支付状态")
|
@Excel(name = "支付状态")
|
||||||
private Integer payStatus;
|
private Integer payStatus;
|
||||||
|
@TableField(exist = false)
|
||||||
|
private String payStatusCn;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付订单号id
|
* 支付订单号id
|
||||||
|
|
@ -108,5 +111,14 @@ public class ParkingBillPaymentInfo {
|
||||||
@Excel(name = "支付订单号id")
|
@Excel(name = "支付订单号id")
|
||||||
private String transactionId;
|
private String transactionId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付时间
|
||||||
|
*/
|
||||||
|
@ApiModelProperty("支付时间")
|
||||||
|
@Excel(name = "支付时间")
|
||||||
|
private Long payTime;
|
||||||
|
@TableField(exist = false)
|
||||||
|
private String payTimeCn;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.ruoyi.database.domain;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class PayFees {
|
||||||
|
|
||||||
|
@ApiModelProperty("账单编号")
|
||||||
|
@NotBlank(message = "账单编号不能为空")
|
||||||
|
private String billCode;
|
||||||
|
|
||||||
|
@ApiModelProperty("支付方式: wechat 或 alipay")
|
||||||
|
@NotBlank(message = "支付方式不能为空")
|
||||||
|
private String payType;
|
||||||
|
|
||||||
|
@ApiModelProperty("微信或支付宝的授权code")
|
||||||
|
@NotBlank(message = "code不能为空")
|
||||||
|
private String code;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.ruoyi.database.enums;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public enum PayType {
|
||||||
|
WECHAT("wechat", "微信支付"),
|
||||||
|
ALIPAY("alipay", "支付宝支付");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
PayType(String code, String description) {
|
||||||
|
this.code = code;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据code获取枚举
|
||||||
|
*/
|
||||||
|
public static PayType getByCode(String code) {
|
||||||
|
for (PayType type : values()) {
|
||||||
|
if (type.getCode().equals(code)) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("不支持的支付方式: " + code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,19 +1,21 @@
|
||||||
package com.ruoyi.database.service;
|
package com.ruoyi.database.service;
|
||||||
|
|
||||||
import com.alipay.api.AlipayClient;
|
import com.alipay.api.AlipayClient;
|
||||||
|
import com.alipay.api.AlipayConfig;
|
||||||
import com.alipay.api.DefaultAlipayClient;
|
import com.alipay.api.DefaultAlipayClient;
|
||||||
|
import com.alipay.api.domain.AlipayTradeCreateModel;
|
||||||
import com.alipay.api.request.AlipayTradeCreateRequest;
|
import com.alipay.api.request.AlipayTradeCreateRequest;
|
||||||
import com.alipay.api.response.AlipayTradeCreateResponse;
|
import com.alipay.api.response.AlipayTradeCreateResponse;
|
||||||
import com.ruoyi.config.AlipayConfig;
|
import com.ruoyi.config.AlipayRYConfig;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class AlipayService {
|
public class AlipayService {
|
||||||
|
|
||||||
private final AlipayConfig alipayConfig;
|
private final AlipayRYConfig alipayRYConfig;
|
||||||
|
|
||||||
public AlipayService(AlipayConfig alipayConfig) {
|
public AlipayService(AlipayRYConfig alipayRYConfig) {
|
||||||
this.alipayConfig = alipayConfig;
|
this.alipayRYConfig = alipayRYConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -27,34 +29,27 @@ public class AlipayService {
|
||||||
*/
|
*/
|
||||||
public String createOrder(String orderId, String amount, String subject, String buyerId) {
|
public String createOrder(String orderId, String amount, String subject, String buyerId) {
|
||||||
try {
|
try {
|
||||||
// 1. 创建AlipayClient实例
|
AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
|
||||||
AlipayClient alipayClient = new DefaultAlipayClient(
|
// 构造请求参数以调用接口
|
||||||
alipayConfig.gateway,
|
|
||||||
alipayConfig.appId,
|
|
||||||
alipayConfig.privateKey,
|
|
||||||
"json",
|
|
||||||
"UTF-8",
|
|
||||||
alipayConfig.alipayPublicKey,
|
|
||||||
"RSA2"
|
|
||||||
);
|
|
||||||
|
|
||||||
// 2. 创建API请求对象,设置请求参数
|
|
||||||
AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
|
AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
|
||||||
request.setNotifyUrl(alipayConfig.notifyUrl);
|
AlipayTradeCreateModel model = new AlipayTradeCreateModel();
|
||||||
|
// 设置商户订单号
|
||||||
// 3. 组装业务参数
|
model.setOutTradeNo(orderId);
|
||||||
String bizContent = "{" +
|
// 设置产品码
|
||||||
"\"out_trade_no\":\"" + orderId + "\"," +
|
model.setProductCode("JSAPI_PAY");
|
||||||
"\"total_amount\":\"" + amount + "\"," +
|
// 设置小程序支付中
|
||||||
"\"subject\":\"" + subject + "\"," +
|
model.setOpAppId(alipayRYConfig.appId);
|
||||||
"\"buyer_id\":\"" + buyerId + "\"," +
|
// 设置订单总金额
|
||||||
"\"product_code\":\"JSAPI_PAY\"" + // 小程序场景固定值
|
model.setTotalAmount(amount);
|
||||||
"}";
|
// 设置订单标题
|
||||||
request.setBizContent(bizContent);
|
model.setSubject(subject);
|
||||||
|
// 设置订单附加信息
|
||||||
// 4. 调用支付宝接口
|
model.setBody(subject);
|
||||||
|
// 设置买家支付宝用户唯一标识
|
||||||
|
model.setBuyerOpenId(buyerId);
|
||||||
|
request.setBizModel(model);
|
||||||
AlipayTradeCreateResponse response = alipayClient.execute(request);
|
AlipayTradeCreateResponse response = alipayClient.execute(request);
|
||||||
|
System.out.println(response.getBody());
|
||||||
// 5. 处理响应
|
// 5. 处理响应
|
||||||
if (response.isSuccess()) {
|
if (response.isSuccess()) {
|
||||||
System.out.println("支付宝预下单成功,交易号: " + response.getTradeNo());
|
System.out.println("支付宝预下单成功,交易号: " + response.getTradeNo());
|
||||||
|
|
@ -69,5 +64,18 @@ public class AlipayService {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("调用支付宝接口异常", e);
|
throw new RuntimeException("调用支付宝接口异常", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private AlipayConfig getAlipayConfig() {
|
||||||
|
AlipayConfig alipayConfig = new AlipayConfig();
|
||||||
|
alipayConfig.setServerUrl(alipayRYConfig.gateway);
|
||||||
|
alipayConfig.setAppId(alipayRYConfig.appId);
|
||||||
|
alipayConfig.setPrivateKey(alipayRYConfig.privateKey);
|
||||||
|
alipayConfig.setFormat("json");
|
||||||
|
alipayConfig.setAlipayPublicKey(alipayRYConfig.alipayPublicKey);
|
||||||
|
alipayConfig.setCharset("UTF-8");
|
||||||
|
alipayConfig.setSignType("RSA2");
|
||||||
|
return alipayConfig;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,88 +1,50 @@
|
||||||
package com.ruoyi.database.service;
|
package com.ruoyi.database.service;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
import com.ruoyi.database.domain.Order;
|
import com.ruoyi.database.domain.Order;
|
||||||
|
import com.ruoyi.database.domain.ParkingBillInfo;
|
||||||
|
import com.ruoyi.database.domain.ParkingBillPaymentInfo;
|
||||||
|
import com.ruoyi.database.domain.PayFees;
|
||||||
import com.ruoyi.database.enums.OrderStatus;
|
import com.ruoyi.database.enums.OrderStatus;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class OrderService {
|
public class OrderService {
|
||||||
|
|
||||||
/**
|
private final ParkingBillPaymentInfoService parkingBillPaymentInfoService;
|
||||||
* 使用内存Map存储订单,生产环境请用数据库
|
private final ParkingBillInfoService parkingBillInfoService;
|
||||||
*/
|
|
||||||
private static final Map<String, Order> orderCache = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建订单
|
* 创建订单
|
||||||
*/
|
*/
|
||||||
public Order createOrder(String orderId, Integer amount, String description, String openid) {
|
public void createOrder(PayFees payFees) {
|
||||||
Order order = new Order();
|
ParkingBillInfo one = parkingBillInfoService.lambdaQuery()
|
||||||
order.setOrderId(orderId);
|
.eq(ParkingBillInfo::getBillCode, payFees.getBillCode())
|
||||||
order.setAmount(amount);
|
.last("limit 1")
|
||||||
order.setDescription(description);
|
.one();
|
||||||
order.setOpenid(openid);
|
if (one == null) {
|
||||||
order.setStatus(OrderStatus.PENDING);
|
throw new RuntimeException("未查询到订单");
|
||||||
order.setCreateTime(LocalDateTime.now());
|
}
|
||||||
|
System.out.println("收到创建支付订单请求: orderId=" + payFees.getBillCode() +
|
||||||
|
", amount=" + one.getTotalCostYuan());
|
||||||
|
// ParkingBillPaymentInfo parkingBillPaymentInfo = new ParkingBillPaymentInfo();
|
||||||
|
// parkingBillPaymentInfo.setBillCode(payFees.getBillCode());
|
||||||
|
// parkingBillPaymentInfo.setPlateNo(one.getPlateNo());
|
||||||
|
// parkingBillPaymentInfo.setPlateColor(one.getPlateColor());
|
||||||
|
// parkingBillPaymentInfo.setOpenId("");
|
||||||
|
// parkingBillPaymentInfo.setAlipayUserId("");
|
||||||
|
// parkingBillPaymentInfo.setPhone();
|
||||||
|
// parkingBillPaymentInfo.setPayStatus(0);
|
||||||
|
|
||||||
|
|
||||||
|
// orderCache.put(orderId, order);
|
||||||
|
|
||||||
orderCache.put(orderId, order);
|
|
||||||
|
|
||||||
System.out.println("创建订单成功: " + orderId + ", 金额: " + amount + "分");
|
|
||||||
return order;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查订单是否已支付(幂等性处理)
|
|
||||||
*/
|
|
||||||
public boolean isOrderPaid(String orderId) {
|
|
||||||
Order order = orderCache.get(orderId);
|
|
||||||
boolean isPaid = order != null && order.getStatus() == OrderStatus.PAID;
|
|
||||||
if (isPaid) {
|
|
||||||
System.out.println("订单已支付: " + orderId);
|
|
||||||
}
|
|
||||||
return isPaid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 验证订单金额
|
|
||||||
*/
|
|
||||||
public boolean verifyOrderAmount(String orderId, Integer totalFee) {
|
|
||||||
Order order = orderCache.get(orderId);
|
|
||||||
boolean isValid = order != null && order.getAmount().equals(totalFee);
|
|
||||||
if (!isValid) {
|
|
||||||
System.out.println("订单金额验证失败: " + orderId +
|
|
||||||
", 期望: " + (order != null ? order.getAmount() : "null") +
|
|
||||||
", 实际: " + totalFee);
|
|
||||||
}
|
|
||||||
return isValid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新订单状态为已支付
|
|
||||||
*/
|
|
||||||
public void updateOrderToPaid(String orderId, String transactionId) {
|
|
||||||
Order order = orderCache.get(orderId);
|
|
||||||
if (order != null) {
|
|
||||||
order.setStatus(OrderStatus.PAID);
|
|
||||||
order.setTransactionId(transactionId);
|
|
||||||
order.setPayTime(LocalDateTime.now());
|
|
||||||
orderCache.put(orderId, order);
|
|
||||||
|
|
||||||
System.out.println("更新订单状态为已支付: " + orderId +
|
|
||||||
", 微信订单号: " + transactionId);
|
|
||||||
|
|
||||||
// 这里可以添加其他业务逻辑,如发送消息、更新库存等
|
|
||||||
} else {
|
|
||||||
System.out.println("订单不存在: " + orderId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取订单信息
|
|
||||||
*/
|
|
||||||
public Order getOrder(String orderId) {
|
|
||||||
return orderCache.get(orderId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,15 @@ public class DictionaryInterceptor implements Interceptor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (StrUtil.equals(field.getName(), "enterTime") || StrUtil.equals(field.getName(), "costTime")) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
Long passTime = (Long) field.get(obj);
|
||||||
|
try {
|
||||||
|
ReflectUtil.setFieldValue(obj, field.getName() + "Cn", DateUtil.format(DateUtil.date(passTime), DatePattern.NORM_DATETIME_PATTERN));
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
package com.ruoyi.web.controller.aspect;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.DesensitizedUtil;
|
||||||
|
import cn.hutool.core.util.ReflectUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
|
import org.aspectj.lang.annotation.Around;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
public class responseAspect {
|
||||||
|
|
||||||
|
@Around("execution(* com.ruoyi.web.controller.system.SysLoginController.getCustomerInfo())")
|
||||||
|
public TableDataInfo<Object> around(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||||
|
Object proceed = joinPoint.proceed();
|
||||||
|
TableDataInfo<Object> tableDataInfo = (TableDataInfo<Object>) proceed;
|
||||||
|
List list = (List) tableDataInfo.getRows();
|
||||||
|
|
||||||
|
for (Object o : list) {
|
||||||
|
// 获取list表中类的类型
|
||||||
|
Class<?> aClass = o.getClass();
|
||||||
|
|
||||||
|
// 遍历实体类的字段
|
||||||
|
for (Field field : aClass.getDeclaredFields()) {
|
||||||
|
String fieldName = field.getName();
|
||||||
|
// 判断字段是否为电话号码或身份证号码,并对其进行脱敏
|
||||||
|
if (StrUtil.containsIgnoreCase(fieldName, "idcard")) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
String value = String.valueOf(field.get(o));
|
||||||
|
try {
|
||||||
|
ReflectUtil.setFieldValue(o, fieldName, DesensitizedUtil.idCardNum(value, 4, 4));
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StrUtil.containsIgnoreCase(fieldName, "phone")) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
String value = String.valueOf(field.get(o));
|
||||||
|
try {
|
||||||
|
ReflectUtil.setFieldValue(o, fieldName, DesensitizedUtil.mobilePhone(value));
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tableDataInfo.setRows(list);
|
||||||
|
return tableDataInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -139,14 +139,14 @@ wx:
|
||||||
mchId: 1251484401 # 你的商户号
|
mchId: 1251484401 # 你的商户号
|
||||||
mchKey: QloRc8RZcKpOVb4hKPFJKRG9stmqSfxD # 你的API密钥(32位)
|
mchKey: QloRc8RZcKpOVb4hKPFJKRG9stmqSfxD # 你的API密钥(32位)
|
||||||
keyPath: classpath:cert/apiclient_cert.p12 # 证书路径
|
keyPath: classpath:cert/apiclient_cert.p12 # 证书路径
|
||||||
notifyUrl: https://tingche.csckl.com/api/wxpay/notify
|
notifyUrl: https://tingche.csckl.com/wisdomPark/wxpay/notify
|
||||||
|
|
||||||
alipay:
|
alipay:
|
||||||
appId: 2021006113615353
|
appId: 2021006113615353
|
||||||
privateKey: MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCiRzdzmuqvz4ohvOacFyKJIKyfyI22HkNgCJV8gWYNn5oR1wFjyt+3/mf1RAYV0yA4YVmnJkiGxtNdTRFQoOJU21NTDutN8MdjY3KgGFAmAffX1uZrLWn37A5SS/Lo6Ym7PSvqUI/dqMl2RY2Bs8BEMABmD4vwonEvBfPjiX3QhQG0NupfsAX6k5eVAsp4OwfWwgA1IY2dLihzLhWT12hElvRKlf5cdoTP8gDiAMLxLy4UbhLiUj4wimrTl5/UruTo+WBwY3E/abxLIx6UvoU6BwJKh+oF2Po5TMRFWq6KDv+nQskDeB296rNGSa45UXxKy4qnDy6Wwut81Ma0Ja1dAgMBAAECggEAVUpS9brNcHwHILZVCmMKbsIymIRjHv4G8VlxoA+uoKhq5Md5XobJUL4wy3LmM+BURe28niJ76gJkItyXpiX47xqbT8M+nydW1ID3RPeiYGeWaOX1Ew26bWivGkf6srnT/womo6+V/a1xvWzO9AWSnwQPoZS4O1BVZp6dUdD4xHfdZDaChnD0avXRMZrBe9HQjhcev6A+nKJyTGFDbooHSi4bzixcaaE595D/Fp9hxvW7V6rpY9pfgYFr/KgRwEgX+LooHCigYXVEi4ckf/JfH0HKYm0nWrcajal5nlUPq5PG6QMqNDl5m6R6llUl/LhM6JjEeMhmqPCHYGZWG/nIbQKBgQDPpn9o4KGdl3a/Jl5ACQVsk5S146sJ3hRkcmamQsXY/Dmxi+DMyBM5PRRRDiWpx9icZ1AdjPlU/aB81waJdExS/EfBACrf3I2KMA9lfYm5J9cMtsrAyFCLFOgcnGUb1apLe6PGafxYhLm4y3OhMhP71i02ofF1WqxpKewBo0bZ9wKBgQDIEDMrz8IgFoPrraU1gMqnvd57KgNhsX3xpSTfgZq+TeQOua6zeJ/EHfk7nxlatdx6pB1kn7zCUJkpMqZmVhXS6ZvJ1DUdinJCDJn/zokmwsDYE8xPNk41cr4ZPy4WR0svhe2xTc3tL2UmfKbLg9SZk7HUYj/KCUfKC2Y8QLY+SwKBgQDHGubgMUPGUA1Ui/2jeQLycTAOmBbQh1kWV3uFwFDlFjRbwbvzn4SPRbnNXrtOaImSrp1rOFl63RadnbBu7Eyi5bQHo5l4vYoaDqs0rYL5PvI9Bqiy4WAZfBp0FKH+Zom7hvoqrkWAuwM55hshXVs8BsmjsPRNinv2+nOJvn2ZUQKBgQCPR8reHbUR9g4UxBAF+W8qIzkrTDOPy+Y/Id7+k3uXv4ENar5LmqARfMX6hT9LT+PPkanbXut43vBSKQwzToPiwZvpOCmyNm0OEKhaJDjloaUrG0K/mEz6ymqK+kyvd+/I4UoSKX7J15/BqJRsPMYOF1DMonC86ViYwwE9NbtPcQKBgQCM7pHhGZJMUz0KKffzCWjqY9NHZjs7JMAexWjboGuaaS2JkGFV8d/4nWBPiFRqK3whhtZ9MeE3Af6SusQAGQ9Guu45PxiAWa8VVeWYEVm+I4MNGN2C/PC4SqdWqluWiUGhg0zFpwzf/eHvFxdxrutUMADF0X6vL2ZxZcHmZdXoXg==
|
privateKey: MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCiRzdzmuqvz4ohvOacFyKJIKyfyI22HkNgCJV8gWYNn5oR1wFjyt+3/mf1RAYV0yA4YVmnJkiGxtNdTRFQoOJU21NTDutN8MdjY3KgGFAmAffX1uZrLWn37A5SS/Lo6Ym7PSvqUI/dqMl2RY2Bs8BEMABmD4vwonEvBfPjiX3QhQG0NupfsAX6k5eVAsp4OwfWwgA1IY2dLihzLhWT12hElvRKlf5cdoTP8gDiAMLxLy4UbhLiUj4wimrTl5/UruTo+WBwY3E/abxLIx6UvoU6BwJKh+oF2Po5TMRFWq6KDv+nQskDeB296rNGSa45UXxKy4qnDy6Wwut81Ma0Ja1dAgMBAAECggEAVUpS9brNcHwHILZVCmMKbsIymIRjHv4G8VlxoA+uoKhq5Md5XobJUL4wy3LmM+BURe28niJ76gJkItyXpiX47xqbT8M+nydW1ID3RPeiYGeWaOX1Ew26bWivGkf6srnT/womo6+V/a1xvWzO9AWSnwQPoZS4O1BVZp6dUdD4xHfdZDaChnD0avXRMZrBe9HQjhcev6A+nKJyTGFDbooHSi4bzixcaaE595D/Fp9hxvW7V6rpY9pfgYFr/KgRwEgX+LooHCigYXVEi4ckf/JfH0HKYm0nWrcajal5nlUPq5PG6QMqNDl5m6R6llUl/LhM6JjEeMhmqPCHYGZWG/nIbQKBgQDPpn9o4KGdl3a/Jl5ACQVsk5S146sJ3hRkcmamQsXY/Dmxi+DMyBM5PRRRDiWpx9icZ1AdjPlU/aB81waJdExS/EfBACrf3I2KMA9lfYm5J9cMtsrAyFCLFOgcnGUb1apLe6PGafxYhLm4y3OhMhP71i02ofF1WqxpKewBo0bZ9wKBgQDIEDMrz8IgFoPrraU1gMqnvd57KgNhsX3xpSTfgZq+TeQOua6zeJ/EHfk7nxlatdx6pB1kn7zCUJkpMqZmVhXS6ZvJ1DUdinJCDJn/zokmwsDYE8xPNk41cr4ZPy4WR0svhe2xTc3tL2UmfKbLg9SZk7HUYj/KCUfKC2Y8QLY+SwKBgQDHGubgMUPGUA1Ui/2jeQLycTAOmBbQh1kWV3uFwFDlFjRbwbvzn4SPRbnNXrtOaImSrp1rOFl63RadnbBu7Eyi5bQHo5l4vYoaDqs0rYL5PvI9Bqiy4WAZfBp0FKH+Zom7hvoqrkWAuwM55hshXVs8BsmjsPRNinv2+nOJvn2ZUQKBgQCPR8reHbUR9g4UxBAF+W8qIzkrTDOPy+Y/Id7+k3uXv4ENar5LmqARfMX6hT9LT+PPkanbXut43vBSKQwzToPiwZvpOCmyNm0OEKhaJDjloaUrG0K/mEz6ymqK+kyvd+/I4UoSKX7J15/BqJRsPMYOF1DMonC86ViYwwE9NbtPcQKBgQCM7pHhGZJMUz0KKffzCWjqY9NHZjs7JMAexWjboGuaaS2JkGFV8d/4nWBPiFRqK3whhtZ9MeE3Af6SusQAGQ9Guu45PxiAWa8VVeWYEVm+I4MNGN2C/PC4SqdWqluWiUGhg0zFpwzf/eHvFxdxrutUMADF0X6vL2ZxZcHmZdXoXg==
|
||||||
apppublicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAokc3c5rqr8+KIbzmnBciiSCsn8iNth5DYAiVfIFmDZ+aEdcBY8rft/5n9UQGFdMgOGFZpyZIhsbTXU0RUKDiVNtTUw7rTfDHY2NyoBhQJgH319bmay1p9+wOUkvy6OmJuz0r6lCP3ajJdkWNgbPARDAAZg+L8KJxLwXz44l90IUBtDbqX7AF+pOXlQLKeDsH1sIANSGNnS4ocy4Vk9doRJb0SpX+XHaEz/IA4gDC8S8uFG4S4lI+MIpq05ef1K7k6PlgcGNxP2m8SyMelL6FOgcCSofqBdj6OUzERVquig7/p0LJA3gdveqzRkmuOVF8SsuKpw8ulsLrfNTGtCWtXQIDAQAB
|
apppublicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAokc3c5rqr8+KIbzmnBciiSCsn8iNth5DYAiVfIFmDZ+aEdcBY8rft/5n9UQGFdMgOGFZpyZIhsbTXU0RUKDiVNtTUw7rTfDHY2NyoBhQJgH319bmay1p9+wOUkvy6OmJuz0r6lCP3ajJdkWNgbPARDAAZg+L8KJxLwXz44l90IUBtDbqX7AF+pOXlQLKeDsH1sIANSGNnS4ocy4Vk9doRJb0SpX+XHaEz/IA4gDC8S8uFG4S4lI+MIpq05ef1K7k6PlgcGNxP2m8SyMelL6FOgcCSofqBdj6OUzERVquig7/p0LJA3gdveqzRkmuOVF8SsuKpw8ulsLrfNTGtCWtXQIDAQAB
|
||||||
publicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhHGI9i9ewOf1lKHkLy8rQS2eLgYwheyzhrfi0fX1BDB7CWKoKu4kqDT52CYP6438K7NvANzh+aSaXvi1vZEAf2ociyjozKypj2qKynL6nW/sLyXWDbCU2u41WJv9iDvm8l/AF6qcanoKSSzZPUFsXHD+ZDsGj/3EyLF+FUN7vQw1Bj9BmYnushjTL/0KQWQNbrZeSHtEPYkhiVGKRD63ZETQPqcTU4vOncmNSb879Z40dAHxob2qUzh7743hk8PnTMkDpacfolMTeeRdDrdsLgmaLypyWtKXe8DASKXE92YnW5Yq8Vkb3aZiS+u903WWNfatOoOGIn0XyuA6T5OCbwIDAQAB
|
publicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhHGI9i9ewOf1lKHkLy8rQS2eLgYwheyzhrfi0fX1BDB7CWKoKu4kqDT52CYP6438K7NvANzh+aSaXvi1vZEAf2ociyjozKypj2qKynL6nW/sLyXWDbCU2u41WJv9iDvm8l/AF6qcanoKSSzZPUFsXHD+ZDsGj/3EyLF+FUN7vQw1Bj9BmYnushjTL/0KQWQNbrZeSHtEPYkhiVGKRD63ZETQPqcTU4vOncmNSb879Z40dAHxob2qUzh7743hk8PnTMkDpacfolMTeeRdDrdsLgmaLypyWtKXe8DASKXE92YnW5Yq8Vkb3aZiS+u903WWNfatOoOGIn0XyuA6T5OCbwIDAQAB
|
||||||
notifyUrl: https://tingche.csckl.com/alipay/notify
|
notifyUrl: https://tingche.csckl.com/wisdomPark/alipay/notify
|
||||||
gateway: https://openapi.alipay.com/gateway.do # 生产环境
|
gateway: https://openapi.alipay.com/gateway.do # 生产环境
|
||||||
|
|
||||||
wechat:
|
wechat:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue