用户退款

This commit is contained in:
yanglei 2025-11-19 17:37:01 +08:00
parent 33a85855d2
commit f0e0086171
25 changed files with 380 additions and 284 deletions

View File

@ -0,0 +1,20 @@
package com.ebike.feign.clients;
import com.cdzy.common.model.response.JsonResult;
import com.ebike.feign.component.FeignTokenInterceptor;
import com.ebike.feign.config.ExampleFeignConfiguration;
import com.ebike.feign.model.dto.FeignEbikeRefundDto;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
/**
* @author yanglei
* @since 2025-11-19 15:29
*/
@FeignClient(name = "ebike-payment", configuration = {ExampleFeignConfiguration.class, FeignTokenInterceptor.class})
public interface PaymentFeignClient {
@PostMapping("wxPayment/refund")
JsonResult<?> refund(@RequestBody FeignEbikeRefundDto refundDto);
}

View File

@ -5,9 +5,11 @@ import com.ebike.feign.component.FeignTokenInterceptor;
import com.ebike.feign.config.ExampleFeignConfiguration;
import com.ebike.feign.model.dto.FeignEbikeRefundProcessDto;
import com.ebike.feign.model.dto.FeignEbikeRefundQueryDto;
import com.ebike.feign.model.dto.FeignOrderPaymentDto;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
/**
* @author yanglei
@ -16,60 +18,51 @@ import org.springframework.web.bind.annotation.*;
@FeignClient(name = "ebike-user", configuration = {ExampleFeignConfiguration.class, FeignTokenInterceptor.class})
public interface UserFeignClient {
/**
* 订单支付完成
*
* @param paymentParam 支付信息
* @return @ {@code 200} 成功{@code 500} 失败
*/
@PostMapping("ebikeOrder/payment")
JsonResult<?> payment(@RequestBody FeignOrderPaymentDto paymentParam);
/**
* 订单发起退款申请
*
* @param orderId 订单ID
* @return @ {@code 200} 成功{@code 500} 失败
*/
@GetMapping("ebikeOrder/refundApply")
JsonResult<?> refundApply(@RequestParam("orderId") Long orderId);
/**
* 订单发起退款
*
* @param orderId 订单ID
* @return @ {@code 200} 成功{@code 500} 失败
*/
@GetMapping("ebikeOrder/refund")
JsonResult<?> refund(@RequestParam("orderId") Long orderId);
/**
* 订单退款完成
*
* @param orderId 订单ID
* @return @ {@code 200} 成功{@code 500} 失败
*/
@GetMapping("ebikeOrder/doneRefund")
JsonResult<?> doneRefund(@RequestParam("orderId") Long orderId);
/**
* 订单退款失败
*
* @param orderId 订单ID
* @return @ {@code 200} 成功{@code 500} 失败
*/
@GetMapping("ebikeOrder/failRefund")
JsonResult<?> failRefund(@RequestParam("orderId") Long orderId);
/**
* 订单退款驳回
*
* @param orderId 订单ID
* @return @ {@code 200} 成功{@code 500} 失败
*/
@GetMapping("ebikeOrder/rejectRefund")
JsonResult<?> rejectRefund(@RequestParam("orderId") Long orderId);
//
// /**
// * 订单发起退款申请
// *
// * @param orderId 订单ID
// * @return @ {@code 200} 成功{@code 500} 失败
// */
// @GetMapping("ebikeOrder/refundApply")
// JsonResult<?> refundApply(@RequestParam("orderId") Long orderId);
//
// /**
// * 订单发起退款
// *
// * @param orderId 订单ID
// * @return @ {@code 200} 成功{@code 500} 失败
// */
// @GetMapping("ebikeOrder/refund")
// JsonResult<?> refund(@RequestParam("orderId") Long orderId);
//
// /**
// * 订单退款完成
// *
// * @param orderId 订单ID
// * @return @ {@code 200} 成功{@code 500} 失败
// */
// @GetMapping("ebikeOrder/doneRefund")
// JsonResult<?> doneRefund(@RequestParam("orderId") Long orderId);
//
// /**
// * 订单退款失败
// *
// * @param orderId 订单ID
// * @return @ {@code 200} 成功{@code 500} 失败
// */
// @GetMapping("ebikeOrder/failRefund")
// JsonResult<?> failRefund(@RequestParam("orderId") Long orderId);
//
// /**
// * 订单退款驳回
// *
// * @param orderId 订单ID
// * @return @ {@code 200} 成功{@code 500} 失败
// */
// @GetMapping("ebikeOrder/rejectRefund")
// JsonResult<?> rejectRefund(@RequestParam("orderId") Long orderId);
/**
* 审核退款申请

View File

@ -0,0 +1,28 @@
package com.ebike.feign.model.dto;
import lombok.Data;
/**
* 退款请求参数
*
* @author yanglei
* @since 2025-10-17 14:37
*/
@Data
public class FeignEbikeRefundDto {
/**
* 主键id
*/
private Long refundId;
/**
* 退款备注
*/
private String remark;
/**
* 操作员工id
*/
private Long staffId;
}

View File

@ -1,5 +1,6 @@
package com.ebike.feign.model.dto;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
@ -14,6 +15,7 @@ public class FeignEbikeRefundProcessDto {
/**
* 审核员工id
*/
@NotNull(message = "审核员工id不能为空")
private Long staffId;
/**

View File

@ -1,50 +0,0 @@
package com.cdzy.payment.component;
import cn.dev33.satoken.stp.StpUtil;
import com.cdzy.common.model.response.CommonEbikeRole;
import com.cdzy.common.model.response.CommonStaffInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.mybatisflex.core.tenant.TenantFactory;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import java.util.List;
import java.util.TimeZone;
public class EbikeTenantFactory implements TenantFactory {
public Object[] getTenantIds() {
if (StpUtil.isLogin()) {
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
Object attribute = attributes.getAttribute("tenantId", RequestAttributes.SCOPE_REQUEST);
if (attribute != null) {
String id = (String) StpUtil.getLoginId();
Object object = StpUtil.getSessionByLoginId(id).get(id);
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule())
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
CommonStaffInfo staffInfo = objectMapper.convertValue(object, CommonStaffInfo.class);
List<CommonEbikeRole> roles = staffInfo.getRoles();
boolean isSysAdmin = false;
for (CommonEbikeRole role : roles) {
if (role.getSysAdmin()) {
isSysAdmin = true;
break;
}
}
long tenantId = Long.parseLong(attribute.toString());
//系统管理员
if (isSysAdmin) {
return null;
} else {
return new Object[]{tenantId};
}
}
}
return null;
}
}

View File

@ -1,46 +0,0 @@
package com.cdzy.payment.component;
import cn.dev33.satoken.stp.StpUtil;
import com.cdzy.common.model.response.CommonStaffInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.jetbrains.annotations.NotNull;
import org.springframework.web.servlet.HandlerInterceptor;
import java.util.TimeZone;
/**
* @author yanglei
* @since 2025-10-15 09:41
*/
public class TenantInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(@NotNull HttpServletRequest request
, @NotNull HttpServletResponse response, @NotNull Object handler) {
boolean login = StpUtil.isLogin();
if (login) {
Long tenantId = getTenantIdByReuqest(request);
request.setAttribute("tenantId", tenantId);
return true;
}
return true;
}
Long getTenantIdByReuqest(HttpServletRequest request) {
String token = request.getHeader("Authorization");
String id = (String) StpUtil.getLoginIdByToken(token);
Object object = StpUtil.getSessionByLoginId(id).get(id);
ObjectMapper objectMapper = new ObjectMapper()
.registerModule(new JavaTimeModule())
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
CommonStaffInfo staffInfo = objectMapper.convertValue(object, CommonStaffInfo.class);
return staffInfo.getOperatorId();
}
}

View File

@ -1,6 +1,5 @@
package com.cdzy.payment.config;
import com.cdzy.payment.component.TenantInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@ -14,6 +13,6 @@ public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new TenantInterceptor());
//registry.addInterceptor(new TenantInterceptor());
}
}

View File

@ -1,10 +1,9 @@
package com.cdzy.payment.controller;
import cn.dev33.satoken.stp.StpUtil;
import com.cdzy.common.model.response.JsonResult;
import com.cdzy.payment.model.dto.EbikeRefundDto;
import com.cdzy.payment.model.vo.EbikeWxHandleNotifyVo;
import com.cdzy.payment.service.EbikeWxPayService;
import com.ebike.feign.model.dto.FeignEbikeRefundDto;
import com.fasterxml.jackson.databind.JsonNode;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.refund.model.Refund;
@ -82,11 +81,9 @@ public class EbikeWxPaymentController {
* @return 退款成功返回true否则返回false
*/
@PostMapping("/refund")
public JsonResult<?> refund(@RequestBody EbikeRefundDto refundDto) {
// 获取审核人信息
Long loginId = StpUtil.getLoginIdAsLong();
EbikeWxHandleNotifyVo r = wxPayService.refund(refundDto, loginId);
return r.isSuccess() ? JsonResult.success(true) : JsonResult.failed(r.getMessage());
public JsonResult<?> refund(@RequestBody FeignEbikeRefundDto refundDto) {
EbikeWxHandleNotifyVo notifyVo = wxPayService.refund(refundDto);
return JsonResult.success(notifyVo);
}
/**

View File

@ -0,0 +1,55 @@
package com.cdzy.payment.enums;
/**
* 用户订单状态
*
* @author attiya
* @since 2025-04-08
*/
public interface EbikeOrderStatus {
/**
* 进行中
*/
int IN_PROGRESS = 0;
/**
* 已取消
*/
int CANCELLED = 1;
/**
* 待支付
*/
int PENDING_PAYMENT = 2;
/**
* 已支付
*/
int PAID = 3;
/**
* 退款中
*/
int REFUNDING = 4;
/**
* 已退款
*/
int REFUNDED = 5;
/**
* 退款申请中
*/
int REFUND_APPLYING = 6;
/**
* 退款申请驳回
*/
int REFUND_REJECTED = 7;
/**
* 退款失败
*/
int REFUND_FAILED = 8;
}

View File

@ -0,0 +1,13 @@
package com.cdzy.payment.mapper;
import com.cdzy.payment.model.entity.EbikeOrder;
import com.mybatisflex.core.BaseMapper;
/**
* 用户订单 映射层
*
* @author yanglei
* @since 2025-11-19 15:54
*/
public interface EbikeOrderMapper extends BaseMapper<EbikeOrder> {
}

View File

@ -0,0 +1,31 @@
package com.cdzy.payment.model.dto;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 远程调用 订单支付 请求参数
*
* @author yanglei
* @since 2025-10-17 10:42
*/
@Data
public class EbikeOrderPaymentDto {
/**
* 订单id
*/
private Long orderId;
/**
* 支付方式1-wechat 2-alipay 3-balance
*/
private Integer paymentMethod;
/**
* 支付时间
*/
private LocalDateTime paymentTime;
}

View File

@ -16,11 +16,6 @@ public class EbikeRefundDto {
*/
private String refundId;
/**
* 退款密码
*/
private String password;
/**
* 退款备注
*/

View File

@ -61,7 +61,7 @@ public class EbikeRefund implements Serializable {
private LocalDateTime refundTime;
/**
* 状态;0退款成功 1关闭 2退款中 3异常
* 微信退款状态;0退款成功 1关闭 2退款中 3异常
*/
private Integer refundStatus;

View File

@ -0,0 +1,43 @@
package com.cdzy.payment.service;
import com.cdzy.payment.model.dto.EbikeOrderPaymentDto;
import com.cdzy.payment.model.entity.EbikeOrder;
import com.mybatisflex.core.service.IService;
/**
* 用户订单 服务层
*
* @author yanglei
* @since 2025-11-19 15:53
*/
public interface EbikeOrderService extends IService<EbikeOrder> {
/**
* 订单退款完成
*
* @param orderId 订单ID
*/
void doneRefund(Long orderId);
/**
* 订单退款
*
* @param orderId 订单ID
*/
void refund(Long orderId);
/**
* 订单退款失败
*
* @param orderId 订单ID
*/
void failRefund(Long orderId);
/**
* 订单支付
*
* @param orderPaymentDto 订单支付信息
*/
void payment(EbikeOrderPaymentDto orderPaymentDto);
}

View File

@ -1,7 +1,7 @@
package com.cdzy.payment.service;
import com.cdzy.payment.model.dto.EbikeRefundDto;
import com.cdzy.payment.model.vo.EbikeWxHandleNotifyVo;
import com.ebike.feign.model.dto.FeignEbikeRefundDto;
import com.fasterxml.jackson.databind.JsonNode;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.refund.model.Refund;
@ -72,10 +72,9 @@ public interface EbikeWxPayService {
* 调用微信退款接口
*
* @param refundDto 退款请求
* @param operator 操作人id
* @return 退款信息id
*/
EbikeWxHandleNotifyVo refund(EbikeRefundDto refundDto, Long operator);
EbikeWxHandleNotifyVo refund(FeignEbikeRefundDto refundDto);
/**

View File

@ -0,0 +1,61 @@
package com.cdzy.payment.service.impl;
import com.cdzy.payment.enums.EbikeOrderStatus;
import com.cdzy.payment.mapper.EbikeOrderMapper;
import com.cdzy.payment.model.dto.EbikeOrderPaymentDto;
import com.cdzy.payment.model.entity.EbikeOrder;
import com.cdzy.payment.service.EbikeOrderService;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import static com.cdzy.payment.model.entity.table.EbikeOrderTableDef.EBIKE_ORDER;
/**
* 用户订单实现类
*
* @author yanglei
* @since 2025-11-19 15:54
*/
@Service
public class EbikeOrderServiceImpl extends ServiceImpl<EbikeOrderMapper, EbikeOrder> implements EbikeOrderService {
@Override
public void refund(Long orderId) {
QueryWrapper queryWrapper = QueryWrapper.create()
.where(EBIKE_ORDER.ORDER_ID.eq(orderId))
.where(EBIKE_ORDER.ORDER_STATUS.eq(EbikeOrderStatus.REFUND_APPLYING));
EbikeOrder userOrders = this.mapper.selectOneByQuery(queryWrapper);
userOrders.setOrderStatus(EbikeOrderStatus.REFUNDING);
this.mapper.update(userOrders);
}
@Override
public void doneRefund(Long orderId) {
QueryWrapper queryWrapper = QueryWrapper.create()
.where(EBIKE_ORDER.ORDER_ID.eq(orderId))
.where(EBIKE_ORDER.ORDER_STATUS.eq(EbikeOrderStatus.REFUNDING));
EbikeOrder userOrders = this.mapper.selectOneByQuery(queryWrapper);
userOrders.setOrderStatus(EbikeOrderStatus.REFUNDED);
this.mapper.update(userOrders);
}
@Override
public void failRefund(Long orderId) {
QueryWrapper queryWrapper = QueryWrapper.create()
.where(EBIKE_ORDER.ORDER_ID.eq(orderId))
.where(EBIKE_ORDER.ORDER_STATUS.eq(EbikeOrderStatus.REFUNDING));
EbikeOrder userOrders = this.mapper.selectOneByQuery(queryWrapper);
userOrders.setOrderStatus(EbikeOrderStatus.REFUND_FAILED);
this.mapper.update(userOrders);
}
@Override
public void payment(EbikeOrderPaymentDto orderPaymentDto) {
EbikeOrder ebikeOrderTransaction = this.mapper.selectOneById(orderPaymentDto.getOrderId());
ebikeOrderTransaction.setOrderStatus(EbikeOrderStatus.PAID);
ebikeOrderTransaction.setPaymentTime(orderPaymentDto.getPaymentTime());
ebikeOrderTransaction.setPaymentMethod(orderPaymentDto.getPaymentMethod());
this.mapper.update(ebikeOrderTransaction);
}
}

View File

@ -4,13 +4,16 @@ import com.cdzy.common.enums.GlobalConstants;
import com.cdzy.common.utils.ConvertUtil;
import com.cdzy.payment.enums.PaymentMethod;
import com.cdzy.payment.mapper.EbikePaymentMapper;
import com.cdzy.payment.model.dto.EbikeOrderPaymentDto;
import com.cdzy.payment.model.entity.EbikeOrderDetail;
import com.cdzy.payment.model.entity.EbikePayment;
import com.cdzy.payment.model.vo.*;
import com.cdzy.payment.model.vo.EbikePaymentAmountVo;
import com.cdzy.payment.model.vo.EbikePaymentCostDetailVo;
import com.cdzy.payment.model.vo.EbikePaymentDetailVo;
import com.cdzy.payment.model.vo.EbikePaymentVo;
import com.cdzy.payment.service.EbikeOrderService;
import com.cdzy.payment.service.EbikePaymentService;
import com.cdzy.payment.utils.StringUtils;
import com.ebike.feign.clients.UserFeignClient;
import com.ebike.feign.model.dto.FeignOrderPaymentDto;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.wechat.pay.java.service.payments.model.Transaction;
@ -39,7 +42,7 @@ import static com.mybatisflex.core.constant.FuncName.*;
public class EbikePaymentServiceImpl extends ServiceImpl<EbikePaymentMapper, EbikePayment> implements EbikePaymentService {
@Resource
private UserFeignClient userFeignClient;
private EbikeOrderService ebikeOrderService;
@Override
public List<EbikePayment> getNoPayOrderByDuration(int duration) {
@ -71,11 +74,11 @@ public class EbikePaymentServiceImpl extends ServiceImpl<EbikePaymentMapper, Ebi
ebikePayment.setPaymentTime(StringUtils.toLocalDatetime(paymentTime));
ebikePayment.setTransactionId(transaction.getTransactionId());
// 同步支付状态
FeignOrderPaymentDto paymentParam = new FeignOrderPaymentDto();
EbikeOrderPaymentDto paymentParam = new EbikeOrderPaymentDto();
paymentParam.setOrderId(ebikePayment.getOrderId());
paymentParam.setPaymentTime(ebikePayment.getPaymentTime());
paymentParam.setPaymentMethod(PaymentMethod.WECHAT);
userFeignClient.payment(paymentParam);
ebikeOrderService.payment(paymentParam);
}
return updateById(ebikePayment);
}

View File

@ -3,9 +3,9 @@ package com.cdzy.payment.service.impl;
import com.cdzy.payment.enums.RefundStatus;
import com.cdzy.payment.mapper.EbikeRefundMapper;
import com.cdzy.payment.model.entity.EbikeRefund;
import com.cdzy.payment.service.EbikeOrderService;
import com.cdzy.payment.service.EbikeRefundService;
import com.cdzy.payment.utils.StringUtils;
import com.ebike.feign.clients.UserFeignClient;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.wechat.pay.java.service.refund.model.Refund;
@ -19,7 +19,6 @@ import java.math.RoundingMode;
import java.util.List;
import static com.cdzy.payment.model.entity.table.EbikeRefundTableDef.EBIKE_REFUND;
import static com.mybatisflex.core.constant.FuncName.*;
/**
* 用户订单退款记录 服务层实现
@ -32,7 +31,7 @@ import static com.mybatisflex.core.constant.FuncName.*;
public class EbikeRefundServiceImpl extends ServiceImpl<EbikeRefundMapper, EbikeRefund> implements EbikeRefundService {
@Resource
private UserFeignClient userFeignClient;
private EbikeOrderService ebikeOrderService;
@Override
public List<EbikeRefund> getNoSuccessRefundOrderByDuration(int duration) {
@ -77,9 +76,9 @@ public class EbikeRefundServiceImpl extends ServiceImpl<EbikeRefundMapper, Ebike
Long orderId = Long.valueOf(refund.getOutTradeNo());
// 更新订单退款状态
switch (refund.getStatus()) {
case PROCESSING, CLOSED -> userFeignClient.refund(orderId);
case SUCCESS -> userFeignClient.doneRefund(orderId);
case ABNORMAL -> userFeignClient.failRefund(orderId);
case PROCESSING, CLOSED -> ebikeOrderService.refund(orderId);
case SUCCESS -> ebikeOrderService.doneRefund(orderId);
case ABNORMAL -> ebikeOrderService.failRefund(orderId);
}
return updateById(ebikeRefund);
}

View File

@ -3,15 +3,16 @@ package com.cdzy.payment.service.impl;
import com.cdzy.common.enums.GlobalConstants;
import com.cdzy.payment.config.WxPayConfig;
import com.cdzy.payment.enums.PaymentMethod;
import com.cdzy.payment.model.dto.EbikeRefundDto;
import com.cdzy.payment.model.entity.EbikePayment;
import com.cdzy.payment.model.entity.EbikeRefund;
import com.cdzy.payment.model.vo.*;
import com.cdzy.payment.service.EbikeOrderService;
import com.cdzy.payment.service.EbikePaymentService;
import com.cdzy.payment.service.EbikeRefundService;
import com.cdzy.payment.service.EbikeWxPayService;
import com.cdzy.payment.utils.HttpServletUtils;
import com.cdzy.payment.utils.StringUtils;
import com.ebike.feign.model.dto.FeignEbikeRefundDto;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
@ -81,6 +82,9 @@ public class EbikeWxPayServiceImpl implements EbikeWxPayService {
@Resource
private ObjectMapper objectMapper;
@Resource
private EbikeOrderService ebikeOrderService;
@Override
public boolean closeOrder(String outTradeNo) {
try {
@ -380,7 +384,7 @@ public class EbikeWxPayServiceImpl implements EbikeWxPayService {
}
@Override
public EbikeWxHandleNotifyVo refund(EbikeRefundDto refundDto, Long operator) {
public EbikeWxHandleNotifyVo refund(FeignEbikeRefundDto refundDto) {
EbikeWxHandleNotifyVo notifyVo = new EbikeWxHandleNotifyVo();
notifyVo.setSuccess(false);
// 检查退款记录是否存在
@ -436,8 +440,12 @@ public class EbikeWxPayServiceImpl implements EbikeWxPayService {
ebikeRefund.setRefundTime(LocalDateTime.now());
ebikeRefund.setRemark(refundDto.getRemark());
ebikeRefund.setRefundTransactionId(result.getRefundId());
ebikeRefund.setCreateBy(operator);
ebikeRefund.setReviewOperator(refundDto.getStaffId());
ebikeRefundService.updateById(ebikeRefund);
// 更新退款单状态
ebikeRefundService.updateRefundStatus(result);
// 更新订单状态 为退款已完成
ebikeOrderService.doneRefund(orderId);
notifyVo.setSuccess(true);
notifyVo.setMessage("退款成功");
return notifyVo;

View File

@ -9,7 +9,6 @@ import com.cdzy.user.model.vo.EbikeUserAllOrdersVo;
import com.cdzy.user.service.EbikeOrderService;
import com.ebike.feign.model.dto.FeignEbikeDto;
import com.ebike.feign.model.dto.FeignEbikeUserBikeInfo;
import com.ebike.feign.model.dto.FeignOrderPaymentDto;
import com.ebike.feign.model.vo.FeignEbikeBikeRadiusVo;
import com.mybatisflex.core.paginate.Page;
import jakarta.annotation.Resource;
@ -88,72 +87,6 @@ public class EbikeOrderController {
return JsonResult.success(orderId);
}
/**
* 订单支付
*
* @param orderPaymentDto 支付信息
*/
@PostMapping("payment")
public JsonResult<?> payment(@RequestBody @Validated FeignOrderPaymentDto orderPaymentDto) {
ebikeOrderService.payment(orderPaymentDto);
return JsonResult.success();
}
/**
* 订单退款申请
*
* @param orderId 订单ID
*/
@GetMapping("refundApply")
public JsonResult<?> refundApply(@RequestParam("orderId") Long orderId) {
ebikeOrderService.refundApply(orderId);
return JsonResult.success();
}
/**
* 订单退款
*
* @param orderId 订单ID
*/
@GetMapping("refund")
public JsonResult<?> refund(@RequestParam("orderId") Long orderId) {
ebikeOrderService.refund(orderId);
return JsonResult.success();
}
/**
* 订单退款完成
*
* @param orderId 订单ID
*/
@GetMapping("doneRefund")
public JsonResult<?> doneRefund(@RequestParam("orderId") Long orderId) {
ebikeOrderService.doneRefund(orderId);
return JsonResult.success();
}
/**
* 订单退款失败
*
* @param orderId 订单ID
*/
@GetMapping("failRefund")
public JsonResult<?> failRefund(@RequestParam("orderId") Long orderId) {
ebikeOrderService.failRefund(orderId);
return JsonResult.success();
}
/**
* 订单退款驳回
*
* @param orderId 订单ID
*/
@GetMapping("rejectRefund")
public JsonResult<?> rejectRefund(@RequestParam("orderId") Long orderId) {
ebikeOrderService.rejectRefund(orderId);
return JsonResult.success();
}
/**
* 根据用户订单表主键获取详细信
*

View File

@ -2,19 +2,17 @@ package com.cdzy.user.controller;
import com.cdzy.common.model.response.JsonResult;
import com.cdzy.user.model.dto.EbikeOrderRefundDto;
import com.ebike.feign.model.dto.FeignEbikeRefundQueryDto;
import com.cdzy.user.model.dto.EbikeTreadRecordDto;
import com.cdzy.user.model.vo.*;
import com.cdzy.user.service.EbikeRefundService;
import com.ebike.feign.model.dto.FeignEbikeRefundProcessDto;
import com.ebike.feign.model.dto.FeignEbikeRefundQueryDto;
import com.ebike.feign.model.vo.FeignEbikeRefundVo;
import com.mybatisflex.core.paginate.Page;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* 用户退款 控制层
*
@ -145,16 +143,4 @@ public class EbikeRefundController {
ebikeRefundService.deletedFile(fileName);
return JsonResult.success();
}
//
// /**
// * 分页获取退款列表
// *
// * @param dto 退款参数
// * @return 退款列表
// */
// @PostMapping("getRefundList")
// public JsonResult<?> getRefundList(@RequestBody FeignEbikeRefundQueryDto dto) {
// Page<FeignEbikeRefundVo> ebikeRefundList = ebikeRefundService.getRefundList(dto);
// return JsonResult.success(ebikeRefundList);
// }
}

View File

@ -22,7 +22,7 @@ public class EbikeOrderRefundDto {
/**
* 商户(骑行)订单号
*/
@NotBlank(message = "订单id不能为空")
@NotNull(message = "订单id不能为空")
private Long orderId;
/**

View File

@ -61,7 +61,7 @@ public class EbikeRefund implements Serializable {
private LocalDateTime refundTime;
/**
* 状态;0退款成功 1关闭 2退款中 3异常
* 微信退款状态;0退款成功 1关闭 2退款中 3异常
*/
private Integer refundStatus;

View File

@ -85,6 +85,11 @@ public class EbikeRefundOrderDetailVo {
*/
private BigDecimal helmetManagementFee;
/**
* 退款申请类型
*/
private Integer problemType;
/**
* 退款申请图片
*/

View File

@ -1,6 +1,8 @@
package com.cdzy.user.service.impl;
import com.cdzy.common.enums.Code;
import com.cdzy.common.ex.EbikeException;
import com.cdzy.common.model.response.JsonResult;
import com.cdzy.user.enums.EbikeFileTypeEnum;
import com.cdzy.user.enums.EbikeProcessStatus;
import com.cdzy.user.enums.EbikeRefundSource;
@ -18,6 +20,8 @@ import com.cdzy.user.model.vo.*;
import com.cdzy.user.service.*;
import com.cdzy.user.utils.MinioUtil;
import com.cdzy.user.utils.StringUtils;
import com.ebike.feign.clients.PaymentFeignClient;
import com.ebike.feign.model.dto.FeignEbikeRefundDto;
import com.ebike.feign.model.dto.FeignEbikeRefundProcessDto;
import com.ebike.feign.model.dto.FeignEbikeRefundQueryDto;
import com.ebike.feign.model.vo.FeignEbikeRefundVo;
@ -73,6 +77,9 @@ public class EbikeRefundServiceImpl extends ServiceImpl<EbikeRefundMapper, Ebike
@Resource
private MinioUtil minioUtil;
@Resource
private PaymentFeignClient paymentFeignClient;
@Transactional
@Override
public Long refundApply(EbikeOrderRefundDto ebikeRefundDto) {
@ -112,24 +119,29 @@ public class EbikeRefundServiceImpl extends ServiceImpl<EbikeRefundMapper, Ebike
Long refundId = ebikeRefund.getRefundId();
// 保存退款图片
List<EbikeRefundFileDto> refundFiles = ebikeRefundDto.getRefundFiles();
List<EbikeRefundFile> ebikeRefundFiles = refundFiles.stream()
.map(dto -> EbikeRefundFile.builder()
.refundId(refundId)
.fileName(dto.getFileName())
.fileType(dto.getFileType())
.fileUrl(dto.getFileUrl())
.fileSize(dto.getFileSize())
.build())
.toList();
ebikeRefundFileMapper.insertBatch(ebikeRefundFiles);
if (!refundFiles.isEmpty()) {
List<EbikeRefundFile> ebikeRefundFiles = refundFiles.stream()
.map(dto -> EbikeRefundFile.builder()
.refundId(refundId)
.fileName(dto.getFileName())
.fileType(dto.getFileType())
.fileUrl(dto.getFileUrl())
.fileSize(dto.getFileSize())
.build())
.toList();
ebikeRefundFileMapper.insertBatch(ebikeRefundFiles);
}
// 同步改变订单状态为退款申请中
ebikeOrderService.refundApply(ebikeRefundDto.getOrderId());
return refundId;
}
@Transactional
@Override
public boolean refundReview(FeignEbikeRefundProcessDto processDto) {
Long staffId = processDto.getStaffId();
if (staffId == null) {
throw new EbikeException("操作员工Id不能为空");
throw new EbikeException("审核员工Id不能为空");
}
EbikeRefund ebikeRefund = getById(processDto.getRefundId());
if (ebikeRefund == null) {
@ -146,6 +158,15 @@ public class EbikeRefundServiceImpl extends ServiceImpl<EbikeRefundMapper, Ebike
ebikeRefund.setRefundMethod(processDto.getRefundMethod());
// 更新订单状态为退款中
ebikeOrderService.refund(ebikeRefund.getOrderId());
// 同步调用微信退款
FeignEbikeRefundDto ebikeRefundDto = new FeignEbikeRefundDto();
ebikeRefundDto.setRefundId(processDto.getRefundId());
ebikeRefundDto.setRemark(processDto.getReason());
ebikeRefundDto.setStaffId(staffId);
JsonResult<?> refund = paymentFeignClient.refund(ebikeRefundDto);
if (refund.getCode() != Code.SUCCESS) {
throw new EbikeException("微信同步退款失败");
}
} else if (EbikeRefundStatus.ABNORMAL == processDto.getOperate()) {
// 审核不通过更新订单申请退款驳回
ebikeOrderService.rejectRefund(ebikeRefund.getOrderId());
@ -500,9 +521,10 @@ public class EbikeRefundServiceImpl extends ServiceImpl<EbikeRefundMapper, Ebike
public EbikeRefundOrderDetailVo getRefundOrderDetail(Long refundId) {
QueryWrapper query = QueryWrapper.create()
.select(EbikeRefundTableDef.EBIKE_REFUND.REFUND_APPLY.as("applyRefundAmount"),
EbikeRefundTableDef.EBIKE_REFUND.PROBLEM_DESCRIPTION.as("applyReason"),
EbikeRefundTableDef.EBIKE_REFUND.ORDER_ID,
.select(EBIKE_REFUND.REFUND_APPLY.as("applyRefundAmount"),
EBIKE_REFUND.PROBLEM_DESCRIPTION.as("applyReason"),
EBIKE_REFUND.ORDER_ID,
EBIKE_REFUND.PROBLEM_TYPE,
EBIKE_PAYMENT.PAYMENT_METHOD,
EBIKE_PAYMENT.TOTAL.as("actualPaymentAmount"),
EBIKE_PAYMENT.COST_PRICE.as("originalOrderPrice"),
@ -511,7 +533,7 @@ public class EbikeRefundServiceImpl extends ServiceImpl<EbikeRefundMapper, Ebike
)
.leftJoin(EBIKE_PAYMENT).on(EBIKE_PAYMENT.ORDER_ID.eq(EbikeRefundTableDef.EBIKE_REFUND.ORDER_ID))
.leftJoin(EBIKE_USER).on(EBIKE_USER.USER_ID.eq(EBIKE_PAYMENT.USER_ID))
.where(EbikeRefundTableDef.EBIKE_REFUND.REFUND_ID.eq(refundId));
.where(EBIKE_REFUND.REFUND_ID.eq(refundId));
EbikeRefundOrderDetailVo detailVo = getOneAs(query, EbikeRefundOrderDetailVo.class);
if (detailVo == null) {
return null;