Quellcode durchsuchen

fix(cfc-backend): connect after-sales request and product order refund flows

AfterSalesService.create() now syncs ProductOrder.status='refunding' so
admin order management can find refunding orders (was filtering by
order.status='refunding' but after-sales was stored in separate table).

ProductOrderService.approveRefund/rejectRefund now syncs back to
AfterSalesRequest.status so mini-program after-sales list stays in sync.

ProductOrderDTO.from() now carries refund/logistics fields that were
previously omitted, so admin refund dialog shows refund reason.
Xiaogang Liao vor 3 Monaten
Ursprung
Commit
224a9314e7

+ 22 - 0
cfc-backend/src/main/java/com/etotem/cfc/dto/ProductOrderDTO.java

@@ -32,6 +32,17 @@ public class ProductOrderDTO {
     private String addressSnapshot;
     private String addressSnapshot;
     private Long consigneeId;
     private Long consigneeId;
     private String purchaseInfo;
     private String purchaseInfo;
+    private Integer refundStatus;
+    private String refundReason;
+    private Integer refundAmount;
+    private Date refundTime;
+    private String logisticsNo;
+    private String logisticsCompany;
+    private String trackingNumber;
+    private String expressCompany;
+    private Integer deliveryMethod;
+    private String pickupCode;
+    private Date confirmTime;
     private Date paidAt;
     private Date paidAt;
     private Date createdAt;
     private Date createdAt;
     private Date updatedAt;
     private Date updatedAt;
@@ -63,6 +74,17 @@ public class ProductOrderDTO {
         d.addressSnapshot = o.getAddressSnapshot();
         d.addressSnapshot = o.getAddressSnapshot();
         d.consigneeId = o.getConsigneeId();
         d.consigneeId = o.getConsigneeId();
         d.purchaseInfo = o.getPurchaseInfo();
         d.purchaseInfo = o.getPurchaseInfo();
+        d.refundStatus = o.getRefundStatus();
+        d.refundReason = o.getRefundReason();
+        d.refundAmount = o.getRefundAmount();
+        d.refundTime = o.getRefundTime();
+        d.logisticsNo = o.getLogisticsNo();
+        d.logisticsCompany = o.getLogisticsCompany();
+        d.trackingNumber = o.getTrackingNumber();
+        d.expressCompany = o.getExpressCompany();
+        d.deliveryMethod = o.getDeliveryMethod();
+        d.pickupCode = o.getPickupCode();
+        d.confirmTime = o.getConfirmTime();
         d.paidAt = o.getPaidAt();
         d.paidAt = o.getPaidAt();
         d.createdAt = o.getCreatedAt();
         d.createdAt = o.getCreatedAt();
         d.updatedAt = o.getUpdatedAt();
         d.updatedAt = o.getUpdatedAt();

+ 13 - 0
cfc-backend/src/main/java/com/etotem/cfc/service/AfterSalesService.java

@@ -6,6 +6,8 @@ import com.etotem.cfc.entity.AfterSalesRequest;
 import com.etotem.cfc.entity.ProductOrder;
 import com.etotem.cfc.entity.ProductOrder;
 import com.etotem.cfc.mapper.AfterSalesRequestMapper;
 import com.etotem.cfc.mapper.AfterSalesRequestMapper;
 import com.etotem.cfc.mapper.ProductOrderMapper;
 import com.etotem.cfc.mapper.ProductOrderMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
 import javax.annotation.Resource;
 import javax.annotation.Resource;
@@ -21,6 +23,8 @@ public class AfterSalesService {
     @Resource
     @Resource
     private ProductOrderMapper productOrderMapper;
     private ProductOrderMapper productOrderMapper;
 
 
+    private static final Logger log = LoggerFactory.getLogger(AfterSalesService.class);
+
     public Result<AfterSalesRequest> create(AfterSalesRequest request, Long userId) {
     public Result<AfterSalesRequest> create(AfterSalesRequest request, Long userId) {
         ProductOrder order = productOrderMapper.selectById(request.getOrderId());
         ProductOrder order = productOrderMapper.selectById(request.getOrderId());
         if (order == null) {
         if (order == null) {
@@ -39,6 +43,15 @@ public class AfterSalesService {
         request.setCreatedAt(new Date());
         request.setCreatedAt(new Date());
         request.setUpdatedAt(new Date());
         request.setUpdatedAt(new Date());
         afterSalesRequestMapper.insert(request);
         afterSalesRequestMapper.insert(request);
+
+        order.setStatus("refunding");
+        order.setRefundStatus(1);
+        order.setRefundReason(request.getReason());
+        order.setRefundAmount(order.getTotalAmount());
+        order.setUpdatedAt(new Date());
+        productOrderMapper.updateById(order);
+
+        log.info("售后申请已创建,同步更新订单状态: orderNo={}, requestId={}", order.getOrderNo(), request.getId());
         return Result.success(request);
         return Result.success(request);
     }
     }
 
 

+ 31 - 6
cfc-backend/src/main/java/com/etotem/cfc/service/ProductOrderService.java

@@ -6,9 +6,11 @@ import com.etotem.cfc.common.Result;
 import com.etotem.cfc.dto.CreateProductOrderDTO;
 import com.etotem.cfc.dto.CreateProductOrderDTO;
 import com.etotem.cfc.dto.OrderItemVO;
 import com.etotem.cfc.dto.OrderItemVO;
 import com.etotem.cfc.dto.ProductOrderDTO;
 import com.etotem.cfc.dto.ProductOrderDTO;
+import com.etotem.cfc.entity.AfterSalesRequest;
 import com.etotem.cfc.entity.Product;
 import com.etotem.cfc.entity.Product;
 import com.etotem.cfc.entity.ProductOrder;
 import com.etotem.cfc.entity.ProductOrder;
 import com.etotem.cfc.entity.User;
 import com.etotem.cfc.entity.User;
+import com.etotem.cfc.mapper.AfterSalesRequestMapper;
 import com.etotem.cfc.mapper.ProductMapper;
 import com.etotem.cfc.mapper.ProductMapper;
 import com.etotem.cfc.mapper.ProductOrderMapper;
 import com.etotem.cfc.mapper.ProductOrderMapper;
 import com.etotem.cfc.mapper.UserMapper;
 import com.etotem.cfc.mapper.UserMapper;
@@ -62,6 +64,9 @@ public class ProductOrderService {
     @Resource
     @Resource
     private PointsService pointsService;
     private PointsService pointsService;
 
 
+    @Resource
+    private AfterSalesRequestMapper afterSalesRequestMapper;
+
     public Result<ProductOrderDTO> create(CreateProductOrderDTO dto, Long buyerId) {
     public Result<ProductOrderDTO> create(CreateProductOrderDTO dto, Long buyerId) {
         if (buyerId == null) {
         if (buyerId == null) {
             return Result.error("请先登录");
             return Result.error("请先登录");
@@ -377,22 +382,20 @@ public class ProductOrderService {
         if (order.getRefundStatus() == null || order.getRefundStatus() != 1) {
         if (order.getRefundStatus() == null || order.getRefundStatus() != 1) {
             return Result.error("没有待处理的退款申请");
             return Result.error("没有待处理的退款申请");
         }
         }
-        // 调用微信支付退款
         try {
         try {
             paymentService.refund(orderNo, order.getTotalAmount(), order.getRefundReason());
             paymentService.refund(orderNo, order.getTotalAmount(), order.getRefundReason());
         } catch (Exception e) {
         } catch (Exception e) {
             log.error("微信退款失败: orderNo={}, error={}", orderNo, e.getMessage());
             log.error("微信退款失败: orderNo={}, error={}", orderNo, e.getMessage());
             return Result.error("退款失败: " + e.getMessage());
             return Result.error("退款失败: " + e.getMessage());
         }
         }
-        // 更新订单状态
-        order.setRefundStatus(2); // 已退款
+        order.setRefundStatus(2);
         order.setRefundAmount(order.getTotalAmount());
         order.setRefundAmount(order.getTotalAmount());
         order.setRefundTime(new Date());
         order.setRefundTime(new Date());
         order.setStatus("refunded");
         order.setStatus("refunded");
         order.setUpdatedAt(new Date());
         order.setUpdatedAt(new Date());
         orderMapper.updateById(order);
         orderMapper.updateById(order);
-        // 恢复库存
         productService.increaseStock(order.getProductId(), order.getQuantity());
         productService.increaseStock(order.getProductId(), order.getQuantity());
+        syncAfterSalesRequestStatus(orderNo, "approved", adminId);
         log.info("退款完成: orderNo={}, adminId={}", orderNo, adminId);
         log.info("退款完成: orderNo={}, adminId={}", orderNo, adminId);
         return Result.success("退款已处理");
         return Result.success("退款已处理");
     }
     }
@@ -406,14 +409,36 @@ public class ProductOrderService {
         if (order.getRefundStatus() == null || order.getRefundStatus() != 1) {
         if (order.getRefundStatus() == null || order.getRefundStatus() != 1) {
             return Result.error("没有待处理的退款申请");
             return Result.error("没有待处理的退款申请");
         }
         }
-        order.setRefundStatus(3); // 拒绝
-        order.setStatus("paid"); // 恢复原状态
+        order.setRefundStatus(3);
+        order.setStatus("paid");
         order.setUpdatedAt(new Date());
         order.setUpdatedAt(new Date());
         orderMapper.updateById(order);
         orderMapper.updateById(order);
+        syncAfterSalesRequestStatus(orderNo, "rejected", adminId);
         log.info("退款申请被拒绝: orderNo={}, adminId={}, reason={}", orderNo, adminId, reason);
         log.info("退款申请被拒绝: orderNo={}, adminId={}, reason={}", orderNo, adminId, reason);
         return Result.success("已拒绝退款申请");
         return Result.success("已拒绝退款申请");
     }
     }
 
 
+    private void syncAfterSalesRequestStatus(String orderNo, String status, Long adminId) {
+        try {
+            LambdaQueryWrapper<AfterSalesRequest> wrapper = new LambdaQueryWrapper<AfterSalesRequest>()
+                .eq(AfterSalesRequest::getOrderNo, orderNo)
+                .eq(AfterSalesRequest::getStatus, "pending");
+            AfterSalesRequest request = afterSalesRequestMapper.selectOne(wrapper);
+            if (request != null) {
+                request.setStatus(status);
+                request.setHandledBy(adminId);
+                request.setHandledAt(new Date());
+                request.setUpdatedAt(new Date());
+                if ("rejected".equals(status)) {
+                    request.setRejectReason("管理员拒绝退款");
+                }
+                afterSalesRequestMapper.updateById(request);
+            }
+        } catch (Exception e) {
+            log.error("同步AfterSalesRequest状态失败: orderNo={}, status={}", orderNo, status, e);
+        }
+    }
+
     public Result<List<ProductOrderDTO>> myOrders(Long buyerId, String status) {
     public Result<List<ProductOrderDTO>> myOrders(Long buyerId, String status) {
         return myOrders(buyerId, status, null);
         return myOrders(buyerId, status, null);
     }
     }