Преглед изворни кода

chore: auto bump version and changelog [skip ci]

iwt пре 11 часа
родитељ
комит
1382d9ee3a

+ 169 - 0
cfc-backend/src/main/java/com/etotem/cfc/service/CommissionService.java

@@ -978,6 +978,175 @@ public class CommissionService {
         return funnel;
     }
 
+/**
+     * 获取团队成长曲线数据(按注册时间分段的成员数量)
+     */
+    public Map<String, Object> getTeamGrowthCurve(Long userId, Integer months) {
+        if (months == null || months <= 0) months = 12;
+        if (months > 36) months = 36;
+
+        Map<String, Object> result = new LinkedHashMap<>();
+        List<String> labels = new ArrayList<>();
+        List<Integer> data = new ArrayList<>();
+
+        Date now = new Date();
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(now);
+        calendar.add(Calendar.MONTH, -months + 1);
+        Date startMonth = calendar.getTime();
+
+        Map<Long, Integer> monthCountMap = new LinkedHashMap<>();
+        for (int i = 0; i < months; i++) {
+            Calendar c = Calendar.getInstance();
+            c.setTime(startMonth);
+            c.add(Calendar.MONTH, i);
+            int dayOfMonth = c.getActualMinimum(Calendar.DAY_OF_MONTH);
+            int lastDayOfMonth = c.getActualMaximum(Calendar.DAY_OF_MONTH);
+            long monthBegin = dayOfMonth * 24 * 60 * 60 * 1000;
+            long monthLast = lastDayOfMonth * 24 * 60 * 60 * 1000;
+
+            LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
+                    .ge(User::getCreatedAt, monthBegin)
+                    .le(User::getCreatedAt, monthLast)
+                    .eq(User::getReferrerId, userId);
+            int count = userMapper.selectCount(wrapper);
+            monthCountMap.put((long) i, count);
+        }
+
+        for (int i = 0; i < months; i++) {
+            Calendar labelCal = Calendar.getInstance();
+            labelCal.setTime(startMonth);
+            labelCal.add(Calendar.MONTH, i);
+            int year = labelCal.get(Calendar.YEAR);
+            int month = labelCal.get(Calendar.MONTH) + 1;
+            labels.add(year + "-" + String.format("%02d", month));
+            data.add(monthCountMap.getOrDefault((long) i, 0));
+        }
+
+        result.put("labels", labels);
+        result.put("data", data);
+        return result;
+    }
+
+    /**
+     * 获取团队所有成员消费曲线数据(按月份统计成员消费总额)
+     */
+    public Map<String, Object> getTeamAllMembersConsumptionCurve(Long userId, Integer months) {
+        if (months == null || months <= 0) months = 12;
+        if (months > 36) months = 36;
+
+        Map<String, Object> result = new LinkedHashMap<>();
+        List<String> labels = new ArrayList<>();
+        List<Integer> data = new ArrayList<>();
+
+        Date now = new Date();
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(now);
+        calendar.add(Calendar.MONTH, -months + 1);
+        Date startMonth = calendar.getTime();
+
+        // 获取所有团队成员buyerId
+        List<Long> memberIds = new ArrayList<>();
+        LambdaQueryWrapper<ReferralTree> treeWrapper = new LambdaQueryWrapper<ReferralTree>()
+                .eq(ReferralTree::getParentId, userId);
+        List<ReferralTree> trees = referralTreeMapper.selectList(treeWrapper);
+        for (ReferralTree tree : trees) {
+            if (tree.getChildId() != null) {
+                memberIds.add(tree.getChildId());
+            }
+        }
+
+        Map<Long, Integer> monthConsumptionMap = new LinkedHashMap<>();
+        for (int i = 0; i < months; i++) {
+            Calendar c = Calendar.getInstance();
+            c.setTime(startMonth);
+            c.add(Calendar.MONTH, i);
+            int dayOfMonth = c.getActualMinimum(Calendar.DAY_OF_MONTH);
+            int lastDayOfMonth = c.getActualMaximum(Calendar.DAY_OF_MONTH);
+            long monthBegin = dayOfMonth * 24 * 60 * 60 * 1000;
+            long monthLast = lastDayOfMonth * 24 * 60 * 60 * 1000;
+
+            LambdaQueryWrapper<ProductOrder> wrapper = new LambdaQueryWrapper<ProductOrder>()
+                    .ge(ProductOrder::getCreatedAt, monthBegin)
+                    .le(ProductOrder::getCreatedAt, monthLast)
+                    .eq(ProductOrder::getFulfillStatus, "completed");
+            if (!memberIds.isEmpty()) {
+                wrapper.in(ProductOrder::getBuyerId, memberIds);
+            }
+            int sum = productOrderMapper.selectList(wrapper).stream()
+                    .mapToLong(o -> o.getTotalAmount() != null ? o.getTotalAmount() : 0)
+                    .sum();
+            monthConsumptionMap.put((long) i, sum);
+        }
+
+        for (int i = 0; i < months; i++) {
+            Calendar labelCal = Calendar.getInstance();
+            labelCal.setTime(startMonth);
+            labelCal.add(Calendar.MONTH, i);
+            int year = labelCal.get(Calendar.YEAR);
+            int month = labelCal.get(Calendar.MONTH) + 1;
+            labels.add(year + "-" + String.format("%02d", month));
+            data.add(monthConsumptionMap.getOrDefault((long) i, 0));
+        }
+
+        result.put("labels", labels);
+        result.put("data", data);
+        return result;
+    }
+
+    /**
+     * 获取直推团队(L1)消费曲线数据(按月份统计L1成员消费总额)
+     */
+    public Map<String, Object> getTeamL1ConsumptionCurve(Long userId, Integer months) {
+        if (months == null || months <= 0) months = 12;
+        if (months > 36) months = 36;
+
+        Map<String, Object> result = new LinkedHashMap<>();
+        List<String> labels = new ArrayList<>();
+        List<Integer> data = new ArrayList<>();
+
+        Date now = new Date();
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(now);
+        calendar.add(Calendar.MONTH, -months + 1);
+        Date startMonth = calendar.getTime();
+
+        Map<Long, Integer> monthL1ConsumptionMap = new LinkedHashMap<>();
+        for (int i = 0; i < months; i++) {
+            Calendar c = Calendar.getInstance();
+            c.setTime(startMonth);
+            c.add(Calendar.MONTH, i);
+            int dayOfMonth = c.getActualMinimum(Calendar.DAY_OF_MONTH);
+            int lastDayOfMonth = c.getActualMaximum(Calendar.DAY_OF_MONTH);
+            long monthBegin = dayOfMonth * 24 * 60 * 60 * 1000;
+            long monthLast = lastDayOfMonth * 24 * 60 * 60 * 1000;
+
+            LambdaQueryWrapper<ProductOrder> wrapper = new LambdaQueryWrapper<ProductOrder>()
+                    .ge(ProductOrder::getCreatedAt, monthBegin)
+                    .le(ProductOrder::getCreatedAt, monthLast)
+                    .eq(ProductOrder::getFulfillStatus, "completed")
+                    .eq(ProductOrder::getReferrerId, userId);
+            int sum = productOrderMapper.selectList(wrapper).stream()
+                    .mapToLong(o -> o.getTotalAmount() != null ? o.getTotalAmount() : 0)
+                    .sum();
+            monthL1ConsumptionMap.put((long) i, sum);
+        }
+
+        for (int i = 0; i < months; i++) {
+            Calendar labelCal = Calendar.getInstance();
+            labelCal.setTime(startMonth);
+            labelCal.add(Calendar.MONTH, i);
+            int year = labelCal.get(Calendar.YEAR);
+            int month = labelCal.get(Calendar.MONTH) + 1;
+            labels.add(year + "-" + String.format("%02d", month));
+            data.add(monthL1ConsumptionMap.getOrDefault((long) i, 0));
+        }
+
+        result.put("labels", labels);
+        result.put("data", data);
+        return result;
+    }
+
     private String generateReferralCode(Long userId) {
         String chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
         Random random = new Random();

+ 1 - 1
cfc-web/.last_build_commit

@@ -1 +1 @@
-7bd0b8de977d1e206619ce7142700c6d06e7cfd2
+01f6f6483765275b413ca0ec19966acb405a13bf

+ 2 - 2
cfc-web/package-lock.json

@@ -1,12 +1,12 @@
 {
   "name": "cfc-web",
-  "version": "1.0.1472",
+  "version": "1.0.1473",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "cfc-web",
-      "version": "1.0.1472",
+      "version": "1.0.1473",
       "dependencies": {
         "@wangeditor/editor": "^5.1.23",
         "@wangeditor/editor-for-vue": "^1.0.2",

+ 1 - 1
cfc-web/package.json

@@ -1,6 +1,6 @@
 {
   "name": "cfc-web",
-  "version": "1.0.1473",
+  "version": "1.0.1474",
   "private": true,
   "scripts": {
     "dev": "vue-cli-service serve",

+ 7 - 0
cfc-web/public/CHANGELOG-v1.0.md

@@ -4,6 +4,13 @@
 
 ---
 
+## v1.0.1474 (2026-09-27)
+
+### 新功能
+- 更新益生元相关文章,引用瓜尔豆胶vs菊粉新内容
+- 新增瓜尔豆胶 vs 菊粉科普文章 - sales/guar-vs-inulin.html:新增益生元对比科普页,8维对比表、适用人群分析、组合方案、科学循证 - sales/index.html:更新分类计数、快速跳转链接、meta description - sales/AGENTS.md:目录结构和文章清单更新
+
+
 ## v1.0.1473 (2026-09-24)
 
 ### 新功能

+ 8 - 1
cfc-web/public/CHANGELOG.md

@@ -1,6 +1,6 @@
 # 更新日志
 
-> 当前版本: v1.0.1473
+> 当前版本: v1.0.1474
 
 ## 历史版本
 
@@ -8,6 +8,13 @@
 
 ---
 
+## v1.0.1474 (2026-09-27)
+
+### 新功能
+- 更新益生元相关文章,引用瓜尔豆胶vs菊粉新内容
+- 新增瓜尔豆胶 vs 菊粉科普文章 - sales/guar-vs-inulin.html:新增益生元对比科普页,8维对比表、适用人群分析、组合方案、科学循证 - sales/index.html:更新分类计数、快速跳转链接、meta description - sales/AGENTS.md:目录结构和文章清单更新
+
+
 ## v1.0.1473 (2026-09-24)
 
 ### 新功能