瀏覽代碼

修改内容:推广每日复充趋势

lth 1 年之前
父節點
當前提交
0b6af21c1b

+ 17 - 8
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/controller/AccountAgentDayController.java

@@ -1,19 +1,21 @@
 package com.zanxiang.game.data.serve.controller;
 
-import com.zanxiang.erp.security.annotation.PreAuthorize;
-import com.zanxiang.game.data.serve.pojo.dto.GamePromoteDayDTO;
-import com.zanxiang.game.data.serve.pojo.dto.GamePromoteDayTotalDTO;
-import com.zanxiang.game.data.serve.pojo.dto.GamePromoteTotalDTO;
-import com.zanxiang.game.data.serve.pojo.vo.GamePromoteDayTotalVO;
-import com.zanxiang.game.data.serve.pojo.vo.GamePromoteDayVO;
-import com.zanxiang.game.data.serve.pojo.vo.GamePromoteTotalVO;
+import com.zanxiang.game.data.serve.pojo.dto.*;
+import com.zanxiang.game.data.serve.pojo.vo.*;
 import com.zanxiang.game.data.serve.service.IAccountAgentDayService;
 import com.zanxiang.game.data.serve.utils.Page;
 import com.zanxiang.module.util.pojo.ResultVO;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.LocalDate;
+import java.util.List;
+import java.util.Map;
 
 @Api(tags = "推广数据")
 @RestController
@@ -42,4 +44,11 @@ public class AccountAgentDayController {
     public ResultVO<Page<GamePromoteTotalVO>> accountAgentTotal(@RequestBody GamePromoteTotalDTO dto) {
         return ResultVO.ok(accountAgentDayService.accountAgentTotal(dto));
     }
+
+    @ApiOperation(value = "推广渠道每日复充数据")
+    //@PreAuthorize(permissionKey = "gameData:accountAgent:again")
+    @PostMapping("/again")
+    public ResultVO<Map<LocalDate, List<AgentDayAgainVO>>> accountAgentDayAgain(@RequestBody AgentDayAgainDTO dto) throws Exception {
+        return ResultVO.ok(accountAgentDayService.accountAgentDayAgain(dto));
+    }
 }

+ 31 - 1
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/dto/AgentDayAgainDTO.java

@@ -1,10 +1,14 @@
 package com.zanxiang.game.data.serve.pojo.dto;
 
+import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.math.BigInteger;
+import java.time.LocalDate;
+
 /**
  * @author tianhua
  * @time 2023/7/18
@@ -17,8 +21,34 @@ import lombok.NoArgsConstructor;
 public class AgentDayAgainDTO {
 
     /**
-     *
+     * 推广账号ID
+     */
+    @ApiModelProperty(value = "推广账号ID")
+    private BigInteger accountId;
+
+    /**
+     * 渠道ID
+     */
+    @ApiModelProperty(value = "渠道ID")
+    private BigInteger agentId;
+
+    /**
+     * 查询开始时间
+     */
+    @ApiModelProperty(value = "查询开始时间")
+    private LocalDate beginDate;
+
+    /**
+     * 查询结束时间
+     */
+    @ApiModelProperty(value = "查询结束时间(前端不需要传递)")
+    private LocalDate endDate;
+
+    /**
+     * SDK来源
      */
+    @ApiModelProperty(value = "SDK来源")
+    private String sourceSystem;
 
 
 }

+ 7 - 0
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/dto/GameDataAgainDayDTO.java

@@ -6,6 +6,7 @@ import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.math.BigInteger;
 import java.time.LocalDate;
 
 /**
@@ -19,6 +20,12 @@ import java.time.LocalDate;
 @Builder
 public class GameDataAgainDayDTO {
 
+    /**
+     * 游戏ID
+     */
+    @ApiModelProperty(value = "游戏ID")
+    private BigInteger gameId;
+
     /**
      * 游戏名称
      */

+ 117 - 0
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/entity/AdsAgentDayAgain.java

@@ -0,0 +1,117 @@
+package com.zanxiang.game.data.serve.pojo.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.nutz.dao.entity.annotation.Column;
+import org.nutz.dao.entity.annotation.PK;
+import org.nutz.dao.entity.annotation.Table;
+
+import java.math.BigInteger;
+import java.time.LocalDate;
+
+/**
+ * <p>
+ * 推广渠道每日复充趋势
+ * </p>
+ *
+ * @author tianhua
+ * @time 2023/7/11
+ * @Description
+ **/
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+@Table(AdsGameDayAgain.TABLE_NAME)
+@PK({"dt", "ddf", "accountId", "agentId", "sourceSystem"})
+public class AdsAgentDayAgain {
+    private static final long serialVersionUID = 1L;
+    public static final String TABLE_NAME = "ads_agent_day_again";
+
+    /**
+     * 日期
+     */
+    private LocalDate dt;
+
+    /**
+     * 复充日期
+     */
+    private LocalDate ddf;
+
+    /**
+     * 推广账号ID
+     */
+    private BigInteger accountId;
+
+    /**
+     * 渠道ID
+     */
+    private BigInteger agentId;
+
+    /**
+     * SDK来源
+     */
+    private String sourceSystem;
+
+    /**
+     * 渠道名称
+     */
+    @Column
+    private String agentName;
+
+    /**
+     * 充值一次
+     */
+    @Column
+    private BigInteger c1;
+
+    /**
+     * 充值大于一次
+     */
+    @Column
+    private BigInteger c2;
+
+    /**
+     * 充值大于两次
+     */
+    @Column
+    private BigInteger c3;
+
+    /**
+     * 充值大于三次
+     */
+    @Column
+    private BigInteger c4;
+
+    /**
+     * 充值大于四次
+     */
+    @Column
+    private BigInteger c5;
+
+    /**
+     * 充值大于五次
+     */
+    @Column
+    private BigInteger c6;
+
+    /**
+     * 充值大于十次
+     */
+    @Column
+    private BigInteger c7;
+
+    /**
+     * 充值大于二十次
+     */
+    @Column
+    private BigInteger c8;
+
+    /**
+     * 充值大于一百次
+     */
+    @Column
+    private BigInteger c9;
+}

+ 1 - 1
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/entity/AdsDaynGame.java

@@ -13,7 +13,7 @@ import java.time.LocalDate;
 
 /**
  * <p>
- * 游戏聚合表(按游戏聚合)
+ * 游戏聚合表(按游戏聚合)(总量)
  * </p>
  *
  * @author tianhua

+ 1 - 1
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/entity/AdsDaynGameNature.java

@@ -13,7 +13,7 @@ import java.time.LocalDate;
 
 /**
  * <p>
- * 游戏聚合表(按游戏聚合)
+ * 游戏聚合表(按游戏聚合)(自然量)
  * </p>
  *
  * @author tianhua

+ 53 - 0
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/vo/AgentDayAgainVO.java

@@ -0,0 +1,53 @@
+package com.zanxiang.game.data.serve.pojo.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+/**
+ * @author tianhua
+ * @time 2023/7/22
+ * @Description 传递给前端的推广每日复充趋势实体
+ **/
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class AgentDayAgainVO {
+
+    /**
+     * 原
+     */
+    @ApiModelProperty(value = "原(总量)")
+    private BigInteger original;
+
+    /**
+     * 现
+     */
+    @ApiModelProperty(value = "现(总量)")
+    private BigInteger present;
+
+    /**
+     * 增
+     */
+    @ApiModelProperty(value = "增(总量)")
+    private BigInteger increase;
+
+    /**
+     * 移
+     */
+    @ApiModelProperty(value = "移(总量)")
+    private BigInteger decrease;
+
+    /**
+     * 比
+     */
+    @ApiModelProperty(value = "比(总量)")
+    private BigDecimal rate;
+
+}

+ 6 - 0
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/vo/GameDataDayVO.java

@@ -21,6 +21,12 @@ import java.time.LocalDate;
 @Builder
 public class GameDataDayVO {
 
+    /**
+     * 游戏ID
+     */
+    @ApiModelProperty(value = "游戏ID")
+    private BigInteger gameId;
+
     /**
      * 推广游戏名称
      */

+ 13 - 0
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/IAccountAgentDayService.java

@@ -1,13 +1,19 @@
 package com.zanxiang.game.data.serve.service;
 
+import com.zanxiang.game.data.serve.pojo.dto.AgentDayAgainDTO;
 import com.zanxiang.game.data.serve.pojo.dto.GamePromoteDayDTO;
 import com.zanxiang.game.data.serve.pojo.dto.GamePromoteDayTotalDTO;
 import com.zanxiang.game.data.serve.pojo.dto.GamePromoteTotalDTO;
+import com.zanxiang.game.data.serve.pojo.vo.AgentDayAgainVO;
 import com.zanxiang.game.data.serve.pojo.vo.GamePromoteDayTotalVO;
 import com.zanxiang.game.data.serve.pojo.vo.GamePromoteDayVO;
 import com.zanxiang.game.data.serve.pojo.vo.GamePromoteTotalVO;
 import com.zanxiang.game.data.serve.utils.Page;
 
+import java.time.LocalDate;
+import java.util.List;
+import java.util.Map;
+
 public interface IAccountAgentDayService {
     /**
      * 推广每日数据
@@ -29,4 +35,11 @@ public interface IAccountAgentDayService {
      * @return
      */
     Page<GamePromoteTotalVO> accountAgentTotal(GamePromoteTotalDTO dto);
+
+    /**
+     * 推广每日复充趋势
+     * @param dto
+     * @return
+     */
+    Map<LocalDate, List<AgentDayAgainVO>> accountAgentDayAgain(AgentDayAgainDTO dto);
 }

+ 173 - 6
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/AccountAgentDayServiceImpl.java

@@ -3,19 +3,17 @@ package com.zanxiang.game.data.serve.service.impl;
 import com.google.common.base.CaseFormat;
 import com.google.gson.Gson;
 import com.zanxiang.erp.security.util.SecurityUtil;
+import com.zanxiang.game.data.serve.pojo.dto.AgentDayAgainDTO;
 import com.zanxiang.game.data.serve.pojo.dto.GamePromoteDayDTO;
 import com.zanxiang.game.data.serve.pojo.dto.GamePromoteDayTotalDTO;
 import com.zanxiang.game.data.serve.pojo.dto.GamePromoteTotalDTO;
-import com.zanxiang.game.data.serve.pojo.entity.AdsAccountAgentDay;
+import com.zanxiang.game.data.serve.pojo.entity.*;
 import com.zanxiang.game.data.serve.pojo.enums.OrderByEnum;
-import com.zanxiang.game.data.serve.pojo.vo.GamePromoteDayTotalVO;
-import com.zanxiang.game.data.serve.pojo.vo.GamePromoteDayVO;
-import com.zanxiang.game.data.serve.pojo.vo.GamePromoteTotalVO;
-import com.zanxiang.game.data.serve.pojo.vo.RechargeTrendVO;
+import com.zanxiang.game.data.serve.pojo.vo.*;
 import com.zanxiang.game.data.serve.service.IAccountAgentDayService;
 import com.zanxiang.game.data.serve.utils.Page;
 import com.zanxiang.module.util.DateUtil;
-import io.swagger.annotations.ApiModelProperty;
+import com.zanxiang.module.util.exception.BaseException;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
@@ -27,6 +25,7 @@ import org.nutz.dao.Dao;
 import org.nutz.dao.Sqls;
 import org.nutz.dao.entity.Entity;
 import org.nutz.dao.pager.Pager;
+import org.nutz.dao.sql.Criteria;
 import org.nutz.dao.sql.Sql;
 import org.nutz.dao.util.Daos;
 import org.nutz.dao.util.cri.SimpleCriteria;
@@ -34,7 +33,9 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
+import java.lang.reflect.Method;
 import java.math.BigDecimal;
+import java.math.BigInteger;
 import java.math.RoundingMode;
 import java.time.LocalDate;
 import java.util.ArrayList;
@@ -441,6 +442,172 @@ public class AccountAgentDayServiceImpl implements IAccountAgentDayService {
         return new Page<>(hasRechargeDayList, pager);
     }
 
+    @Override
+    public Map<LocalDate, List<AgentDayAgainVO>> accountAgentDayAgain(AgentDayAgainDTO dto) {
+
+        //如果查询时间不传递默认从今天开始查询
+        if (dto.getBeginDate() == null) {
+            dto.setBeginDate(LocalDate.now());
+        }
+        //判断开始时间后的30天是否超过当前日期
+        if (dto.getBeginDate().plusDays(30).isAfter(LocalDate.now())) {
+            //只查询到当前的数据
+            dto.setEndDate(LocalDate.now());
+        } else {
+            //只考虑30天的数据
+            dto.setEndDate(dto.getBeginDate().plusDays(30));
+        }
+        //拼接查询条件
+        Criteria cri = Cnd.cri();
+        if (dto.getAccountId() != null){
+            cri.where().andEquals("account_id",dto.getAccountId());
+        }
+        if (dto.getAgentId() != null){
+            cri.where().andEquals("agent_id",dto.getAgentId());
+        }
+        if (StringUtils.isNotBlank(dto.getSourceSystem())) {
+            //拼接SDK来源
+            cri.where().andEquals("source_system", dto.getSourceSystem());
+        }
+        if (dto.getBeginDate() != null) {
+            cri.where().andEquals("dt", dto.getBeginDate());
+            cri.where().andBetween("ddf", dto.getBeginDate(), dto.getEndDate());
+        }
+        //按 "ddf" 升序排序
+        cri.getOrderBy().asc("ddf");
+
+        //获取推广每日复充表的查询结果
+        Sql againSql = Sqls.create( agentDayAgainSql() + cri);
+        againSql.setCallback(Sqls.callback.entities());
+        againSql.setEntity(dao.getEntity(AdsAgentDayAgain.class));
+        //执行sql
+        dao.execute(againSql);
+        //获取到原始数据list
+        List<AdsAgentDayAgain> list = againSql.getList(AdsAgentDayAgain.class);
+
+        //创建Map记录数据
+        Map<LocalDate, List<AgentDayAgainVO>> map = new HashMap<>();
+        //有序存储每个list,每个list包含当天的所有充值次数的复充数据
+        List<List<AgentDayAgainVO>> tempList = new ArrayList<>();
+        //记录查询出的记录条数
+        int count = list.size();
+        //初始化list
+        initList(tempList, count);
+
+        //外层循环8次 表示不同复充次数的数据
+        for (int i = 0; i < 8; i++) {
+            //用来计算Ci
+            int ci = i + 1;
+            //第一天的所有充值次数都是先计算的
+            AgentDayAgainVO tempVO = tempList.get(0).get(i);
+            //"原": Ci
+            tempList.get(0).get(i).setOriginal(getCnByNum(list.get(0), ci));
+            //"增":初始为 0
+            tempList.get(0).get(i).setIncrease(BigInteger.ZERO);
+            //"移":下一个充值次数的Ci 即C(i+1)
+            tempList.get(0).get(i).setDecrease(getCnByNum(list.get(0), ci + 1));
+            //"现":公式计算 = 原 + 增 - 移
+            tempList.get(0).get(i).setPresent(
+                    tempVO.getOriginal().add(tempVO.getIncrease()).subtract(tempVO.getDecrease())
+            );
+            //"比"
+            tempList.get(0).get(i).setRate(getCnByNum(list.get(0), 1).compareTo(BigInteger.ZERO) == 0 ? BigDecimal.ZERO :
+                    BigDecimal.valueOf(tempVO.getPresent().doubleValue() / getCnByNum(list.get(0), 1).doubleValue()).setScale(4, RoundingMode.HALF_UP)
+            );
+
+            //计算第2-n天的数据 复充次数i的数据
+            for (int j = 1; j < count; j++) {
+                //"原":前一天的"现"
+                tempList.get(j).get(i).setOriginal(tempList.get(j - 1).get(i).getPresent());
+                //"现":当天的Ci - 当天的C(i+1)
+                tempList.get(j).get(i).setPresent(
+                        getCnByNum(list.get(j), ci).subtract(getCnByNum(list.get(j), ci + 1)));
+                //"增":当天的Ci - 前一天的Ci
+                tempList.get(j).get(i).setIncrease(
+                        getCnByNum(list.get(j), ci).subtract(getCnByNum(list.get(j - 1), ci)));
+                //"移":当天的C(i+1) - 前一天的C(i+1)
+                tempList.get(j).get(i).setDecrease(
+                        getCnByNum(list.get(j), ci + 1).subtract(getCnByNum(list.get(j - 1), ci + 1)));
+                //"比":当天的现 / 前一天的C1
+                tempList.get(j).get(i).setRate(getCnByNum(list.get(j - 1), 1).compareTo(BigInteger.ZERO) == 0 ? BigDecimal.ZERO :
+                        BigDecimal.valueOf(tempList.get(j).get(i).getPresent().doubleValue() / getCnByNum(list.get(j - 1), 1).doubleValue()).setScale(4, RoundingMode.HALF_UP));
+            }
+        }
+        //赋值时间数据
+        for (int i = 0; i < tempList.size(); i++) {
+            map.put(list.get(i).getDdf(), tempList.get(i));
+        }
+
+        return map;
+    }
+
+    /**
+     * 初始化List数据
+     * @param list 需要初始化的数据
+     * @param num 多少天的数据
+     */
+    private void initList(List<List<AgentDayAgainVO>> list, Integer num) {
+        //外层循环 num 次 表示多少天的数据
+        for (int i = 0; i < num; i++) {
+            list.add(new ArrayList<>());
+            //内层循环8次 一共初始化8种复充次数数据对象
+            for (int j = 0; j < 8; j++) {
+                list.get(i).add(
+                        AgentDayAgainVO.builder()
+                                .decrease(BigInteger.ZERO)
+                                .increase(BigInteger.ZERO)
+                                .original(BigInteger.ZERO)
+                                .present(BigInteger.ZERO)
+                                .rate(BigDecimal.ZERO)
+                                .build()
+                );
+            }
+        }
+    }
+
+    /**
+     * 通过反射来获取Cn的值
+     * @param dto 数据库查询出来的原始数据对象实体
+     * @param num 1-9
+     * @return Cn
+     */
+    private BigInteger getCnByNum(Object dto, int num) {
+        try {
+            Method m1 = AdsAgentDayAgain.class.getDeclaredMethod(String.format("getC%s", num));
+            //返回对应的Cn值
+            return (BigInteger) m1.invoke(dto);
+        } catch (Exception e) {
+            throw new BaseException("发生错误");
+        }
+    }
+
+    /**
+     * 推广每日复充趋势sql
+     * @return
+     */
+    private String agentDayAgainSql() {
+        return """
+                SELECT
+                    dt,
+                    ddf,
+                    account_id,
+                    agent_id,
+                    agent_name,
+                    source_system,
+                    c1,
+                    c2,
+                    c3,
+                    c4,
+                    c5,
+                    c6,
+                    c7,
+                    c8,
+                    c9
+                FROM
+                    ads_agent_day_again
+                """;
+    }
+
     /**
      * 推广每日数据SQL
      * @return

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

@@ -721,6 +721,9 @@ public class GameDataServiceImpl implements IGameDataService {
         if (StringUtils.isNotBlank(dto.getGameName())) {
             cri.where().andEquals("game_name", dto.getGameName());
         }
+        if (dto.getGameId() != null){
+            cri.where().andEquals("game_id",dto.getGameId());
+        }
         if (dto.getBeginDate() != null) {
             cri.where().andEquals("dt", dto.getBeginDate());
             cri.where().andBetween("ddf", dto.getBeginDate(), dto.getEndDate());
@@ -1102,6 +1105,7 @@ public class GameDataServiceImpl implements IGameDataService {
                 SELECT
                     dt cost_date,
                     game_name,
+                    game_id,
                     game_classify,
                                     
                     buy_reg_num,