Jelajahi Sumber

feat: 新增LifetimeStatsMapper消费/销售滚动365天聚合查询

Xiaogang Liao 1 bulan lalu
induk
melakukan
4ab3d9552c

+ 62 - 0
cfc-backend/src/main/java/com/etotem/cfc/mapper/LifetimeStatsMapper.java

@@ -0,0 +1,62 @@
+package com.etotem.cfc.mapper;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 终身会员达标统计(滚动365天,仅 paid 订单)
+ */
+@Mapper
+public interface LifetimeStatsMapper {
+
+    /**
+     * 每用户消费总额(365天窗口,paid 订单,按用户聚合)
+     * 返回 List<Map>: {userId, totalAmount}
+     */
+    @Select("SELECT t.user_id AS userId, SUM(t.amount) AS totalAmount FROM ( " +
+            "SELECT buyer_id AS user_id, total_amount AS amount FROM product_orders " +
+            "  WHERE status = 'paid' AND paid_at >= #{cutoff} " +
+            "UNION ALL " +
+            "SELECT user_id, actual_price AS amount FROM assessment_orders " +
+            "  WHERE status = 'paid' AND created_at >= #{cutoff} " +
+            "UNION ALL " +
+            "SELECT user_id, price AS amount FROM package_orders " +
+            "  WHERE status = 'paid' AND paid_at >= #{cutoff} " +
+            "UNION ALL " +
+            "SELECT f.creator_id AS user_id, so.amount AS amount FROM member_subscription_order so " +
+            "  INNER JOIN families f ON so.family_id = f.id " +
+            "  WHERE so.status = 'paid' AND so.paid_at >= #{cutoff} " +
+            "UNION ALL " +
+            "SELECT user_id, total_amount AS amount FROM activity_orders " +
+            "  WHERE status = 'paid' AND paid_at >= #{cutoff} " +
+            ") t WHERE t.user_id IS NOT NULL GROUP BY t.user_id")
+    List<Map<String, Object>> selectConsumptionSummary(@Param("cutoff") String cutoff);
+
+    /**
+     * 一级推广团队销售额(referrer_id 直接下线在365天窗口的 paid 消费之和)
+     * 返回 List<Map>: {userId(推广者), totalAmount}
+     */
+    @Select("SELECT u.referrer_id AS userId, SUM(t.amount) AS totalAmount FROM ( " +
+            "SELECT buyer_id AS user_id, total_amount AS amount FROM product_orders " +
+            "  WHERE status = 'paid' AND paid_at >= #{cutoff} " +
+            "UNION ALL " +
+            "SELECT user_id, actual_price AS amount FROM assessment_orders " +
+            "  WHERE status = 'paid' AND created_at >= #{cutoff} " +
+            "UNION ALL " +
+            "SELECT user_id, price AS amount FROM package_orders " +
+            "  WHERE status = 'paid' AND paid_at >= #{cutoff} " +
+            "UNION ALL " +
+            "SELECT f.creator_id AS user_id, so.amount AS amount FROM member_subscription_order so " +
+            "  INNER JOIN families f ON so.family_id = f.id " +
+            "  WHERE so.status = 'paid' AND so.paid_at >= #{cutoff} " +
+            "UNION ALL " +
+            "SELECT user_id, total_amount AS amount FROM activity_orders " +
+            "  WHERE status = 'paid' AND paid_at >= #{cutoff} " +
+            ") t INNER JOIN users u ON u.id = t.user_id AND u.referrer_id IS NOT NULL " +
+            "GROUP BY u.referrer_id")
+    List<Map<String, Object>> selectSalesSummary(@Param("cutoff") String cutoff);
+}