Parcourir la source

整体概况的服务层逻辑编写

lth il y a 1 an
Parent
commit
de6a339c3f

+ 6 - 0
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/entity/AdsOverallSummary.java

@@ -81,6 +81,12 @@ public class AdsOverallSummary implements Serializable {
     @Column
     private BigDecimal yesterdayTotalCost;
 
+    /**
+     * 首日新用户充值
+     */
+    @Column
+    private BigDecimal firstNewUserAmount;
+
     /**
      * 今日新用户充值
      */

+ 145 - 82
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/AdsOverallSummaryServiceImpl.java

@@ -12,13 +12,20 @@ import org.nutz.dao.Dao;
 import org.nutz.dao.Sqls;
 import org.nutz.dao.sql.Criteria;
 import org.nutz.dao.sql.Sql;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.BeanWrapper;
+import org.springframework.beans.BeanWrapperImpl;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.beans.PropertyDescriptor;
 import java.math.BigDecimal;
-import java.math.BigInteger;
+import java.math.RoundingMode;
 import java.time.LocalDate;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Objects;
+import java.util.Set;
 
 /**
  * @author tianhua
@@ -35,93 +42,102 @@ public class AdsOverallSummaryServiceImpl implements IAdsOverallSummaryService {
     @Override
     public AdsOverallSummaryVO getOverallSummaryData(AdsOverallSummaryParam param) {
 
-        //前端展示数据的实体对象
-        AdsOverallSummaryVO adsOverallSummaryVO = new AdsOverallSummaryVO();
         //获取查询条件 整体数据查询 不需要日期
-        Condition totalDataCon = myCondition(param, false, false);
+        Condition totalDataCon = myCondition(param, false, -1);
+        //查询条件转换为sql语句 设置映射 Entity为 AdsOverallSummary对象
+        String totalDataConString = totalDataCon.toSql(dao.getEntity(AdsOverallSummary.class));
+        //自定义sql语句
+        Sql totalDataSql = Sqls.create("SELECT \n" +
+                "SUM(x.today_player_count) total_players ,\n" +
+                "SUM(x.today_total_cost) total_cost ,\n" +
+                "SUM(x.today_amount) total_amount ,\n" +
+                "SUM(x.today_agent_count) total_agent_count ,\n" +
+                "SUM(x.today_game_count) total_game_count ,\n" +
+                "SUM(x.today_new_player_amount)/SUM(x.today_total_cost) total_roi \n" +
+                "FROM ads_overall_summary x " + totalDataConString);
+
+        //自定义回显对象 结果自动封装到给定的Entity对象中
+        totalDataSql.setCallback(Sqls.callback.entity());
+        totalDataSql.setEntity(dao.getEntity(AdsOverallSummaryVO.class));
+        //执行自定义sql语句
+        dao.execute(totalDataSql);
+        //得到一个包含有总数据的AdsOverallSummaryVO对象
+        AdsOverallSummaryVO totalDataVO = totalDataSql.getObject(AdsOverallSummaryVO.class);
+
+
         //获取查询条件 查询今日数据 需要按当前日期查询
-        Condition todayDataCon = myCondition(param, false, true);
-
-        //查询数据 设置到实体类中
-        //总玩家数
-        adsOverallSummaryVO.setTotalPlayers(BigInteger.valueOf(dao.func(AdsOverallSummary.class, "sum", "todayPlayerCount", totalDataCon)));
-        //今日新增玩家数
-        adsOverallSummaryVO.setTodayPlayerCount(BigInteger.valueOf(dao.func(AdsOverallSummary.class, "sum", "todayPlayerCount", todayDataCon)));
-        //昨日新增玩家数
-        adsOverallSummaryVO.setYesterdayPlayerCount(BigInteger.valueOf(dao.func(AdsOverallSummary.class, "sum", "yesterdayPlayerCount", todayDataCon)));
-
-        //累计消耗
-        adsOverallSummaryVO.setTotalCost(BigDecimal.valueOf(dao.func(AdsOverallSummary.class, "sum", "todayTotalCost", totalDataCon)));
-        //今日消耗
-        adsOverallSummaryVO.setTodayTotalCost(BigDecimal.valueOf(dao.func(AdsOverallSummary.class, "sum", "todayTotalCost", todayDataCon)));
-        //昨日消耗
-        adsOverallSummaryVO.setYesterdayTotalCost(BigDecimal.valueOf(dao.func(AdsOverallSummary.class, "sum", "yesterdayTotalCost", todayDataCon)));
-
-        //累计充值
-        adsOverallSummaryVO.setTotalAmount(BigDecimal.valueOf(dao.func(AdsOverallSummary.class, "sum", "todayAmount", totalDataCon)));
-        //今日新用户充值
-        adsOverallSummaryVO.setTodayNewPlayerAmount(BigDecimal.valueOf(dao.func(AdsOverallSummary.class, "sum", "todayNewPlayerAmount", todayDataCon)));
-        //今日账面充值
-        adsOverallSummaryVO.setTodayAmount(BigDecimal.valueOf(dao.func(AdsOverallSummary.class, "sum", "todayAmount", todayDataCon)));
-        //昨日新用户充值
-        adsOverallSummaryVO.setYesterdayNewPlayerAmount(BigDecimal.valueOf(dao.func(AdsOverallSummary.class, "sum", "yesterdayNewPlayerAmount", todayDataCon)));
-        //昨日账面充值
-        adsOverallSummaryVO.setYesterdayAmount(BigDecimal.valueOf(dao.func(AdsOverallSummary.class, "sum", "yesterdayAmount", todayDataCon)));
-
-        //总渠道数量
-        adsOverallSummaryVO.setTotalAgentCount(BigInteger.valueOf(dao.func(AdsOverallSummary.class, "sum", "todayAgentCount", totalDataCon)));
-        //今日新增渠道数量
-        adsOverallSummaryVO.setTodayAgentCount(BigInteger.valueOf(dao.func(AdsOverallSummary.class, "sum", "todayAgentCount", todayDataCon)));
-        //昨日新增渠道数量
-        adsOverallSummaryVO.setYesterdayAgentCount(BigInteger.valueOf(dao.func(AdsOverallSummary.class, "sum", "yesterdayAgentCount", todayDataCon)));
-
-        //游戏总计数量
-        adsOverallSummaryVO.setTotalGameCount(BigInteger.valueOf(dao.func(AdsOverallSummary.class, "sum", "todayGameCount", totalDataCon)));
-        //今日新增游戏数量
-        adsOverallSummaryVO.setTodayGameCount(BigInteger.valueOf(dao.func(AdsOverallSummary.class, "sum", "todayGameCount", todayDataCon)));
-        //昨日新增游戏数量
-        adsOverallSummaryVO.setYesterdayGameCount(BigInteger.valueOf(dao.func(AdsOverallSummary.class, "sum", "yesterdayGameCount", todayDataCon)));
-
-        //总回本率
-        adsOverallSummaryVO.setTotalRoi(BigDecimal.valueOf(dao.func(AdsOverallSummary.class, "sum", "totalRoi", totalDataCon)));
-        //首日回本率
-        adsOverallSummaryVO.setFirstRoi(BigDecimal.valueOf(dao.func(AdsOverallSummary.class, "sum", "firstRoi", totalDataCon)));
-        //7天回本率
-        adsOverallSummaryVO.setD7TotalRoi(BigDecimal.valueOf(dao.func(AdsOverallSummary.class, "sum", "d7TotalRoi", totalDataCon)));
-        //30天回本率
-        adsOverallSummaryVO.setD30TotalRoi(BigDecimal.valueOf(dao.func(AdsOverallSummary.class, "sum", "d30TotalRoi", totalDataCon)));
-
-        return adsOverallSummaryVO;
+        Condition todayDataCon = myCondition(param, false, 1);
+        //查询条件转换为sql语句 设置映射 Entity为 AdsOverallSummary对象
+        String todayDataConString = todayDataCon.toSql(dao.getEntity(AdsOverallSummary.class));
+        Sql todayDataSql = Sqls.create("SELECT  \n" +
+                "SUM(x.today_player_count) today_player_count ,\n" +
+                "SUM(x.yesterday_player_count) yesterday_player_count ,\n" +
+                "SUM(x.today_total_cost) today_total_cost ,\n" +
+                "SUM(x.yesterday_total_cost) yesterday_total_cost ,\n" +
+                "SUM(x.today_new_player_amount) today_new_player_amount ,\n" +
+                "SUM(x.today_amount) today_amount ,\n" +
+                "SUM(x.yesterday_new_player_amount) yesterday_new_player_amount ,\n" +
+                "SUM(x.yesterday_amount) yesterday_amount ,\n" +
+                "SUM(x.today_agent_count) today_agent_count ,\n" +
+                "SUM(x.yesterday_agent_count) yesterday_agent_count ,\n" +
+                "SUM(x.today_game_count) today_game_count ,\n" +
+                "SUM(x.yesterday_game_count) yesterday_game_count ,\n" +
+                "SUM(x.first_new_user_amount)/SUM(x.today_total_cost) first_roi \n" +
+                "FROM ads_overall_summary x" + todayDataConString);
+
+        //自定义回显对象 结果自动封装到给定的Entity对象中
+        todayDataSql.setCallback(Sqls.callback.entity());
+        todayDataSql.setEntity(dao.getEntity(AdsOverallSummaryVO.class));
+        //执行自定义sql语句
+        dao.execute(todayDataSql);
+        //得到一个包含有今日和昨日数据的AdsOverallSummaryVO对象
+        AdsOverallSummaryVO todayDataVO = todayDataSql.getObject(AdsOverallSummaryVO.class);
+
+        //拼接参数
+        copyNullProperties(totalDataVO, todayDataVO);
+
+        //7日和30日Roi数据需要手动计算
+        //7日内新用户累计充值
+        BigDecimal d7NewPlayerAmount = BigDecimal.valueOf(dao.func(AdsOverallSummary.class, "sum", "todayNewPlayerAmount", myCondition(param, false, 7)));
+        //7日内总消耗
+        BigDecimal d7TotalCost = BigDecimal.valueOf(dao.func(AdsOverallSummary.class, "sum", "todayTotalCost", myCondition(param, false, 7)));
+        //计算7日Roi
+        todayDataVO.setD7TotalRoi(d7NewPlayerAmount.divide(d7TotalCost, 4, RoundingMode.HALF_UP));
+
+        //30日内新用户累计充值
+        BigDecimal d30NewPlayerAmount = BigDecimal.valueOf(dao.func(AdsOverallSummary.class, "sum", "todayNewPlayerAmount", myCondition(param, false, 30)));
+        //30日内总消耗
+        BigDecimal d30TotalCost = BigDecimal.valueOf(dao.func(AdsOverallSummary.class, "sum", "todayTotalCost", myCondition(param, false, 30)));
+        //计算30日Roi
+        todayDataVO.setD30TotalRoi(d30NewPlayerAmount.divide(d30TotalCost, 4, RoundingMode.HALF_UP));
+
+        //存在首日Roi为null的情况 消耗为0 但是有用户充值 无法计算 设置为 0
+        if (todayDataVO.getFirstRoi() == null) {
+            todayDataVO.setFirstRoi(BigDecimal.ZERO);
+        }
+
+        return todayDataVO;
     }
 
     @Override
     public List<AdsOverallSummaryLineDataVO> getOverallSummaryLineData(AdsOverallSummaryParam param) {
 
-        //前端展示的折线数据对象实体
-        AdsOverallSummaryLineDataVO adsOverallSummaryLineDataVO = new AdsOverallSummaryLineDataVO();
-
         //根据条件获取数据
-        Condition lineCon = myCondition(param, true, false);
+        Condition lineCon = myCondition(param, true, -1);
         //查询条件变为字符串
-        String s = lineCon.toSql(dao.getEntity(AdsOverallSummary.class));
+        String lineConString = lineCon.toSql(dao.getEntity(AdsOverallSummary.class));
 
-        //自定义sql语句
+        //自定义sql语句 加上条件字符串
         Sql sql = Sqls.create("Select dt," +
                 "SUM(x.today_total_cost) cost, " +
-                "SUM(x.today_buy_amount)+SUM(x.today_nature_amount) amount," +
+                "SUM(x.today_amount) amount, " +
                 "SUM(x.today_buy_amount) buy_amount," +
                 "SUM(x.today_nature_amount) nature_amount, " +
-                "SUM(x.first_roi) first_roi," +
+                "SUM(x.first_new_user_amount)/SUM(x.today_total_cost) first_roi," +
                 "SUM(x.today_player_count) player_account " +
-                "from ads_overall_summary x " + s);
-
-        //拼接查询条件
-        //sql.setCondition(lineCon);
-
-
-        log.info("sql:" + sql.toString());
+                "from ads_overall_summary x " + lineConString);
 
-        //自定义回显对象
+        //自定义回显对象 结果自动添加到一个List中 List<Entity>
         sql.setCallback(Sqls.callback.entities());
         sql.setEntity(dao.getEntity(AdsOverallSummaryLineDataVO.class));
 
@@ -131,16 +147,15 @@ public class AdsOverallSummaryServiceImpl implements IAdsOverallSummaryService {
         return sql.getList(AdsOverallSummaryLineDataVO.class);
     }
 
-
     /**
      * 自定义查询条件
      *
-     * @param param            前端传递的查询参数实体
-     * @param needLocalDate    是否拼接日期查询条件
-     * @param isQueryTodayData 是否是查询今日数据
+     * @param param         前端传递的查询参数实体
+     * @param needLocalDate 是否拼接日期查询条件
+     * @param queryDays     拼接需要查询数据的天数条件(给今日昨日、首日Roi、7日Roi以及30日Roi使用)
      * @return Condition
      */
-    private Condition myCondition(AdsOverallSummaryParam param, Boolean needLocalDate, Boolean isQueryTodayData) {
+    private Condition myCondition(AdsOverallSummaryParam param, Boolean needLocalDate, Integer queryDays) {
 
         Criteria cri = Cnd.cri();
         //默认查询条件
@@ -161,9 +176,22 @@ public class AdsOverallSummaryServiceImpl implements IAdsOverallSummaryService {
             cri.where().andEquals("accountId", param.getAccountId());
         }
 
-        //如果需要查询今日及昨日数据 就指定查询日期条件为当天日期
-        if (isQueryTodayData) {
-            cri.where().andEquals("dt", LocalDate.now());
+        //根据参数拼接条件
+        switch (queryDays) {
+            case 1:
+                cri.where().andEquals("dt", LocalDate.now());
+                break;
+
+            case 7:
+                cri.where().andBetween("dt", LocalDate.now().minusDays(7), LocalDate.now());
+                break;
+
+            case 30:
+                cri.where().andBetween("dt", LocalDate.now().minusDays(30), LocalDate.now());
+                break;
+
+            default:
+                break;
         }
 
         //折线数据需要拼接时间查询条件
@@ -173,15 +201,50 @@ public class AdsOverallSummaryServiceImpl implements IAdsOverallSummaryService {
                 cri.where().andBetween("dt", param.getBeginDate(), param.getEndDate());
                 //日期排序
             } else {
-                //没有具体时间默认查询今天数据
+                //没有具体时间默认查询至今30日的数据
                 cri.where().andBetween("dt", LocalDate.now().minusDays(30), LocalDate.now());
             }
             //按日期分组
-            cri.getGroupBy().groupBy("dt").asc("dt");
+            cri.getGroupBy().groupBy("dt");
+            //按日期排序 升序
+            cri.getOrderBy().asc("dt");
         }
 
         return cri;
     }
 
+    /**
+     * 所有为空值的属性都不copy
+     *
+     * @param source
+     * @param target
+     */
+    public static void copyNullProperties(Object source, Object target) {
+        BeanUtils.copyProperties(source, target, getNullField(source));
+    }
+
+    /**
+     * 获取属性中为空的字段
+     *
+     * @param target
+     * @return
+     */
+    private static String[] getNullField(Object target) {
+        BeanWrapper beanWrapper = new BeanWrapperImpl(target);
+        PropertyDescriptor[] propertyDescriptors = beanWrapper.getPropertyDescriptors();
+        Set<String> notNullFieldSet = new HashSet<>();
+        if (propertyDescriptors.length > 0) {
+            for (PropertyDescriptor p : propertyDescriptors) {
+                String name = p.getName();
+                Object value = beanWrapper.getPropertyValue(name);
+                if (Objects.isNull(value)) {
+                    notNullFieldSet.add(name);
+                }
+            }
+        }
+        String[] notNullField = new String[notNullFieldSet.size()];
+        return notNullFieldSet.toArray(notNullField);
+    }
+
 
 }