Ver código fonte

海博退款单模块

fubojin 6 dias atrás
pai
commit
4105ee49b2

+ 2 - 1
yami-shop-bean/src/main/java/com/yami/shop/bean/enums/ReturnMoneyStsType.java

@@ -21,6 +21,7 @@ public enum ReturnMoneyStsType {
      * 待确认收货(二审待审核)
      */
     RECEIVE(65),
+
     /**
      * 退款成功
      */
@@ -32,7 +33,7 @@ public enum ReturnMoneyStsType {
     CANCEL(40),
 
     /**
-     * 商家拒绝
+     * 商家拒绝(驳回)
      */
     REJECT(30),
 

+ 1 - 1
yami-shop-bean/src/main/java/com/yami/shop/bean/model/OrderRefundSku.java

@@ -30,7 +30,7 @@ public class OrderRefundSku implements Serializable{
     private Long id;
 
     /**
-     * 退款编号
+     * 退款商品ID
      */
     private Long skuId;
 

+ 64 - 0
yami-shop-bean/src/main/java/com/yami/shop/bean/param/OrderRefundParam.java

@@ -10,10 +10,14 @@
 
 package com.yami.shop.bean.param;
 
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.yami.shop.bean.model.OrderRefundSku;
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import javax.validation.constraints.NotEmpty;
 import javax.validation.constraints.NotNull;
+import java.util.List;
 
 @Data
 public class OrderRefundParam {
@@ -23,12 +27,67 @@ public class OrderRefundParam {
     @NotEmpty(message = "退款ID不能为空")
     private Long refundId;
 
+
+    @ApiModelProperty(value = "订单编号", required = true)
+    @NotEmpty(message = "订单编号不能为空")
+    private String orderNumber;
+
+
+    @ApiModelProperty(value = "退款金额", required = true)
+    @NotNull(message = "退款金额不能为空")
+    private Double refundAmount;
+    @ApiModelProperty(value = "申请类型(1:仅退款 2退款退货)", required = true)
+    @NotNull(message = "申请类型不能为空")
+    private Integer applyType;
+
+    @ApiModelProperty(value = "退款数量(0或不传值则为全部数量)", required = true)
+    private Integer goodsNum = 0;
+
+    /**
+     * 仅退款-未收到货申请原因
+     *      11(质量问题)
+     *      12(拍错/多拍/不喜欢)
+     *      3(商品描述不符)
+     *      14(假货), 15(商家发错货)
+     *      16(商品破损/少件)
+     *      17(其他)
+     * 仅退款-已收到货申请原因
+     *      51(多买/买错/不想要)
+     *      52(快递无记录)
+     *      53(少货/空包裹)
+     *      54(未按约定时间发货)
+     *      55(快递一直未送达)
+     *      56(其他)
+     * 退货退款-申请原因
+     *      101(商品破损/少件)
+     *      102(商家发错货)
+     *      103(商品描述不符)
+     *      104(拍错/多拍/不喜欢)
+     *      105(质量问题)
+     *      107(其他)
+     */
+    @ApiModelProperty(value = "申请原因(下拉选择)", required = true)
+    @NotNull(message = "申请原因不能为空")
+    private String buyerReason;
+    @ApiModelProperty(value = "手机号码(默认当前订单手机号码)", required = true)
+    @NotNull(message = "手机号码不能为空")
+    private String buyerMobile;
+
+    @ApiModelProperty(value = "备注说明", required = true)
+    private String buyerDesc;
+
+    @ApiModelProperty(value = "凭证图片列表", required = true)
+    private String photoFiles;
+
     /**
      * 退款编号
      */
     @NotEmpty(message = "退款编号不能为空")
     private String refundSn;
 
+    @ApiModelProperty(value = "退款单类型(1:整单退款,2:单个物品退款)", required = true)
+    @NotNull(message = "退款单类型不能为空")
+    private Integer refundType;
     /**
      * 处理状态(2:同意,3:不同意)
      */
@@ -60,4 +119,9 @@ public class OrderRefundParam {
      * 是否收到货
      */
     private Boolean isReceiver;
+
+    @TableField(exist = false)
+    @ApiModelProperty(value = "退款商品详情")
+    private List<OrderRefundSku> orderRefundSkuList;
+
 }

+ 3 - 2
yami-shop-platform/src/main/java/com/yami/shop/platform/controller/hb/HBOrderRefundController.java

@@ -57,11 +57,12 @@ public class HBOrderRefundController {
     /**
      * 退款-退款单状态同步(上行)
      * @param afterSaleOrder  退款单号
+     *  @param  refundStatus 退款单状态 10:待审核 20:处理中 30:驳回退款 40:撤销退款 60:待退货(一审同意) 65:待确认收货(二审待审核) 70:退款完成
      */
     @PostMapping("/changeStatus")
-    public HBR changeStatus(String afterSaleOrder) {
+    public HBR changeStatus(String afterSaleOrder,Integer refundStatus) {
         log.info("海博售后订单状态同步afterSaleOrder:{}",afterSaleOrder);
-        return HBR.success(orderRefundService.changeStatus(afterSaleOrder));
+        return HBR.success(orderRefundService.changeStatus(afterSaleOrder,refundStatus));
     }
 
 

+ 2 - 2
yami-shop-service/src/main/java/com/yami/shop/service/OrderRefundService.java

@@ -141,7 +141,6 @@ public interface OrderRefundService extends IService<OrderRefund> {
     void overTimeRefundOrder(com.yami.shop.bean.app.param.OrderRefundParam orderRefundParam);
 
 
-
     //*************************** 售后接口 ***************************
     /**
      * 创建退款订单接口-推送接口
@@ -153,8 +152,9 @@ public interface OrderRefundService extends IService<OrderRefund> {
     /**
      * 退款-退款单状态同步(上行)
      * @param afterSaleOrder  退款单号
+     *  退款单状态 退款单状态 10:待审核 20:处理中 30:驳回退款 40:撤销退款 60:待退货(一审同意) 65:待确认收货(二审待审核) 70:退款完成
      */
-    String changeStatus(String afterSaleOrder);
+    String changeStatus(String afterSaleOrder,Integer  refundStatus);
 
 
     /**

+ 10 - 0
yami-shop-service/src/main/java/com/yami/shop/service/OrderService.java

@@ -21,6 +21,7 @@ import com.yami.shop.bean.model.OrderItem;
 import com.yami.shop.bean.param.CancelOrderParam;
 import com.yami.shop.bean.param.OrderParam;
 import com.yami.shop.bean.param.OrderPayParam;
+import com.yami.shop.bean.param.OrderRefundParam;
 import org.springframework.web.bind.annotation.RequestBody;
 
 import javax.servlet.http.HttpServletResponse;
@@ -113,4 +114,13 @@ public interface OrderService extends IService<Order> {
     Map<Long, Integer> getOrderItemMap(Long orderId);
 
     String cancelOrder(CancelOrderParam cancelOrderParam);
+
+
+    /**
+     * 订单申请退款
+     * @param orderRefundParam 订单申请退款参数
+     * @param rReturnMoneySts 退款状态
+     * @return 订单申请退款结果
+     */
+    String applyAgain(OrderRefundParam orderRefundParam , Integer  rReturnMoneySts);
 }

+ 77 - 73
yami-shop-service/src/main/java/com/yami/shop/service/impl/OrderRefundServiceImpl.java

@@ -34,6 +34,7 @@ import com.yami.shop.common.util.hb.HBR;
 import com.yami.shop.dao.*;
 import com.yami.shop.service.*;
 import com.yami.shop.service.hb.IHBOrderService;
+import com.yami.shop.utils.CullenUtils;
 import com.yami.shop.utils.HBSignUtil;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -268,7 +269,12 @@ public class OrderRefundServiceImpl extends ServiceImpl<OrderRefundMapper, Order
         save(orderRefund);
         // 更新订单状态
         Order order = orderService.getById(orderRefund.getOrderId());
-        order.setRefundStatus(RefundStatusEnum.APPLY.value());
+        Integer refundType = orderRefund.getRefundType();
+        if (Objects.equals(refundType, RefundType.ALL.value())) {
+            order.setRefundStatus(RefundStatusEnum.APPLY.value());
+        } else {
+            order.setRefundStatus(RefundStatusEnum.PARTIAL_SUCCESS.value());
+        }
         orderService.updateById(order);
         return orderRefund;
     }
@@ -952,23 +958,25 @@ public class OrderRefundServiceImpl extends ServiceImpl<OrderRefundMapper, Order
         build.setBody(JSON.toJSONString(requestBody));
 
         build.setSign(hbSignUtil.signMd5(build));
-        log.info("post 单推送单号参数:{}", JSON.toJSONString(build));
+        log.info("post 退款单推送单号参数:{}", JSON.toJSONString(build));
         String post = post(hbSignUtil.getHBHost() + "/api/refund/asyncSave", build);
-        log.info("post 单推送结果:{}", post);
+        log.info("post 退款单推送结果:{}", post);
         return post;
     }
 
     @Override
-    public String changeStatus(String afterSaleOrder) {
+    public String changeStatus(String afterSaleOrder, Integer refundStatus) {
         HBBaseReq<Object> build = HBBaseReq.create();
         build.setAppId(hbSignUtil.getAppId());
         OrderRefund orderRefund = orderRefundMapper.selectOne(new LambdaQueryWrapper<OrderRefund>().eq(OrderRefund::getRefundSn, afterSaleOrder));
+        orderRefund.setReturnMoneySts(refundStatus);
+        orderRefundMapper.updateById(orderRefund);
 
         // 3. 构建外层请求体
         JSONObject requestBody = new JSONObject();
         requestBody.put("afterSaleOrder", afterSaleOrder);
 //        退款单状态 10:待审核 20:处理中 30:驳回退款 40:撤销退款 60:待退货(一审同意) 65:待确认收货(二审待审核) 70:退款完成
-        requestBody.put("refundStatus", refundHbStatus(orderRefund.getReturnMoneySts()));
+        requestBody.put("refundStatus", refundStatus);
         requestBody.put("timestamp", orderRefund.getApplyTime().getTime());
 
 //        deliveryMan 退货的配送员名称
@@ -978,9 +986,15 @@ public class OrderRefundServiceImpl extends ServiceImpl<OrderRefundMapper, Order
         // 4. 将整个JSON对象序列化为字符串并设置
         build.setBody(JSON.toJSONString(requestBody));
         build.setSign(hbSignUtil.signMd5(build));
-        log.info("post 单推送单号参数:{}", JSON.toJSONString(build));
+        log.info("post 退款单推送单号参数:{}", JSON.toJSONString(build));
         String post = post(hbSignUtil.getHBHost() + "/api/refund/changeStatus", build);
-        log.info("post 订单推送结果:{}", post);
+        log.info("post 退款单推送结果:{}", post);
+
+        //TODO 退款单完成处理积分
+        if (refundStatus == 70){
+//            orderService.returnRefund(orderRefund.getOrderNumber());
+        }
+
         return post;
     }
 
@@ -1002,8 +1016,7 @@ public class OrderRefundServiceImpl extends ServiceImpl<OrderRefundMapper, Order
             thirdPartyRefundRequest.setProblemDescription(orderRefund.getBuyerDesc());
             thirdPartyRefundRequest.setPictures(orderRefund.getPhotoFiles());
 
-            Integer returnMoneySts = orderRefund.getReturnMoneySts();
-            thirdPartyRefundRequest.setRefundStatus(refundHbStatus(returnMoneySts));
+            thirdPartyRefundRequest.setRefundStatus(orderRefund.getReturnMoneySts());
             Integer applyType = orderRefund.getApplyType();
             if (Objects.equals(applyType, 2)) {
                 thirdPartyRefundRequest.setApplyDeal(40);
@@ -1019,15 +1032,15 @@ public class OrderRefundServiceImpl extends ServiceImpl<OrderRefundMapper, Order
 
 
             List<ProductRequest> productRequests = new ArrayList<>();
-            orderItemService.list(new LambdaQueryWrapper<OrderItem>().eq(OrderItem::getOrderNumber, orderRefund.getOrderId())).forEach(orderItem -> {
-                Sku sku = skuService.getById(orderItem.getSkuId());
+            orderRefundSkuMapper.selectList(new LambdaQueryWrapper<OrderRefundSku>().eq(OrderRefundSku::getOrderRefundId, orderRefund.getRefundId())).forEach(orderRefundSku -> {
+                Sku sku = skuService.getById(orderRefundSku.getSkuId());
                 ProductRequest productRequest = new ProductRequest();
-                productRequest.setSkuName(orderItem.getSkuName());
-                productRequest.setSkuId(orderItem.getSkuId());
+                productRequest.setSkuName(sku.getSkuName());
+                productRequest.setSkuId(orderRefundSku.getSkuId());
                 productRequest.setChannelSkuId(sku.getHbSkuId());
 //                productRequest.setUpcCode(orderItem.getSkuId());
-                productRequest.setRefundCount(orderItem.getProdCount());
-                productRequest.setRefundMoney((long) (orderItem.getProductTotalAmount() == null ? 0 : orderItem.getProductTotalAmount() * 100));
+                productRequest.setRefundCount(orderRefundSku.getProductCount());
+                productRequest.setRefundMoney((long) (orderRefundSku.getSkuPrice() == null ? 0 : orderRefundSku.getProductCount() * orderRefundSku.getSkuPrice() * 100));
                 productRequest.setTransId(sku.getSkuId().toString());
                 productRequests.add(productRequest);
 
@@ -1043,16 +1056,15 @@ public class OrderRefundServiceImpl extends ServiceImpl<OrderRefundMapper, Order
             thirdPartyRefundRequest.setOrderPayments(orderPaymentRequests);
             log.info("退款订单信息,参数:{}", thirdPartyRefundRequest);
 
-
             // 返回退款单信息
-            changeStatus(orderRefund.getRefundSn());
+            changeStatus(orderRefund.getRefundSn(), orderRefund.getReturnMoneySts());
 
         } catch (Exception e) {
             log.error("海博退款订单查询异常:{}", e);
             HBR.error("未知异常");
         }
 
-
+        log.info("退款订单信息,返回:{}", thirdPartyRefundRequest);
         return HBR.success(thirdPartyRefundRequest);
     }
 
@@ -1076,14 +1088,11 @@ public class OrderRefundServiceImpl extends ServiceImpl<OrderRefundMapper, Order
 
             OrderRefund orderRefund = orderRefundMapper.selectOne(new LambdaQueryWrapper<OrderRefund>().eq(OrderRefund::getRefundSn, afterSaleOrder));
 
-            if (auditType == 2) {
-                orderRefund.setApplyType(applyDeal);
-                orderRefund.setReturnMoneySts(2);
-            } else if (auditType == 4) {
+            if (auditType == 2 || auditType == 4) {
                 orderRefund.setApplyType(applyDeal);
-                orderRefund.setReturnMoneySts(2);
+                orderRefund.setReturnMoneySts(ReturnMoneyStsType.PROCESSING.value());
             } else {
-                orderRefund.setReturnMoneySts(7);
+                orderRefund.setReturnMoneySts(ReturnMoneyStsType.REJECT.value());
                 orderRefund.setRejectMessage(bodyStr.getString("reason"));
             }
             orderRefundMapper.updateById(orderRefund);
@@ -1115,16 +1124,14 @@ public class OrderRefundServiceImpl extends ServiceImpl<OrderRefundMapper, Order
 
             OrderRefund orderRefund = orderRefundMapper.selectOne(new LambdaQueryWrapper<OrderRefund>().eq(OrderRefund::getRefundSn, afterSaleOrder));
 
-            if (auditType == 2) {
-                orderRefund.setReturnMoneySts(2);
+            if (auditType == 2 || auditType == 4) {
                 orderRefund.setIsReceiver(true);
-            } else if (auditType == 4) {
-                orderRefund.setIsReceiver(true);
-                orderRefund.setReturnMoneySts(2);
+                orderRefund.setReturnMoneySts(ReturnMoneyStsType.PROCESSING.value());
             } else {
-                orderRefund.setReturnMoneySts(7);
+                orderRefund.setReturnMoneySts(ReturnMoneyStsType.REJECT.value());
                 orderRefund.setRejectMessage(bodyStr.getString("reason"));
             }
+
             orderRefundMapper.updateById(orderRefund);
 
 
@@ -1151,8 +1158,21 @@ public class OrderRefundServiceImpl extends ServiceImpl<OrderRefundMapper, Order
             Integer auditType = bodyStr.getInteger("auditType");
             Integer applyDeal = bodyStr.getInteger("applyDeal");
 
-            OrderRefund orderRefund = orderRefundMapper.selectOne(new LambdaQueryWrapper<OrderRefund>().eq(OrderRefund::getOrderNumber, channelOrderId));
 
+            OrderRefundParam orderRefundParam = new OrderRefundParam();
+            Order order = orderMapper.getOrderAndOrderItemByOrderNumber(channelOrderId);
+
+            orderRefundParam.setOrderNumber(channelOrderId);
+            orderRefundParam.setRefundType( RefundType.SINGLE.value());
+            orderRefundParam.setApplyType(1);
+            orderRefundParam.setRefundType(1);
+            orderRefundParam.setIsReceiver(false);
+            orderRefundParam.setBuyerReason("17");
+            orderRefundParam.setBuyerDesc(bodyStr.getString("reason"));
+            orderRefundParam.setBuyerMobile(order.getUserMobile());
+            orderRefundParam.setRefundAmount(order.getActualTotal());
+
+            OrderRefund orderRefund = new OrderRefund();
             if (ObjectUtil.isNotEmpty(applyDeal)) {
                 if (applyDeal == 10) {
                     orderRefund.setApplyType(1);
@@ -1161,32 +1181,42 @@ public class OrderRefundServiceImpl extends ServiceImpl<OrderRefundMapper, Order
                 }
             }
 
-            if (auditType == 2) {
-                orderRefund.setReturnMoneySts(2);
-                orderRefund.setIsReceiver(true);
-            } else if (auditType == 4) {
+            if (auditType == 2 || auditType == 4) {
                 orderRefund.setIsReceiver(true);
-                orderRefund.setReturnMoneySts(2);
+                orderRefund.setReturnMoneySts(ReturnMoneyStsType.PROCESSING.value());
             } else {
-                orderRefund.setReturnMoneySts(7);
+                orderRefund.setReturnMoneySts(ReturnMoneyStsType.REJECT.value());
                 orderRefund.setRejectMessage(bodyStr.getString("reason"));
             }
 
             JSONArray products = bodyStr.getJSONArray("products");
             log.info("部分退款接口-回调接口,products:{}", products);
+
+
+            List<OrderRefundSku> orderRefundSkuList = new ArrayList<>();
+            int goodsNum = 0;
             for (Object product : products) {
-                JSONObject productJson = (JSONObject) product;
+                JSONObject productJson = JSON.parseObject(product.toString());
+                long channelSkuId = Long.parseLong(productJson.getString("channelSkuId"));
                 OrderRefundSku orderRefundSku = new OrderRefundSku();
-                String skuId = productJson.getString("skuId");
-                orderRefundSku.setSkuId(Long.parseLong(productJson.getString("channelSkuId")));
-                orderRefundSku.setProductCount(Integer.parseInt(productJson.getString("productCount")));
-                orderRefundSkuMapper.insert(orderRefundSku);
+//                String skuId = productJson.getString("skuId");
+                skuService.getOne(new LambdaQueryWrapper<Sku>().eq(Sku::getHbSkuId, channelSkuId));
+                OrderItem orderItem = orderItemService.getOne(new LambdaQueryWrapper<OrderItem>().eq(OrderItem::getSkuId, channelSkuId)
+                        .eq(OrderItem::getOrderNumber, channelOrderId));
+
+                orderRefundSku.setSkuId(orderItem.getSkuId());
+                orderRefundSku.setOrderItemId(orderItem.getOrderItemId());
+                orderRefundSku.setSkuPrice(orderItem.getPrice());
+                int count = Integer.parseInt(productJson.getString("productCount"));
+                goodsNum += count;
+                orderRefundSku.setProductCount(count);
+                orderRefundSkuList.add(orderRefundSku);
             }
+            orderRefund.setGoodsNum(goodsNum);
+            orderRefundParam.setOrderRefundSkuList(orderRefundSkuList);
 
 
-            Order orderByOrderNumber = orderService.getById(orderRefund.getOrderId());
-            orderByOrderNumber.setRefundStatus(3);
-            orderService.updateById(orderByOrderNumber);
+            orderService.applyAgain(orderRefundParam,ReturnMoneyStsType.APPLY.value());
 
         } catch (Exception e) {
             log.error("海博退款订单查询异常:{}", e);
@@ -1204,7 +1234,7 @@ public class OrderRefundServiceImpl extends ServiceImpl<OrderRefundMapper, Order
             String afterSaleOrder = bodyStr.getString("afterSaleOrder");
 
             OrderRefund orderRefund = orderRefundMapper.selectOne(new LambdaQueryWrapper<OrderRefund>().eq(OrderRefund::getRefundSn, afterSaleOrder));
-            orderRefund.setReturnMoneySts(5);
+            orderRefund.setReturnMoneySts(ReturnMoneyStsType.SUCCESS.value());
             orderRefundMapper.updateById(orderRefund);
 
             Order orderByOrderNumber = orderService.getById(orderRefund.getOrderId());
@@ -1218,31 +1248,5 @@ public class OrderRefundServiceImpl extends ServiceImpl<OrderRefundMapper, Order
         return HBR.success();
     }
 
-    /**
-     * 系统订单状态转换为海博订单状态
-     * 退款单状态 10:待审核 20:处理中 30:驳回退款 40:撤销退款 60:待退货(一审同意) 65:待确认收货(二审待审核) 70:退款完成
-     * 处理退款状态:(1.买家申请 2.卖家接受 3.买家发货 4.卖家收货 5.退款成功 6.买家撤回申请 7.商家拒绝 -1.退款关闭)详情见ReturnMoneyStsType
-     *
-     * @param returnMoneySts 退款单状态
-     * @return HB退款单状态
-     */
-    private Integer refundHbStatus(Integer returnMoneySts) {
-        switch (returnMoneySts) {
-            case 1:
-                return 10;
-            case 2:
-                return 60;
-            case 3:
-                return 10;
-            case 4:
-                return 20;
-            case 6:
-                return 40;
-            case 7:
-                return 30;
-            case 5:
-                return 70;
-        }
-        return 10;
-    }
+
 }

+ 191 - 4
yami-shop-service/src/main/java/com/yami/shop/service/impl/OrderServiceImpl.java

@@ -15,9 +15,11 @@ import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.io.IORuntimeException;
 import cn.hutool.core.lang.Snowflake;
+import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.poi.excel.ExcelUtil;
 import cn.hutool.poi.excel.ExcelWriter;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -36,16 +38,15 @@ import com.yami.shop.common.exception.GlobalException;
 import com.yami.shop.common.exception.YamiShopBindException;
 import com.yami.shop.common.util.Arith;
 import com.yami.shop.common.util.PageAdapter;
-import com.yami.shop.dao.OrderMapper;
-import com.yami.shop.dao.OrderRefundMapper;
-import com.yami.shop.dao.ProductMapper;
-import com.yami.shop.dao.SkuMapper;
+import com.yami.shop.dao.*;
 import com.yami.shop.service.OrderItemService;
 import com.yami.shop.service.OrderRefundService;
 import com.yami.shop.service.OrderService;
 import com.yami.shop.service.OrderSettlementService;
 import com.yami.shop.service.hb.IHBOrderService;
+import com.yami.shop.utils.CullenUtils;
 import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.poi.ss.usermodel.Sheet;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -61,12 +62,14 @@ import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletResponse;
 import javax.validation.Valid;
 import java.io.IOException;
+import java.time.Instant;
 import java.util.*;
 import java.util.stream.Collectors;
 
 /**
  * @author lgh on 2018/09/15.
  */
+@Slf4j
 @Service
 @AllArgsConstructor
 public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
@@ -88,6 +91,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
     private Snowflake snowflake;
 
 
+    private final OrderRefundSkuMapper orderRefundSkuMapper;
 
 
     @Override
@@ -735,4 +739,187 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
             }
         }
     }
+
+
+    /**
+     * 生成退款单 请求
+     *
+     * @param orderRefundParam 退款单数据
+     * @return rReturnMoneySts
+     */
+    @Override
+    public String applyAgain(OrderRefundParam orderRefundParam, Integer rReturnMoneySts) {
+        log.info(" 海博申请退款参数:{}", JSONObject.toJSONString(orderRefundParam));
+        List<OrderRefundSku> orderRefundSkuList = orderRefundParam.getOrderRefundSkuList();
+
+        Order order = orderMapper.getOrderAndOrderItemByOrderNumber(orderRefundParam.getOrderNumber());
+
+        if (!Objects.equals(order.getIsPayed(), 1)) {
+            throw new GlobalException("当前订单还未付款,无法申请");
+        }
+
+
+        if (Objects.equals(orderRefundParam.getRefundType(), RefundType.ALL.value()) && (!Objects.isNull(order.getRefundStatus()) && !Objects.equals(order.getRefundStatus(), RefundStatusEnum.DISAGREE.value()))) {
+            throw new GlobalException("该订单已有商品正在退款中,不能再进行整单退款");
+        }
+
+        OrderRefund newOrderRefund = new OrderRefund();
+
+        // 获取所有正在进行中的退款订单
+        List<OrderRefund> orderRefunds = orderRefundMapper.getProcessingOrderRefundByOrderId(order.getOrderId());
+
+        for (OrderRefund orderRefund : orderRefunds) {
+            if (Objects.equals(RefundType.ALL.value(), orderRefund.getRefundType())) {
+                throw new GlobalException("该订单正在进行整单退款,无法进行新的退款操作");
+            }
+
+//            if (Objects.equals(orderRefund.getOrderItemId(), orderRefundParam.getOrderItemId())) {
+//                throw new GlobalException("该商品正在进行退款中,无法进行新的退款操作");
+//            }
+        }
+
+        // 如果存在分销订单,则计算分销总金额
+        List<OrderItem> orderItemList = orderItemService.getOrderItemsByOrderNumber(order.getOrderNumber());
+        // 判断退款单类型(1:整单退款,2:单个物品退款)
+
+
+        //TODO 待处理 全部和部分退款积分问题
+        if (orderRefundParam.getRefundType().equals(RefundType.ALL.value())) {
+            // 全部物品退款
+            // 计算该订单项的分销金额
+            newOrderRefund.setDistributionTotalAmount(sumTotalDistributionAmountByOrderItem(orderItemList));
+            // 计算平台退款金额(退款时将这部分钱退回给平台,所以商家要扣除从平台这里获取的金额)
+            newOrderRefund.setPlatformRefundAmount(order.getPlatformAmount());
+            newOrderRefund.setOrderItemId(0L);
+        } else {
+            CullenUtils.validateDataThrowException(orderRefundSkuList.isEmpty(), "退款商品不能为空...");
+            // 部分物品退款
+            OrderItem orderItem = orderItemService.getOne(new LambdaQueryWrapper<OrderItem>()
+                    .eq(OrderItem::getOrderNumber, orderRefundParam.getOrderNumber()));
+            if (orderItem == null) {
+                throw new GlobalException("该物品在订单中不存在");
+            }
+            boolean isCanRefund = false;
+            //  查看是否有支付金额和积分都为空的订单,有则抛出异常
+            for (OrderItem item : orderItemList) {
+                if (item.getActualTotal() <= 0.0 && item.getUseScore() <= 0.0) {
+                    isCanRefund = true;
+                    break;
+                }
+            }
+            if (isCanRefund) {
+                throw new GlobalException("该订单部分订单项支付金额和积分为0,无法使用部分退款!");
+            }
+
+            // 计算该订单项的分销金额
+            newOrderRefund.setDistributionTotalAmount(sumTotalDistributionAmountByOrderItem(Collections.singletonList(orderItem)));
+
+            // 计算平台退款金额(退款时将这部分钱退回给平台,所以商家要扣除从平台这里获取的金额)
+            newOrderRefund.setPlatformRefundAmount(orderItem.getPlatformShareReduce());
+
+            // 退款物品数量为null或者0时,则为退款全部数量
+            if (orderRefundParam.getGoodsNum() <= 0) {
+                orderRefundParam.setGoodsNum(orderItem.getProdCount());
+            }
+
+            // 判断退款数量是否溢出
+            if (orderRefundParam.getGoodsNum() > orderItem.getProdCount()) {
+                throw new GlobalException("退款物品数量已超出订单中的数量,不允许申请");
+            }
+
+            // 判断退款金额是否超出订单金额
+            double refundSingleAmount = Arith.div(orderRefundParam.getRefundAmount(), orderRefundParam.getGoodsNum(), 3);
+            double singleAmount = Arith.div(orderItem.getActualTotal(), orderItem.getProdCount(), 3);
+            if (refundSingleAmount > orderItem.getProductTotalAmount() || refundSingleAmount > singleAmount) {
+                throw new GlobalException("退款金额已超出订单金额,无法申请");
+            }
+
+            // 待发货状态-最后一件商品进行退款,退款金额 =  商品金额 + 订单运费金额
+            if (Objects.equals(order.getHbOrderStatus(), OrderStatus.PADYED.value()) && order.getFreightAmount() > 0) {
+                int orderItenCount = orderItemService.count(new LambdaQueryWrapper<OrderItem>().eq(OrderItem::getOrderNumber, order.getOrderNumber()));
+                if (Objects.equals(orderRefunds.size(), orderItenCount - 1)) {
+                    newOrderRefund.setRefundAmount(Arith.add(newOrderRefund.getRefundAmount(), order.getFreightAmount()));
+                }
+            }
+        }
+
+        newOrderRefund.setShopId(order.getShopId());
+        newOrderRefund.setUserId(order.getUserId());
+        newOrderRefund.setOrderId(order.getOrderId());
+        newOrderRefund.setOrderNumber(order.getOrderNumber());
+        newOrderRefund.setRefundSn(String.valueOf(snowflake.nextId()));
+        newOrderRefund.setRefundType(orderRefundParam.getRefundType());
+        newOrderRefund.setRefundAmount(orderRefundParam.getRefundAmount());
+
+
+        newOrderRefund.setGoodsNum(orderRefundParam.getGoodsNum());
+        newOrderRefund.setApplyType(orderRefundParam.getApplyType());
+        if (Objects.equals(orderRefundParam.getApplyType(), 2)) {
+            newOrderRefund.setIsReceiver(true);
+        } else {
+            newOrderRefund.setIsReceiver(orderRefundParam.getIsReceiver());
+        }
+        newOrderRefund.setBuyerReason(orderRefundParam.getBuyerReason());
+        newOrderRefund.setBuyerDesc(orderRefundParam.getBuyerDesc());
+        newOrderRefund.setBuyerMobile(orderRefundParam.getBuyerMobile());
+        newOrderRefund.setPhotoFiles(orderRefundParam.getPhotoFiles());
+        newOrderRefund.setReturnMoneySts(rReturnMoneySts);
+        newOrderRefund.setApplyTime(new Date());
+        newOrderRefund.setUpdateTime(new Date());
+        log.info("生成退款单:{}", newOrderRefund);
+
+
+        // 生成退款单
+        orderRefundMapper.insert(newOrderRefund);
+        // 更新订单状态
+        Integer refundType = newOrderRefund.getRefundType();
+        if (Objects.equals(refundType, RefundType.ALL.value())) {
+            order.setRefundStatus(RefundStatusEnum.APPLY.value());
+        } else {
+            order.setRefundStatus(RefundStatusEnum.PARTIAL_SUCCESS.value());
+        }
+        orderMapper.updateById(order);
+
+        if (ObjectUtil.isNotEmpty(orderRefundSkuList)) {
+            orderRefundSkuList.forEach(c -> {
+                c.setOrderRefundId(newOrderRefund.getRefundId());
+                orderRefundSkuMapper.insert(c);
+            });
+        }
+        return newOrderRefund.getRefundSn();
+    }
+
+
+    /**
+     * 退货退款
+     */
+    private void returnRefund(String orderNumber) {
+        Order order = orderMapper.selectOne(new LambdaQueryWrapper<Order>()
+                .eq(Order::getOrderNumber, orderNumber)
+                .in(Order::getHbOrderStatus, List.of(OrderStatus.CONSIGNMENT.value(), OrderStatus.SUCCESS.value()))
+        );
+        if (null != order) {
+            //判定已完成的时间
+            if (Objects.equals(order.getHbOrderStatus(), OrderStatus.SUCCESS.value()) && isPaymentOver7Days(order.getPayTime())) {
+                throw new GlobalException("支付完成已经超过7天,不支持退款");
+            }
+            //可以直接退积分或者是钱
+            if (order.getActualTotal() > 0) {
+                //退,微信支付
+            } else {
+                //退,积分
+            }
+        }
+    }
+
+    private boolean isPaymentOver7Days(Date paymentDate) {
+        // 1. 将支付时间转换为 Instant
+        Instant paymentInstant = paymentDate.toInstant();
+        // 2. 增加 7 天(精确到毫秒,考虑时区)
+        Instant expirationInstant = paymentInstant.plus(7, java.time.temporal.ChronoUnit.DAYS);
+        // 3. 获取当前时间
+        Instant nowInstant = Instant.now();
+        // 4. 比较时间
+        return nowInstant.isAfter(expirationInstant) || nowInstant.equals(expirationInstant);
+    }
 }