|
|
@@ -6,8 +6,10 @@ import com.etotem.cfc.dto.CommissionSummaryDTO;
|
|
|
import com.etotem.cfc.dto.ReferralSummaryDTO;
|
|
|
import com.etotem.cfc.entity.CommissionRecord;
|
|
|
import com.etotem.cfc.entity.Product;
|
|
|
+import com.etotem.cfc.entity.ProductOrder;
|
|
|
import com.etotem.cfc.entity.PromotionTier;
|
|
|
import com.etotem.cfc.entity.PromotionTierConfig;
|
|
|
+import com.etotem.cfc.entity.ReferralTree;
|
|
|
import com.etotem.cfc.entity.User;
|
|
|
import com.etotem.cfc.entity.WithdrawalRequest;
|
|
|
import com.etotem.cfc.mapper.CommissionRecordMapper;
|
|
|
@@ -606,6 +608,70 @@ public class CommissionService {
|
|
|
return stats;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 团队总消费额分级汇总(按 referral_tree level 聚合)
|
|
|
+ * maxLevel 默认 3,可后台配置
|
|
|
+ */
|
|
|
+ public Map<String, Object> getTeamConsumption(Long userId, Integer maxLevel) {
|
|
|
+ if (maxLevel == null || maxLevel <= 0) maxLevel = 3;
|
|
|
+ if (maxLevel > 10) maxLevel = 10; // 安全上限
|
|
|
+
|
|
|
+ Map<String, Object> result = new LinkedHashMap<>();
|
|
|
+ List<Map<String, Object>> levelBreakdown = new ArrayList<>();
|
|
|
+
|
|
|
+ // 1. 查 referral_tree: parentId = userId 且 level <= maxLevel
|
|
|
+ List<ReferralTree> treeNodes = referralTreeMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<ReferralTree>()
|
|
|
+ .eq(ReferralTree::getParentId, userId)
|
|
|
+ .le(ReferralTree::getLevel, maxLevel)
|
|
|
+ .orderByAsc(ReferralTree::getLevel)
|
|
|
+ );
|
|
|
+
|
|
|
+ if (treeNodes.isEmpty()) {
|
|
|
+ result.put("totalConsumption", 0);
|
|
|
+ result.put("levelBreakdown", levelBreakdown);
|
|
|
+ result.put("totalMembers", 0);
|
|
|
+ result.put("maxLevel", maxLevel);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 按 level 分组收集 childId
|
|
|
+ Map<Integer, List<Long>> levelToChildIds = new LinkedHashMap<>();
|
|
|
+ for (ReferralTree node : treeNodes) {
|
|
|
+ levelToChildIds.computeIfAbsent(node.getLevel(), k -> new ArrayList<>()).add(node.getChildId());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 查 product_orders: buyerId IN childIds 且 fulfillStatus = 'completed'
|
|
|
+ int totalConsumption = 0;
|
|
|
+ for (Map.Entry<Integer, List<Long>> entry : levelToChildIds.entrySet()) {
|
|
|
+ Integer level = entry.getKey();
|
|
|
+ List<Long> childIds = entry.getValue();
|
|
|
+ if (childIds.isEmpty()) continue;
|
|
|
+
|
|
|
+ LambdaQueryWrapper<ProductOrder> orderWrapper = new LambdaQueryWrapper<ProductOrder>()
|
|
|
+ .in(ProductOrder::getBuyerId, childIds)
|
|
|
+ .eq(ProductOrder::getFulfillStatus, "completed");
|
|
|
+ Long sum = productOrderMapper.selectList(orderWrapper).stream()
|
|
|
+ .mapToLong(o -> o.getTotalAmount() != null ? o.getTotalAmount() : 0)
|
|
|
+ .sum();
|
|
|
+
|
|
|
+ int memberCount = childIds.size();
|
|
|
+ totalConsumption += sum;
|
|
|
+
|
|
|
+ Map<String, Object> levelInfo = new LinkedHashMap<>();
|
|
|
+ levelInfo.put("level", level);
|
|
|
+ levelInfo.put("memberCount", memberCount);
|
|
|
+ levelInfo.put("consumption", sum.intValue());
|
|
|
+ levelBreakdown.add(levelInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ result.put("totalConsumption", totalConsumption);
|
|
|
+ result.put("levelBreakdown", levelBreakdown);
|
|
|
+ result.put("totalMembers", treeNodes.size());
|
|
|
+ result.put("maxLevel", maxLevel);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 获取佣金统计(首页面板数据)
|
|
|
*/
|