From ef66972437dce1d459409415add4f08f1c1629c8 Mon Sep 17 00:00:00 2001
From: phpcjl <phpcjl@gmail.com>
Date: 星期二, 03 十二月 2024 16:07:18 +0800
Subject: [PATCH] 1.分佣延迟队列

---
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/CommissionServiceImpl.java           |  111 +++++++++++++++++++++++++++
 ruoyi-api/ruoyi-api-order/src/main/java/model/Order.java                                                  |    4 +
 ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserClientFallbackFactory.java |   10 ++
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/AppUserServiceImpl.java          |   39 +++++++++
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/OrderService.java                         |    2 
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java                |   17 +---
 ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/task/AfterSalesTask.java                              |   19 ++--
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/AppUserController.java             |    9 ++
 ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/AppUserService.java                   |    5 +
 ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/AppUserClient.java            |    6 +
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/CommissionService.java                    |   12 +++
 11 files changed, 210 insertions(+), 24 deletions(-)

diff --git a/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserClientFallbackFactory.java b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserClientFallbackFactory.java
index 050669a..76ed1fd 100644
--- a/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserClientFallbackFactory.java
+++ b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserClientFallbackFactory.java
@@ -6,6 +6,7 @@
 import com.ruoyi.common.core.domain.R;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.web.bind.annotation.PostMapping;
 
 import java.util.List;
 
@@ -22,7 +23,8 @@
 	public AppUserClient create(Throwable cause) {
 		
 		return new AppUserClient() {
-			@Override
+			@PostMapping("/appUser/getAppUserById")
+            @Override
 			public AppUser getAppUserById(Long id) {
                 log.error("根据id获取用户失败:{}", cause.getMessage());
 				throw new RuntimeException("根据id获取用户失败");
@@ -45,6 +47,12 @@
 				log.error("获取用户门店信息失败:{}", cause.getMessage());
 				throw new RuntimeException("获取用户门店信息失败");
 			}
+
+			@Override
+			public R<List<AppUser>> getUserAncestorList(Long id) {
+				log.error("获取用户祖籍列表失败:{}", cause.getMessage());
+				throw new RuntimeException("获取用户祖籍列表失败");
+			}
 		};
 	}
 }
diff --git a/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/AppUserClient.java b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/AppUserClient.java
index 57e4ac5..3d49960 100644
--- a/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/AppUserClient.java
+++ b/ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/AppUserClient.java
@@ -43,4 +43,10 @@
 	@GetMapping("/appUserShop/shop/{userId}")
 	R<List<AppUserShop>> getAppUserShop(@PathVariable("userId") Long userId);
 
+	/**
+	 * 根据用户id获取用户的祖籍列表
+	 */
+	@GetMapping("/appletLogin/getUserAncestorList")
+	R<List<AppUser>> getUserAncestorList(@RequestParam("id") Long id);
+
 }
diff --git a/ruoyi-api/ruoyi-api-order/src/main/java/model/Order.java b/ruoyi-api/ruoyi-api-order/src/main/java/model/Order.java
index adccbf4..bbb2401 100644
--- a/ruoyi-api/ruoyi-api-order/src/main/java/model/Order.java
+++ b/ruoyi-api/ruoyi-api-order/src/main/java/model/Order.java
@@ -44,6 +44,10 @@
     @TableField("order_status")
     private Integer orderStatus;
 
+    @ApiModelProperty(value = "是否已分佣: 0-否 1-是")
+    @TableField("is_commission")
+    private Integer isCommission;
+
     @ApiModelProperty(value = "核销时间")
     @TableField("end_time")
     private LocalDateTime endTime;
diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/task/AfterSalesTask.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/task/AfterSalesTask.java
index ab84d57..f6915f7 100644
--- a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/task/AfterSalesTask.java
+++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/task/AfterSalesTask.java
@@ -14,7 +14,7 @@
     private RedisTemplate<String, String> redisTemplate;
 
     /**
-     * 计算佣金
+     * 计算佣金(设置每分钟执行一次)
      */
     public void afterSales()
     {
@@ -22,15 +22,18 @@
         // 从延迟队列中获取需要处理的订单
         Set<String> orderIds = redisTemplate.opsForZSet().rangeByScore("delay_queue:commission", 0, now);
         if (orderIds != null && !orderIds.isEmpty()) {
-            for (String orderId : orderIds) {
-                try {
-                    Long id = Long.parseLong(orderId);
-                } catch (NumberFormatException e) {
-                    log.error("延迟队列中的订单ID无效: {}", orderId, e);
-                }
-            }
             // 处理完后移除已处理的订单
             redisTemplate.opsForZSet().removeRangeByScore("delay_queue:commission", 0, now);
         }
     }
+
+    /**
+     * 佣金补偿(每天执行一次)
+     * redis未配置持久化,为防止数据丢失,每天执行一次,将到期未处理的订单重新放入延迟队列中
+     */
+    public void afterSalesCompensation()
+    {
+        // 获取未处理的订单
+
+    }
 }
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/AppUserController.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/AppUserController.java
index f627213..2664471 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/AppUserController.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/AppUserController.java
@@ -185,6 +185,15 @@
 
 	}
 
+	/**
+	 * 获取用户的祖籍列表
+	 */
+	@GetMapping("/getUserAncestorList")
+	public R<List<AppUser>> getUserAncestorList(Long id){
+		List<AppUser> list = appUserService.getUserAncestorList(id,null);
+		return R.ok(list);
+	}
+
 
 
 }
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/AppUserService.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/AppUserService.java
index 96f9fec..a313542 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/AppUserService.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/AppUserService.java
@@ -57,4 +57,9 @@
 	 * @return
 	 */
 	List<NearbyReferrerVo> getNearbyReferrer(NearbyReferrer nearbyReferrer);
+
+	/**
+	 * 获取用户的祖籍列表
+	 */
+	List<AppUser> getUserAncestorList(Long id,List<AppUser> list);
 }
diff --git a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/AppUserServiceImpl.java b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/AppUserServiceImpl.java
index bfb01d7..535e9dd 100644
--- a/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/AppUserServiceImpl.java
+++ b/ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/service/impl/AppUserServiceImpl.java
@@ -18,14 +18,13 @@
 import com.ruoyi.system.api.domain.SysUser;
 import com.ruoyi.system.api.feignClient.SysUserClient;
 import com.ruoyi.system.api.model.LoginUser;
+import org.checkerframework.checker.units.qual.A;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 /**
  * <p>
@@ -330,4 +329,38 @@
 		List<NearbyReferrerVo> list = this.baseMapper.getNearbyReferrer(cityCode, nearbyReferrer);
 		return list;
 	}
+
+	@Override
+	public List<AppUser> getUserAncestorList(Long id, List<AppUser> list) {
+		if (list == null) {
+			list = new ArrayList<>();
+		}
+
+		Set<Long> visitedIds = new HashSet<>();
+		Long currentId = id;
+
+		while (currentId != null && !visitedIds.contains(currentId)) {
+			AppUser appUser = getById(currentId);
+			if (appUser == null) {
+				break; // 如果用户不存在,终止循环
+			}
+
+			Long inviteUserId = appUser.getInviteUserId();
+			if (inviteUserId != null) {
+				AppUser invitedUser = getById(inviteUserId);
+				if (invitedUser != null) {
+					list.add(invitedUser);
+					visitedIds.add(currentId);
+					currentId = inviteUserId;
+				} else {
+					break; // 如果邀请用户不存在,终止循环
+				}
+			} else {
+				break; // 如果没有邀请用户,终止循环
+			}
+		}
+
+		return list;
+	}
+
 }
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/CommissionService.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/CommissionService.java
new file mode 100644
index 0000000..da99507
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/CommissionService.java
@@ -0,0 +1,12 @@
+package com.ruoyi.order.service;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+public interface CommissionService {
+
+    // 计算佣金
+    void calculationCommission(List<Long> orderIds);
+
+    void addToCommissionDelayQueue(Long orderId, LocalDateTime afterSalesDeadline);
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/OrderService.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/OrderService.java
index 60fda94..aa5038b 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/OrderService.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/OrderService.java
@@ -23,4 +23,6 @@
     boolean check(Order order, Integer shopId, Long userId);
 
     void writeOff(String code,Integer shopId);
+
+    void commission(Long orderId);
 }
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/CommissionServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/CommissionServiceImpl.java
new file mode 100644
index 0000000..d8fa0ef
--- /dev/null
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/CommissionServiceImpl.java
@@ -0,0 +1,111 @@
+package com.ruoyi.order.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.ruoyi.account.api.feignClient.AppUserClient;
+import com.ruoyi.account.api.model.AppUser;
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.order.service.CommissionService;
+import com.ruoyi.order.service.OrderGoodService;
+import com.ruoyi.order.service.OrderService;
+import com.ruoyi.other.api.domain.Shop;
+import com.ruoyi.other.api.feignClient.ShopClient;
+import model.Order;
+import model.OrderGood;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Service
+public class CommissionServiceImpl implements CommissionService {
+    @Resource
+    private OrderService orderService;
+    @Resource
+    private OrderGoodService orderGoodService;
+    @Resource
+    private AppUserClient appUserClient;
+    @Resource
+    private ShopClient shopClient;
+    @Resource
+    private RedisTemplate<String, String> redisTemplate;
+
+    /**
+     * 返佣延迟队列(redis有序集合)
+     *
+     * @param orderId           订单ID
+     * @param afterSalesDeadline 售后截止日期(计算日期)
+     */
+    @Override
+    public void addToCommissionDelayQueue(Long orderId, LocalDateTime afterSalesDeadline) {
+        // 获取订单售后截止日期时间戳(秒)
+        long deadlineTimestamp = afterSalesDeadline.atZone(ZoneId.systemDefault()).toEpochSecond();
+        redisTemplate.opsForZSet().add("delay_queue:commission", orderId.toString(), deadlineTimestamp);
+    }
+
+    @Override
+    public void calculationCommission(List<Long> orderIds) {
+        List<OrderGood> orderGoods = orderGoodService.list(new LambdaQueryWrapper<OrderGood>()
+                .in(OrderGood::getOrderId, orderIds));
+
+        Map<Long, List<OrderGood>> ogMap = orderGoods.stream().collect(Collectors.groupingBy(OrderGood::getOrderId));
+
+        for (Map.Entry<Long, List<OrderGood>> entry : ogMap.entrySet()) {
+            Long k = entry.getKey();
+            List<OrderGood> v = entry.getValue();
+            Order order = orderService.getById(k);
+            if (order.getIsCommission() == 1) {
+                continue;
+            }
+            R<Shop> r = shopClient.getShopById(order.getShopId());
+            if (!R.isSuccess(r)) {
+                throw new RuntimeException("获取门店信息失败");
+            }
+            Shop shop = r.getData();
+            if (shop == null) {
+                throw new RuntimeException("获取门店信息失败");
+            }
+
+            Long appUserId = order.getAppUserId();
+            AppUser appUser = appUserClient.getAppUserById(appUserId);
+            if (appUser == null) {
+                throw new RuntimeException("获取用户信息失败");
+            }
+            Long inviteUserId = appUser.getInviteUserId();
+            AppUser inviteUser = appUserClient.getAppUserById(inviteUserId);
+
+            for (OrderGood og : v) {// 累计分销金额
+
+                // 上级分销金额
+                if (inviteUser != null){
+                    BigDecimal superiorSubcommission = og.getSuperiorSubcommission();
+                    BigDecimal totalDistributionAmount = inviteUser.getTotalDistributionAmount();
+                    totalDistributionAmount = totalDistributionAmount.add(superiorSubcommission);
+                    //
+                    Integer superiorType = og.getSuperiorType();
+                    Integer sharePoint = inviteUser.getSharePoint();
+                    if (superiorType == 1) {
+                        Integer superiorRebatePoints = og.getSuperiorRebatePoints();
+                        sharePoint = sharePoint + superiorRebatePoints;
+                    } else if (superiorType == 2) {
+
+                    } else {
+                        continue;
+                    }
+                    inviteUser.setTotalDistributionAmount(totalDistributionAmount);
+                    inviteUser.setSharePoint(sharePoint);
+                }
+
+                // 门店分销金额
+                og.getBoundShopCharges()
+            }
+        }
+
+
+    }
+}
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java
index d31cc5b..9cbcdc4 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java
@@ -57,8 +57,7 @@
     private TokenService tokenService;
     @Resource
     private TechnicianClient technicianClient;
-    @Resource
-    private RedisTemplate<String, String> redisTemplate;
+
 
     @Override
     public List<OrderVO> selectOrderListByUserId(Integer status, Long userId) {
@@ -191,15 +190,9 @@
     }
 
 
-    /**
-     * 返佣延迟队列
-     *
-     * @param orderId           订单ID
-     * @param afterSalesDeadline 售后截止日期(计算日期)
-     */
-    private void addToCommissionDelayQueue(Long orderId, LocalDateTime afterSalesDeadline) {
-        // 获取订单售后截止日期时间戳(秒)
-        long deadlineTimestamp = afterSalesDeadline.atZone(ZoneId.systemDefault()).toEpochSecond();
-        redisTemplate.opsForZSet().add("delay_queue:commission", orderId.toString(), deadlineTimestamp);
+
+    @Override
+    public void commission(Long orderId) {
+
     }
 }

--
Gitblit v1.7.1