瀏覽代碼

Merge remote-tracking branch 'origin/package' into package

bilingfeng 1 年之前
父節點
當前提交
0d919b0c99

+ 4 - 4
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/dto/PromotionDayDTO.java

@@ -57,15 +57,15 @@ public class PromotionDayDTO extends BasePage {
     private String status;
 
     /**
-     * 计划ID
+     * 项目ID
      */
-    @ApiModelProperty(value = "计划ID")
+    @ApiModelProperty(value = "项目ID")
     private Long projectId;
 
     /**
-     * 计划名称
+     * 项目名称
      */
-    @ApiModelProperty(value = "计划名称")
+    @ApiModelProperty(value = "项目名称")
     private String projectName;
 
     /**

+ 4 - 4
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/dto/PromotionDayTotalDTO.java

@@ -56,15 +56,15 @@ public class PromotionDayTotalDTO {
     private String status;
 
     /**
-     * 计划ID
+     * 项目ID
      */
-    @ApiModelProperty(value = "计划ID")
+    @ApiModelProperty(value = "项目ID")
     private Long projectId;
 
     /**
-     * 计划名称
+     * 项目名称
      */
-    @ApiModelProperty(value = "计划名称")
+    @ApiModelProperty(value = "项目名称")
     private String projectName;
 
     /**

+ 161 - 30
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/AccountAgentDayServiceImpl.java

@@ -36,6 +36,7 @@ import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.time.LocalDate;
 import java.util.*;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
 
 @Slf4j
@@ -365,28 +366,74 @@ public class AccountAgentDayServiceImpl implements IAccountAgentDayService {
         dayNMap.put("endDay", dto.getCostEndDay());
 
         String show = """
-                    select
-                    ifnull(sum(amount_count),0) as show_recharge_count,
-                    ifnull(sum(amount_num),0) as show_recharge_user,
-                    ifnull(sum(amount),0) as show_recharge_money,
-                    round(if(sum(amount_count) > 0, sum(amount) / sum(amount_count), 0), 4) as avg_show_user_recharge,
-                    round(if(sum(amount_num) > 0, sum(amount) / sum(amount_num), 0), 4) as show_recharge_arpu
-                    from
-                    ads_account_agent_day
-                    where
-                    source_system = @sourceSystem
-                    and agent_id = @agentId
-                    and account_id = @accountId
-                    and dt >= @rechargeBeginDay
-                    and dt <= @rechargeEndDay
-                    group by
-                    account_id,agent_id,source_system
-                    """;
+                select
+                ifnull(sum(a.amount_count), 0) as show_recharge_count,
+                (select count(distinct user_id) from ads_information
+                where
+                source_system = a.source_system
+                and agent_id = a.agent_id
+                and account_id = a.account_id
+                and order_time >= @rechargeBeginDay
+                and order_time <= @rechargeEndDay) as show_recharge_user,
+                ifnull(sum(a.amount), 0) as show_recharge_money,
+                round(if(sum(a.amount_count) > 0, sum(a.amount) / sum(a.amount_count), 0), 4) as avg_show_user_recharge
+                from
+                ads_account_agent_day a
+                where
+                a.source_system = @sourceSystem
+                and a.agent_id = @agentId
+                and a.account_id = @accountId
+                and a.dt >= @rechargeBeginDay
+                and a.dt <= @rechargeEndDay
+                group by
+                a.account_id,
+                a.agent_id,
+                a.source_system
+                """;
         Sql showSql = Sqls.queryEntity(show);
         Entity<ShowRecharge> showEntity = dao.getEntity(ShowRecharge.class);
         showSql.setEntity(showEntity);
         showSql.setParam("rechargeBeginDay", dto.getRechargeBeginDay());
         showSql.setParam("rechargeEndDay", dto.getRechargeEndDay());
+
+        Map<String, Object> newUserNumMap = new HashMap<>(7);
+        newUserNumMap.put("costBeginDay", dto.getCostBeginDay());
+        newUserNumMap.put("costEndDay", dto.getCostEndDay());
+        newUserNumMap.put("rechargeBeginDay", dto.getRechargeBeginDay());
+        newUserNumMap.put("rechargeEndDay", dto.getRechargeEndDay());
+        Sql newUserNum = Sqls.fetchLong("""
+                select
+                	count(DISTINCT user_id) as repeatNum
+                from
+                	ads_information
+                where
+                    source_system = @sourceSystem
+                    and agent_id = @agentId
+                    and account_id = @accountId
+                    and order_time >= @rechargeBeginDay
+                    and order_time <= @rechargeEndDay
+                    and reg_time >= @costBeginDay
+                    and reg_time <= @costEndDay
+                """);
+
+        Sql newUserRepeatNum = Sqls.fetchLong("""
+                SELECT count(*)
+                FROM
+                (select
+                	count(user_id) as repeatNum
+                from
+                	ads_information
+                where
+                    source_system = @sourceSystem
+                    and agent_id = @agentId
+                    and account_id = @accountId
+                    and order_time >= @rechargeBeginDay
+                    and order_time <= @rechargeEndDay
+                    and reg_time >= @costBeginDay
+                    and reg_time <= @costEndDay
+                    group by user_id) a
+                WHERE a.repeatNum > 1
+                """);
         //循环总数据的每条数据
         List<GamePromoteTotalVO> hasRechargeDayList = list.stream().map(item -> {
             showSql.setParam("sourceSystem", item.getSourceSystem());
@@ -395,11 +442,12 @@ public class AccountAgentDayServiceImpl implements IAccountAgentDayService {
             dao.execute(showSql);
             ShowRecharge showRecharge = showSql.getObject(ShowRecharge.class);
             if (null != showRecharge){
-                item.setShowRechargeArpu(showRecharge.showRechargeArpu);
+                item.setShowRechargeArpu(showRecharge.getShowRechargeUser() == 0 ? BigDecimal.ZERO :
+                        showRecharge.getShowRechargeMoney().divide(new BigDecimal(showRecharge.getShowRechargeUser()), 4, RoundingMode.DOWN));
                 item.setShowRechargeCount(showRecharge.getShowRechargeCount());
-                item.setShowRechargeMoney(showRecharge.showRechargeMoney);
+                item.setShowRechargeMoney(showRecharge.getShowRechargeMoney());
                 item.setShowRechargeUser(showRecharge.getShowRechargeUser());
-                item.setAvgShowUserRecharge(showRecharge.avgShowUserRecharge);
+                item.setAvgShowUserRecharge(showRecharge.getAvgShowUserRecharge());
             }else {
                 item.setShowRechargeArpu(BigDecimal.ZERO);
                 item.setShowRechargeCount(0L);
@@ -409,7 +457,7 @@ public class AccountAgentDayServiceImpl implements IAccountAgentDayService {
             }
             Sql sqlDayN = Sqls.queryString("""
                     select dayN
-                    from ads_dayn_amount 
+                    from ads_dayn_amount
                     where
                     dt>=@beginDay and dt<=@endDay
                     and account_id = @accountId
@@ -447,13 +495,24 @@ public class AccountAgentDayServiceImpl implements IAccountAgentDayService {
                         }
                     }
                 }
+
+                newUserNumMap.put("accountId", item.getAccountId());
+                newUserNumMap.put("agentId", item.getAgentId());
+                newUserNumMap.put("sourceSystem", item.getSourceSystem());
+                newUserNum.setParams(newUserNumMap);
+                dao.execute(newUserNum);
+                Long newUserNumLong = newUserNum.getLong();
+
+                newUserRepeatNum.setParams(newUserNumMap);
+                dao.execute(newUserRepeatNum);
+                Long newUserRepeatNumLong = newUserRepeatNum.getLong();
                 if (!resultMap.isEmpty() && !resultMap.get("dayN").isEmpty()) {
                     String[] parts = resultMap.get("dayN").split("-");
                     dayN = DayN.builder()
                             .rechargeMoney(new BigDecimal(parts[0]))
                             .rechargeCount(Long.valueOf(parts[1]))
-                            .rechargeNum(Long.valueOf(parts[2]))
-                            .repeatNum(Long.valueOf(parts[3]))
+                            .rechargeNum(newUserNumLong)
+                            .repeatNum(newUserRepeatNumLong)
                             .build();
                 }
             }
@@ -663,12 +722,25 @@ public class AccountAgentDayServiceImpl implements IAccountAgentDayService {
         showSql.setEntity(showEntity).setCondition(showCri);
         dao.execute(showSql);
         ShowRecharge showRecharge = showSql.getObject(ShowRecharge.class);
+
+        String showRechargeUser = """
+                select count(distinct user_id) from ads_information
+                where
+                source_system = @sourceSystem
+                and agent_id = @agentId
+                and account_id = @accountId
+                and order_time >= @rechargeBeginDay
+                and order_time <= @rechargeEndDay
+                """;
+        Sql showRechargeUserSql = Sqls.fetchLong(showRechargeUser);
+        showRechargeUserSql.setParam("rechargeBeginDay", dto.getRechargeBeginDay());
+        showRechargeUserSql.setParam("rechargeEndDay", dto.getRechargeEndDay());
         if (null != showRecharge) {
-            gamePromoteTotalSumVO.setShowRechargeArpu(showRecharge.showRechargeArpu);
+            gamePromoteTotalSumVO.setShowRechargeArpu(showRecharge.getShowRechargeArpu());
             gamePromoteTotalSumVO.setShowRechargeCount(showRecharge.getShowRechargeCount());
-            gamePromoteTotalSumVO.setShowRechargeMoney(showRecharge.showRechargeMoney);
+            gamePromoteTotalSumVO.setShowRechargeMoney(showRecharge.getShowRechargeMoney());
             gamePromoteTotalSumVO.setShowRechargeUser(showRecharge.getShowRechargeUser());
-            gamePromoteTotalSumVO.setAvgShowUserRecharge(showRecharge.avgShowUserRecharge);
+            gamePromoteTotalSumVO.setAvgShowUserRecharge(showRecharge.getAvgShowUserRecharge());
         } else {
             gamePromoteTotalSumVO.setShowRechargeArpu(BigDecimal.ZERO);
             gamePromoteTotalSumVO.setShowRechargeCount(0L);
@@ -695,6 +767,12 @@ public class AccountAgentDayServiceImpl implements IAccountAgentDayService {
         Map<String, Object> dayNMap = new HashMap<>(4);
         dayNMap.put("beginDay", dto.getCostBeginDay());
         dayNMap.put("endDay", dto.getCostEndDay());
+
+        Map<String, Object> newUserNumMap = new HashMap<>(7);
+        newUserNumMap.put("costBeginDay", dto.getCostBeginDay());
+        newUserNumMap.put("costEndDay", dto.getCostEndDay());
+        newUserNumMap.put("rechargeBeginDay", dto.getRechargeBeginDay());
+        newUserNumMap.put("rechargeEndDay", dto.getRechargeEndDay());
         Sql sqlDayN = Sqls.queryString("""
                 select dayN
                 from ads_dayn_amount
@@ -704,7 +782,48 @@ public class AccountAgentDayServiceImpl implements IAccountAgentDayService {
                 and agent_id = @agentId
                 and source_system = @sourceSystem
                 """);
+
+        Sql newUserNum = Sqls.fetchLong("""
+                select
+                	count(DISTINCT user_id) as repeatNum
+                from
+                	ads_information
+                where
+                    source_system = @sourceSystem
+                    and agent_id = @agentId
+                    and account_id = @accountId
+                    and order_time >= @rechargeBeginDay
+                    and order_time <= @rechargeEndDay
+                    and reg_time >= @costBeginDay
+                    and reg_time <= @costEndDay
+                """);
+
+        Sql newUserRepeatNum = Sqls.fetchLong("""
+                SELECT count(*)
+                FROM
+                (select
+                	count(user_id) as repeatNum
+                from
+                	ads_information
+                where
+                    source_system = @sourceSystem
+                    and agent_id = @agentId
+                    and account_id = @accountId
+                    and order_time >= @rechargeBeginDay
+                    and order_time <= @rechargeEndDay
+                    and reg_time >= @costBeginDay
+                    and reg_time <= @costEndDay
+                    group by user_id) a
+                WHERE a.repeatNum > 1
+                """);
+        AtomicReference<Long> showRechargeUserNum = new AtomicReference<>(0L);
         DayN dayNTotal = agentAccountList.stream().map(item -> {
+            showRechargeUserSql.setParam("sourceSystem", item.getSourceSystem());
+            showRechargeUserSql.setParam("agentId", item.getAgentId());
+            showRechargeUserSql.setParam("accountId", item.getAccountId());
+            dao.execute(showRechargeUserSql);
+            long showRechargeUserSqlLong = showRechargeUserSql.getLong();
+            showRechargeUserNum.set(showRechargeUserNum.get() + showRechargeUserSqlLong);
             dayNMap.put("accountId", item.getAccountId());
             dayNMap.put("agentId", item.getAgentId());
             dayNMap.put("sourceSystem", item.getSourceSystem());
@@ -737,26 +856,38 @@ public class AccountAgentDayServiceImpl implements IAccountAgentDayService {
                     }
                 }
                 if (!resultMap.isEmpty() && !resultMap.get("dayN").isEmpty()) {
+                    newUserNumMap.put("accountId", item.getAccountId());
+                    newUserNumMap.put("agentId", item.getAgentId());
+                    newUserNumMap.put("sourceSystem", item.getSourceSystem());
+                    newUserNum.setParams(newUserNumMap);
+                    dao.execute(newUserNum);
+                    Long newUserNumLong = newUserNum.getLong();
+
+                    newUserRepeatNum.setParams(newUserNumMap);
+                    dao.execute(newUserRepeatNum);
+                    Long newUserRepeatNumLong = newUserRepeatNum.getLong();
                     String[] parts = resultMap.get("dayN").split("-");
                     dayN = DayN.builder()
                             .rechargeMoney(new BigDecimal(parts[0]))
                             .rechargeCount(Long.valueOf(parts[1]))
-                            .rechargeNum(Long.valueOf(parts[2]))
-                            .repeatNum(Long.valueOf(parts[3]))
+                            .rechargeNum(newUserNumLong)
+                            .repeatNum(newUserRepeatNumLong)
                             .build();
                 }
             }
             return dayN;
         }).filter(Objects::nonNull).reduce((accumulator, currentItem) -> {
-            // 如果 accumulator 为空,直接返回 currentItem
+            //其他字段相加的逻辑
             accumulator.setRechargeCount(accumulator.getRechargeCount() + currentItem.getRechargeCount());
             accumulator.setRechargeMoney(accumulator.getRechargeMoney().add(currentItem.getRechargeMoney()));
             accumulator.setRechargeNum(accumulator.getRechargeNum() + currentItem.getRechargeNum());
             accumulator.setRepeatNum(accumulator.getRepeatNum() + currentItem.getRepeatNum());
-            // 其他字段相加的逻辑
             return accumulator;
         }).orElse(new DayN());
 
+        gamePromoteTotalSumVO.setShowRechargeUser(showRechargeUserNum.get());
+        gamePromoteTotalSumVO.setShowRechargeArpu(gamePromoteTotalSumVO.getShowRechargeUser() == 0 ? BigDecimal.ZERO :
+                gamePromoteTotalSumVO.getShowRechargeMoney().divide(new BigDecimal(gamePromoteTotalSumVO.getShowRechargeUser()), 4, RoundingMode.DOWN));
         //充值时间范围内存在充值数据
         gamePromoteTotalSumVO.setUserRechargeMoney(dayNTotal.getRechargeMoney());
         gamePromoteTotalSumVO.setUserRechargeCount(dayNTotal.getRechargeCount());

+ 276 - 16
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/GameDataServiceImpl.java

@@ -335,20 +335,13 @@ public class GameDataServiceImpl implements IGameDataService {
             //总量表的充值相关数据
             DayN dayN = getDayNByTableName(dayNMap, "ads_dayn_game");
 
-            //新用户充值人数(总量)
-            dayN.setRechargeNum(getNewUserAmountNum(dayNMap, ""));
-            //新用户充值人数(买量)
-            buyDayN.setRechargeNum(getNewUserAmountNum(dayNMap, "buy"));
-            //新用户充值人数(自然量)
-            natureDayN.setRechargeNum(getNewUserAmountNum(dayNMap, "nature"));
-
             //设置买量数据
             //新用户充值次数、金额、人数
             vo.setBuyNewUserAmount(buyDayN == null ? BigDecimal.ZERO : buyDayN.getRechargeMoney());
-            vo.setBuyNewUserAmountNum(buyDayN == null ? 0L : buyDayN.getRechargeNum());
+            vo.setBuyNewUserAmountNum(getNewUserAmountNum(dayNMap, "buy"));
             vo.setBuyNewUserAmountCount(buyDayN == null ? 0L : buyDayN.getRechargeCount());
             //新用户复充人数
-            vo.setBuyNewUserAgainNum(buyDayN == null ? 0L : buyDayN.getRechargeAgainNum());
+            vo.setBuyNewUserAgainNum(getNewUserAmountAgainNum(dayNMap, "buy"));
 
             //老用户充值次数、人数、金额
             vo.setBuyOldUserAmount(vo.getBuyAmount().subtract(vo.getBuyNewUserAmount()));
@@ -387,10 +380,10 @@ public class GameDataServiceImpl implements IGameDataService {
             //设置自然量数据
             //新用户充值次数、金额、人数
             vo.setNatureNewUserAmount(natureDayN == null ? BigDecimal.ZERO : natureDayN.getRechargeMoney());
-            vo.setNatureNewUserAmountNum(natureDayN == null ? 0L : natureDayN.getRechargeNum());
+            vo.setNatureNewUserAmountNum(getNewUserAmountNum(dayNMap, "nature"));
             vo.setNatureNewUserAmountCount(natureDayN == null ? 0L : natureDayN.getRechargeCount());
             //新用户复充人数
-            vo.setNatureNewUserAgainNum(natureDayN == null ? 0L : natureDayN.getRechargeAgainNum());
+            vo.setNatureNewUserAgainNum(getNewUserAmountAgainNum(dayNMap, "nature"));
 
             //老用户充值次数、人数、金额
             vo.setNatureOldUserAmount(vo.getNatureAmount().subtract(vo.getNatureNewUserAmount()));
@@ -429,10 +422,10 @@ public class GameDataServiceImpl implements IGameDataService {
             //设置总量数据
             //新用户充值次数、金额、人数
             vo.setNewUserAmount(dayN == null ? BigDecimal.ZERO : dayN.getRechargeMoney());
-            vo.setNewUserAmountNum(dayN == null ? 0L : dayN.getRechargeNum());
+            vo.setNewUserAmountNum(getNewUserAmountNum(dayNMap, ""));
             vo.setNewUserAmountCount(dayN == null ? 0L : dayN.getRechargeCount());
             //新用户复充人数
-            vo.setNewUserAgainNum(dayN == null ? 0L : dayN.getRechargeAgainNum());
+            vo.setNewUserAgainNum(getNewUserAmountAgainNum(dayNMap, ""));
 
             //老用户充值次数、人数、金额
             vo.setOldUserAmount(vo.getAmount().subtract(vo.getNewUserAmount()));
@@ -554,12 +547,191 @@ public class GameDataServiceImpl implements IGameDataService {
         sqlWithRechargeDate.setEntity(dao.getEntity(GameDataTotalTotalVO.class));
         dao.execute(sqlWithRechargeDate);
         GameDataTotalTotalVO tempVO = sqlWithRechargeDate.getObject(GameDataTotalTotalVO.class);
+
+        //设置查询参数map
+        Map<String, Object> queryMap = new HashMap<>(4);
+        queryMap.put("rechargeBeginDate", dto.getRechargeBeginDate());
+        queryMap.put("rechargeEndDate", dto.getRechargeEndDate());
+        queryMap.put("gameId", dto.getGameId());
+        if (StringUtils.isNotBlank(dto.getSourceSystem())) {
+            queryMap.put("sourceSystem", dto.getSourceSystem());
+        }
+        //账面充值人数(总量、买量、自然量)
+        Long amountNum = getNewUserAmountNum(queryMap, "");
+        Long buyAmountNum = getNewUserAmountNum(queryMap, "buy");
+        Long natureAmountNum = getNewUserAmountNum(queryMap, "nature");
+        //设置账面充值人数
+        tempVO.setAmountNum(amountNum);
+        tempVO.setBuyAmountNum(buyAmountNum);
+        tempVO.setNatureAmountNum(natureAmountNum);
+        //设置账面ARPU(总量、买量、自然量)
+        tempVO.setAmountArpu(amountNum == 0L ? BigDecimal.ZERO :
+                tempVO.getAmount().divide(BigDecimal.valueOf(amountNum), 2, RoundingMode.HALF_UP));
+        tempVO.setBuyAmountArpu(buyAmountNum == 0L ? BigDecimal.ZERO :
+                tempVO.getBuyAmount().divide(BigDecimal.valueOf(buyAmountNum), 2, RoundingMode.HALF_UP));
+        tempVO.setNatureAmountArpu(natureAmountNum == 0L ? BigDecimal.ZERO :
+                tempVO.getNatureAmount().divide(BigDecimal.valueOf(natureAmountNum), 2, RoundingMode.HALF_UP));
         //将两个对象内的数据合并
         copyNullProperties(tempVO, vo);
+        //获取新用户充值人数相关数据
+        getGameDataTotalTotalRechargeData(dto, vo);
 
         return vo;
     }
 
+    /**
+     * 游戏总数据总计的新用户充值人数相关值得计算方法
+     * @param dto 前端查询条件
+     * @param vo 返回给前端得实体
+     */
+    private void getGameDataTotalTotalRechargeData(GameDataTotalTotalDTO dto, GameDataTotalTotalVO vo) {
+
+        //设置查询参数map
+        Map<String, Object> dayNMap = new HashMap<>(6);
+        dayNMap.put("registerBeginDate", dto.getRegisteredBeginDate());
+        dayNMap.put("registerEndDate", dto.getRegisteredEndDate());
+        dayNMap.put("rechargeBeginDate", dto.getRechargeBeginDate());
+        dayNMap.put("rechargeEndDate", dto.getRechargeEndDate());
+        dayNMap.put("gameId", dto.getGameId());
+        if (StringUtils.isNotBlank(dto.getSourceSystem())) {
+            dayNMap.put("sourceSystem", dto.getSourceSystem());
+        }
+
+        //买量表的充值相关数据
+        DayN buyDayN = getDayNByTableName(dayNMap, "ads_dayn_game_buy");
+        //自然量表的充值相关数据
+        DayN natureDayN = getDayNByTableName(dayNMap, "ads_dayn_game_nature");
+        //总量表的充值相关数据
+        DayN dayN = getDayNByTableName(dayNMap, "ads_dayn_game");
+
+        //设置买量数据
+        //新用户充值次数、金额、人数
+        vo.setBuyNewUserAmount(buyDayN == null ? BigDecimal.ZERO : buyDayN.getRechargeMoney());
+        vo.setBuyNewUserAmountNum(getNewUserAmountNum(dayNMap, "buy"));
+        vo.setBuyNewUserAmountCount(buyDayN == null ? 0L : buyDayN.getRechargeCount());
+        //新用户复充人数
+        vo.setBuyNewUserAgainNum(getNewUserAmountAgainNum(dayNMap, "buy"));
+
+        //老用户充值次数、人数、金额
+        vo.setBuyOldUserAmount(vo.getBuyAmount().subtract(vo.getBuyNewUserAmount()));
+        vo.setBuyOldUserCount(vo.getBuyAmountCount() - (vo.getBuyNewUserAmountCount()));
+        vo.setBuyOldUserNum(vo.getBuyAmountNum() - (vo.getBuyNewUserAmountNum()));
+
+        //新用户付费比
+        vo.setBuyNewUserRate(vo.getBuyAmountNum().compareTo(0L) == 0 ? BigDecimal.ZERO :
+                BigDecimal.valueOf(vo.getBuyNewUserAmountNum().doubleValue() / vo.getBuyAmountNum().doubleValue()).setScale(4, RoundingMode.HALF_UP));
+        //新用户付费率
+        vo.setBuyNewUserRoi(vo.getBuyRegNum().compareTo(0L) == 0 ? BigDecimal.ZERO :
+                BigDecimal.valueOf(vo.getBuyNewUserAmountNum().doubleValue() / vo.getBuyRegNum().doubleValue()).setScale(4, RoundingMode.HALF_UP));
+
+        //新用户客单价
+        vo.setBuyNewUserAvgAmount(vo.getBuyNewUserAmountCount().compareTo(0L) == 0 ? BigDecimal.ZERO :
+                BigDecimal.valueOf(vo.getBuyNewUserAmount().doubleValue() / vo.getBuyNewUserAmountCount().doubleValue()).setScale(4, RoundingMode.HALF_UP));
+
+        //复充率
+        vo.setBuyUserAgainRate(vo.getBuyNewUserAmountNum().compareTo(0L) == 0 ? BigDecimal.ZERO :
+                BigDecimal.valueOf(vo.getBuyNewUserAgainNum().doubleValue() / vo.getBuyNewUserAmountNum().doubleValue()).setScale(4, RoundingMode.HALF_UP));
+        //新用户复充率
+        vo.setBuyNewUserAgainRate(vo.getBuyNewUserTotalAmountNum().compareTo(0L) == 0 ? BigDecimal.ZERO :
+                BigDecimal.valueOf(vo.getBuyNewUserAgainNum().doubleValue() / vo.getBuyNewUserTotalAmountNum().doubleValue()).setScale(4, RoundingMode.HALF_UP));
+
+        //新用户付费ARPU
+        vo.setBuyNewUserAmountArpu(vo.getBuyNewUserAmountNum().compareTo(0L) == 0 ? BigDecimal.ZERO :
+                BigDecimal.valueOf(vo.getBuyNewUserAmount().doubleValue() / vo.getBuyNewUserAmountNum().doubleValue()).setScale(4, RoundingMode.HALF_UP));
+
+        //新用户回收率
+        vo.setBuyNewUserRechargeRate(vo.getCost().compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO :
+                vo.getBuyNewUserAmount().divide(vo.getCost(), 4, RoundingMode.HALF_UP));
+        //新用户充值成本
+        vo.setBuyNewUserRechargeCost(vo.getBuyNewUserAmountNum() == 0 ? BigDecimal.ZERO :
+                vo.getCost().divide(BigDecimal.valueOf(vo.getBuyNewUserAmountNum()), 4, RoundingMode.HALF_UP));
+
+        //设置自然量数据
+        //新用户充值次数、金额、人数
+        vo.setNatureNewUserAmount(natureDayN == null ? BigDecimal.ZERO : natureDayN.getRechargeMoney());
+        vo.setNatureNewUserAmountNum(getNewUserAmountNum(dayNMap, "nature"));
+        vo.setNatureNewUserAmountCount(natureDayN == null ? 0L : natureDayN.getRechargeCount());
+        //新用户复充人数
+        vo.setNatureNewUserAgainNum(getNewUserAmountAgainNum(dayNMap, "nature"));
+
+        //老用户充值次数、人数、金额
+        vo.setNatureOldUserAmount(vo.getNatureAmount().subtract(vo.getNatureNewUserAmount()));
+        vo.setNatureOldUserCount(vo.getNatureAmountCount() - (vo.getNatureNewUserAmountCount()));
+        vo.setNatureOldUserNum(vo.getNatureAmountNum() - (vo.getNatureNewUserAmountNum()));
+
+        //新用户付费比
+        vo.setNatureNewUserRate(vo.getNatureAmountNum().compareTo(0L) == 0 ? BigDecimal.ZERO :
+                BigDecimal.valueOf(vo.getNatureNewUserAmountNum().doubleValue() / vo.getNatureAmountNum().doubleValue()).setScale(4, RoundingMode.HALF_UP));
+        //新用户付费率
+        vo.setNatureNewUserRoi(vo.getNatureRegNum().compareTo(0L) == 0 ? BigDecimal.ZERO :
+                BigDecimal.valueOf(vo.getNatureNewUserAmountNum().doubleValue() / vo.getNatureRegNum().doubleValue()).setScale(4, RoundingMode.HALF_UP));
+
+        //新用户客单价
+        vo.setNatureNewUserAvgAmount(vo.getNatureNewUserAmountCount().compareTo(0L) == 0 ? BigDecimal.ZERO :
+                BigDecimal.valueOf(vo.getNatureNewUserAmount().doubleValue() / vo.getNatureNewUserAmountCount().doubleValue()).setScale(4, RoundingMode.HALF_UP));
+
+        //复充率
+        vo.setNatureUserAgainRate(vo.getNatureNewUserAmountNum().compareTo(0L) == 0 ? BigDecimal.ZERO :
+                BigDecimal.valueOf(vo.getNatureNewUserAgainNum().doubleValue() / vo.getNatureNewUserAmountNum().doubleValue()).setScale(4, RoundingMode.HALF_UP));
+        //新用户复充率
+        vo.setNatureNewUserAgainRate(vo.getNatureNewUserTotalAmountNum().compareTo(0L) == 0 ? BigDecimal.ZERO :
+                BigDecimal.valueOf(vo.getNatureNewUserAgainNum().doubleValue() / vo.getNatureNewUserTotalAmountNum().doubleValue()).setScale(4, RoundingMode.HALF_UP));
+
+        //新用户付费ARPU
+        vo.setNatureNewUserAmountArpu(vo.getNatureNewUserAmountNum().compareTo(0L) == 0 ? BigDecimal.ZERO :
+                BigDecimal.valueOf(vo.getNatureNewUserAmount().doubleValue() / vo.getNatureNewUserAmountNum().doubleValue()).setScale(4, RoundingMode.HALF_UP));
+
+        //新用户回收率
+        vo.setNatureNewUserRechargeRate(vo.getCost().compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO :
+                vo.getNatureNewUserAmount().divide(vo.getCost(), 4, RoundingMode.HALF_UP));
+        //新用户充值成本
+        vo.setNatureNewUserRechargeCost(vo.getNatureNewUserAmountNum() == 0 ? BigDecimal.ZERO :
+                vo.getCost().divide(BigDecimal.valueOf(vo.getNatureNewUserAmountNum()), 4, RoundingMode.HALF_UP));
+
+        //设置总量数据
+        //新用户充值次数、金额、人数
+        vo.setNewUserAmount(dayN == null ? BigDecimal.ZERO : dayN.getRechargeMoney());
+        vo.setNewUserAmountNum(getNewUserAmountNum(dayNMap, ""));
+        vo.setNewUserAmountCount(dayN == null ? 0L : dayN.getRechargeCount());
+        //新用户复充人数
+        vo.setNewUserAgainNum(getNewUserAmountAgainNum(dayNMap, ""));
+
+        //老用户充值次数、人数、金额
+        vo.setOldUserAmount(vo.getAmount().subtract(vo.getNewUserAmount()));
+        vo.setOldUserCount(vo.getAmountCount() - (vo.getNewUserAmountCount()));
+        vo.setOldUserNum(vo.getAmountNum() - (vo.getNewUserAmountNum()));
+
+        //新用户付费比
+        vo.setNewUserRate(vo.getAmountNum().compareTo(0L) == 0 ? BigDecimal.ZERO :
+                BigDecimal.valueOf(vo.getNewUserAmountNum().doubleValue() / vo.getAmountNum().doubleValue()).setScale(4, RoundingMode.HALF_UP));
+        //新用户付费率
+        vo.setNewUserRoi(vo.getRegNum().compareTo(0L) == 0 ? BigDecimal.ZERO :
+                BigDecimal.valueOf(vo.getNewUserAmountNum().doubleValue() / vo.getRegNum().doubleValue()).setScale(4, RoundingMode.HALF_UP));
+
+        //新用户客单价
+        vo.setNewUserAvgAmount(vo.getNewUserAmountCount().compareTo(0L) == 0 ? BigDecimal.ZERO :
+                BigDecimal.valueOf(vo.getNewUserAmount().doubleValue() / vo.getNewUserAmountCount().doubleValue()).setScale(4, RoundingMode.HALF_UP));
+
+        //复充率
+        vo.setUserAgainRate(vo.getNewUserAmountNum().compareTo(0L) == 0 ? BigDecimal.ZERO :
+                BigDecimal.valueOf(vo.getNewUserAgainNum().doubleValue() / vo.getNewUserAmountNum().doubleValue()).setScale(4, RoundingMode.HALF_UP));
+        //新用户复充率
+        vo.setNewUserAgainRate(vo.getNewUserTotalAmountNum().compareTo(0L) == 0 ? BigDecimal.ZERO :
+                BigDecimal.valueOf(vo.getNewUserAgainNum().doubleValue() / vo.getNewUserTotalAmountNum().doubleValue()).setScale(4, RoundingMode.HALF_UP));
+
+        //新用户付费ARPU
+        vo.setNewUserAmountArpu(vo.getNewUserAmountNum().compareTo(0L) == 0 ? BigDecimal.ZERO :
+                BigDecimal.valueOf(vo.getNewUserAmount().doubleValue() / vo.getNewUserAmountNum().doubleValue()).setScale(4, RoundingMode.HALF_UP));
+
+        //新用户回收率
+        vo.setNewUserRechargeRate(vo.getCost().compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO :
+                vo.getNewUserAmount().divide(vo.getCost(), 4, RoundingMode.HALF_UP));
+        //新用户充值成本
+        vo.setNewUserRechargeCost(vo.getNewUserAmountNum() == 0 ? BigDecimal.ZERO :
+                vo.getCost().divide(BigDecimal.valueOf(vo.getNewUserAmountNum()), 4, RoundingMode.HALF_UP));
+
+    }
+
     /**
      * 每日流水贡献
      *
@@ -1011,7 +1183,6 @@ public class GameDataServiceImpl implements IGameDataService {
                 dayN = DayN.builder()
                         .rechargeMoney(new BigDecimal(values[0]))
                         .rechargeCount(Long.valueOf(values[1]))
-                        .rechargeAgainNum(Long.valueOf(values[3]))
                         .build();
             }
         }
@@ -1024,7 +1195,7 @@ public class GameDataServiceImpl implements IGameDataService {
      *
      * @param dayNMap 参数Map
      * @param type    查询的字段类型:buy、nature、总
-     * @return 新用户充值认识
+     * @return 新用户充值人数
      */
     private Long getNewUserAmountNum(Map<String, Object> dayNMap, String type) {
         //查询新用户充值人数
@@ -1064,6 +1235,59 @@ public class GameDataServiceImpl implements IGameDataService {
         return newUserAmountNumSql.getLong();
     }
 
+    /**
+     * 获取新用户复充人数方法
+     *
+     * @param dayNMap 参数列表
+     * @param type    查询字段类型: buy、nature、总量
+     * @return 新用户复充人数
+     */
+    private Long getNewUserAmountAgainNum(Map<String, Object> dayNMap, String type) {
+        //查询新用户充值人数
+        Criteria cri = Cnd.cri();
+        if (dayNMap.get("registerBeginDate") != null && dayNMap.get("registerEndDate") != null) {
+            //拼接注册时间查询条件
+            cri.where().andBetween("reg_time", dayNMap.get("registerBeginDate"), dayNMap.get("registerEndDate"));
+        }
+        if (dayNMap.get("gameId") != null) {
+            //拼接游戏ID查询条件
+            cri.where().andEquals("game_id", dayNMap.get("gameId"));
+        }
+        if (dayNMap.get("sourceSystem") != null) {
+            //拼接SDK来源查询条件
+            cri.where().andEquals("source_system", dayNMap.get("sourceSystem"));
+        }
+        if (dayNMap.get("rechargeBeginDate") != null && dayNMap.get("rechargeEndDate") != null) {
+            //拼接充值时间查询条件
+            cri.where().andBetween("order_time", dayNMap.get("rechargeBeginDate"), dayNMap.get("rechargeEndDate"));
+        }
+        //拼接渠道id条件 取出自然量、买量、总量值
+        if (type.equals("buy")) {
+            cri.where().andNotEquals("agent_id", 0);
+        } else if (type.equals("nature")) {
+            cri.where().andEquals("agent_id", 0);
+        }
+        Sql newUserAmountAgainNumSql = Sqls.create("""
+                    SELECT
+                        COUNT(a.num)
+                    FROM(
+                        SELECT
+                        	COUNT(user_id) num
+                        FROM
+                        	game_ads.ads_information
+                """ + cri +
+                """
+                           GROUP BY user_id
+                           HAVING COUNT(user_id) > 1
+                           ) a;
+                        """);
+        newUserAmountAgainNumSql.setCallback(Sqls.callback.longValue());
+        //执行sql
+        dao.execute(newUserAmountAgainNumSql);
+        //得到结果 新用户充值人数
+        return newUserAmountAgainNumSql.getLong();
+    }
+
     /**
      * 通过反射来获取Cn的值
      *
@@ -2075,7 +2299,43 @@ public class GameDataServiceImpl implements IGameDataService {
                     
                     round(if(SUM(buy_new_user_total_amount_num) > 0, SUM(cost) / SUM(buy_new_user_total_amount_num), 0), 2) buy_total_recharge_cost,
                     round(if(SUM(nature_new_user_total_amount_num) > 0, SUM(cost) / SUM(nature_new_user_total_amount_num), 0), 2) nature_total_recharge_cost,
-                    round(if(SUM(new_user_total_amount_num) > 0, SUM(cost) / SUM(new_user_total_amount_num), 0), 2) total_recharge_cost
+                    round(if(SUM(new_user_total_amount_num) > 0, SUM(cost) / SUM(new_user_total_amount_num), 0), 2) total_recharge_cost,
+                    
+                    SUM(buy_hundred_user_num) buy_hundred_user_num,
+                    round(IF(SUM(buy_hundred_user_num) > 0, SUM(cost) / SUM(buy_hundred_user_num), 0), 2) buy_hundred_user_num_cost,
+                    SUM(buy_first_role_num) buy_first_role_num,
+                    SUM(buy_role_num) buy_role_num,
+                    SUM(buy_new_user_total_role_num) buy_new_user_total_role_num,
+                    round(IF(SUM(buy_first_role_num) > 0, SUM(cost) / SUM(buy_first_role_num), 0), 2) buy_first_role_num_cost,
+                    round(IF(SUM(buy_role_num) > 0, SUM(cost) / SUM(buy_role_num), 0), 2) buy_role_num_cost,
+                    round(IF(SUM(buy_new_user_total_role_num) >0, SUM(cost) / SUM(buy_new_user_total_role_num), 0), 2) buy_new_user_total_role_num_cost,
+                    round(IF(SUM(buy_reg_num) >0, SUM(buy_first_role_num) / SUM(buy_reg_num), 0), 4) buy_first_role_num_rate,
+                    round(IF(SUM(buy_reg_num) >0, SUM(buy_role_num) / SUM(buy_reg_num), 0), 4) buy_role_num_rate,
+                    round(IF(SUM(buy_reg_num) >0, SUM(buy_new_user_total_role_num) / SUM(buy_reg_num), 0), 4) buy_new_user_total_role_num_rate,
+                    
+                    SUM(nature_hundred_user_num) nature_hundred_user_num,
+                    round(IF(SUM(nature_hundred_user_num) > 0, SUM(cost) / SUM(nature_hundred_user_num), 0), 2) nature_hundred_user_num_cost,
+                    SUM(nature_first_role_num) nature_first_role_num,
+                    SUM(nature_role_num) nature_role_num,
+                    SUM(nature_new_user_total_role_num) nature_new_user_total_role_num,
+                    round(IF(SUM(nature_first_role_num) > 0, SUM(cost) / SUM(nature_first_role_num), 0), 2) nature_first_role_num_cost,
+                    round(IF(SUM(nature_role_num) > 0, SUM(cost) / SUM(nature_role_num), 0), 2) nature_role_num_cost,
+                    round(IF(SUM(nature_new_user_total_role_num) >0, SUM(cost) / SUM(nature_new_user_total_role_num), 0), 2) nature_new_user_total_role_num_cost,
+                    round(IF(SUM(nature_reg_num) >0, SUM(nature_first_role_num) / SUM(nature_reg_num), 0), 4) nature_first_role_num_rate,
+                    round(IF(SUM(nature_reg_num) >0, SUM(nature_role_num) / SUM(nature_reg_num), 0), 4) nature_role_num_rate,
+                    round(IF(SUM(nature_reg_num) >0, SUM(nature_new_user_total_role_num) / SUM(nature_reg_num), 0), 4) nature_new_user_total_role_num_rate,
+                   
+                    SUM(hundred_user_num) hundred_user_num,
+                    round(IF(SUM(hundred_user_num) > 0, SUM(cost) / SUM(hundred_user_num), 0), 2) hundred_user_num_cost,
+                    SUM(first_role_num) first_role_num,
+                    SUM(role_num) role_num,
+                    SUM(new_user_total_role_num) new_user_total_role_num,
+                    round(IF(SUM(first_role_num) > 0, SUM(cost) / SUM(first_role_num), 0), 2) first_role_num_cost,
+                    round(IF(SUM(role_num) > 0, SUM(cost) / SUM(role_num), 0), 2) role_num_cost,
+                    round(IF(SUM(new_user_total_role_num) >0, SUM(cost) / SUM(new_user_total_role_num), 0), 2) new_user_total_role_num_cost,
+                    round(IF(SUM(reg_num) >0, SUM(first_role_num) / SUM(reg_num), 0), 4) first_role_num_rate,
+                    round(IF(SUM(reg_num) >0, SUM(role_num) / SUM(reg_num), 0), 4) role_num_rate,
+                    round(IF(SUM(reg_num) >0, SUM(new_user_total_role_num) / SUM(reg_num), 0), 4) new_user_total_role_num_rate
                     
                 FROM
                     game_ads.ads_game_day

+ 4 - 4
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/PromotionDayServiceImpl.java

@@ -110,7 +110,7 @@ public class PromotionDayServiceImpl implements IAdsPromotionDayService {
                             vo.getD2().divide(vo.getTodayCost(), 4, RoundingMode.HALF_UP))
                     .rechargeMoney(vo.getD2())
                     .multiples(vo.getD1().compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO :
-                            vo.getD2().divide(vo.getD1(), 4, RoundingMode.HALF_UP))
+                            vo.getD2().divide(vo.getD1(), 2, RoundingMode.HALF_UP))
                     .build());
             //计算d3数据
             vo.setD3Trend(PromotionRechargeTrendVO.builder()
@@ -118,7 +118,7 @@ public class PromotionDayServiceImpl implements IAdsPromotionDayService {
                             vo.getD3().divide(vo.getTodayCost(), 4, RoundingMode.HALF_UP))
                     .rechargeMoney(vo.getD3())
                     .multiples(vo.getD1().compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO :
-                            vo.getD3().divide(vo.getD1(), 4, RoundingMode.HALF_UP))
+                            vo.getD3().divide(vo.getD1(), 2, RoundingMode.HALF_UP))
                     .build());
             //计算d7数据
             vo.setD7Trend(PromotionRechargeTrendVO.builder()
@@ -126,7 +126,7 @@ public class PromotionDayServiceImpl implements IAdsPromotionDayService {
                             vo.getD7().divide(vo.getTodayCost(), 4, RoundingMode.HALF_UP))
                     .rechargeMoney(vo.getD7())
                     .multiples(vo.getD1().compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO :
-                            vo.getD7().divide(vo.getD1(), 4, RoundingMode.HALF_UP))
+                            vo.getD7().divide(vo.getD1(), 2, RoundingMode.HALF_UP))
                     .build());
             //计算d15数据
             vo.setD15Trend(PromotionRechargeTrendVO.builder()
@@ -134,7 +134,7 @@ public class PromotionDayServiceImpl implements IAdsPromotionDayService {
                             vo.getD15().divide(vo.getTodayCost(), 4, RoundingMode.HALF_UP))
                     .rechargeMoney(vo.getD15())
                     .multiples(vo.getD1().compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO :
-                            vo.getD15().divide(vo.getD1(), 4, RoundingMode.HALF_UP))
+                            vo.getD15().divide(vo.getD1(), 2, RoundingMode.HALF_UP))
                     .build());
 
             //返回最终数据