Merge remote-tracking branch 'origin/main'

This commit is contained in:
attiya 2025-05-19 15:33:25 +08:00
commit 2494cdad98
9 changed files with 159 additions and 52 deletions

View File

@ -21,6 +21,10 @@ public class PayDetailDto implements Serializable {
* 费用项目ID * 费用项目ID
*/ */
private String itemId; private String itemId;
/**
* 费用类型 1-骑行时长费 2-运营区调度费用 3-停车区调度费用 4-高峰时段出行费用 5-高峰日出行费用 6-起步费用
*/
private Integer itemType;
/** /**
* 费用名称 * 费用名称
*/ */

View File

@ -397,6 +397,7 @@ public class UserOrdersServiceImpl extends ServiceImpl<UserOrdersMapper, EbikeUs
detailDto.setCostPrice(orderDetailsInfo.getTotalAmount().doubleValue()); detailDto.setCostPrice(orderDetailsInfo.getTotalAmount().doubleValue());
detailDto.setGoodsDetail(orderDetailsInfo.getDetails().stream().map(orderDetail -> { detailDto.setGoodsDetail(orderDetailsInfo.getDetails().stream().map(orderDetail -> {
PayDetailDto payDetailDto = new PayDetailDto(); PayDetailDto payDetailDto = new PayDetailDto();
payDetailDto.setItemType(orderDetail.getItemType());
payDetailDto.setItemName(orderDetail.getItemName()); payDetailDto.setItemName(orderDetail.getItemName());
payDetailDto.setItemId(String.valueOf(orderDetail.getItemId())); payDetailDto.setItemId(String.valueOf(orderDetail.getItemId()));
payDetailDto.setQuantity(1); payDetailDto.setQuantity(1);

View File

@ -84,20 +84,25 @@ public class EbikeWxPaymentController {
*/ */
@PostMapping("/refund") @PostMapping("/refund")
public JsonResult<?> refund(@RequestBody ReqRefundDto refundDto) { public JsonResult<?> refund(@RequestBody ReqRefundDto refundDto) {
boolean r = wxPayService.refund(refundDto); HandleNotifyResult r = wxPayService.refund(refundDto);
return r?JsonResult.failed("退款失败"):JsonResult.success(r); if (r.isSuccess())
return JsonResult.success();
JSONObject error = JSONObject.parseObject(r.getMessage());
if (error==null)
return JsonResult.failed(r.getMessage());
return JsonResult.failed("退款失败", error);
} }
/** /**
* 审核退款申请 * 审核退款申请
* *
* @param processDto 退款处理信息 * @param processDto 退款处理信息
* @return 退款成功返回true否则返回false * @return 审核成功返回true否则返回false
*/ */
@PostMapping("/reviewRefund") @PostMapping("/reviewRefund")
public JsonResult<?> rejectRefund(@RequestBody ReqRefundProcessDto processDto) { public JsonResult<?> reviewRefund(@RequestBody ReqRefundProcessDto processDto) {
boolean r = wxPayService.refundReview(processDto); boolean r = wxPayService.refundReview(processDto);
return r?JsonResult.failed("退款失败"):JsonResult.success(r); return r?JsonResult.success(true):JsonResult.failed("审核失败");
} }
/** /**
@ -124,5 +129,15 @@ public class EbikeWxPaymentController {
return JsonResult.success(list); return JsonResult.success(list);
} }
/**
* 退款订单详情
*
* @param refundId 退款id
* @return 退款详情
*/
@GetMapping("/refundOrderDetail/{refundId}")
public JsonResult<?> refundOrderDetail(@PathVariable(name = "refundId") String refundId) {
ResOrderInfoDto r = wxPayService.queryRefundOrderById(refundId);
return r == null?JsonResult.failed(String.format("退款单号{%s}查询订单详情失败", refundId)):JsonResult.success(r);
}
} }

View File

@ -16,70 +16,75 @@ import java.time.LocalDateTime;
@Data @Data
public class ResOrderInfoDto { public class ResOrderInfoDto {
/**
* 订单id
*/
private String orderId;
/** /**
* 订单金额 * 订单金额
*/ */
private BigDecimal totalAmount; private Double totalAmount = 0.0;
/** /**
* 起步费用 * 起步费用
*/ */
private BigDecimal startupCost; private Double startupCost = 0.0;
/** /**
* 时长费 * 时长费
*/ */
private BigDecimal durationCost; private Double durationCost = 0.0;
/** /**
* 调度费 * 调度费
*/ */
private BigDecimal dispatchFee; private Double dispatchFee = 0.0;
/** /**
* 运营区外掉付费 * 运营区外掉付费
*/ */
private BigDecimal dispatchFeeOutOperateArea; private Double dispatchFeeOutOperateArea = 0.0;
/** /**
* 禁停区调度费 * 禁停区调度费
*/ */
private BigDecimal dispatchFeeBanArea; private Double dispatchFeeBanArea = 0.0;
/** /**
* 停车区外调度费 * 停车区外调度费
*/ */
private BigDecimal parkingAreaOutDispatchFee; private Double parkingAreaOutDispatchFee = 0.0;
/** /**
* 头盔管理费 * 头盔管理费
*/ */
private BigDecimal helmetManagementFee; private Double helmetManagementFee = 0.0;
/** /**
* 不规范停车费 * 不规范停车费
*/ */
private BigDecimal improperParkFee; private Double improperParkFee = 0.0;
/** /**
* 实付金额 * 实付金额
*/ */
private BigDecimal actualAmount; private Double actualAmount = 0.0;
/** /**
* 优惠金额 * 优惠金额
*/ */
private BigDecimal discountAmount; private Double discountAmount = 0.0;
/** /**
* 优惠卷抵扣金额 * 优惠卷抵扣金额
*/ */
private BigDecimal couponAmount; private Double couponAmount = 0.0;
/** /**
* 骑行卡抵扣金额 * 骑行卡抵扣金额
*/ */
private BigDecimal cyclingCardAmount; private Double cyclingCardAmount = 0.0;
/** /**
* 支付方式 * 支付方式
@ -87,9 +92,14 @@ public class ResOrderInfoDto {
private String payMethod; private String payMethod;
/** /**
* 用户手机与姓名 * 用户姓名
*/ */
private String phoneAndUser; private String user;
/**
* 用户手机
*/
private String phone;
/** /**
* 申请原因 * 申请原因
@ -99,6 +109,6 @@ public class ResOrderInfoDto {
/** /**
* 申请退款金额 * 申请退款金额
*/ */
private BigDecimal applyRefundAmount; private Double applyRefundAmount = 0.0;
} }

View File

@ -80,9 +80,9 @@ public class EbikePayment implements Serializable {
*/ */
private Double costPrice; private Double costPrice;
/** /**
* 货币 * 货币 默认人民币CNY
*/ */
private String currency; private String currency = "CNY";
/** /**
* 实际支付金额 * 实际支付金额

View File

@ -79,4 +79,11 @@ public interface EbikeRefundService extends IService<EbikeRefund> {
*/ */
Page<ResCloseRefundDto> getClosedList(ReqRefundQueryDto refundDto); Page<ResCloseRefundDto> getClosedList(ReqRefundQueryDto refundDto);
/**
* 退款订单详情
*
* @param refundId 退款id
* @return 退款详情
*/
ResOrderInfoDto getRefundOrderDetail(String refundId);
} }

View File

@ -2,10 +2,7 @@ package com.cdzy.payment.service;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.cdzy.payment.model.dto.HandleNotifyResult; import com.cdzy.payment.model.dto.*;
import com.cdzy.payment.model.dto.ReqRefundDto;
import com.cdzy.payment.model.dto.ReqRefundProcessDto;
import com.cdzy.payment.model.dto.ReqRefundQueryDto;
import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.paginate.Page;
import com.wechat.pay.java.service.payments.model.Transaction; import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.refund.model.Refund; import com.wechat.pay.java.service.refund.model.Refund;
@ -94,7 +91,7 @@ public interface WxPayService {
* @param refundDto 退款请求 * @param refundDto 退款请求
* @return 退款信息id * @return 退款信息id
*/ */
Boolean refund(ReqRefundDto refundDto); HandleNotifyResult refund(ReqRefundDto refundDto);
/** /**
@ -128,4 +125,12 @@ public interface WxPayService {
* @return 退款列表 * @return 退款列表
*/ */
Page<?> queryRefundList(ReqRefundQueryDto refundDto); Page<?> queryRefundList(ReqRefundQueryDto refundDto);
/**
* 退款订单详情
*
* @param refundId 退款id
* @return 退款详情
*/
ResOrderInfoDto queryRefundOrderById(String refundId);
} }

View File

@ -209,4 +209,22 @@ public class EbikeRefundServiceImpl extends ServiceImpl<EbikeRefundMapper, Ebike
Page<ResCloseRefundDto> page = refundDto.getPageParam().getPage(); Page<ResCloseRefundDto> page = refundDto.getPageParam().getPage();
return pageAs(page, query, ResCloseRefundDto.class); return pageAs(page, query, ResCloseRefundDto.class);
} }
@Override
public ResOrderInfoDto getRefundOrderDetail(String refundId) {
QueryWrapper query = QueryWrapper.create()
.select(EBIKE_REFUND.REFUND_APPLY.as("apply_refund_amount"), EBIKE_REFUND.REASON.as("apply_reason"),
EBIKE_REFUND.ORDER_ID.as("order_id"),
QueryMethods.case_(EBIKE_PAYMENT.PAYMENT_METHOD)
.when(PayMethod.wechat.name()).then("微信支付")
.when(PayMethod.alipay.name()).then("支付宝")
.when(PayMethod.balance.name()).then("余额").end().as("pay_method"),
EBIKE_PAYMENT.TOTAL.as("actual_amount"),EBIKE_PAYMENT.COST_PRICE.as("total_amount"),
EBIKE_USER.NICKNAME.as("user"), EBIKE_USER.MOBILE.as("phone")
)
.leftJoin(EBIKE_PAYMENT).on(EBIKE_PAYMENT.ORDER_ID.eq(EBIKE_REFUND.ORDER_ID))
.leftJoin(EBIKE_USER).on(EBIKE_USER.USER_ID.eq(EBIKE_PAYMENT.USER_ID))
.where(EBIKE_REFUND.REFUND_ID.eq(refundId));
return getOneAs(query, ResOrderInfoDto.class);
}
} }

View File

@ -19,6 +19,7 @@ import com.ebike.feign.clients.OrdersFeignClient;
import com.ebike.feign.model.rsp.AmountDto; import com.ebike.feign.model.rsp.AmountDto;
import com.ebike.feign.model.rsp.DetailDto; import com.ebike.feign.model.rsp.DetailDto;
import com.ebike.feign.model.rsp.EbikePaymentDto; import com.ebike.feign.model.rsp.EbikePaymentDto;
import com.ebike.feign.model.rsp.PayDetailDto;
import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.paginate.Page;
import com.wechat.pay.java.core.Config; import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.cipher.Signer; import com.wechat.pay.java.core.cipher.Signer;
@ -219,6 +220,7 @@ public class WxPayServiceImpl implements WxPayService {
ebikePayment.setPaymentMethod(PayMethod.wechat.name()); ebikePayment.setPaymentMethod(PayMethod.wechat.name());
ebikePayment.setCostPrice(amount.getTotal()); ebikePayment.setCostPrice(amount.getTotal());
ebikePayment.setTradeState(String.valueOf(Transaction.TradeStateEnum.NOTPAY.ordinal())); ebikePayment.setTradeState(String.valueOf(Transaction.TradeStateEnum.NOTPAY.ordinal()));
ebikePayment.setCurrency(paymentDto.getAmount().getCurrency());
ebikePaymentService.save(ebikePayment); ebikePaymentService.save(ebikePayment);
} else { } else {
ebikePayment.setPaymentId(payId); ebikePayment.setPaymentId(payId);
@ -382,7 +384,7 @@ public class WxPayServiceImpl implements WxPayService {
ebikeRefund.setProcessState(processDto.getOperate()); ebikeRefund.setProcessState(processDto.getOperate());
ebikeRefund.setProcessTime(LocalDateTime.now()); ebikeRefund.setProcessTime(LocalDateTime.now());
ebikeRefund.setRemark(processDto.getReason()); ebikeRefund.setRemark(processDto.getReason());
if (String.valueOf(RefundProcessState.processing).equals(processDto.getOperate())) { if (String.valueOf(RefundProcessState.processing.ordinal()).equals(processDto.getOperate())) {
ebikeRefund.setRefund(ebikeRefund.getRefundApply()); ebikeRefund.setRefund(ebikeRefund.getRefundApply());
ebikeRefund.setRefundMethod(processDto.getMethod()); ebikeRefund.setRefundMethod(processDto.getMethod());
} }
@ -390,7 +392,9 @@ public class WxPayServiceImpl implements WxPayService {
} }
@Override @Override
public Boolean refund(ReqRefundDto refundDto) { public HandleNotifyResult refund(ReqRefundDto refundDto) {
HandleNotifyResult result_ = new HandleNotifyResult();
result_.setSuccess(false);
// 首先验证密码 // 首先验证密码
//if (!wxPayConfig.getRefundPassword().equals(refundDto.getPassword())) { //if (!wxPayConfig.getRefundPassword().equals(refundDto.getPassword())) {
// //
@ -399,7 +403,8 @@ public class WxPayServiceImpl implements WxPayService {
EbikeRefund ebikeRefund = ebikeRefundService.getById(refundDto.getRefundId()); EbikeRefund ebikeRefund = ebikeRefundService.getById(refundDto.getRefundId());
if (ebikeRefund == null) { if (ebikeRefund == null) {
log.error("退款refund失败{} 退款申请不存在", refundDto.getRefundId()); log.error("退款refund失败{} 退款申请不存在", refundDto.getRefundId());
return false; result_.setMessage(String.format("{%s}退款申请不存在", refundDto.getRefundId()));
return result_;
} }
// 查询支付记录 // 查询支付记录
String outTradeNo = ebikeRefund.getOrderId(); String outTradeNo = ebikeRefund.getOrderId();
@ -408,7 +413,7 @@ public class WxPayServiceImpl implements WxPayService {
AmountRefundDto amount = new AmountRefundDto(); AmountRefundDto amount = new AmountRefundDto();
amount.setTotal(ebikePayment.getCostPrice()); amount.setTotal(ebikePayment.getCostPrice());
amount.setRefund(ebikePayment.getTotal()); amount.setRefund(ebikePayment.getTotal());
amount.setCurrency(ebikePayment.getCurrency()); amount.setCurrency(ebikeRefund.getCurrency());
// 发起退款 // 发起退款
CreateRequest request = new CreateRequest(); CreateRequest request = new CreateRequest();
request.setTransactionId(transactionId); request.setTransactionId(transactionId);
@ -421,25 +426,34 @@ public class WxPayServiceImpl implements WxPayService {
amountReq.setTotal(BigDecimal.valueOf(amount.getTotal() * 100.0).longValue()); amountReq.setTotal(BigDecimal.valueOf(amount.getTotal() * 100.0).longValue());
amountReq.setCurrency(amount.getCurrency()); amountReq.setCurrency(amount.getCurrency());
request.setAmount(amountReq); request.setAmount(amountReq);
Refund result = wxRefundService.create(request); try {
// 更新退款信息 Refund result = wxRefundService.create(request);
if (result != null) { // 更新退款信息
ebikeRefund.setOrderId(outTradeNo); if (result != null) {
ebikeRefund.setTransactionId(transactionId); ebikeRefund.setOrderId(outTradeNo);
ebikeRefund.setTotal(amount.getTotal()); ebikeRefund.setTransactionId(transactionId);
ebikeRefund.setStatus(String.valueOf(result.getStatus().ordinal())); ebikeRefund.setTotal(amount.getTotal());
ebikeRefund.setCurrency(amount.getCurrency()); ebikeRefund.setStatus(String.valueOf(result.getStatus().ordinal()));
if (Status.SUCCESS.equals(result.getStatus())) { ebikeRefund.setCurrency(amount.getCurrency());
ebikeRefund.setRefund(result.getAmount().getRefund().doubleValue() / 100.0); if (Status.SUCCESS.equals(result.getStatus())) {
ebikeRefund.setRefundTime(LocalDateTime.now()); ebikeRefund.setRefund(result.getAmount().getRefund().doubleValue() / 100.0);
ebikeRefund.setRemark(refundDto.getRemark()); ebikeRefund.setRefundTime(LocalDateTime.now());
ebikeRefund.setRefundTransactionId(result.getRefundId()); ebikeRefund.setRemark(refundDto.getRemark());
ebikeRefund.setRefundTransactionId(result.getRefundId());
}
ebikeRefundService.updateById(ebikeRefund);
result_.setSuccess(true);
result_.setMessage("退款成功");
return result_;
} }
ebikeRefundService.updateById(ebikeRefund); log.error("退款refund失败订单号{}", outTradeNo);
return Status.SUCCESS.equals(result.getStatus()); result_.setMessage("退款失败");
return result_;
} catch (Exception e) {
String err = logError("退款refund", e);
result_.setMessage(err);
return result_;
} }
log.error("退款refund失败订单号{}", outTradeNo);
return false;
} }
@Override @Override
@ -523,24 +537,57 @@ public class WxPayServiceImpl implements WxPayService {
}; };
} }
@Override
public ResOrderInfoDto queryRefundOrderById(String refundId) {
ResOrderInfoDto orderDto = ebikeRefundService.getRefundOrderDetail(refundId);
if (orderDto==null){
log.error("{}退款订单不存在", refundId);
return null;
}
//查询订单, orderFeingClient.getOrderById(orderId)
JsonResult<?> result = ordersFeignClient.getPaymentDetails(Long.valueOf(orderDto.getOrderId()));
if (result.getCode() != 200) {
log.error("查询订单 {} 失败, {}", orderDto.getOrderId(), result.getMessage());
return null;
}
EbikePaymentDto paymentDto = JSON.parseObject(JSONObject.toJSONString(result.getData()), EbikePaymentDto.class);
for (PayDetailDto detailDto : paymentDto.getDetail().getGoodsDetail()) {
//1-骑行时长费 2-运营区调度费用 3-停车区调度费用 4-高峰时段出行费用 5-高峰日出行费用 6-起步费用
switch (detailDto.getItemType()) {
case 1, 4, 5 -> orderDto.setDurationCost(orderDto.getDurationCost()+detailDto.getUnitPrice());
case 2 -> orderDto.setDispatchFeeOutOperateArea(orderDto.getParkingAreaOutDispatchFee() + detailDto.getUnitPrice());
case 3 -> orderDto.setParkingAreaOutDispatchFee(orderDto.getParkingAreaOutDispatchFee() + detailDto.getUnitPrice());
case 6 -> orderDto.setStartupCost(orderDto.getStartupCost() + detailDto.getUnitPrice());
}
}
orderDto.setDispatchFee(orderDto.getDispatchFee() + orderDto.getParkingAreaOutDispatchFee()+orderDto.getDispatchFeeOutOperateArea()+orderDto.getDispatchFeeBanArea());
orderDto.setOrderId(null);
return orderDto;
}
/** /**
* 打印日志 * 打印日志
* *
* @param desc 描述 * @param desc 描述
* @param e 异常 * @param e 异常
*/ */
private void logError(String desc, Exception e) { private String logError(String desc, Exception e) {
String msg = e.getMessage();
if (e instanceof HttpException httpException) { if (e instanceof HttpException httpException) {
log.error("{} 发送HTTP请求失败, {}", desc, httpException.getHttpRequest()); log.error("{} 发送HTTP请求失败, {}", desc, httpException.getHttpRequest());
} else if (e instanceof ServiceException serviceException) { } else if (e instanceof ServiceException serviceException) {
log.error("{} 服务返回状态不正常, {}", desc, serviceException.getResponseBody()); log.error("{} 服务返回状态不正常, {}", desc, serviceException.getResponseBody());
msg = serviceException.getResponseBody();
} else if (e instanceof MalformedMessageException malformedMessageException) { } else if (e instanceof MalformedMessageException malformedMessageException) {
log.error("{} 返回体类型不合法或者解析返回体失败, {}", desc, malformedMessageException.getMessage()); log.error("{} 返回体类型不合法或者解析返回体失败, {}", desc, malformedMessageException.getMessage());
msg = malformedMessageException.getMessage();
} else if (e instanceof ValidationException validationException) { } else if (e instanceof ValidationException validationException) {
log.error("{} 验签失败,验证签名失败,{}", desc, validationException.getMessage()); log.error("{} 验签失败,验证签名失败,{}", desc, validationException.getMessage());
msg = validationException.getMessage();
} else { } else {
log.error("{} 执行异常, {}", desc, e.getMessage()); log.error("{} 执行异常, {}", desc, e.getMessage());
} }
return msg;
} }
} }