Forráskód Böngészése

Merge branch 'package' of GameCenter/game-center into dev

zhimo 11 hónapja
szülő
commit
697baedd3c
39 módosított fájl, 1548 hozzáadás és 609 törlés
  1. 0 1
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/config/CheckConfig.java
  2. 0 1
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/controller/AdsPromotionDayController.java
  3. 8 3
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/controller/GameMonitorAlarmController.java
  4. 22 5
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/controller/GameUserConfigController.java
  5. 0 1
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/controller/RankingController.java
  6. 7 10
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/controller/RoleManageController.java
  7. 37 0
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/dto/GameUserConfigCreateOrUpdateDTO.java
  8. 30 0
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/entity/GameUserConfig.java
  9. 3 0
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/vo/AdsOrderDetailVO.java
  10. 0 3
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/vo/GSGameServerDayVO.java
  11. 8 0
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/vo/GSServerRetentionVO.java
  12. 52 0
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/vo/GameDataDayTotalVO.java
  13. 55 0
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/vo/GameDataDayVO.java
  14. 51 0
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/vo/GameDataTotalTotalVO.java
  15. 51 0
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/vo/GameDataTotalVO.java
  16. 7 1
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/IGameServerService.java
  17. 22 0
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/IGameUserConfigService.java
  18. 2 3
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/AdsOrderDetailServiceImpl.java
  19. 0 2
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/GSGameServerTotalRVo.java
  20. 615 130
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/GameDataServiceImpl.java
  21. 85 42
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/GameServerServiceImpl.java
  22. 49 2
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/GameUserConfigServiceImpl.java
  23. 0 1
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/IWebVisitLogServiceImpl.java
  24. 4 1
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/PitcherDataServiceImpl.java
  25. 3 7
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/RoleManageServiceImpl.java
  26. 7 4
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/task/GameMonitorAlarmTask.java
  27. 0 1
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/task/OrderCostMonitorAlarmTask.java
  28. 1 1
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/ManageApplication.java
  29. 46 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/controller/api/CpServerApi.java
  30. 53 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/params/ChatSubmitParam.java
  31. 65 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/params/OpenGameServerParam.java
  32. 4 17
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/rpc/impl/PayBoxRpcImpl.java
  33. 0 23
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IAppletCheckService.java
  34. 18 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IListenCallService.java
  35. 129 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/api/CpServerApiService.java
  36. 0 289
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/AppletCheckServiceImpl.java
  37. 109 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/ListenCallServiceImpl.java
  38. 0 61
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/task/PayApplicationTask.java
  39. 5 0
      game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/entity/GameSupper.java

+ 0 - 1
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/config/CheckConfig.java

@@ -1,6 +1,5 @@
 package com.zanxiang.game.data.serve.config;
 
-import com.aliyun.tea.interceptor.RequestInterceptor;
 import com.zanxiang.game.data.serve.intercept.WebVisitLogIntercept;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;

+ 0 - 1
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/controller/AdsPromotionDayController.java

@@ -1,7 +1,6 @@
 package com.zanxiang.game.data.serve.controller;
 
 import com.zanxiang.erp.security.annotation.PreAuthorize;
-import com.zanxiang.game.data.serve.annotation.Log;
 import com.zanxiang.game.data.serve.pojo.dto.PromotionDayDTO;
 import com.zanxiang.game.data.serve.pojo.dto.PromotionDayTotalDTO;
 import com.zanxiang.game.data.serve.pojo.dto.TencentPromotionDayDTO;

+ 8 - 3
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/controller/GameMonitorAlarmController.java

@@ -1,6 +1,7 @@
 package com.zanxiang.game.data.serve.controller;
 
 import com.zanxiang.game.data.serve.service.IGameMonitorAlarmService;
+import com.zanxiang.game.data.serve.service.IGameServerService;
 import com.zanxiang.game.data.serve.service.IOrderCostMonitorAlarmService;
 import com.zanxiang.module.util.pojo.ResultVO;
 import io.swagger.annotations.Api;
@@ -11,6 +12,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
+import java.util.List;
 
 /**
  * @author tianhua
@@ -27,6 +29,8 @@ public class GameMonitorAlarmController {
     private IGameMonitorAlarmService gameMonitorAlarmService;
     @Resource
     private IOrderCostMonitorAlarmService orderCostMonitorAlarmService;
+    @Resource
+    private IGameServerService gameServerService;
 
     @ApiOperation(value = "发送钉钉消息")
     @PutMapping("/sendMsg")
@@ -35,10 +39,11 @@ public class GameMonitorAlarmController {
     }
 
 
-    @ApiOperation(value = "监控")
+    @ApiOperation(value = "测试")
     @PutMapping("/monitor")
-    public ResultVO<Boolean> monitor() {
-        orderCostMonitorAlarmService.testSendSms("测试短信");
+    public ResultVO<Boolean> test() {
+        List<String> serverIdByGSId = gameServerService.getServerIdByGSId(120L);
+        serverIdByGSId.forEach(System.out::println);
 //        orderCostMonitorAlarmService.monitorTencentCostStatus();
 //        orderCostMonitorAlarmService.monitorDataStatus();
         return ResultVO.ok();

+ 22 - 5
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/controller/GameUserConfigController.java

@@ -1,6 +1,7 @@
 package com.zanxiang.game.data.serve.controller;
 
 import com.zanxiang.erp.security.annotation.PreAuthorize;
+import com.zanxiang.game.data.serve.pojo.dto.GameUserConfigCreateOrUpdateDTO;
 import com.zanxiang.game.data.serve.pojo.dto.GameUserConfigListDTO;
 import com.zanxiang.game.data.serve.pojo.vo.GameUserConfigListVO;
 import com.zanxiang.game.data.serve.service.IGameUserConfigService;
@@ -8,13 +9,9 @@ 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 lombok.Data;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.validation.annotation.Validated;
-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 org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 
@@ -41,4 +38,24 @@ public class GameUserConfigController {
         return ResultVO.ok(gameUserConfigService.validRoleConfigList(dto));
     }
 
+    @ApiOperation(value = "新增有效创角配置")
+    @PreAuthorize(permissionKey = "roleManage:validRoleConfig:create")
+    @PostMapping(value = "/create")
+    public ResultVO<Boolean> create(@Validated @RequestBody GameUserConfigCreateOrUpdateDTO dto) {
+        return ResultVO.ok(gameUserConfigService.create(dto));
+    }
+    @ApiOperation(value = "修改有效创角配置")
+    @PreAuthorize(permissionKey = "roleManage:validRoleConfig:update")
+    @PostMapping(value = "/update")
+    public ResultVO<Boolean> update(@Validated @RequestBody GameUserConfigCreateOrUpdateDTO dto) {
+        return ResultVO.ok(gameUserConfigService.update(dto));
+    }
+
+    @ApiOperation(value = "删除有效创角配置")
+    @PreAuthorize(permissionKey = "roleManage:validRoleConfig:delete")
+    @PostMapping(value = "/delete")
+    public ResultVO<Boolean> delete(@RequestParam("id") Long id) {
+        return ResultVO.ok(gameUserConfigService.delete(id));
+    }
+
 }

+ 0 - 1
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/controller/RankingController.java

@@ -3,7 +3,6 @@ package com.zanxiang.game.data.serve.controller;
 import com.zanxiang.erp.security.annotation.PreAuthorize;
 import com.zanxiang.game.data.serve.pojo.dto.AdsAccountRechargeRankingListDTO;
 import com.zanxiang.game.data.serve.pojo.dto.AdsAgentRechargeRankingListDTO;
-import com.zanxiang.game.data.serve.pojo.dto.GamePromoteDayDTO;
 import com.zanxiang.game.data.serve.pojo.dto.RechargeRankingDTO;
 import com.zanxiang.game.data.serve.pojo.vo.AdsAccountRechargeRankingVO;
 import com.zanxiang.game.data.serve.pojo.vo.AdsAgentRechargeRankingVO;

+ 7 - 10
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/controller/RoleManageController.java

@@ -1,23 +1,20 @@
 package com.zanxiang.game.data.serve.controller;
 
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.zanxiang.game.data.serve.annotation.Log;
-import com.zanxiang.game.data.serve.pojo.dto.*;
-import com.zanxiang.game.data.serve.pojo.vo.GameUserConfigListVO;
-import com.zanxiang.game.module.base.pojo.vo.SendMsgResultVO;
-import com.zanxiang.game.module.base.pojo.vo.SendMsgVO;
 import com.zanxiang.erp.security.annotation.PreAuthorize;
+import com.zanxiang.game.data.serve.pojo.dto.*;
 import com.zanxiang.game.data.serve.service.IRoleManageService;
 import com.zanxiang.game.data.serve.utils.Page;
+import com.zanxiang.game.module.base.pojo.vo.SendMsgResultVO;
+import com.zanxiang.game.module.base.pojo.vo.SendMsgVO;
 import com.zanxiang.module.util.pojo.ResultVO;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiResponse;
-import io.swagger.annotations.ApiResponses;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.validation.annotation.Validated;
-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 javax.validation.Valid;
 import java.util.Map;

+ 37 - 0
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/dto/GameUserConfigCreateOrUpdateDTO.java

@@ -0,0 +1,37 @@
+package com.zanxiang.game.data.serve.pojo.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * packageName com.zanxiang.game.data.serve.pojo.dto
+ *
+ * @author ZhangXianyu
+ * @date 2024/4/22
+ * @description 用户配置新增修改DTO
+ */
+@Data
+public class GameUserConfigCreateOrUpdateDTO {
+
+    /**
+     * 主键id
+     */
+    @ApiModelProperty(notes = "主键id, 传则是更新, 不传则是添加")
+    private Long id;
+
+    /**
+     * 游戏id
+     */
+    @NotNull(message = "游戏id不可为空, 必传")
+    @ApiModelProperty(notes = "游戏id")
+    private Long gameId;
+
+    /**
+     * 游戏角色等级
+     */
+    @NotNull(message = "游戏角色等级不可为空, 必传")
+    @ApiModelProperty(notes = "游戏角色等级")
+    private Long roleLevel;
+}

+ 30 - 0
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/entity/GameUserConfig.java

@@ -0,0 +1,30 @@
+package com.zanxiang.game.data.serve.pojo.entity;
+
+import lombok.Data;
+import org.nutz.dao.entity.annotation.Id;
+import org.nutz.dao.entity.annotation.Prev;
+import org.nutz.dao.entity.annotation.SQL;
+import org.nutz.dao.entity.annotation.Table;
+
+import java.time.LocalDateTime;
+
+/**
+ * packageName com.zanxiang.game.data.serve.pojo.entity
+ *
+ * @author ZhangXianyu
+ * @date 2024/4/22
+ * @description 游戏角色有效创角配置
+ */
+@Data
+@Table("dm_game_order.t_game_user_config")
+public class GameUserConfig {
+    @Prev( @SQL("SELECT IFNULL(MAX(id),0)+1 FROM dm_game_order.t_game_user_config") )
+    @Id(auto = false)
+    private Long id;
+    private String sourceSystem;
+    private Long gameId;
+    private Long roleLevel;
+    private LocalDateTime createTime;
+    private LocalDateTime updateTime;
+
+}

+ 3 - 0
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/vo/AdsOrderDetailVO.java

@@ -10,6 +10,9 @@ import java.time.LocalDateTime;
 @Data
 public class AdsOrderDetailVO {
 
+    @ApiModelProperty(value = "主键")
+    private Long id;
+
     @ApiModelProperty(notes = "订单创建日期")
     private LocalDate day;
 

+ 0 - 3
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/vo/GSGameServerDayVO.java

@@ -2,12 +2,9 @@ package com.zanxiang.game.data.serve.pojo.vo;
 
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
-import org.ini4j.Reg;
-import org.nutz.dao.entity.annotation.Many;
 
 import java.io.Serializable;
 import java.time.LocalDate;
-import java.util.List;
 
 /**
  * @author ZhangXianyu

+ 8 - 0
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/vo/GSServerRetentionVO.java

@@ -65,6 +65,14 @@ public class GSServerRetentionVO {
      * 超大r人数
      */
     private String superRNum;
+    /**
+     * R总
+     */
+    private String rTotal;
+    /**
+     * R总留存率
+     */
+    private String rTotalRetention;
 
 
 }

+ 52 - 0
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/vo/GameDataDayTotalVO.java

@@ -1117,4 +1117,56 @@ public class GameDataDayTotalVO {
     @ApiModelProperty(value = "da1的用户详情")
     private FirstNewUserAgainTrendVO userDetails;
 
+
+    @ApiModelProperty(value = "首日有效创角人数")
+    private Long firstEffectiveRoleNum;
+
+    @ApiModelProperty(value = "新用户累计有效创角人数")
+    private Long newUserTotalEffectiveRoleNum;
+
+    @ApiModelProperty(value =  "有效创角人数")
+    private Long effectiveRoleNum;
+
+    @ApiModelProperty(value = "首日有效创角率")
+    private BigDecimal firstEffectiveRoleRate;
+
+    @ApiModelProperty(value = "新用户累计有效创角率")
+    private BigDecimal newUserTotalEffectiveRoleNumRate;
+
+    @ApiModelProperty(value = "有效创角率")
+    private BigDecimal effectiveRoleNumRate;
+
+    @ApiModelProperty(value = "首日有效创角成本")
+    private Long firstEffectiveRoleNumCost;
+
+    @ApiModelProperty(value = "新用户累计有效创角成本")
+    private Long newUserTotalEffectiveRoleNumCost;
+
+    @ApiModelProperty(value = "有效创角成本")
+    private Long effectiveRoleNumCost;
+
+    @ApiModelProperty(value = "首日有效创角付费人数")
+    private Long firstEffectiveRoleAmountNum;
+
+    @ApiModelProperty(value = "新用户累计有效创角付费人数")
+    private Long newUserTotalEffectiveRoleAmountNum;
+
+    @ApiModelProperty(value = "首日有效创角付费成本")
+    private Long firstEffectiveRoleAmountNumCost;
+
+    @ApiModelProperty(value = "新用户累计有效创角付费成本")
+    private Long newUserTotalEffectiveRoleAmountNumCost;
+
+    @ApiModelProperty(value = "首日有效创角付费比")
+    private BigDecimal firstEffectiveRoleAmountNumRate;
+
+    @ApiModelProperty(value = "新用户累计有效创角付费比")
+    private BigDecimal newUserTotalEffectiveRoleAmountNumRate;
+
+    @ApiModelProperty(value = "首日有效创角ARPU")
+    private BigDecimal firstEffectiveRoleArpu;
+
+    @ApiModelProperty(value = "新用户累计有效创角XARPU")
+    private BigDecimal newUserTotalEffectiveRoleArpu;
+
 }

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

@@ -1142,4 +1142,59 @@ public class GameDataDayVO {
     @ApiModelProperty(value = "da1的用户详情")
     private FirstNewUserAgainTrendVO userDetails;
 
+
+    @ApiModelProperty(value = "首日有效创角人数")
+    private Long firstEffectiveRoleNum;
+
+    @ApiModelProperty(value = "新用户累计有效创角人数")
+    private Long newUserTotalEffectiveRoleNum;
+
+    @ApiModelProperty(value =  "有效创角人数")
+    private Long effectiveRoleNum;
+
+    @ApiModelProperty(value = "首日有效创角率")
+    private BigDecimal firstEffectiveRoleRate;
+
+    @ApiModelProperty(value = "新用户累计有效创角率")
+    private BigDecimal newUserTotalEffectiveRoleNumRate;
+
+    @ApiModelProperty(value = "有效创角率")
+    private BigDecimal effectiveRoleNumRate;
+
+    @ApiModelProperty(value = "首日有效创角成本")
+    private Long firstEffectiveRoleNumCost;
+
+    @ApiModelProperty(value = "新用户累计有效创角成本")
+    private Long newUserTotalEffectiveRoleNumCost;
+
+    @ApiModelProperty(value = "有效创角成本")
+    private Long effectiveRoleNumCost;
+
+    @ApiModelProperty(value = "首日有效创角付费人数")
+    private Long firstEffectiveRoleAmountNum;
+
+    @ApiModelProperty(value = "新用户累计有效创角付费人数")
+    private Long newUserTotalEffectiveRoleAmountNum;
+
+    @ApiModelProperty(value = "首日有效创角付费成本")
+    private Long firstEffectiveRoleAmountNumCost;
+
+    @ApiModelProperty(value = "新用户累计有效创角付费成本")
+    private Long newUserTotalEffectiveRoleAmountNumCost;
+
+    @ApiModelProperty(value = "首日有效创角付费比")
+    private BigDecimal firstEffectiveRoleAmountNumRate;
+
+    @ApiModelProperty(value = "新用户累计有效创角付费比")
+    private BigDecimal newUserTotalEffectiveRoleAmountNumRate;
+
+    @ApiModelProperty(value = "首日有效创角ARPU")
+    private BigDecimal firstEffectiveRoleArpu;
+
+    @ApiModelProperty(value = "新用户累计有效创角ARPU")
+    private BigDecimal newUserTotalEffectiveRoleArpu;
+
+
+
+
 }

+ 51 - 0
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/vo/GameDataTotalTotalVO.java

@@ -278,4 +278,55 @@ public class GameDataTotalTotalVO {
     @ApiModelProperty(value = "新用户累计创角率(总量)")
     private BigDecimal newUserTotalRoleNumRate;
 
+    @ApiModelProperty(value = "首日有效创角人数")
+    private Long firstEffectiveRoleNum;
+
+    @ApiModelProperty(value = "新用户累计有效创角人数")
+    private Long newUserTotalEffectiveRoleNum;
+
+    @ApiModelProperty(value =  "有效创角人数")
+    private Long effectiveRoleNum;
+
+    @ApiModelProperty(value = "首日有效创角率")
+    private BigDecimal firstEffectiveRoleRate;
+
+    @ApiModelProperty(value = "新用户累计有效创角率")
+    private BigDecimal newUserTotalEffectiveRoleNumRate;
+
+    @ApiModelProperty(value = "有效创角率")
+    private BigDecimal effectiveRoleNumRate;
+
+    @ApiModelProperty(value = "首日有效创角成本")
+    private Long firstEffectiveRoleNumCost;
+
+    @ApiModelProperty(value = "新用户累计有效创角成本")
+    private Long newUserTotalEffectiveRoleNumCost;
+
+    @ApiModelProperty(value = "有效创角成本")
+    private Long effectiveRoleNumCost;
+
+    @ApiModelProperty(value = "首日有效创角付费人数")
+    private Long firstEffectiveRoleAmountNum;
+
+    @ApiModelProperty(value = "新用户累计有效创角付费人数")
+    private Long newUserTotalEffectiveRoleAmountNum;
+
+    @ApiModelProperty(value = "首日有效创角付费成本")
+    private Long firstEffectiveRoleAmountNumCost;
+
+    @ApiModelProperty(value = "新用户累计有效创角付费成本")
+    private Long newUserTotalEffectiveRoleAmountNumCost;
+
+    @ApiModelProperty(value = "首日有效创角付费比")
+    private BigDecimal firstEffectiveRoleAmountNumRate;
+
+    @ApiModelProperty(value = "新用户累计有效创角付费比")
+    private BigDecimal newUserTotalEffectiveRoleAmountNumRate;
+
+    @ApiModelProperty(value = "首日有效创角ARPU")
+    private BigDecimal firstEffectiveRoleArpu;
+
+    @ApiModelProperty(value = "新用户累计有效创角ARPU")
+    private BigDecimal newUserTotalEffectiveRoleArpu;
+
 }

+ 51 - 0
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/vo/GameDataTotalVO.java

@@ -296,4 +296,55 @@ public class GameDataTotalVO {
     @ApiModelProperty(value = "新用户累计创角率(总量)")
     private BigDecimal newUserTotalRoleNumRate;
 
+    @ApiModelProperty(value = "首日有效创角人数")
+    private Long firstEffectiveRoleNum;
+
+    @ApiModelProperty(value = "新用户累计有效创角人数")
+    private Long newUserTotalEffectiveRoleNum;
+
+    @ApiModelProperty(value =  "有效创角人数")
+    private Long effectiveRoleNum;
+
+    @ApiModelProperty(value = "首日有效创角率")
+    private BigDecimal firstEffectiveRoleRate;
+
+    @ApiModelProperty(value = "新用户累计有效创角率")
+    private BigDecimal newUserTotalEffectiveRoleNumRate;
+
+    @ApiModelProperty(value = "有效创角率")
+    private BigDecimal effectiveRoleNumRate;
+
+    @ApiModelProperty(value = "首日有效创角成本")
+    private Long firstEffectiveRoleNumCost;
+
+    @ApiModelProperty(value = "新用户累计有效创角成本")
+    private Long newUserTotalEffectiveRoleNumCost;
+
+    @ApiModelProperty(value = "有效创角成本")
+    private Long effectiveRoleNumCost;
+
+    @ApiModelProperty(value = "首日有效创角付费人数")
+    private Long firstEffectiveRoleAmountNum;
+
+    @ApiModelProperty(value = "新用户累计有效创角付费人数")
+    private Long newUserTotalEffectiveRoleAmountNum;
+
+    @ApiModelProperty(value = "首日有效创角付费成本")
+    private Long firstEffectiveRoleAmountNumCost;
+
+    @ApiModelProperty(value = "新用户累计有效创角付费成本")
+    private Long newUserTotalEffectiveRoleAmountNumCost;
+
+    @ApiModelProperty(value = "首日有效创角付费比")
+    private BigDecimal firstEffectiveRoleAmountNumRate;
+
+    @ApiModelProperty(value = "新用户累计有效创角付费比")
+    private BigDecimal newUserTotalEffectiveRoleAmountNumRate;
+
+    @ApiModelProperty(value = "首日有效创角ARPU")
+    private BigDecimal firstEffectiveRoleArpu;
+
+    @ApiModelProperty(value = "新用户累计有效创角ARPU")
+    private BigDecimal newUserTotalEffectiveRoleArpu;
+
 }

+ 7 - 1
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/IGameServerService.java

@@ -1,6 +1,5 @@
 package com.zanxiang.game.data.serve.service;
 
-import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.zanxiang.game.data.serve.pojo.dto.*;
 import com.zanxiang.game.data.serve.pojo.vo.*;
 import com.zanxiang.game.data.serve.utils.Page;
@@ -51,6 +50,13 @@ public interface IGameServerService {
      */
     Page<GSGameServerDayVO> getGSGameServerDataDay(GSGameServerDayDTO dto);
 
+    /**
+     * 根据GSId得到区服列表
+     * @param gsId
+     * @return
+     */
+    public List<String> getServerIdByGSId(Long gsId);
+
     /**
      * GS区服总数据
      * @param dto

+ 22 - 0
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/IGameUserConfigService.java

@@ -1,5 +1,6 @@
 package com.zanxiang.game.data.serve.service;
 
+import com.zanxiang.game.data.serve.pojo.dto.GameUserConfigCreateOrUpdateDTO;
 import com.zanxiang.game.data.serve.pojo.dto.GameUserConfigListDTO;
 import com.zanxiang.game.data.serve.pojo.vo.GameUserConfigListVO;
 import com.zanxiang.game.data.serve.utils.Page;
@@ -12,4 +13,25 @@ public interface IGameUserConfigService {
      * @return
      */
     Page<GameUserConfigListVO> validRoleConfigList(GameUserConfigListDTO dto);
+
+    /**
+     * 新增有效创角配置
+     * @param dto
+     * @return
+     */
+    Boolean create(GameUserConfigCreateOrUpdateDTO dto);
+
+    /**
+     * 删除有效创角配置
+     * @param id
+     * @return
+     */
+    Boolean delete(Long id);
+
+    /**
+     * 修改有效创角配置
+     * @param dto
+     * @return
+     */
+    Boolean update(GameUserConfigCreateOrUpdateDTO dto);
 }

+ 2 - 3
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/AdsOrderDetailServiceImpl.java

@@ -27,7 +27,6 @@ import org.nutz.dao.sql.Sql;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -425,7 +424,7 @@ public class AdsOrderDetailServiceImpl implements IAdsOrderDetailService {
                  		l.back_table_name as back_table_name -- 回传表名
                 	FROM dm_game_order.t_game_order a
                 	LEFT JOIN dm_game_order.t_game_user_role ab
-                	on a.source_system = ab.source_system AND a.role_id = ab.role_id AND a.user_id = ab.user_id
+                	on a.source_system = ab.source_system AND a.role_id = ab.role_id AND a.user_id = ab.user_id and a.game_id = ab.game_id
                 	LEFT JOIN dm_game_order.t_game_user_burst b
                 	on a.source_system = b.source_system AND a.user_id = b.id AND ab.create_time >= b.create_time AND ab.create_time <b.end_time
                 	LEFT JOIN dm_game_order.t_pitcher_agent c on a.source_system = c.source_system AND a.agent_id = c.id
@@ -596,7 +595,7 @@ public class AdsOrderDetailServiceImpl implements IAdsOrderDetailService {
                  		l.back_table_name as back_table_name -- 回传表名
                 	FROM dm_game_order.t_game_order a
                 	LEFT JOIN dm_game_order.t_game_user_role ab
-                	on a.source_system = ab.source_system AND a.role_id = ab.role_id AND a.user_id = ab.user_id
+                	on a.source_system = ab.source_system AND a.role_id = ab.role_id AND a.user_id = ab.user_id and a.game_id = ab.game_id
                 	LEFT JOIN dm_game_order.t_game_user_burst b
                 	on a.source_system = b.source_system AND a.user_id = b.id AND ab.create_time >= b.create_time AND ab.create_time <b.end_time
                 	LEFT JOIN dm_game_order.t_pitcher_agent c on a.source_system = c.source_system AND a.agent_id = c.id

+ 0 - 2
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/GSGameServerTotalRVo.java

@@ -2,8 +2,6 @@ package com.zanxiang.game.data.serve.service.impl;
 
 import lombok.Data;
 
-import java.time.LocalDate;
-
 /**
  * packageName com.zanxiang.game.data.serve.service.impl
  *

+ 615 - 130
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/GameDataServiceImpl.java

@@ -8,7 +8,6 @@ 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.*;
 import com.zanxiang.game.data.serve.service.IGameDataService;
-import com.zanxiang.game.data.serve.service.IRoleManageService;
 import com.zanxiang.game.data.serve.utils.Page;
 import com.zanxiang.module.util.DateUtil;
 import com.zanxiang.module.util.exception.BaseException;
@@ -750,7 +749,6 @@ public class GameDataServiceImpl implements IGameDataService {
     public Page<GameDataTotalVO> getGameDataTotal(GameDataTotalDTO dto) {
         com.github.sd4324530.jtuple.Tuple2<List<Long>, List<Long>> poerInfo = dataPowerComponent.getPowerInfo(dto.getSourceSystem());
         List<Long> gameIds = CollectionUtils.isEmpty(dto.getGameId()) ? poerInfo.second : dto.getGameId();
-
         if (dto.getGameDimension() == null) {
             //默认查询子游戏维度
             dto.setGameDimension(1L);
@@ -896,7 +894,6 @@ public class GameDataServiceImpl implements IGameDataService {
     public GameDataTotalTotalVO getGameDataTotalTotal(GameDataTotalTotalDTO dto) {
         com.github.sd4324530.jtuple.Tuple2<List<Long>, List<Long>> poerInfo = dataPowerComponent.getPowerInfo(dto.getSourceSystem());
         List<Long> gameIds = CollectionUtils.isEmpty(dto.getGameId()) ? poerInfo.second : dto.getGameId();
-
         if (dto.getGameDimension() == null) {
             //默认查询子游戏维度
             dto.setGameDimension(1L);
@@ -2678,7 +2675,30 @@ public class GameDataServiceImpl implements IGameDataService {
                                 round(IF(SUM(buy_new_user_total_role_num) >0, SUM(cost) / SUM(buy_new_user_total_role_num), 0), 2) new_user_total_role_num_cost,
                                 round(IF(SUM(buy_reg_num) >0, SUM(buy_first_role_num) / SUM(buy_reg_num), 0), 4) first_role_num_rate,
                                 round(IF(SUM(buy_reg_num) >0, SUM(buy_role_num) / SUM(buy_reg_num), 0), 4) role_num_rate,
-                                round(IF(SUM(buy_reg_num) >0, SUM(buy_new_user_total_role_num) / SUM(buy_reg_num), 0), 4) new_user_total_role_num_rate
+                                round(IF(SUM(buy_reg_num) >0, SUM(buy_new_user_total_role_num) / SUM(buy_reg_num), 0), 4) new_user_total_role_num_rate,
+                                
+                                ANY_VALUE(buy_first_effective_role_num) as first_effective_role_num,  -- 首日有效创角人数
+                                ANY_VALUE(buy_new_user_total_effective_role_num) as new_user_total_effective_role_num,  -- 新用户累计有效创角人数
+                                ANY_VALUE(buy_effective_role_num) as effective_role_num,  -- 有效创角人数
+                                
+                                round(ANY_VALUE(buy_first_effective_role_num_rate)*100,2) AS first_effective_role_rate, -- 首日有效创角率
+                                round(ANY_VALUE(buy_new_user_total_effective_role_num_rate)*100,2) as new_user_total_effective_role_num_rate, -- 新用户累计有效创角率
+                                round(ANY_VALUE(buy_effective_role_num_rate)*100,2) as effective_role_num_rate, -- 有效创角率
+                                
+                                ANY_VALUE(buy_first_effective_role_num_cost) AS first_effective_role_num_cost, -- 首日有效创角成本
+                                ANY_VALUE(buy_new_user_total_effective_role_num_cost) as new_user_total_effective_role_num_cost, -- 新用户累计有效创角成本
+                                ANY_VALUE(buy_effective_role_num_cost) as effective_role_num_cost,    -- 有效创角成本
+                                
+                                ANY_VALUE(buy_first_effective_role_amount_num) as first_effective_role_amount_num, -- 首日有效创角付费人数
+                                ANY_VALUE(buy_new_user_total_effective_role_amount_num) as new_user_total_effective_role_amount_num, -- 新用户累计有效创角付费人数
+                                
+                                ANY_VALUE(buy_first_effective_role_amount_num_cost) as first_effective_role_amount_num_cost, -- 首日有效创角付费成本
+                                ANY_VALUE(buy_new_user_total_effective_role_amount_num_cost) as new_user_total_effective_role_amount_num_cost, -- 新用户累计有效创角付费成本
+                                
+                                round(ANY_VALUE(buy_first_effective_role_amount_num_rate)*100,2) as first_effective_role_amount_num_rate, -- 首日有效创角付费比
+                                round(ANY_VALUE(buy_new_user_total_effective_role_amount_num_rate)*100,2) as new_user_total_effective_role_amount_num_rate, -- 新用户累计有效创角付费比
+                                ANY_VALUE(buy_first_effective_role_arpu) as first_effective_role_arpu, -- 首日有效创角ARPU
+                                ANY_VALUE(buy_new_user_total_effective_role_arpu) as new_user_total_effective_role_arpu -- 新用户累计有效创角ARPU
                             FROM
                                 ads_game_day
                             """;
@@ -2732,7 +2752,30 @@ public class GameDataServiceImpl implements IGameDataService {
                                 round(IF(SUM(nature_new_user_total_role_num) >0, SUM(cost) / SUM(nature_new_user_total_role_num), 0), 2) new_user_total_role_num_cost,
                                 round(IF(SUM(nature_reg_num) >0, SUM(nature_first_role_num) / SUM(nature_reg_num), 0), 4) first_role_num_rate,
                                 round(IF(SUM(nature_reg_num) >0, SUM(nature_role_num) / SUM(nature_reg_num), 0), 4) role_num_rate,
-                                round(IF(SUM(nature_reg_num) >0, SUM(nature_new_user_total_role_num) / SUM(nature_reg_num), 0), 4) new_user_total_role_num_rate
+                                round(IF(SUM(nature_reg_num) >0, SUM(nature_new_user_total_role_num) / SUM(nature_reg_num), 0), 4) new_user_total_role_num_rate,
+                                
+                                ANY_VALUE(nature_first_effective_role_num) as first_effective_role_num,  -- 首日有效创角人数
+                                ANY_VALUE(nature_new_user_total_effective_role_num) as new_user_total_effective_role_num,  -- 新用户累计有效创角人数
+                                ANY_VALUE(nature_effective_role_num) as effective_role_num,  -- 有效创角人数
+                                
+                                round(ANY_VALUE(nature_first_effective_role_num_rate)*100,2) AS first_effective_role_rate, -- 首日有效创角率
+                                round(ANY_VALUE(nature_new_user_total_effective_role_num_rate)*100,2) as new_user_total_effective_role_num_rate, -- 新用户累计有效创角率
+                                round(ANY_VALUE(nature_effective_role_num_rate)*100,2) as effective_role_num_rate, -- 有效创角率
+                                
+                                ANY_VALUE(nature_first_effective_role_num_cost) AS first_effective_role_num_cost, -- 首日有效创角成本
+                                ANY_VALUE(nature_new_user_total_effective_role_num_cost) as new_user_total_effective_role_num_cost, -- 新用户累计有效创角成本
+                                ANY_VALUE(nature_effective_role_num_cost) as effective_role_num_cost,    -- 有效创角成本
+                                
+                                ANY_VALUE(nature_first_effective_role_amount_num) as first_effective_role_amount_num, -- 首日有效创角付费人数
+                                ANY_VALUE(nature_new_user_total_effective_role_amount_num) as new_user_total_effective_role_amount_num, -- 新用户累计有效创角付费人数
+                                
+                                ANY_VALUE(nature_first_effective_role_amount_num_cost) as first_effective_role_amount_num_cost, -- 首日有效创角付费成本
+                                ANY_VALUE(nature_new_user_total_effective_role_amount_num_cost) as new_user_total_effective_role_amount_num_cost, -- 新用户累计有效创角付费成本
+                                
+                                round(ANY_VALUE(nature_first_effective_role_amount_num_rate)*100,2) as first_effective_role_amount_num_rate, -- 首日有效创角付费比
+                                round(ANY_VALUE(nature_new_user_total_effective_role_amount_num_rate)*100,2) as new_user_total_effective_role_amount_num_rate, -- 新用户累计有效创角付费比
+                                ANY_VALUE(nature_first_effective_role_arpu) as first_effective_role_arpu, -- 首日有效创角ARPU
+                                ANY_VALUE(nature_new_user_total_effective_role_arpu) as new_user_total_effective_role_arpu -- 新用户累计有效创角ARPU
                             FROM
                                 ads_game_day
                             """;
@@ -2787,7 +2830,29 @@ public class GameDataServiceImpl implements IGameDataService {
                             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
+                            round(IF(SUM(reg_num) >0, SUM(new_user_total_role_num) / SUM(reg_num), 0), 4) new_user_total_role_num_rate,
+                            
+                            ANY_VALUE(first_effective_role_num) as first_effective_role_num,  -- 首日有效创角人数
+                            ANY_VALUE(new_user_total_effective_role_num) as new_user_total_effective_role_num,  -- 新用户累计有效创角人数
+                            ANY_VALUE(effective_role_num) as effective_role_num,  -- 有效创角人数
+                            
+                            round(ANY_VALUE(first_effective_role_num_rate)*100,2) AS first_effective_role_rate, -- 首日有效创角率
+                            round(ANY_VALUE(new_user_total_effective_role_num_rate)*100,2) as new_user_total_effective_role_num_rate, -- 新用户累计有效创角率
+                            round(ANY_VALUE(effective_role_num_rate)*100,2) as effective_role_num_rate, -- 有效创角率
+                                
+                            
+                            ANY_VALUE(first_effective_role_num_cost) AS first_effective_role_num_cost, -- 首日有效创角成本
+                            ANY_VALUE(new_user_total_effective_role_num_cost) as new_user_total_effective_role_num_cost, -- 新用户累计有效创角成本
+                            ANY_VALUE(effective_role_num_cost) as effective_role_num_cost,    -- 有效创角成本
+                            
+                            ANY_VALUE(first_effective_role_amount_num) as first_effective_role_amount_num, -- 首日有效创角付费人数
+                            ANY_VALUE(new_user_total_effective_role_amount_num) as new_user_total_effective_role_amount_num, -- 新用户累计有效创角付费人数
+                            
+                            
+                             round(ANY_VALUE(first_effective_role_amount_num_rate)*100,2) as first_effective_role_amount_num_rate, -- 首日有效创角付费比
+                             round(ANY_VALUE(new_user_total_effective_role_amount_num_rate)*100,2) as new_user_total_effective_role_amount_num_rate, -- 新用户累计有效创角付费比
+                             ANY_VALUE(first_effective_role_arpu) as first_effective_role_arpu, -- 首日有效创角ARPU
+                             ANY_VALUE(new_user_total_effective_role_arpu) as new_user_total_effective_role_arpu -- 新用户累计有效创角ARPU
                         FROM
                             ads_game_day
                         """;
@@ -2850,7 +2915,30 @@ public class GameDataServiceImpl implements IGameDataService {
                                 round(IF(SUM(buy_new_user_total_role_num) >0, SUM(cost) / SUM(buy_new_user_total_role_num), 0), 2) new_user_total_role_num_cost,
                                 round(IF(SUM(buy_reg_num) >0, SUM(buy_first_role_num) / SUM(buy_reg_num), 0), 4) first_role_num_rate,
                                 round(IF(SUM(buy_reg_num) >0, SUM(buy_role_num) / SUM(buy_reg_num), 0), 4) role_num_rate,
-                                round(IF(SUM(buy_reg_num) >0, SUM(buy_new_user_total_role_num) / SUM(buy_reg_num), 0), 4) new_user_total_role_num_rate
+                                round(IF(SUM(buy_reg_num) >0, SUM(buy_new_user_total_role_num) / SUM(buy_reg_num), 0), 4) new_user_total_role_num_rate,
+                                
+                                ANY_VALUE(buy_first_effective_role_num) as first_effective_role_num,  -- 首日有效创角人数
+                                ANY_VALUE(buy_new_user_total_effective_role_num) as new_user_total_effective_role_num,  -- 新用户累计有效创角人数
+                                ANY_VALUE(buy_effective_role_num) as effective_role_num,  -- 有效创角人数
+                                
+                                round(ANY_VALUE(buy_first_effective_role_num_rate)*100,2) AS first_effective_role_rate, -- 首日有效创角率
+                                round(ANY_VALUE(buy_new_user_total_effective_role_num_rate)*100,2) as new_user_total_effective_role_num_rate, -- 新用户累计有效创角率
+                                round(ANY_VALUE(buy_effective_role_num_rate)*100,2) as effective_role_num_rate, -- 有效创角率
+                                
+                                ANY_VALUE(buy_first_effective_role_num_cost) AS first_effective_role_num_cost, -- 首日有效创角成本
+                                ANY_VALUE(buy_new_user_total_effective_role_num_cost) as new_user_total_effective_role_num_cost, -- 新用户累计有效创角成本
+                                ANY_VALUE(buy_effective_role_num_cost) as effective_role_num_cost,    -- 有效创角成本
+                                
+                                ANY_VALUE(buy_first_effective_role_amount_num) as first_effective_role_amount_num, -- 首日有效创角付费人数
+                                ANY_VALUE(buy_new_user_total_effective_role_amount_num) as new_user_total_effective_role_amount_num, -- 新用户累计有效创角付费人数
+                                
+                                ANY_VALUE(buy_first_effective_role_amount_num_cost) as first_effective_role_amount_num_cost, -- 首日有效创角付费成本
+                                ANY_VALUE(buy_new_user_total_effective_role_amount_num_cost) as new_user_total_effective_role_amount_num_cost, -- 新用户累计有效创角付费成本
+                                
+                                round(ANY_VALUE(buy_first_effective_role_amount_num_rate)*100,2) as first_effective_role_amount_num_rate, -- 首日有效创角付费比
+                                round(ANY_VALUE(buy_new_user_total_effective_role_amount_num_rate)*100,2) as new_user_total_effective_role_amount_num_rate, -- 新用户累计有效创角付费比
+                                ANY_VALUE(buy_first_effective_role_arpu) as first_effective_role_arpu, -- 首日有效创角ARPU
+                                ANY_VALUE(buy_new_user_total_effective_role_arpu) as new_user_total_effective_role_arpu -- 新用户累计有效创角ARPU
                             FROM
                                 game_ads_parent.ads_game_day_parent
                             """;
@@ -2904,7 +2992,30 @@ public class GameDataServiceImpl implements IGameDataService {
                                 round(IF(SUM(nature_new_user_total_role_num) >0, SUM(cost) / SUM(nature_new_user_total_role_num), 0), 2) new_user_total_role_num_cost,
                                 round(IF(SUM(nature_reg_num) >0, SUM(nature_first_role_num) / SUM(nature_reg_num), 0), 4) first_role_num_rate,
                                 round(IF(SUM(nature_reg_num) >0, SUM(nature_role_num) / SUM(nature_reg_num), 0), 4) role_num_rate,
-                                round(IF(SUM(nature_reg_num) >0, SUM(nature_new_user_total_role_num) / SUM(nature_reg_num), 0), 4) new_user_total_role_num_rate
+                                round(IF(SUM(nature_reg_num) >0, SUM(nature_new_user_total_role_num) / SUM(nature_reg_num), 0), 4) new_user_total_role_num_rate,
+                                
+                                ANY_VALUE(nature_first_effective_role_num) as first_effective_role_num,  -- 首日有效创角人数
+                                ANY_VALUE(nature_new_user_total_effective_role_num) as new_user_total_effective_role_num,  -- 新用户累计有效创角人数
+                                ANY_VALUE(nature_effective_role_num) as effective_role_num,  -- 有效创角人数
+                                
+                                round(ANY_VALUE(nature_first_effective_role_num_rate)*100,2) AS first_effective_role_rate, -- 首日有效创角率
+                                round(ANY_VALUE(nature_new_user_total_effective_role_num_rate)*100,2) as new_user_total_effective_role_num_rate, -- 新用户累计有效创角率
+                                round(ANY_VALUE(nature_effective_role_num_rate)*100,2) as effective_role_num_rate, -- 有效创角率
+                                
+                                ANY_VALUE(nature_first_effective_role_num_cost) AS first_effective_role_num_cost, -- 首日有效创角成本
+                                ANY_VALUE(nature_new_user_total_effective_role_num_cost) as new_user_total_effective_role_num_cost, -- 新用户累计有效创角成本
+                                ANY_VALUE(nature_effective_role_num_cost) as effective_role_num_cost,    -- 有效创角成本
+                                
+                                ANY_VALUE(nature_first_effective_role_amount_num) as first_effective_role_amount_num, -- 首日有效创角付费人数
+                                ANY_VALUE(nature_new_user_total_effective_role_amount_num) as new_user_total_effective_role_amount_num, -- 新用户累计有效创角付费人数
+                                
+                                ANY_VALUE(nature_first_effective_role_amount_num_cost) as first_effective_role_amount_num_cost, -- 首日有效创角付费成本
+                                ANY_VALUE(nature_new_user_total_effective_role_amount_num_cost) as new_user_total_effective_role_amount_num_cost, -- 新用户累计有效创角付费成本
+                                
+                                round(ANY_VALUE(nature_first_effective_role_amount_num_rate)*100,2) as first_effective_role_amount_num_rate, -- 首日有效创角付费比
+                                round(ANY_VALUE(nature_new_user_total_effective_role_amount_num_rate)*100,2) as new_user_total_effective_role_amount_num_rate, -- 新用户累计有效创角付费比
+                                ANY_VALUE(nature_first_effective_role_arpu) as first_effective_role_arpu, -- 首日有效创角ARPU
+                                ANY_VALUE(nature_new_user_total_effective_role_arpu) as new_user_total_effective_role_arpu -- 新用户累计有效创角ARPU
                             FROM
                                 game_ads_parent.ads_game_day_parent
                             """;
@@ -2959,7 +3070,29 @@ public class GameDataServiceImpl implements IGameDataService {
                             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
+                            round(IF(SUM(reg_num) >0, SUM(new_user_total_role_num) / SUM(reg_num), 0), 4) new_user_total_role_num_rate,
+                            
+                            ANY_VALUE(first_effective_role_num) as first_effective_role_num,  -- 首日有效创角人数
+                            ANY_VALUE(new_user_total_effective_role_num) as new_user_total_effective_role_num,  -- 新用户累计有效创角人数
+                            ANY_VALUE(effective_role_num) as effective_role_num,  -- 有效创角人数
+                            
+                            round(ANY_VALUE(first_effective_role_num_rate)*100,2) AS first_effective_role_rate, -- 首日有效创角率
+                            round(ANY_VALUE(new_user_total_effective_role_num_rate)*100,2) as new_user_total_effective_role_num_rate, -- 新用户累计有效创角率
+                            round(ANY_VALUE(effective_role_num_rate)*100,2) as effective_role_num_rate, -- 有效创角率
+                                
+                            
+                            ANY_VALUE(first_effective_role_num_cost) AS first_effective_role_num_cost, -- 首日有效创角成本
+                            ANY_VALUE(new_user_total_effective_role_num_cost) as new_user_total_effective_role_num_cost, -- 新用户累计有效创角成本
+                            ANY_VALUE(effective_role_num_cost) as effective_role_num_cost,    -- 有效创角成本
+                            
+                            ANY_VALUE(first_effective_role_amount_num) as first_effective_role_amount_num, -- 首日有效创角付费人数
+                            ANY_VALUE(new_user_total_effective_role_amount_num) as new_user_total_effective_role_amount_num, -- 新用户累计有效创角付费人数
+                            
+                            
+                             round(ANY_VALUE(first_effective_role_amount_num_rate)*100,2) as first_effective_role_amount_num_rate, -- 首日有效创角付费比
+                             round(ANY_VALUE(new_user_total_effective_role_amount_num_rate)*100,2) as new_user_total_effective_role_amount_num_rate, -- 新用户累计有效创角付费比
+                             ANY_VALUE(first_effective_role_arpu) as first_effective_role_arpu, -- 首日有效创角ARPU
+                             ANY_VALUE(new_user_total_effective_role_arpu) as new_user_total_effective_role_arpu -- 新用户累计有效创角ARPU
                         FROM
                             game_ads_parent.ads_game_day_parent
                         """;
@@ -3395,7 +3528,31 @@ public class GameDataServiceImpl implements IGameDataService {
                                 round(IF(SUM(buy_new_user_total_role_num) >0, SUM(cost) / SUM(buy_new_user_total_role_num), 0), 2) new_user_total_role_num_cost,
                                 round(IF(SUM(buy_reg_num) >0, SUM(buy_first_role_num) / SUM(buy_reg_num), 0), 4) first_role_num_rate,
                                 round(IF(SUM(buy_reg_num) >0, SUM(buy_role_num) / SUM(buy_reg_num), 0), 4) role_num_rate,
-                                round(IF(SUM(buy_reg_num) >0, SUM(buy_new_user_total_role_num) / SUM(buy_reg_num), 0), 4) new_user_total_role_num_rate
+                                round(IF(SUM(buy_reg_num) >0, SUM(buy_new_user_total_role_num) / SUM(buy_reg_num), 0), 4) new_user_total_role_num_rate,
+                                
+                                sum(buy_first_effective_role_num) as first_effective_role_num,  -- 首日有效创角人数
+                                sum(buy_new_user_total_effective_role_num) as new_user_total_effective_role_num,  -- 新用户累计有效创角人数
+                                SUM(buy_effective_role_num) as effective_role_num, -- 有效创角人数
+                                
+                                ROUND(IFNULL(SUM(buy_first_effective_role_num)/sum(buy_first_role_num),0)*100,2) as first_effective_role_rate,   -- 首日有效创角率 = 首日有效创角人数/首日创角人数
+                                round(IFNULL(SUM(buy_new_user_total_effective_role_num)/SUM(buy_new_user_total_role_num),0)*100,2) as new_user_total_effective_role_num_rate,         -- 新用户累计有效创角率 = 新用户累计有效创角人数/新用户累计创角人数
+                                round(IFNULL(SUM(buy_effective_role_num)/SUM(buy_role_num),0)*100,2) as effective_role_num_rate,        -- 有效创角率 = 有效创角人数/创角人数
+                                
+                                round(IFNULL(SUM(cost)/SUM(buy_first_effective_role_num),0),2) as first_effective_role_num_cost, -- 首日有效创角成本= 消耗/首日有效创角人数
+                                round(IFNULL(SUM(cost)/SUM(buy_new_user_total_effective_role_num),0),2)  as new_user_total_effective_role_num_cost, -- 新用户累计有效创角成本 = 消耗/新用户累计有效创角人数
+                                round(IFNULL(SUM(cost)/sum(buy_effective_role_num),0),2) as effective_role_num_cost, -- 有效创角成本 = 消耗/有效创角人数
+                                
+                                SUM(buy_first_effective_role_amount_num) as first_effective_role_amount_num, -- 首日有效创角付费人数
+                                sum(buy_new_user_total_effective_role_amount_num) as new_user_total_effective_role_amount_num, -- 新用户累计有效创角付费人数
+                                
+                                round(IFNULL(SUM(cost)/sum(buy_first_effective_role_amount_num),0),2) as first_effective_role_amount_num_cost, -- 首日有效创角付费成本=消耗/首日有效创角付费人数
+                                round(IFNULL(SUM(cost)/SUM(buy_new_user_total_effective_role_amount_num),0),2) as new_user_total_effective_role_amount_num_cost, -- 新用户累计有效创角付费成本=消耗/新用户累计有效创角付费人数
+                                
+                                round(IFNULL(SUM(buy_first_effective_role_amount_num)/SUM(buy_first_new_user_amount_count),0)*100,2) as first_effective_role_amount_num_rate,  -- 首日有效创角付费比=首日有效创角付费人数/首日新用户充值人数
+                                round(IFNULL(SUM(buy_new_user_total_effective_role_amount_num)/SUM(buy_new_user_total_amount_count),0)*100,2) as new_user_total_effective_role_amount_num_rate, -- 新用户累计有效创角付费比=新用户累计有效创角付费人数/新用户累计充值人数
+                                ROUND(IFNULL(SUM(buy_new_user_total_amount)/SUM(buy_new_user_total_effective_role_num),0),2) as first_effective_role_arpu,    -- 新用户累计有效创角ARPU=新用户累计充值金额/新用户累计有效创角人数
+                                ROUND(IFNULL(SUM(buy_first_new_user_amount)/SUM(buy_first_effective_role_num),0),2) as new_user_total_effective_role_arpu -- 首日有效创角ARPU=首日新用户充值金额/首日有效创角人数
+                                
                             FROM game_ads.ads_game_day as a
                                 LEFT JOIN game_dw.dw_game_amount_day_buy
                                 b on a.source_system = b.source_system
@@ -3447,7 +3604,30 @@ public class GameDataServiceImpl implements IGameDataService {
                                 round(IF(SUM(nature_new_user_total_role_num) >0, SUM(cost) / SUM(nature_new_user_total_role_num), 0), 2) new_user_total_role_num_cost,
                                 round(IF(SUM(nature_reg_num) >0, SUM(nature_first_role_num) / SUM(nature_reg_num), 0), 4) first_role_num_rate,
                                 round(IF(SUM(nature_reg_num) >0, SUM(nature_role_num) / SUM(nature_reg_num), 0), 4) role_num_rate,
-                                round(IF(SUM(nature_reg_num) >0, SUM(nature_new_user_total_role_num) / SUM(nature_reg_num), 0), 4) new_user_total_role_num_rate
+                                round(IF(SUM(nature_reg_num) >0, SUM(nature_new_user_total_role_num) / SUM(nature_reg_num), 0), 4) new_user_total_role_num_rate,
+                                
+                                sum(nature_first_effective_role_num) as first_effective_role_num,  -- 首日有效创角人数
+                                sum(nature_new_user_total_effective_role_num) as new_user_total_effective_role_num,  -- 新用户累计有效创角人数
+                                SUM(nature_effective_role_num) as effective_role_num, -- 有效创角人数
+                                
+                                ROUND(IFNULL(SUM(nature_first_effective_role_num)/sum(nature_first_role_num),0)*100,2) as first_effective_role_rate,   -- 首日有效创角率 = 首日有效创角人数/首日创角人数
+                                round(IFNULL(SUM(nature_new_user_total_effective_role_num)/SUM(nature_new_user_total_role_num),0)*100,2) as new_user_total_effective_role_num_rate,         -- 新用户累计有效创角率 = 新用户累计有效创角人数/新用户累计创角人数
+                                round(IFNULL(SUM(nature_effective_role_num)/SUM(nature_role_num),0)*100,2) as effective_role_num_rate,        -- 有效创角率 = 有效创角人数/创角人数
+                                
+                                round(IFNULL(SUM(cost)/SUM(nature_first_effective_role_num),0),2) as first_effective_role_num_cost, -- 首日有效创角成本= 消耗/首日有效创角人数
+                                round(IFNULL(SUM(cost)/SUM(nature_new_user_total_effective_role_num),0),2)  as new_user_total_effective_role_num_cost, -- 新用户累计有效创角成本 = 消耗/新用户累计有效创角人数
+                                round(IFNULL(SUM(cost)/sum(nature_effective_role_num),0),2) as effective_role_num_cost, -- 有效创角成本 = 消耗/有效创角人数
+                                
+                                SUM(nature_first_effective_role_amount_num) as first_effective_role_amount_num, -- 首日有效创角付费人数
+                                sum(nature_new_user_total_effective_role_amount_num) as new_user_total_effective_role_amount_num, -- 新用户累计有效创角付费人数
+                                
+                                round(IFNULL(SUM(cost)/sum(nature_first_effective_role_amount_num),0),2) as first_effective_role_amount_num_cost, -- 首日有效创角付费成本=消耗/首日有效创角付费人数
+                                round(IFNULL(SUM(cost)/SUM(nature_new_user_total_effective_role_amount_num),0),2) as new_user_total_effective_role_amount_num_cost, -- 新用户累计有效创角付费成本=消耗/新用户累计有效创角付费人数
+                                
+                                round(IFNULL(SUM(nature_first_effective_role_amount_num)/SUM(nature_first_new_user_amount_count),0)*100,2) as first_effective_role_amount_num_rate,  -- 首日有效创角付费比=首日有效创角付费人数/首日新用户充值人数
+                                round(IFNULL(SUM(nature_new_user_total_effective_role_amount_num)/SUM(nature_new_user_total_amount_count),0)*100,2) as new_user_total_effective_role_amount_num_rate, -- 新用户累计有效创角付费比=新用户累计有效创角付费人数/新用户累计充值人数
+                                ROUND(IFNULL(SUM(nature_new_user_total_amount)/SUM(nature_new_user_total_effective_role_num),0),2) as first_effective_role_arpu,    -- 新用户累计有效创角ARPU=新用户累计充值金额/新用户累计有效创角人数
+                                ROUND(IFNULL(SUM(nature_first_new_user_amount)/SUM(nature_first_effective_role_num),0),2) as new_user_total_effective_role_arpu -- 首日有效创角ARPU=首日新用户充值金额/首日有效创角人数
                             FROM game_ads.ads_game_day as a
                                 left join  game_dw.dw_game_amount_day_nature d
                                 on a.dt=d.dt and a.game_id = d.nature_game_id
@@ -3461,53 +3641,78 @@ public class GameDataServiceImpl implements IGameDataService {
                 """
                 + amountDayStr("") +
                 """
-                            IFNULL(SUM(first_new_user_amount_count), 0) first_new_user_amount_count,
-                            IFNULL(SUM(first_new_user_amount_num), 0) first_new_user_amount_num,
-                            IFNULL(SUM(first_new_user_amount), 0) first_new_user_amount,
-                            IFNULL(SUM(old_user_count), 0) old_user_count,
-                            IFNULL(SUM(old_user_num), 0) old_user_num,
-                            IFNULL(SUM(old_user_amount), 0) old_user_amount,
-                            IFNULL(SUM(amount_count), 0) amount_count,
-                            IFNULL(SUM(amount_num), 0) amount_num,
-                            IFNULL(SUM(amount), 0) amount,
-                            IFNULL(SUM(new_user_total_amount_count), 0) new_user_total_amount_count,
-                            IFNULL(SUM(new_user_total_amount_num), 0) new_user_total_amount_num,
-                            IFNULL(SUM(new_user_total_amount), 0) new_user_total_amount,
-                            round(if(SUM(cost) > 0 , SUM(first_new_user_amount) / SUM(cost) ,0), 4) first_roi,
-                            round(if(SUM(reg_num) > 0 , SUM(first_new_user_amount_num) / SUM(reg_num) ,0), 4) first_amount_rate,
-                            round(if(SUM(reg_num) > 0, SUM(new_user_total_amount_num) / SUM(reg_num), 0) ,4) today_amount_rate,
-                            round(if(SUM(amount_num) > 0 , SUM(first_new_user_amount_num) / SUM(amount_num) ,0), 4) new_user_rate,
-                            round(if(SUM(first_new_user_amount_count) > 0, SUM(first_new_user_amount) / SUM(first_new_user_amount_count), 0), 2) first_avg_amount,
-                            round(if(SUM(new_user_total_amount_count) > 0, SUM(new_user_total_amount) / SUM(new_user_total_amount_count), 0), 2) today_avg_amount,
-                            round(if(SUM(amount_count) > 0, SUM(amount) / SUM(amount_count), 0), 2) avg_amount,
-                            round(if(SUM(new_user_total_amount_num) > 0, SUM(reg_order_user_again) / SUM(new_user_total_amount_num), 0), 4) user_again_rate,
-                            round(if(SUM(reg_num) > 0, SUM(new_user_total_amount) / SUM(reg_num), 0), 2) reg_user_arpu,
-                            round(if(SUM(first_new_user_amount_num) > 0 , SUM(first_new_user_amount) / SUM(first_new_user_amount_num), 0), 2) first_amount_arpu,
-                            round(if(SUM(new_user_total_amount_num) > 0 , SUM(new_user_total_amount) / SUM(new_user_total_amount_num), 0), 2) today_amount_arpu,
-                            round(if(SUM(amount_num) > 0, SUM(amount) / SUM(amount_num), 0), 2) amount_arpu,
-                            round(if(SUM(reg_num) > 0, SUM(cost) / SUM(reg_num), 0), 2) reg_cost,
-                            round(if(SUM(first_new_user_amount_num) > 0, SUM(cost) / SUM(first_new_user_amount_num), 0), 2) first_new_user_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(cost) > 0, SUM(new_user_total_amount) / SUM(cost), 0), 4) total_roi,
-                            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 as a
-                        left join   game_dw.dw_game_amount_day
-                        b on a.dt=b.dt and a.game_id = b.game_id
-                      """;
+                              IFNULL(SUM(first_new_user_amount_count), 0) first_new_user_amount_count,
+                              IFNULL(SUM(first_new_user_amount_num), 0) first_new_user_amount_num,
+                              IFNULL(SUM(first_new_user_amount), 0) first_new_user_amount,
+                              IFNULL(SUM(old_user_count), 0) old_user_count,
+                              IFNULL(SUM(old_user_num), 0) old_user_num,
+                              IFNULL(SUM(old_user_amount), 0) old_user_amount,
+                              IFNULL(SUM(amount_count), 0) amount_count,
+                              IFNULL(SUM(amount_num), 0) amount_num,
+                              IFNULL(SUM(amount), 0) amount,
+                              IFNULL(SUM(new_user_total_amount_count), 0) new_user_total_amount_count,
+                              IFNULL(SUM(new_user_total_amount_num), 0) new_user_total_amount_num,
+                              IFNULL(SUM(new_user_total_amount), 0) new_user_total_amount,
+                              round(if(SUM(cost) > 0 , SUM(first_new_user_amount) / SUM(cost) ,0), 4) first_roi,
+                              round(if(SUM(reg_num) > 0 , SUM(first_new_user_amount_num) / SUM(reg_num) ,0), 4) first_amount_rate,
+                              round(if(SUM(reg_num) > 0, SUM(new_user_total_amount_num) / SUM(reg_num), 0) ,4) today_amount_rate,
+                              round(if(SUM(amount_num) > 0 , SUM(first_new_user_amount_num) / SUM(amount_num) ,0), 4) new_user_rate,
+                              round(if(SUM(first_new_user_amount_count) > 0, SUM(first_new_user_amount) / SUM(first_new_user_amount_count), 0), 2) first_avg_amount,
+                              round(if(SUM(new_user_total_amount_count) > 0, SUM(new_user_total_amount) / SUM(new_user_total_amount_count), 0), 2) today_avg_amount,
+                              round(if(SUM(amount_count) > 0, SUM(amount) / SUM(amount_count), 0), 2) avg_amount,
+                              round(if(SUM(new_user_total_amount_num) > 0, SUM(reg_order_user_again) / SUM(new_user_total_amount_num), 0), 4) user_again_rate,
+                              round(if(SUM(reg_num) > 0, SUM(new_user_total_amount) / SUM(reg_num), 0), 2) reg_user_arpu,
+                              round(if(SUM(first_new_user_amount_num) > 0 , SUM(first_new_user_amount) / SUM(first_new_user_amount_num), 0), 2) first_amount_arpu,
+                              round(if(SUM(new_user_total_amount_num) > 0 , SUM(new_user_total_amount) / SUM(new_user_total_amount_num), 0), 2) today_amount_arpu,
+                              round(if(SUM(amount_num) > 0, SUM(amount) / SUM(amount_num), 0), 2) amount_arpu,
+                              round(if(SUM(reg_num) > 0, SUM(cost) / SUM(reg_num), 0), 2) reg_cost,
+                              round(if(SUM(first_new_user_amount_num) > 0, SUM(cost) / SUM(first_new_user_amount_num), 0), 2) first_new_user_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(cost) > 0, SUM(new_user_total_amount) / SUM(cost), 0), 4) total_roi,
+                              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,
+                              
+                              sum(first_effective_role_num) as first_effective_role_num,  -- 首日有效创角人数
+                              sum(new_user_total_effective_role_num) as new_user_total_effective_role_num,  -- 新用户累计有效创角人数
+                              SUM(effective_role_num) as effective_role_num, -- 有效创角人数
+                          
+                              ROUND(IFNULL(SUM(first_effective_role_num)/sum(first_role_num),0)*100,2) as first_effective_role_rate,   -- 首日有效创角率 = 首日有效创角人数/首日创角人数
+                              round(IFNULL(SUM(new_user_total_effective_role_num)/SUM(new_user_total_role_num),0)*100,2) as new_user_total_effective_role_num_rate,         -- 新用户累计有效创角率 = 新用户累计有效创角人数/新用户累计创角人数
+                              round(IFNULL(SUM(effective_role_num)/SUM(role_num),0)*100,2) as effective_role_num_rate,        -- 有效创角率 = 有效创角人数/创角人数
+                          
+                              round(IFNULL(SUM(cost)/SUM(first_effective_role_num),0),2) as first_effective_role_num_cost, -- 首日有效创角成本= 消耗/首日有效创角人数
+                              round(IFNULL(SUM(cost)/SUM(new_user_total_effective_role_num),0),2)  as new_user_total_effective_role_num_cost, -- 新用户累计有效创角成本 = 消耗/新用户累计有效创角人数
+                              round(IFNULL(SUM(cost)/sum(effective_role_num),0),2) as effective_role_num_cost, -- 有效创角成本 = 消耗/有效创角人数
+                          
+                              SUM(first_effective_role_amount_num) as first_effective_role_amount_num, -- 首日有效创角付费人数
+                              sum(new_user_total_effective_role_amount_num) as new_user_total_effective_role_amount_num, -- 新用户累计有效创角付费人数
+                          
+                          
+                              round(IFNULL(SUM(cost)/sum(first_effective_role_amount_num),0),2) as first_effective_role_amount_num_cost, -- 首日有效创角付费成本=消耗/首日有效创角付费人数
+                              round(IFNULL(SUM(cost)/SUM(new_user_total_effective_role_amount_num),0),2) as new_user_total_effective_role_amount_num_cost, -- 新用户累计有效创角付费成本=消耗/新用户累计有效创角付费人数
+                          
+                              round(IFNULL(SUM(first_effective_role_amount_num)/SUM(first_new_user_amount_count),0)*100,2) as first_effective_role_amount_num_rate,  -- 首日有效创角付费比=首日有效创角付费人数/首日新用户充值人数
+                              round(IFNULL(SUM(new_user_total_effective_role_amount_num)/SUM(new_user_total_amount_count),0)*100,2) as new_user_total_effective_role_amount_num_rate, -- 新用户累计有效创角付费比=新用户累计有效创角付费人数/新用户累计充值人数
+                              ROUND(IFNULL(SUM(new_user_total_amount)/SUM(new_user_total_effective_role_num),0),2) as first_effective_role_arpu,    -- 新用户累计有效创角ARPU=新用户累计充值金额/新用户累计有效创角人数
+                              ROUND(IFNULL(SUM(first_new_user_amount)/SUM(first_effective_role_num),0),2) as new_user_total_effective_role_arpu -- 首日有效创角ARPU=首日新用户充值金额/首日有效创角人数
+                          FROM game_ads.ads_game_day as a
+                          left join   game_dw.dw_game_amount_day
+                          b on a.dt=b.dt and a.game_id = b.game_id
+                        """;
     }
 
     /**
      * 游戏每日数据总计sql - 父游戏维度 (新)
+     *
      * @param tableType 查询类型
      * @return
      */
@@ -3558,7 +3763,31 @@ public class GameDataServiceImpl implements IGameDataService {
                                 round(IF(SUM(buy_new_user_total_role_num) >0, SUM(cost) / SUM(buy_new_user_total_role_num), 0), 2) new_user_total_role_num_cost,
                                 round(IF(SUM(buy_reg_num) >0, SUM(buy_first_role_num) / SUM(buy_reg_num), 0), 4) first_role_num_rate,
                                 round(IF(SUM(buy_reg_num) >0, SUM(buy_role_num) / SUM(buy_reg_num), 0), 4) role_num_rate,
-                                round(IF(SUM(buy_reg_num) >0, SUM(buy_new_user_total_role_num) / SUM(buy_reg_num), 0), 4) new_user_total_role_num_rate
+                                round(IF(SUM(buy_reg_num) >0, SUM(buy_new_user_total_role_num) / SUM(buy_reg_num), 0), 4) new_user_total_role_num_rate,
+                                
+                                sum(buy_first_effective_role_num) as first_effective_role_num,  -- 首日有效创角人数
+                                sum(buy_new_user_total_effective_role_num) as new_user_total_effective_role_num,  -- 新用户累计有效创角人数
+                                SUM(buy_effective_role_num) as effective_role_num, -- 有效创角人数
+                                
+                                ROUND(IFNULL(SUM(buy_first_effective_role_num)/sum(buy_first_role_num),0)*100,2) as first_effective_role_rate,   -- 首日有效创角率 = 首日有效创角人数/首日创角人数
+                                round(IFNULL(SUM(buy_new_user_total_effective_role_num)/SUM(buy_new_user_total_role_num),0)*100,2) as new_user_total_effective_role_num_rate,         -- 新用户累计有效创角率 = 新用户累计有效创角人数/新用户累计创角人数
+                                round(IFNULL(SUM(buy_effective_role_num)/SUM(buy_role_num),0)*100,2) as effective_role_num_rate,        -- 有效创角率 = 有效创角人数/创角人数
+                                
+                                round(IFNULL(SUM(cost)/SUM(buy_first_effective_role_num),0),2) as first_effective_role_num_cost, -- 首日有效创角成本= 消耗/首日有效创角人数
+                                round(IFNULL(SUM(cost)/SUM(buy_new_user_total_effective_role_num),0),2)  as new_user_total_effective_role_num_cost, -- 新用户累计有效创角成本 = 消耗/新用户累计有效创角人数
+                                round(IFNULL(SUM(cost)/sum(buy_effective_role_num),0),2) as effective_role_num_cost, -- 有效创角成本 = 消耗/有效创角人数
+                                
+                                SUM(buy_first_effective_role_amount_num) as first_effective_role_amount_num, -- 首日有效创角付费人数
+                                sum(buy_new_user_total_effective_role_amount_num) as new_user_total_effective_role_amount_num, -- 新用户累计有效创角付费人数
+                                
+                                
+                                round(IFNULL(SUM(cost)/sum(buy_first_effective_role_amount_num),0),2) as first_effective_role_amount_num_cost, -- 首日有效创角付费成本=消耗/首日有效创角付费人数
+                                round(IFNULL(SUM(cost)/SUM(buy_new_user_total_effective_role_amount_num),0),2) as new_user_total_effective_role_amount_num_cost, -- 新用户累计有效创角付费成本=消耗/新用户累计有效创角付费人数
+                                
+                                round(IFNULL(SUM(buy_first_effective_role_amount_num)/SUM(buy_first_new_user_amount_count),0)*100,2) as first_effective_role_amount_num_rate,  -- 首日有效创角付费比=首日有效创角付费人数/首日新用户充值人数
+                                round(IFNULL(SUM(buy_new_user_total_effective_role_amount_num)/SUM(buy_new_user_total_amount_count),0)*100,2) as new_user_total_effective_role_amount_num_rate, -- 新用户累计有效创角付费比=新用户累计有效创角付费人数/新用户累计充值人数
+                                ROUND(IFNULL(SUM(buy_new_user_total_amount)/SUM(buy_new_user_total_effective_role_num),0),2) as first_effective_role_arpu,    -- 新用户累计有效创角ARPU=新用户累计充值金额/新用户累计有效创角人数
+                                ROUND(IFNULL(SUM(buy_first_new_user_amount)/SUM(buy_first_effective_role_num),0),2) as new_user_total_effective_role_arpu -- 首日有效创角ARPU=首日新用户充值金额/首日有效创角人数
                             FROM game_ads_parent.ads_game_day_parent as a
                             LEFT JOIN  game_dw_parent.dw_game_amount_day_buy_parent b
                             on a.source_system = b.source_system
@@ -3610,7 +3839,30 @@ public class GameDataServiceImpl implements IGameDataService {
                                 round(IF(SUM(nature_new_user_total_role_num) >0, SUM(cost) / SUM(nature_new_user_total_role_num), 0), 2) new_user_total_role_num_cost,
                                 round(IF(SUM(nature_reg_num) >0, SUM(nature_first_role_num) / SUM(nature_reg_num), 0), 4) first_role_num_rate,
                                 round(IF(SUM(nature_reg_num) >0, SUM(nature_role_num) / SUM(nature_reg_num), 0), 4) role_num_rate,
-                                round(IF(SUM(nature_reg_num) >0, SUM(nature_new_user_total_role_num) / SUM(nature_reg_num), 0), 4) new_user_total_role_num_rate
+                                round(IF(SUM(nature_reg_num) >0, SUM(nature_new_user_total_role_num) / SUM(nature_reg_num), 0), 4) new_user_total_role_num_rate,
+                                
+                                sum(nature_first_effective_role_num) as first_effective_role_num,  -- 首日有效创角人数
+                                sum(nature_new_user_total_effective_role_num) as new_user_total_effective_role_num,  -- 新用户累计有效创角人数
+                                SUM(nature_effective_role_num) as effective_role_num, -- 有效创角人数
+                                
+                                ROUND(IFNULL(SUM(nature_first_effective_role_num)/sum(nature_first_role_num),0)*100,2) as first_effective_role_rate,   -- 首日有效创角率 = 首日有效创角人数/首日创角人数
+                                round(IFNULL(SUM(nature_new_user_total_effective_role_num)/SUM(nature_new_user_total_role_num),0)*100,2) as new_user_total_effective_role_num_rate,         -- 新用户累计有效创角率 = 新用户累计有效创角人数/新用户累计创角人数
+                                round(IFNULL(SUM(nature_effective_role_num)/SUM(nature_role_num),0)*100,2) as effective_role_num_rate,        -- 有效创角率 = 有效创角人数/创角人数
+                                
+                                round(IFNULL(SUM(cost)/SUM(nature_first_effective_role_num),0),2) as first_effective_role_num_cost, -- 首日有效创角成本= 消耗/首日有效创角人数
+                                round(IFNULL(SUM(cost)/SUM(nature_new_user_total_effective_role_num),0),2)  as new_user_total_effective_role_num_cost, -- 新用户累计有效创角成本 = 消耗/新用户累计有效创角人数
+                                round(IFNULL(SUM(cost)/sum(nature_effective_role_num),0),2) as effective_role_num_cost, -- 有效创角成本 = 消耗/有效创角人数
+                                
+                                SUM(nature_first_effective_role_amount_num) as first_effective_role_amount_num, -- 首日有效创角付费人数
+                                sum(nature_new_user_total_effective_role_amount_num) as new_user_total_effective_role_amount_num, -- 新用户累计有效创角付费人数
+                                
+                                round(IFNULL(SUM(cost)/sum(nature_first_effective_role_amount_num),0),2) as first_effective_role_amount_num_cost, -- 首日有效创角付费成本=消耗/首日有效创角付费人数
+                                round(IFNULL(SUM(cost)/SUM(nature_new_user_total_effective_role_amount_num),0),2) as new_user_total_effective_role_amount_num_cost, -- 新用户累计有效创角付费成本=消耗/新用户累计有效创角付费人数
+                                
+                                round(IFNULL(SUM(nature_first_effective_role_amount_num)/SUM(nature_first_new_user_amount_count),0)*100,2) as first_effective_role_amount_num_rate,  -- 首日有效创角付费比=首日有效创角付费人数/首日新用户充值人数
+                                round(IFNULL(SUM(nature_new_user_total_effective_role_amount_num)/SUM(nature_new_user_total_amount_count),0)*100,2) as new_user_total_effective_role_amount_num_rate, -- 新用户累计有效创角付费比=新用户累计有效创角付费人数/新用户累计充值人数
+                                ROUND(IFNULL(SUM(nature_new_user_total_amount)/SUM(nature_new_user_total_effective_role_num),0),2) as first_effective_role_arpu,    -- 新用户累计有效创角ARPU=新用户累计充值金额/新用户累计有效创角人数
+                                ROUND(IFNULL(SUM(nature_first_new_user_amount)/SUM(nature_first_effective_role_num),0),2) as new_user_total_effective_role_arpu -- 首日有效创角ARPU=首日新用户充值金额/首日有效创角人数
                             FROM game_ads_parent.ads_game_day_parent as a
                                 left join   game_dw_parent.dw_game_amount_day_nature_parent d
                                 on a.dt=d.dt and a.parent_game_id = d.nature_parent_game_id
@@ -3624,49 +3876,73 @@ public class GameDataServiceImpl implements IGameDataService {
                 """
                 + amountDayStr("") +
                 """
-                            IFNULL(SUM(first_new_user_amount_count), 0) first_new_user_amount_count,
-                            IFNULL(SUM(first_new_user_amount_num), 0) first_new_user_amount_num,
-                            IFNULL(SUM(first_new_user_amount), 0) first_new_user_amount,
-                            IFNULL(SUM(old_user_count), 0) old_user_count,
-                            IFNULL(SUM(old_user_num), 0) old_user_num,
-                            IFNULL(SUM(old_user_amount), 0) old_user_amount,
-                            IFNULL(SUM(amount_count), 0) amount_count,
-                            IFNULL(SUM(amount_num), 0) amount_num,
-                            IFNULL(SUM(amount), 0) amount,
-                            IFNULL(SUM(new_user_total_amount_count), 0) new_user_total_amount_count,
-                            IFNULL(SUM(new_user_total_amount_num), 0) new_user_total_amount_num,
-                            IFNULL(SUM(new_user_total_amount), 0) new_user_total_amount,
-                            round(if(SUM(cost) > 0 , SUM(first_new_user_amount) / SUM(cost) ,0), 4) first_roi,
-                            round(if(SUM(reg_num) > 0 , SUM(first_new_user_amount_num) / SUM(reg_num) ,0), 4) first_amount_rate,
-                            round(if(SUM(reg_num) > 0, SUM(new_user_total_amount_num) / SUM(reg_num), 0) ,4) today_amount_rate,
-                            round(if(SUM(amount_num) > 0 , SUM(first_new_user_amount_num) / SUM(amount_num) ,0), 4) new_user_rate,
-                            round(if(SUM(first_new_user_amount_count) > 0, SUM(first_new_user_amount) / SUM(first_new_user_amount_count), 0), 2) first_avg_amount,
-                            round(if(SUM(new_user_total_amount_count) > 0, SUM(new_user_total_amount) / SUM(new_user_total_amount_count), 0), 2) today_avg_amount,
-                            round(if(SUM(amount_count) > 0, SUM(amount) / SUM(amount_count), 0), 2) avg_amount,
-                            round(if(SUM(new_user_total_amount_num) > 0, SUM(reg_order_user_again) / SUM(new_user_total_amount_num), 0), 4) user_again_rate,
-                            round(if(SUM(reg_num) > 0, SUM(new_user_total_amount) / SUM(reg_num), 0), 2) reg_user_arpu,
-                            round(if(SUM(first_new_user_amount_num) > 0 , SUM(first_new_user_amount) / SUM(first_new_user_amount_num), 0), 2) first_amount_arpu,
-                            round(if(SUM(new_user_total_amount_num) > 0 , SUM(new_user_total_amount) / SUM(new_user_total_amount_num), 0), 2) today_amount_arpu,
-                            round(if(SUM(amount_num) > 0, SUM(amount) / SUM(amount_num), 0), 2) amount_arpu,
-                            round(if(SUM(reg_num) > 0, SUM(cost) / SUM(reg_num), 0), 2) reg_cost,
-                            round(if(SUM(first_new_user_amount_num) > 0, SUM(cost) / SUM(first_new_user_amount_num), 0), 2) first_new_user_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(cost) > 0, SUM(new_user_total_amount) / SUM(cost), 0), 4) total_roi,
-                            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_parent.ads_game_day_parent as a
-                        left join   game_dw_parent.dw_game_amount_day_parent as b
-                        on a.dt = b.dt and a.parent_game_id = b.parent_game_id 
-                      """;
+                              IFNULL(SUM(first_new_user_amount_count), 0) first_new_user_amount_count,
+                              IFNULL(SUM(first_new_user_amount_num), 0) first_new_user_amount_num,
+                              IFNULL(SUM(first_new_user_amount), 0) first_new_user_amount,
+                              IFNULL(SUM(old_user_count), 0) old_user_count,
+                              IFNULL(SUM(old_user_num), 0) old_user_num,
+                              IFNULL(SUM(old_user_amount), 0) old_user_amount,
+                              IFNULL(SUM(amount_count), 0) amount_count,
+                              IFNULL(SUM(amount_num), 0) amount_num,
+                              IFNULL(SUM(amount), 0) amount,
+                              IFNULL(SUM(new_user_total_amount_count), 0) new_user_total_amount_count,
+                              IFNULL(SUM(new_user_total_amount_num), 0) new_user_total_amount_num,
+                              IFNULL(SUM(new_user_total_amount), 0) new_user_total_amount,
+                              round(if(SUM(cost) > 0 , SUM(first_new_user_amount) / SUM(cost) ,0), 4) first_roi,
+                              round(if(SUM(reg_num) > 0 , SUM(first_new_user_amount_num) / SUM(reg_num) ,0), 4) first_amount_rate,
+                              round(if(SUM(reg_num) > 0, SUM(new_user_total_amount_num) / SUM(reg_num), 0) ,4) today_amount_rate,
+                              round(if(SUM(amount_num) > 0 , SUM(first_new_user_amount_num) / SUM(amount_num) ,0), 4) new_user_rate,
+                              round(if(SUM(first_new_user_amount_count) > 0, SUM(first_new_user_amount) / SUM(first_new_user_amount_count), 0), 2) first_avg_amount,
+                              round(if(SUM(new_user_total_amount_count) > 0, SUM(new_user_total_amount) / SUM(new_user_total_amount_count), 0), 2) today_avg_amount,
+                              round(if(SUM(amount_count) > 0, SUM(amount) / SUM(amount_count), 0), 2) avg_amount,
+                              round(if(SUM(new_user_total_amount_num) > 0, SUM(reg_order_user_again) / SUM(new_user_total_amount_num), 0), 4) user_again_rate,
+                              round(if(SUM(reg_num) > 0, SUM(new_user_total_amount) / SUM(reg_num), 0), 2) reg_user_arpu,
+                              round(if(SUM(first_new_user_amount_num) > 0 , SUM(first_new_user_amount) / SUM(first_new_user_amount_num), 0), 2) first_amount_arpu,
+                              round(if(SUM(new_user_total_amount_num) > 0 , SUM(new_user_total_amount) / SUM(new_user_total_amount_num), 0), 2) today_amount_arpu,
+                              round(if(SUM(amount_num) > 0, SUM(amount) / SUM(amount_num), 0), 2) amount_arpu,
+                              round(if(SUM(reg_num) > 0, SUM(cost) / SUM(reg_num), 0), 2) reg_cost,
+                              round(if(SUM(first_new_user_amount_num) > 0, SUM(cost) / SUM(first_new_user_amount_num), 0), 2) first_new_user_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(cost) > 0, SUM(new_user_total_amount) / SUM(cost), 0), 4) total_roi,
+                              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,
+                              
+                              sum(first_effective_role_num) as first_effective_role_num,  -- 首日有效创角人数
+                              sum(new_user_total_effective_role_num) as new_user_total_effective_role_num,  -- 新用户累计有效创角人数
+                              SUM(effective_role_num) as effective_role_num, -- 有效创角人数
+                              
+                              ROUND(IFNULL(SUM(first_effective_role_num)/sum(first_role_num),0)*100,2) as first_effective_role_rate,   -- 首日有效创角率 = 首日有效创角人数/首日创角人数
+                              round(IFNULL(SUM(new_user_total_effective_role_num)/SUM(new_user_total_role_num),0)*100,2) as new_user_total_effective_role_num_rate,         -- 新用户累计有效创角率 = 新用户累计有效创角人数/新用户累计创角人数
+                              round(IFNULL(SUM(effective_role_num)/SUM(role_num),0)*100,2) as effective_role_num_rate,        -- 有效创角率 = 有效创角人数/创角人数
+                              
+                              round(IFNULL(SUM(cost)/SUM(first_effective_role_num),0),2) as first_effective_role_num_cost, -- 首日有效创角成本= 消耗/首日有效创角人数
+                              round(IFNULL(SUM(cost)/SUM(new_user_total_effective_role_num),0),2)  as new_user_total_effective_role_num_cost, -- 新用户累计有效创角成本 = 消耗/新用户累计有效创角人数
+                              round(IFNULL(SUM(cost)/sum(effective_role_num),0),2) as effective_role_num_cost, -- 有效创角成本 = 消耗/有效创角人数
+                              
+                              SUM(first_effective_role_amount_num) as first_effective_role_amount_num, -- 首日有效创角付费人数
+                              sum(new_user_total_effective_role_amount_num) as new_user_total_effective_role_amount_num, -- 新用户累计有效创角付费人数
+                              
+                              
+                              round(IFNULL(SUM(cost)/sum(first_effective_role_amount_num),0),2) as first_effective_role_amount_num_cost, -- 首日有效创角付费成本=消耗/首日有效创角付费人数
+                              round(IFNULL(SUM(cost)/SUM(new_user_total_effective_role_amount_num),0),2) as new_user_total_effective_role_amount_num_cost, -- 新用户累计有效创角付费成本=消耗/新用户累计有效创角付费人数
+                              
+                              round(IFNULL(SUM(first_effective_role_amount_num)/SUM(first_new_user_amount_count),0)*100,2) as first_effective_role_amount_num_rate,  -- 首日有效创角付费比=首日有效创角付费人数/首日新用户充值人数
+                              round(IFNULL(SUM(new_user_total_effective_role_amount_num)/SUM(new_user_total_amount_count),0)*100,2) as new_user_total_effective_role_amount_num_rate, -- 新用户累计有效创角付费比=新用户累计有效创角付费人数/新用户累计充值人数
+                              ROUND(IFNULL(SUM(new_user_total_amount)/SUM(new_user_total_effective_role_num),0),2) as first_effective_role_arpu,    -- 新用户累计有效创角ARPU=新用户累计充值金额/新用户累计有效创角人数
+                              ROUND(IFNULL(SUM(first_new_user_amount)/SUM(first_effective_role_num),0),2) as new_user_total_effective_role_arpu -- 首日有效创角ARPU=首日新用户充值金额/首日有效创角人数
+                          FROM game_ads_parent.ads_game_day_parent as a
+                          left join   game_dw_parent.dw_game_amount_day_parent as b
+                          on a.dt = b.dt and a.parent_game_id = b.parent_game_id 
+                        """;
     }
 
     /**
@@ -3929,21 +4205,21 @@ public class GameDataServiceImpl implements IGameDataService {
 
 
     /**
-     *  Dn的充值金额 / D1-Dn的充值总金额 / Dn的充值人数 /当前消耗(剔除不存在的天数数据) /D1充值金额总和(剔除不存在的天数数据)
+     * Dn的充值金额 / D1-Dn的充值总金额 / Dn的充值人数 /当前消耗(剔除不存在的天数数据) /D1充值金额总和(剔除不存在的天数数据)
      * 游戏每日总计趋势sql
      */
-    private static String amountDayStr(String type){
+    private static String amountDayStr(String type) {
         //拼接查询条件
         StringBuilder trendDay = new StringBuilder(StringUtils.EMPTY);
         trendDay.append("""
-                    CONCAT(
-                      SUM(IF(DATE_ADD(a.dt, INTERVAL 0 day) <= DATE(NOW()), %sda1, 0)),'/',
-                      IFNULL(sum(%sda1),0),'/', 
-                      sum(ifnull(%sda1_num,0)),'/',
-                      SUM(IF(DATE_ADD(a.dt, INTERVAL 0 day) <= DATE(NOW()), cost, 0)),'/',
-                      SUM(IF(DATE_ADD(a.dt, INTERVAL 0 day) <= DATE(NOW()), %sda1, 0))
-                    ) AS amount_d1 ,
-                    """.formatted(type, type, type, type));
+                CONCAT(
+                  SUM(IF(DATE_ADD(a.dt, INTERVAL 0 day) <= DATE(NOW()), %sda1, 0)),'/',
+                  IFNULL(sum(%sda1),0),'/', 
+                  sum(ifnull(%sda1_num,0)),'/',
+                  SUM(IF(DATE_ADD(a.dt, INTERVAL 0 day) <= DATE(NOW()), cost, 0)),'/',
+                  SUM(IF(DATE_ADD(a.dt, INTERVAL 0 day) <= DATE(NOW()), %sda1, 0))
+                ) AS amount_d1 ,
+                """.formatted(type, type, type, type));
 
         for (int day = 2; day < 90; day++) {
             trendDay.append("""
@@ -3954,19 +4230,19 @@ public class GameDataServiceImpl implements IGameDataService {
                       SUM(IF(DATE_ADD(a.dt, INTERVAL %d day) <= DATE(NOW()), cost, 0)),'/',
                       SUM(IF(DATE_ADD(a.dt, INTERVAL %d day) <= DATE(NOW()), %sda1, 0))
                     ) AS amount_d%s ,
-                    """.formatted( day - 1,type,day,type,day - 1,type, day, type, day, day - 1, day - 1, type, day));
+                    """.formatted(day - 1, type, day, type, day - 1, type, day, type, day, day - 1, day - 1, type, day));
         }
 
         //三月
         trendDay.append("""
-                    CONCAT(
-                      SUM(IF(DATE_ADD(a.dt, INTERVAL 2 month) <= DATE(NOW()), %sm3-%sda89, 0)),'/',
-                      IFNULL(sum(%sm3),0),'/',
-                      sum(ifnull(%sda90_num,0)),'/',
-                      SUM(IF(DATE_ADD(a.dt, INTERVAL 2 month) <= DATE(NOW()), cost, 0)),'/',
-                      SUM(IF(DATE_ADD(a.dt, INTERVAL 2 month) <= DATE(NOW()), %sda1, 0))
-                    ) AS amount_d90 ,
-                    """.formatted(type, type, type, type,type));
+                CONCAT(
+                  SUM(IF(DATE_ADD(a.dt, INTERVAL 2 month) <= DATE(NOW()), %sm3-%sda89, 0)),'/',
+                  IFNULL(sum(%sm3),0),'/',
+                  sum(ifnull(%sda90_num,0)),'/',
+                  SUM(IF(DATE_ADD(a.dt, INTERVAL 2 month) <= DATE(NOW()), cost, 0)),'/',
+                  SUM(IF(DATE_ADD(a.dt, INTERVAL 2 month) <= DATE(NOW()), %sda1, 0))
+                ) AS amount_d90 ,
+                """.formatted(type, type, type, type, type));
         for (int month = 4; month <= 12; month++) {
             trendDay.append("""
                     CONCAT(
@@ -3976,7 +4252,7 @@ public class GameDataServiceImpl implements IGameDataService {
                       SUM(IF(DATE_ADD(a.dt, INTERVAL %d month) <= DATE(NOW()), cost, 0)),'/',
                       SUM(IF(DATE_ADD(a.dt, INTERVAL %d month) <= DATE(NOW()), %sda1, 0))
                     ) AS amount_m%s ,
-                    """.formatted(month -1 , type,month,type,month - 1,type, month, type, month, month - 1,month - 1, type,month));
+                    """.formatted(month - 1, type, month, type, month - 1, type, month, type, month, month - 1, month - 1, type, month));
         }
 //        //拼接sum数据
         trendDay.append("""
@@ -4050,7 +4326,30 @@ public class GameDataServiceImpl implements IGameDataService {
                             round(IF(SUM(buy_first_role_num) > 0, SUM(cost) / SUM(buy_first_role_num), 0), 2) first_role_num_cost,
                             round(IF(SUM(buy_new_user_total_role_num) >0, SUM(cost) / SUM(buy_new_user_total_role_num), 0), 2) new_user_total_role_num_cost,
                             round(IF(SUM(buy_reg_num) >0, SUM(buy_first_role_num) / SUM(buy_reg_num), 0), 4) first_role_num_rate,
-                            round(IF(SUM(buy_reg_num) >0, SUM(buy_new_user_total_role_num) / SUM(buy_reg_num), 0), 4) new_user_total_role_num_rate
+                            round(IF(SUM(buy_reg_num) >0, SUM(buy_new_user_total_role_num) / SUM(buy_reg_num), 0), 4) new_user_total_role_num_rate,
+                            
+                            sum(buy_first_effective_role_num) as first_effective_role_num,  -- 首日有效创角人数
+                            sum(buy_new_user_total_effective_role_num) as new_user_total_effective_role_num,  -- 新用户累计有效创角人数
+                            SUM(buy_effective_role_num) as effective_role_num, -- 有效创角人数
+                            
+                            ROUND(IFNULL(SUM(buy_first_effective_role_num)/sum(buy_first_role_num),0)*100,2) as first_effective_role_rate,   -- 首日有效创角率 = 首日有效创角人数/首日创角人数
+                            round(IFNULL(SUM(buy_new_user_total_effective_role_num)/SUM(buy_new_user_total_role_num),0)*100,2) as new_user_total_effective_role_num_rate,         -- 新用户累计有效创角率 = 新用户累计有效创角人数/新用户累计创角人数
+                            round(IFNULL(SUM(buy_effective_role_num)/SUM(buy_role_num),0)*100,2) as effective_role_num_rate,        -- 有效创角率 = 有效创角人数/创角人数
+                            
+                            round(IFNULL(SUM(cost)/SUM(buy_first_effective_role_num),0),2) as first_effective_role_num_cost, -- 首日有效创角成本= 消耗/首日有效创角人数
+                            round(IFNULL(SUM(cost)/SUM(buy_new_user_total_effective_role_num),0),2)  as new_user_total_effective_role_num_cost, -- 新用户累计有效创角成本 = 消耗/新用户累计有效创角人数
+                            round(IFNULL(SUM(cost)/sum(buy_effective_role_num),0),2) as effective_role_num_cost, -- 有效创角成本 = 消耗/有效创角人数
+                            
+                            SUM(buy_first_effective_role_amount_num) as first_effective_role_amount_num, -- 首日有效创角付费人数
+                            sum(buy_new_user_total_effective_role_amount_num) as new_user_total_effective_role_amount_num, -- 新用户累计有效创角付费人数
+                            
+                            round(IFNULL(SUM(cost)/sum(buy_first_effective_role_amount_num),0),2) as first_effective_role_amount_num_cost, -- 首日有效创角付费成本=消耗/首日有效创角付费人数
+                            round(IFNULL(SUM(cost)/SUM(buy_new_user_total_effective_role_amount_num),0),2) as new_user_total_effective_role_amount_num_cost, -- 新用户累计有效创角付费成本=消耗/新用户累计有效创角付费人数
+                            
+                            round(IFNULL(SUM(buy_first_effective_role_amount_num)/SUM(buy_first_new_user_amount_count),0)*100,2) as first_effective_role_amount_num_rate,  -- 首日有效创角付费比=首日有效创角付费人数/首日新用户充值人数
+                            round(IFNULL(SUM(buy_new_user_total_effective_role_amount_num)/SUM(buy_new_user_total_amount_count),0)*100,2) as new_user_total_effective_role_amount_num_rate, -- 新用户累计有效创角付费比=新用户累计有效创角付费人数/新用户累计充值人数
+                            ROUND(IFNULL(SUM(buy_new_user_total_amount)/SUM(buy_new_user_total_effective_role_num),0),2) as first_effective_role_arpu,    -- 新用户累计有效创角ARPU=新用户累计充值金额/新用户累计有效创角人数
+                            ROUND(IFNULL(SUM(buy_first_new_user_amount)/SUM(buy_first_effective_role_num),0),2) as new_user_total_effective_role_arpu -- 首日有效创角ARPU=首日新用户充值金额/首日有效创角人数
                         FROM
                             ads_game_day
                     """ + criA +
@@ -4176,7 +4475,30 @@ public class GameDataServiceImpl implements IGameDataService {
                             round(IF(SUM(nature_first_role_num) > 0, SUM(cost) / SUM(nature_first_role_num), 0), 2) first_role_num_cost,
                             round(IF(SUM(nature_new_user_total_role_num) >0, SUM(cost) / SUM(nature_new_user_total_role_num), 0), 2) new_user_total_role_num_cost,
                             round(IF(SUM(nature_reg_num) >0, SUM(nature_first_role_num) / SUM(nature_reg_num), 0), 4) first_role_num_rate,
-                            round(IF(SUM(nature_reg_num) >0, SUM(nature_new_user_total_role_num) / SUM(nature_reg_num), 0), 4) new_user_total_role_num_rate
+                            round(IF(SUM(nature_reg_num) >0, SUM(nature_new_user_total_role_num) / SUM(nature_reg_num), 0), 4) new_user_total_role_num_rate,
+                            
+                            sum(nature_first_effective_role_num) as first_effective_role_num,  -- 首日有效创角人数
+                            sum(nature_new_user_total_effective_role_num) as new_user_total_effective_role_num,  -- 新用户累计有效创角人数
+                            SUM(nature_effective_role_num) as effective_role_num, -- 有效创角人数
+                            
+                            ROUND(IFNULL(SUM(nature_first_effective_role_num)/sum(nature_first_role_num),0)*100,2) as first_effective_role_rate,   -- 首日有效创角率 = 首日有效创角人数/首日创角人数
+                            round(IFNULL(SUM(nature_new_user_total_effective_role_num)/SUM(nature_new_user_total_role_num),0)*100,2) as new_user_total_effective_role_num_rate,         -- 新用户累计有效创角率 = 新用户累计有效创角人数/新用户累计创角人数
+                            round(IFNULL(SUM(nature_effective_role_num)/SUM(nature_role_num),0)*100,2) as effective_role_num_rate,        -- 有效创角率 = 有效创角人数/创角人数
+                            
+                            round(IFNULL(SUM(cost)/SUM(nature_first_effective_role_num),0),2) as first_effective_role_num_cost, -- 首日有效创角成本= 消耗/首日有效创角人数
+                            round(IFNULL(SUM(cost)/SUM(nature_new_user_total_effective_role_num),0),2)  as new_user_total_effective_role_num_cost, -- 新用户累计有效创角成本 = 消耗/新用户累计有效创角人数
+                            round(IFNULL(SUM(cost)/sum(nature_effective_role_num),0),2) as effective_role_num_cost, -- 有效创角成本 = 消耗/有效创角人数
+                            
+                            SUM(nature_first_effective_role_amount_num) as first_effective_role_amount_num, -- 首日有效创角付费人数
+                            sum(nature_new_user_total_effective_role_amount_num) as new_user_total_effective_role_amount_num, -- 新用户累计有效创角付费人数
+                            
+                            round(IFNULL(SUM(cost)/sum(nature_first_effective_role_amount_num),0),2) as first_effective_role_amount_num_cost, -- 首日有效创角付费成本=消耗/首日有效创角付费人数
+                            round(IFNULL(SUM(cost)/SUM(nature_new_user_total_effective_role_amount_num),0),2) as new_user_total_effective_role_amount_num_cost, -- 新用户累计有效创角付费成本=消耗/新用户累计有效创角付费人数
+                            
+                            round(IFNULL(SUM(nature_first_effective_role_amount_num)/SUM(nature_first_new_user_amount_count),0)*100,2) as first_effective_role_amount_num_rate,  -- 首日有效创角付费比=首日有效创角付费人数/首日新用户充值人数
+                            round(IFNULL(SUM(nature_new_user_total_effective_role_amount_num)/SUM(nature_new_user_total_amount_count),0)*100,2) as new_user_total_effective_role_amount_num_rate, -- 新用户累计有效创角付费比=新用户累计有效创角付费人数/新用户累计充值人数
+                            ROUND(IFNULL(SUM(nature_new_user_total_amount)/SUM(nature_new_user_total_effective_role_num),0),2) as first_effective_role_arpu,    -- 新用户累计有效创角ARPU=新用户累计充值金额/新用户累计有效创角人数
+                            ROUND(IFNULL(SUM(nature_first_new_user_amount)/SUM(nature_first_effective_role_num),0),2) as new_user_total_effective_role_arpu -- 首日有效创角ARPU=首日新用户充值金额/首日有效创角人数
                         FROM
                             ads_game_day
                     """ + criA +
@@ -4303,7 +4625,31 @@ public class GameDataServiceImpl implements IGameDataService {
                 		round(IF(SUM(first_role_num) > 0, SUM(cost) / SUM(first_role_num), 0), 2) first_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(new_user_total_role_num) / SUM(reg_num), 0), 4) new_user_total_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,
+                		
+                		sum(first_effective_role_num) as first_effective_role_num,  -- 首日有效创角人数
+                        sum(new_user_total_effective_role_num) as new_user_total_effective_role_num,  -- 新用户累计有效创角人数
+                        SUM(effective_role_num) as effective_role_num, -- 有效创角人数
+                       
+                        ROUND(IFNULL(SUM(first_effective_role_num)/sum(first_role_num),0)*100,2) as first_effective_role_rate,   -- 首日有效创角率 = 首日有效创角人数/首日创角人数
+                        round(IFNULL(SUM(new_user_total_effective_role_num)/SUM(new_user_total_role_num),0)*100,2) as new_user_total_effective_role_num_rate,         -- 新用户累计有效创角率 = 新用户累计有效创角人数/新用户累计创角人数
+                        round(IFNULL(SUM(effective_role_num)/SUM(role_num),0)*100,2) as effective_role_num_rate,        -- 有效创角率 = 有效创角人数/创角人数
+                       
+                        round(IFNULL(SUM(cost)/SUM(first_effective_role_num),0),2) as first_effective_role_num_cost, -- 首日有效创角成本= 消耗/首日有效创角人数
+                        round(IFNULL(SUM(cost)/SUM(new_user_total_effective_role_num),0),2)  as new_user_total_effective_role_num_cost, -- 新用户累计有效创角成本 = 消耗/新用户累计有效创角人数
+                        round(IFNULL(SUM(cost)/sum(effective_role_num),0),2) as effective_role_num_cost, -- 有效创角成本 = 消耗/有效创角人数
+                       
+                        SUM(first_effective_role_amount_num) as first_effective_role_amount_num, -- 首日有效创角付费人数
+                        sum(new_user_total_effective_role_amount_num) as new_user_total_effective_role_amount_num, -- 新用户累计有效创角付费人数
+                       
+                       
+                        round(IFNULL(SUM(cost)/sum(first_effective_role_amount_num),0),2) as first_effective_role_amount_num_cost, -- 首日有效创角付费成本=消耗/首日有效创角付费人数
+                        round(IFNULL(SUM(cost)/SUM(new_user_total_effective_role_amount_num),0),2) as new_user_total_effective_role_amount_num_cost, -- 新用户累计有效创角付费成本=消耗/新用户累计有效创角付费人数
+                       
+                        round(IFNULL(SUM(first_effective_role_amount_num)/SUM(first_new_user_amount_count),0)*100,2) as first_effective_role_amount_num_rate,  -- 首日有效创角付费比=首日有效创角付费人数/首日新用户充值人数
+                        round(IFNULL(SUM(new_user_total_effective_role_amount_num)/SUM(new_user_total_amount_count),0)*100,2) as new_user_total_effective_role_amount_num_rate, -- 新用户累计有效创角付费比=新用户累计有效创角付费人数/新用户累计充值人数
+                        ROUND(IFNULL(SUM(new_user_total_amount)/SUM(new_user_total_effective_role_num),0),2) as first_effective_role_arpu,    -- 新用户累计有效创角ARPU=新用户累计充值金额/新用户累计有效创角人数
+                        ROUND(IFNULL(SUM(first_new_user_amount)/SUM(first_effective_role_num),0),2) as new_user_total_effective_role_arpu -- 首日有效创角ARPU=首日新用户充值金额/首日有效创角人数
                 	FROM
                 		ads_game_day
                 """ + criA +
@@ -4440,7 +4786,29 @@ public class GameDataServiceImpl implements IGameDataService {
                             round(IF(SUM(buy_first_role_num) > 0, SUM(cost) / SUM(buy_first_role_num), 0), 2) first_role_num_cost,
                             round(IF(SUM(buy_new_user_total_role_num) >0, SUM(cost) / SUM(buy_new_user_total_role_num), 0), 2) new_user_total_role_num_cost,
                             round(IF(SUM(buy_reg_num) >0, SUM(buy_first_role_num) / SUM(buy_reg_num), 0), 4) first_role_num_rate,
-                            round(IF(SUM(buy_reg_num) >0, SUM(buy_new_user_total_role_num) / SUM(buy_reg_num), 0), 4) new_user_total_role_num_rate
+                            round(IF(SUM(buy_reg_num) >0, SUM(buy_new_user_total_role_num) / SUM(buy_reg_num), 0), 4) new_user_total_role_num_rate,
+                              sum(buy_first_effective_role_num) as first_effective_role_num,  -- 首日有效创角人数
+                            sum(buy_new_user_total_effective_role_num) as new_user_total_effective_role_num,  -- 新用户累计有效创角人数
+                            SUM(buy_effective_role_num) as effective_role_num, -- 有效创角人数
+                            
+                            ROUND(IFNULL(SUM(buy_first_effective_role_num)/sum(buy_first_role_num),0)*100,2) as first_effective_role_rate,   -- 首日有效创角率 = 首日有效创角人数/首日创角人数
+                            round(IFNULL(SUM(buy_new_user_total_effective_role_num)/SUM(buy_new_user_total_role_num),0)*100,2) as new_user_total_effective_role_num_rate,         -- 新用户累计有效创角率 = 新用户累计有效创角人数/新用户累计创角人数
+                            round(IFNULL(SUM(buy_effective_role_num)/SUM(buy_role_num),0)*100,2) as effective_role_num_rate,        -- 有效创角率 = 有效创角人数/创角人数
+                            
+                            round(IFNULL(SUM(cost)/SUM(buy_first_effective_role_num),0),2) as first_effective_role_num_cost, -- 首日有效创角成本= 消耗/首日有效创角人数
+                            round(IFNULL(SUM(cost)/SUM(buy_new_user_total_effective_role_num),0),2)  as new_user_total_effective_role_num_cost, -- 新用户累计有效创角成本 = 消耗/新用户累计有效创角人数
+                            round(IFNULL(SUM(cost)/sum(buy_effective_role_num),0),2) as effective_role_num_cost, -- 有效创角成本 = 消耗/有效创角人数
+                            
+                            SUM(buy_first_effective_role_amount_num) as first_effective_role_amount_num, -- 首日有效创角付费人数
+                            sum(buy_new_user_total_effective_role_amount_num) as new_user_total_effective_role_amount_num, -- 新用户累计有效创角付费人数
+                            
+                            round(IFNULL(SUM(cost)/sum(buy_first_effective_role_amount_num),0),2) as first_effective_role_amount_num_cost, -- 首日有效创角付费成本=消耗/首日有效创角付费人数
+                            round(IFNULL(SUM(cost)/SUM(buy_new_user_total_effective_role_amount_num),0),2) as new_user_total_effective_role_amount_num_cost, -- 新用户累计有效创角付费成本=消耗/新用户累计有效创角付费人数
+                            
+                            round(IFNULL(SUM(buy_first_effective_role_amount_num)/SUM(buy_first_new_user_amount_count),0)*100,2) as first_effective_role_amount_num_rate,  -- 首日有效创角付费比=首日有效创角付费人数/首日新用户充值人数
+                            round(IFNULL(SUM(buy_new_user_total_effective_role_amount_num)/SUM(buy_new_user_total_amount_count),0)*100,2) as new_user_total_effective_role_amount_num_rate, -- 新用户累计有效创角付费比=新用户累计有效创角付费人数/新用户累计充值人数
+                            ROUND(IFNULL(SUM(buy_new_user_total_amount)/SUM(buy_new_user_total_effective_role_num),0),2) as first_effective_role_arpu,    -- 新用户累计有效创角ARPU=新用户累计充值金额/新用户累计有效创角人数
+                            ROUND(IFNULL(SUM(buy_first_new_user_amount)/SUM(buy_first_effective_role_num),0),2) as new_user_total_effective_role_arpu -- 首日有效创角ARPU=首日新用户充值金额/首日有效创角人数
                         FROM
                             game_ads_parent.ads_game_day_parent
                     """ + criA +
@@ -4566,7 +4934,30 @@ public class GameDataServiceImpl implements IGameDataService {
                             round(IF(SUM(nature_first_role_num) > 0, SUM(cost) / SUM(nature_first_role_num), 0), 2) first_role_num_cost,
                             round(IF(SUM(nature_new_user_total_role_num) >0, SUM(cost) / SUM(nature_new_user_total_role_num), 0), 2) new_user_total_role_num_cost,
                             round(IF(SUM(nature_reg_num) >0, SUM(nature_first_role_num) / SUM(nature_reg_num), 0), 4) first_role_num_rate,
-                            round(IF(SUM(nature_reg_num) >0, SUM(nature_new_user_total_role_num) / SUM(nature_reg_num), 0), 4) new_user_total_role_num_rate
+                            round(IF(SUM(nature_reg_num) >0, SUM(nature_new_user_total_role_num) / SUM(nature_reg_num), 0), 4) new_user_total_role_num_rate,
+                            
+                            sum(nature_first_effective_role_num) as first_effective_role_num,  -- 首日有效创角人数
+                            sum(nature_new_user_total_effective_role_num) as new_user_total_effective_role_num,  -- 新用户累计有效创角人数
+                            SUM(nature_effective_role_num) as effective_role_num, -- 有效创角人数
+                            
+                            ROUND(IFNULL(SUM(nature_first_effective_role_num)/sum(nature_first_role_num),0)*100,2) as first_effective_role_rate,   -- 首日有效创角率 = 首日有效创角人数/首日创角人数
+                            round(IFNULL(SUM(nature_new_user_total_effective_role_num)/SUM(nature_new_user_total_role_num),0)*100,2) as new_user_total_effective_role_num_rate,         -- 新用户累计有效创角率 = 新用户累计有效创角人数/新用户累计创角人数
+                            round(IFNULL(SUM(nature_effective_role_num)/SUM(nature_role_num),0)*100,2) as effective_role_num_rate,        -- 有效创角率 = 有效创角人数/创角人数
+                            
+                            round(IFNULL(SUM(cost)/SUM(nature_first_effective_role_num),0),2) as first_effective_role_num_cost, -- 首日有效创角成本= 消耗/首日有效创角人数
+                            round(IFNULL(SUM(cost)/SUM(nature_new_user_total_effective_role_num),0),2)  as new_user_total_effective_role_num_cost, -- 新用户累计有效创角成本 = 消耗/新用户累计有效创角人数
+                            round(IFNULL(SUM(cost)/sum(nature_effective_role_num),0),2) as effective_role_num_cost, -- 有效创角成本 = 消耗/有效创角人数
+                            
+                            SUM(nature_first_effective_role_amount_num) as first_effective_role_amount_num, -- 首日有效创角付费人数
+                            sum(nature_new_user_total_effective_role_amount_num) as new_user_total_effective_role_amount_num, -- 新用户累计有效创角付费人数
+                            
+                            round(IFNULL(SUM(cost)/sum(nature_first_effective_role_amount_num),0),2) as first_effective_role_amount_num_cost, -- 首日有效创角付费成本=消耗/首日有效创角付费人数
+                            round(IFNULL(SUM(cost)/SUM(nature_new_user_total_effective_role_amount_num),0),2) as new_user_total_effective_role_amount_num_cost, -- 新用户累计有效创角付费成本=消耗/新用户累计有效创角付费人数
+                            
+                            round(IFNULL(SUM(nature_first_effective_role_amount_num)/SUM(nature_first_new_user_amount_count),0)*100,2) as first_effective_role_amount_num_rate,  -- 首日有效创角付费比=首日有效创角付费人数/首日新用户充值人数
+                            round(IFNULL(SUM(nature_new_user_total_effective_role_amount_num)/SUM(nature_new_user_total_amount_count),0)*100,2) as new_user_total_effective_role_amount_num_rate, -- 新用户累计有效创角付费比=新用户累计有效创角付费人数/新用户累计充值人数
+                            ROUND(IFNULL(SUM(nature_new_user_total_amount)/SUM(nature_new_user_total_effective_role_num),0),2) as first_effective_role_arpu,    -- 新用户累计有效创角ARPU=新用户累计充值金额/新用户累计有效创角人数
+                            ROUND(IFNULL(SUM(nature_first_new_user_amount)/SUM(nature_first_effective_role_num),0),2) as new_user_total_effective_role_arpu -- 首日有效创角ARPU=首日新用户充值金额/首日有效创角人数
                         FROM
                             game_ads_parent.ads_game_day_parent
                     """ + criA +
@@ -4693,7 +5084,31 @@ public class GameDataServiceImpl implements IGameDataService {
                 		round(IF(SUM(first_role_num) > 0, SUM(cost) / SUM(first_role_num), 0), 2) first_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(new_user_total_role_num) / SUM(reg_num), 0), 4) new_user_total_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,
+                		
+                		sum(first_effective_role_num) as first_effective_role_num,  -- 首日有效创角人数
+                        sum(new_user_total_effective_role_num) as new_user_total_effective_role_num,  -- 新用户累计有效创角人数
+                        SUM(effective_role_num) as effective_role_num, -- 有效创角人数
+                       
+                        ROUND(IFNULL(SUM(first_effective_role_num)/sum(first_role_num),0)*100,2) as first_effective_role_rate,   -- 首日有效创角率 = 首日有效创角人数/首日创角人数
+                        round(IFNULL(SUM(new_user_total_effective_role_num)/SUM(new_user_total_role_num),0)*100,2) as new_user_total_effective_role_num_rate,         -- 新用户累计有效创角率 = 新用户累计有效创角人数/新用户累计创角人数
+                        round(IFNULL(SUM(effective_role_num)/SUM(role_num),0)*100,2) as effective_role_num_rate,        -- 有效创角率 = 有效创角人数/创角人数
+                       
+                        round(IFNULL(SUM(cost)/SUM(first_effective_role_num),0),2) as first_effective_role_num_cost, -- 首日有效创角成本= 消耗/首日有效创角人数
+                        round(IFNULL(SUM(cost)/SUM(new_user_total_effective_role_num),0),2)  as new_user_total_effective_role_num_cost, -- 新用户累计有效创角成本 = 消耗/新用户累计有效创角人数
+                        round(IFNULL(SUM(cost)/sum(effective_role_num),0),2) as effective_role_num_cost, -- 有效创角成本 = 消耗/有效创角人数
+                       
+                        SUM(first_effective_role_amount_num) as first_effective_role_amount_num, -- 首日有效创角付费人数
+                        sum(new_user_total_effective_role_amount_num) as new_user_total_effective_role_amount_num, -- 新用户累计有效创角付费人数
+                       
+                       
+                        round(IFNULL(SUM(cost)/sum(first_effective_role_amount_num),0),2) as first_effective_role_amount_num_cost, -- 首日有效创角付费成本=消耗/首日有效创角付费人数
+                        round(IFNULL(SUM(cost)/SUM(new_user_total_effective_role_amount_num),0),2) as new_user_total_effective_role_amount_num_cost, -- 新用户累计有效创角付费成本=消耗/新用户累计有效创角付费人数
+                       
+                        round(IFNULL(SUM(first_effective_role_amount_num)/SUM(first_new_user_amount_count),0)*100,2) as first_effective_role_amount_num_rate,  -- 首日有效创角付费比=首日有效创角付费人数/首日新用户充值人数
+                        round(IFNULL(SUM(new_user_total_effective_role_amount_num)/SUM(new_user_total_amount_count),0)*100,2) as new_user_total_effective_role_amount_num_rate, -- 新用户累计有效创角付费比=新用户累计有效创角付费人数/新用户累计充值人数
+                        ROUND(IFNULL(SUM(new_user_total_amount)/SUM(new_user_total_effective_role_num),0),2) as first_effective_role_arpu,    -- 新用户累计有效创角ARPU=新用户累计充值金额/新用户累计有效创角人数
+                        ROUND(IFNULL(SUM(first_new_user_amount)/SUM(first_effective_role_num),0),2) as new_user_total_effective_role_arpu -- 首日有效创角ARPU=首日新用户充值金额/首日有效创角人数
                 	FROM
                 		game_ads_parent.ads_game_day_parent
                 """ + criA +
@@ -4811,7 +5226,31 @@ public class GameDataServiceImpl implements IGameDataService {
                         round(IF(SUM(buy_first_role_num) > 0, SUM(cost) / SUM(buy_first_role_num), 0), 2) first_role_num_cost,
                         round(IF(SUM(buy_new_user_total_role_num) >0, SUM(cost) / SUM(buy_new_user_total_role_num), 0), 2) new_user_total_role_num_cost,
                         round(IF(SUM(buy_reg_num) >0, SUM(buy_first_role_num) / SUM(buy_reg_num), 0), 4) first_role_num_rate,
-                        round(IF(SUM(buy_reg_num) >0, SUM(buy_new_user_total_role_num) / SUM(buy_reg_num), 0), 4) new_user_total_role_num_rate
+                        round(IF(SUM(buy_reg_num) >0, SUM(buy_new_user_total_role_num) / SUM(buy_reg_num), 0), 4) new_user_total_role_num_rate,
+                        
+                        sum(buy_first_effective_role_num) as first_effective_role_num,  -- 首日有效创角人数
+                        sum(buy_new_user_total_effective_role_num) as new_user_total_effective_role_num,  -- 新用户累计有效创角人数
+                        SUM(buy_effective_role_num) as effective_role_num, -- 有效创角人数
+                        
+                        ROUND(IFNULL(SUM(buy_first_effective_role_num)/sum(buy_first_role_num),0)*100,2) as first_effective_role_rate,   -- 首日有效创角率 = 首日有效创角人数/首日创角人数
+                        round(IFNULL(SUM(buy_new_user_total_effective_role_num)/SUM(buy_new_user_total_role_num),0)*100,2) as new_user_total_effective_role_num_rate,         -- 新用户累计有效创角率 = 新用户累计有效创角人数/新用户累计创角人数
+                        round(IFNULL(SUM(buy_effective_role_num)/SUM(buy_role_num),0)*100,2) as effective_role_num_rate,        -- 有效创角率 = 有效创角人数/创角人数
+                        
+                        round(IFNULL(SUM(cost)/SUM(buy_first_effective_role_num),0),2) as first_effective_role_num_cost, -- 首日有效创角成本= 消耗/首日有效创角人数
+                        round(IFNULL(SUM(cost)/SUM(buy_new_user_total_effective_role_num),0),2)  as new_user_total_effective_role_num_cost, -- 新用户累计有效创角成本 = 消耗/新用户累计有效创角人数
+                        round(IFNULL(SUM(cost)/sum(buy_effective_role_num),0),2) as effective_role_num_cost, -- 有效创角成本 = 消耗/有效创角人数
+                        
+                        SUM(buy_first_effective_role_amount_num) as first_effective_role_amount_num, -- 首日有效创角付费人数
+                        sum(buy_new_user_total_effective_role_amount_num) as new_user_total_effective_role_amount_num, -- 新用户累计有效创角付费人数
+                        
+                        
+                        round(IFNULL(SUM(cost)/sum(buy_first_effective_role_amount_num),0),2) as first_effective_role_amount_num_cost, -- 首日有效创角付费成本=消耗/首日有效创角付费人数
+                        round(IFNULL(SUM(cost)/SUM(buy_new_user_total_effective_role_amount_num),0),2) as new_user_total_effective_role_amount_num_cost, -- 新用户累计有效创角付费成本=消耗/新用户累计有效创角付费人数
+                        
+                        round(IFNULL(SUM(buy_first_effective_role_amount_num)/SUM(buy_first_new_user_amount_count),0)*100,2) as first_effective_role_amount_num_rate,  -- 首日有效创角付费比=首日有效创角付费人数/首日新用户充值人数
+                        round(IFNULL(SUM(buy_new_user_total_effective_role_amount_num)/SUM(buy_new_user_total_amount_count),0)*100,2) as new_user_total_effective_role_amount_num_rate, -- 新用户累计有效创角付费比=新用户累计有效创角付费人数/新用户累计充值人数
+                        ROUND(IFNULL(SUM(buy_new_user_total_amount)/SUM(buy_new_user_total_effective_role_num),0),2) as first_effective_role_arpu,    -- 新用户累计有效创角ARPU=新用户累计充值金额/新用户累计有效创角人数
+                        ROUND(IFNULL(SUM(buy_first_new_user_amount)/SUM(buy_first_effective_role_num),0),2) as new_user_total_effective_role_arpu -- 首日有效创角ARPU=首日新用户充值金额/首日有效创角人数
                     FROM 
                     """ + tableName;
         } else if ("nature".equals(tableType)) {
@@ -4845,7 +5284,30 @@ public class GameDataServiceImpl implements IGameDataService {
                         round(IF(SUM(nature_first_role_num) > 0, SUM(cost) / SUM(nature_first_role_num), 0), 2) first_role_num_cost,
                         round(IF(SUM(nature_new_user_total_role_num) >0, SUM(cost) / SUM(nature_new_user_total_role_num), 0), 2) new_user_total_role_num_cost,
                         round(IF(SUM(nature_reg_num) >0, SUM(nature_first_role_num) / SUM(nature_reg_num), 0), 4) first_role_num_rate,
-                        round(IF(SUM(nature_reg_num) >0, SUM(nature_new_user_total_role_num) / SUM(nature_reg_num), 0), 4) new_user_total_role_num_rate
+                        round(IF(SUM(nature_reg_num) >0, SUM(nature_new_user_total_role_num) / SUM(nature_reg_num), 0), 4) new_user_total_role_num_rate,
+                        
+                        sum(nature_first_effective_role_num) as first_effective_role_num,  -- 首日有效创角人数
+                        sum(nature_new_user_total_effective_role_num) as new_user_total_effective_role_num,  -- 新用户累计有效创角人数
+                        SUM(nature_effective_role_num) as effective_role_num, -- 有效创角人数
+                        
+                        ROUND(IFNULL(SUM(nature_first_effective_role_num)/sum(nature_first_role_num),0)*100,2) as first_effective_role_rate,   -- 首日有效创角率 = 首日有效创角人数/首日创角人数
+                        round(IFNULL(SUM(nature_new_user_total_effective_role_num)/SUM(nature_new_user_total_role_num),0)*100,2) as new_user_total_effective_role_num_rate,         -- 新用户累计有效创角率 = 新用户累计有效创角人数/新用户累计创角人数
+                        round(IFNULL(SUM(nature_effective_role_num)/SUM(nature_role_num),0)*100,2) as effective_role_num_rate,        -- 有效创角率 = 有效创角人数/创角人数
+                        
+                        round(IFNULL(SUM(cost)/SUM(nature_first_effective_role_num),0),2) as first_effective_role_num_cost, -- 首日有效创角成本= 消耗/首日有效创角人数
+                        round(IFNULL(SUM(cost)/SUM(nature_new_user_total_effective_role_num),0),2)  as new_user_total_effective_role_num_cost, -- 新用户累计有效创角成本 = 消耗/新用户累计有效创角人数
+                        round(IFNULL(SUM(cost)/sum(nature_effective_role_num),0),2) as effective_role_num_cost, -- 有效创角成本 = 消耗/有效创角人数
+                        
+                        SUM(nature_first_effective_role_amount_num) as first_effective_role_amount_num, -- 首日有效创角付费人数
+                        sum(nature_new_user_total_effective_role_amount_num) as new_user_total_effective_role_amount_num, -- 新用户累计有效创角付费人数
+                        
+                        round(IFNULL(SUM(cost)/sum(nature_first_effective_role_amount_num),0),2) as first_effective_role_amount_num_cost, -- 首日有效创角付费成本=消耗/首日有效创角付费人数
+                        round(IFNULL(SUM(cost)/SUM(nature_new_user_total_effective_role_amount_num),0),2) as new_user_total_effective_role_amount_num_cost, -- 新用户累计有效创角付费成本=消耗/新用户累计有效创角付费人数
+                        
+                        round(IFNULL(SUM(nature_first_effective_role_amount_num)/SUM(nature_first_new_user_amount_count),0)*100,2) as first_effective_role_amount_num_rate,  -- 首日有效创角付费比=首日有效创角付费人数/首日新用户充值人数
+                        round(IFNULL(SUM(nature_new_user_total_effective_role_amount_num)/SUM(nature_new_user_total_amount_count),0)*100,2) as new_user_total_effective_role_amount_num_rate, -- 新用户累计有效创角付费比=新用户累计有效创角付费人数/新用户累计充值人数
+                        ROUND(IFNULL(SUM(nature_new_user_total_amount)/SUM(nature_new_user_total_effective_role_num),0),2) as first_effective_role_arpu,    -- 新用户累计有效创角ARPU=新用户累计充值金额/新用户累计有效创角人数
+                        ROUND(IFNULL(SUM(nature_first_new_user_amount)/SUM(nature_first_effective_role_num),0),2) as new_user_total_effective_role_arpu -- 首日有效创角ARPU=首日新用户充值金额/首日有效创角人数
                     FROM 
                     """ + tableName;
         }
@@ -4880,7 +5342,30 @@ public class GameDataServiceImpl implements IGameDataService {
                     round(IF(SUM(first_role_num) > 0, SUM(cost) / SUM(first_role_num), 0), 2) first_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(new_user_total_role_num) / SUM(reg_num), 0), 4) new_user_total_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,
+                    
+                    sum(first_effective_role_num) as first_effective_role_num,  -- 首日有效创角人数
+                    sum(new_user_total_effective_role_num) as new_user_total_effective_role_num,  -- 新用户累计有效创角人数
+                    SUM(effective_role_num) as effective_role_num, -- 有效创角人数
+                    
+                    ROUND(IFNULL(SUM(first_effective_role_num)/sum(first_role_num),0)*100,2) as first_effective_role_rate,   -- 首日有效创角率 = 首日有效创角人数/首日创角人数
+                    round(IFNULL(SUM(new_user_total_effective_role_num)/SUM(new_user_total_role_num),0)*100,2) as new_user_total_effective_role_num_rate,         -- 新用户累计有效创角率 = 新用户累计有效创角人数/新用户累计创角人数
+                    round(IFNULL(SUM(effective_role_num)/SUM(role_num),0)*100,2) as effective_role_num_rate,        -- 有效创角率 = 有效创角人数/创角人数
+                    
+                    round(IFNULL(SUM(cost)/SUM(first_effective_role_num),0),2) as first_effective_role_num_cost, -- 首日有效创角成本= 消耗/首日有效创角人数
+                    round(IFNULL(SUM(cost)/SUM(new_user_total_effective_role_num),0),2)  as new_user_total_effective_role_num_cost, -- 新用户累计有效创角成本 = 消耗/新用户累计有效创角人数
+                    round(IFNULL(SUM(cost)/sum(effective_role_num),0),2) as effective_role_num_cost, -- 有效创角成本 = 消耗/有效创角人数
+                    
+                    SUM(first_effective_role_amount_num) as first_effective_role_amount_num, -- 首日有效创角付费人数
+                    sum(new_user_total_effective_role_amount_num) as new_user_total_effective_role_amount_num, -- 新用户累计有效创角付费人数
+                    
+                    round(IFNULL(SUM(cost)/sum(first_effective_role_amount_num),0),2) as first_effective_role_amount_num_cost, -- 首日有效创角付费成本=消耗/首日有效创角付费人数
+                    round(IFNULL(SUM(cost)/SUM(new_user_total_effective_role_amount_num),0),2) as new_user_total_effective_role_amount_num_cost, -- 新用户累计有效创角付费成本=消耗/新用户累计有效创角付费人数
+                    
+                    round(IFNULL(SUM(first_effective_role_amount_num)/SUM(first_new_user_amount_count),0)*100,2) as first_effective_role_amount_num_rate,  -- 首日有效创角付费比=首日有效创角付费人数/首日新用户充值人数
+                    round(IFNULL(SUM(new_user_total_effective_role_amount_num)/SUM(new_user_total_amount_count),0)*100,2) as new_user_total_effective_role_amount_num_rate, -- 新用户累计有效创角付费比=新用户累计有效创角付费人数/新用户累计充值人数
+                    ROUND(IFNULL(SUM(new_user_total_amount)/SUM(new_user_total_effective_role_num),0),2) as first_effective_role_arpu,    -- 新用户累计有效创角ARPU=新用户累计充值金额/新用户累计有效创角人数
+                    ROUND(IFNULL(SUM(first_new_user_amount)/SUM(first_effective_role_num),0),2) as new_user_total_effective_role_arpu -- 首日有效创角ARPU=首日新用户充值金额/首日有效创角人数
                 FROM 
                 """ + tableName;
     }
@@ -5694,9 +6179,9 @@ public class GameDataServiceImpl implements IGameDataService {
 
         //查询总记录数
         //默认子游戏
-        Sql countSql = Sqls.create(getCountNumSubgameSql2(cri, agentCri, subGameSql,yesterdayTotalAmountCri));
+        Sql countSql = Sqls.create(getCountNumSubgameSql2(cri, agentCri, subGameSql, yesterdayTotalAmountCri));
         if (dto.getGameDimension() == 2) {
-            countSql = Sqls.create(getCountNumSql(cri, agentCri,yesterdayTotalAmountCri));
+            countSql = Sqls.create(getCountNumSql(cri, agentCri, yesterdayTotalAmountCri));
         }
         countSql.setCallback(Sqls.callback.integer());
         dao.execute(countSql);

+ 85 - 42
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/GameServerServiceImpl.java

@@ -3,6 +3,7 @@ package com.zanxiang.game.data.serve.service.impl;
 import com.google.common.base.CaseFormat;
 import com.zanxiang.erp.base.ErpServer;
 import com.zanxiang.erp.base.rpc.ISysUserRpc;
+import com.zanxiang.erp.security.util.SecurityUtil;
 import com.zanxiang.game.data.serve.component.DataPowerComponent;
 import com.zanxiang.game.data.serve.pojo.dto.*;
 import com.zanxiang.game.data.serve.pojo.entity.AdsGameServerDay;
@@ -13,6 +14,10 @@ import com.zanxiang.game.data.serve.pojo.enums.OrderByEnum;
 import com.zanxiang.game.data.serve.pojo.vo.*;
 import com.zanxiang.game.data.serve.service.IGameServerService;
 import com.zanxiang.game.data.serve.utils.Page;
+import com.zanxiang.game.module.base.ServerInfo;
+import com.zanxiang.game.module.base.pojo.enums.GameAuthEnum;
+import com.zanxiang.game.module.base.pojo.vo.GameAuthUserVO;
+import com.zanxiang.game.module.base.rpc.GameAuthRpc;
 import com.zanxiang.module.util.pojo.ResultVO;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
@@ -24,7 +29,6 @@ import org.nutz.dao.Sqls;
 import org.nutz.dao.pager.Pager;
 import org.nutz.dao.sql.Criteria;
 import org.nutz.dao.sql.Sql;
-import org.nutz.dao.util.cri.SqlExpression;
 import org.nutz.dao.util.cri.Static;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -50,6 +54,9 @@ public class GameServerServiceImpl implements IGameServerService {
     @DubboReference(providedBy = ErpServer.SERVER_DUBBO_NAME)
     private ISysUserRpc sysUserRpc;
 
+    @DubboReference(providedBy = ServerInfo.SERVER_DUBBO_NAME)
+    private GameAuthRpc gameAuthRpc;
+
     //存储映射的List
     private static final List<Tuple2<Field, Field>> dayNFieldMapList;
     private static final List<Tuple2<Field, Field>> dayNTotalFieldMapList;
@@ -549,13 +556,13 @@ public class GameServerServiceImpl implements IGameServerService {
                 .peek(field -> field.setAccessible(true))
                 .toList();
         //把所有gsIds取出来用,拼起来
-        String gsIds = vos.stream().map(GSGameServerDayVO::getGsIds).collect(Collectors.joining(","));
+        String gsIds = vos.stream().filter(i -> StringUtils.isNotEmpty(i.getGsIds())).map(GSGameServerDayVO::getGsIds).collect(Collectors.joining(","));
         ResultVO<Map<Long, String>> userMap = null;
-        if(StringUtils.isNotEmpty(gsIds)){
+        if (StringUtils.isNotEmpty(gsIds)) {
             //转换为Long类型
             List<Long> userIds = Arrays.stream(gsIds.split(",")).map(Long::parseLong).toList();
             //发送RPC接口查询所有用户
-             userMap = sysUserRpc.getUserNameByIds(userIds);
+            userMap = sysUserRpc.getUserNameByIds(userIds);
         }
         for (GSGameServerDayVO vo : vos) {
             List<GSGameServerDayRVO> rDataList = collect.get(vo.getSourceSystem() + vo.getServerId() + vo.getParentGameId());
@@ -565,10 +572,12 @@ public class GameServerServiceImpl implements IGameServerService {
                     String value = (String) field.get(vo);
                     String rData;
                     if (rDataList != null && rDataList.size() >= i + 1) {
+                        //累计的充值人数,为了/r数据
+                        String[] split = value.split("/");
                         GSGameServerDayRVO gsGameServerDayRVO = rDataList.get(i);
-                        rData = getRDataStr(gsGameServerDayRVO, vo);
+                        rData = getRDataStr(gsGameServerDayRVO, Long.valueOf(split[split.length - 1]));
                     } else {
-                        rData = "0/0/0/0/0/0/0/0";
+                        rData = "0/0/0/0/0/0/0/0/0/0";
                     }
                     value += "/" + rData;
 //                    field.set(vo, value + "/" + rData);
@@ -578,21 +587,23 @@ public class GameServerServiceImpl implements IGameServerService {
                             .PaidRetentionRate(split[1])
                             .totalRegNum(split[2])
                             .totalAmountNum(split[3])
-                            .smallR(split[4])
-                            .mediumR(split[5])
-                            .largeR(split[6])
-                            .superR(split[7])
-                            .smallRNum(split[8])
-                            .mediumRNum(split[9])
-                            .largeRNum(split[10])
-                            .superRNum(split[11])
+                            .smallR(split[5])
+                            .mediumR(split[6])
+                            .largeR(split[7])
+                            .superR(split[8])
+                            .smallRNum(split[9])
+                            .mediumRNum(split[10])
+                            .largeRNum(split[11])
+                            .superRNum(split[12])
+                            .rTotal(split[13])
+                            .rTotalRetention(split[14])
                             .build();
                     fieldObjectList.get(i).set(vo, retentionVO);
                 } catch (IllegalAccessException e) {
                     throw new RuntimeException(e);
                 }
             }
-            if(userMap != null && userMap.getData() != null&&StringUtils.isNotEmpty(vo.getGsIds())){
+            if (userMap != null && userMap.getData() != null && StringUtils.isNotEmpty(vo.getGsIds())) {
                 Map<Long, String> data = userMap.getData();
                 List<Long> userIds = Arrays.stream(vo.getGsIds().split(",")).map(Long::parseLong).toList();
                 String gsNames = userIds.stream().map(data::get).collect(Collectors.joining(","));
@@ -603,6 +614,23 @@ public class GameServerServiceImpl implements IGameServerService {
         return new Page<>(vos, pager);
     }
 
+    @Override
+    public List<String> getServerIdByGSId(Long gsId) {
+        if (gsId == null) {
+            return null;
+        }
+        Sql sql = Sqls.create(getServerIdByGSIdSql(gsId));
+        sql.setCallback(Sqls.callback.strList());
+        dao.execute(sql);
+        List<String> list = sql.getList(String.class);
+        return list;
+    }
+
+    private String getServerIdByGSIdSql(Long gsId) {
+        String sql = "select server_id from dm_game_order.t_game_server_merge where find_in_set(" + gsId + ", gs_ids) ";
+        return sql;
+    }
+
 
     /**
      * 区服总数据
@@ -667,9 +695,10 @@ public class GameServerServiceImpl implements IGameServerService {
             Field field = fieldList.get(i);
             try {
                 String value = (String) field.get(vo);
+                //总的累计数据
+                String[] split1 = value.split("/");
                 GSGameServerDayRVO gsGameServerDayRVO = dayRVOMap.get(i);
-                String rData = getRDataStr(gsGameServerDayRVO, vo);
-
+                String rData = getRDataStr(gsGameServerDayRVO, Long.valueOf(split1[split1.length - 1]));
                 value += "/" + rData;
                 String[] split = value.split("/");
                 GSServerRetentionVO retentionVO = GSServerRetentionVO.builder()
@@ -677,14 +706,16 @@ public class GameServerServiceImpl implements IGameServerService {
                         .PaidRetentionRate(split[1])
                         .totalRegNum(split[2])
                         .totalAmountNum(split[3])
-                        .smallR(split[4])
-                        .mediumR(split[5])
-                        .largeR(split[6])
-                        .superR(split[7])
-                        .smallRNum(split[8])
-                        .mediumRNum(split[9])
-                        .largeRNum(split[10])
-                        .superRNum(split[11])
+                        .smallR(split[5])
+                        .mediumR(split[6])
+                        .largeR(split[7])
+                        .superR(split[8])
+                        .smallRNum(split[9])
+                        .mediumRNum(split[10])
+                        .largeRNum(split[11])
+                        .superRNum(split[12])
+                        .rTotal(split[13])
+                        .rTotalRetention(split[14])
                         .build();
                 fieldObjectList.get(i).set(vo, retentionVO);
 //                field.set(vo, value + "/" + rData);
@@ -728,26 +759,27 @@ public class GameServerServiceImpl implements IGameServerService {
      * 拼接R留存率  (R/充值总人数)
      *
      * @param rvo
-     * @param vo
      * @return
      */
-    private String getRDataStr(GSGameServerDayRVO rvo, GSGameServerDayVO vo) {
-        if (rvo != null && vo.getTotalAmountNum() != null && vo.getTotalAmountNum() != 0) {
-            //充值总人数
-            BigDecimal totalAmountNum = new BigDecimal(vo.getTotalAmountNum());
+    private String getRDataStr(GSGameServerDayRVO rvo, Long totalNum) {
+        if (rvo != null && totalNum != null && totalNum != 0) {
             //R人数
             Long smallRCount = rvo.getSmallR();
             Long mediumRCount = rvo.getMediumR();
             Long largeRCont = rvo.getLargeR();
             Long superRCount = rvo.getSuperR();
+            //R总
+            long rCount = smallRCount + mediumRCount + largeRCont + superRCount;
             //R留存率
-            BigDecimal smallR = new BigDecimal(smallRCount).divide(totalAmountNum, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.DOWN);
-            BigDecimal mediumR = new BigDecimal(mediumRCount).divide(totalAmountNum, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.DOWN);
-            BigDecimal largeR = new BigDecimal(largeRCont).divide(totalAmountNum, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.DOWN);
-            BigDecimal superR = new BigDecimal(superRCount).divide(totalAmountNum, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.DOWN);
-            return smallR + "/" + mediumR + "/" + largeR + "/" + superR + "/" + smallRCount + "/" + mediumRCount + "/" + largeRCont + "/" + superRCount;
+            BigDecimal smallR = new BigDecimal(smallRCount).divide(new BigDecimal(totalNum), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.DOWN);
+            BigDecimal mediumR = new BigDecimal(mediumRCount).divide(new BigDecimal(totalNum), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.DOWN);
+            BigDecimal largeR = new BigDecimal(largeRCont).divide(new BigDecimal(totalNum), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.DOWN);
+            BigDecimal superR = new BigDecimal(superRCount).divide(new BigDecimal(totalNum), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.DOWN);
+            //R总留存
+            BigDecimal r = new BigDecimal(rCount).divide(new BigDecimal(totalNum), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.DOWN);
+            return smallR + "/" + mediumR + "/" + largeR + "/" + superR + "/" + smallRCount + "/" + mediumRCount + "/" + largeRCont + "/" + superRCount+"/"+rCount+"/"+r;
         } else {
-            return "0/0/0/0/0/0/0/0";
+            return "0/0/0/0/0/0/0/0/0/0";
         }
     }
 
@@ -799,8 +831,18 @@ public class GameServerServiceImpl implements IGameServerService {
 
 
     private Criteria getGameServerDayCriteria(GSGameServerDayDTO dto) {
+        GameAuthUserVO userGameInfo = gameAuthRpc.getGameAuthByUserIds().getData();
+        List<Long> serverIdByGS = null;
+        //判断是不是GS
+        if (GameAuthEnum.getByValue(userGameInfo.getGameAuthEnum().getValue()) != null) {
+            //查询GS管理的区服列表
+            serverIdByGS = getServerIdByGSId(SecurityUtil.getUserId()).stream().filter(StringUtils::isNotEmpty).map(Long::parseLong).collect(Collectors.toList());
+        }
         //创建查询条件
         Criteria cri = Cnd.cri();
+        if (CollectionUtils.isNotEmpty(serverIdByGS)) {
+            cri.where().andInList("a.server_id", serverIdByGS);
+        }
         if (StringUtils.isNotEmpty(dto.getSourceSystem())) {
             cri.where().andEquals("a.source_system", dto.getSourceSystem());
         }
@@ -816,8 +858,8 @@ public class GameServerServiceImpl implements IGameServerService {
         if (StringUtils.isNotEmpty(dto.getServerName())) {
             cri.where().andLike("a.server_name", dto.getServerName());
         }
-        if(dto.getGsId()!=null){
-            cri.where().and(new Static("find_in_set("+dto.getGsId()+",a.gs_ids)"));
+        if (dto.getGsId() != null) {
+            cri.where().and(new Static("find_in_set(" + dto.getGsId() + ",a.gs_ids)"));
         }
         return cri;
     }
@@ -830,7 +872,7 @@ public class GameServerServiceImpl implements IGameServerService {
                 a.server_id,
                 a.server_name,
                 a.dt,
-                datediff(Date(now()),a.dt) as days,
+                datediff(Date(now()),a.dt)+ 1 as days, -- 开服日期 要算当天所以+1
                 a.parent_game_id,
                 a.parent_game_classify,
                 a.parent_game_name,
@@ -863,13 +905,14 @@ public class GameServerServiceImpl implements IGameServerService {
 
     /**
      * 获取每天活跃留存率/付费留存率的sql
+     * -
      */
     private String getRemainDaySql() {
         StringBuilder sql = new StringBuilder(StringUtils.EMPTY);
         for (int i = 1; i <= 90; i++) {
             sql.append("""
-                    concat(ifnull(round(c.da%d_active_num / e.new_da%d_total_num,4),0),'/',round(ifnull(d.new_da%d_total_num/(d.new_da%d_num + d.old_da%d_num) ,0),4),'/',IFNULL(c.da%d_role_num,0),'/',IFNULL(c.da%d_num,0)) as da_str%d,
-                     """.formatted(i, i, i, i, i, i, i, i));
+                    concat(a.da%d,'/',IFNULL(c.da%d_role_num,0),'/',IFNULL(c.da%d_num,0),'/',IFNULL(c.da%d_total_num,0)) as da_str%d,
+                     """.formatted(i, i, i, i, i));
 
         }
         return sql.toString();
@@ -882,7 +925,7 @@ public class GameServerServiceImpl implements IGameServerService {
         StringBuilder sql = new StringBuilder(StringUtils.EMPTY);
         for (int i = 1; i <= 90; i++) {
             sql.append("""
-                    concat(ifnull(round(SUM(c.da%d_active_num) / SUM(e.new_da%d_total_num) ,4),0),'/',ifnull(round(SUM(d.new_da%d_total_num)/((SUM(d.new_da%d_num) + SUM(d.old_da%d_num))),4),0),'/',IFNULL(SUM(c.da%d_role_num),0),'/',IFNULL(SUM(c.da%d_num),0)) as da_str%d,
+                    concat(ifnull(round(SUM(c.da%d_active_num) / SUM(e.new_da%d_total_num) ,4),0),'/',ifnull(round(sum(c.da%d_num)/sum(c.da%d_total_num),4),0),'/',IFNULL(SUM(c.da%d_role_num),0),'/',IFNULL(SUM(c.da%d_num),0),'/',IFNULL(sum(c.da%d_total_num),0)) as da_str%d,
                      """.formatted(i, i, i, i, i, i, i, i));
         }
         return sql.toString();

+ 49 - 2
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/GameUserConfigServiceImpl.java

@@ -1,13 +1,17 @@
 package com.zanxiang.game.data.serve.service.impl;
 
 import com.zanxiang.game.data.serve.pojo.dto.GameDTO;
+import com.zanxiang.game.data.serve.pojo.dto.GameUserConfigCreateOrUpdateDTO;
 import com.zanxiang.game.data.serve.pojo.dto.GameUserConfigListDTO;
+import com.zanxiang.game.data.serve.pojo.entity.GameUserConfig;
 import com.zanxiang.game.data.serve.pojo.vo.GameUserConfigListVO;
 import com.zanxiang.game.data.serve.service.IGameUserConfigService;
 import com.zanxiang.game.data.serve.utils.Page;
+import com.zanxiang.module.util.exception.BaseException;
 import org.apache.commons.lang3.StringUtils;
 import org.nutz.dao.Cnd;
 import org.nutz.dao.Dao;
+import org.nutz.dao.FieldFilter;
 import org.nutz.dao.Sqls;
 import org.nutz.dao.pager.Pager;
 import org.nutz.dao.sql.Criteria;
@@ -15,6 +19,7 @@ import org.nutz.dao.sql.Sql;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.time.LocalDateTime;
 import java.util.List;
 import java.util.Map;
 import java.util.function.Function;
@@ -25,7 +30,7 @@ import java.util.stream.Collectors;
  *
  * @author ZhangXianyu
  * @date 2024/4/18
- * @description TODO
+ * @description 创角配置
  */
 @Service
 public class GameUserConfigServiceImpl implements IGameUserConfigService {
@@ -37,7 +42,7 @@ public class GameUserConfigServiceImpl implements IGameUserConfigService {
     public Page<GameUserConfigListVO> validRoleConfigList(GameUserConfigListDTO dto) {
         Criteria criA = Cnd.cri();
         if (dto.getGameId() != null) {
-            criA.where().andEquals("role_id", dto.getGameId());
+            criA.where().andEquals("game_id", dto.getGameId());
         }
         if (StringUtils.isNotEmpty(dto.getSourceSystem())) {
             criA.where().andEquals("source_system", dto.getSourceSystem());
@@ -68,6 +73,48 @@ public class GameUserConfigServiceImpl implements IGameUserConfigService {
         return new Page<>(list, pager);
     }
 
+    @Override
+    public Boolean create(GameUserConfigCreateOrUpdateDTO dto) {
+        int gameId = dao.count(GameUserConfig.class, Cnd.where("game_id", "=", dto.getGameId()));
+        if (gameId > 0) {
+           throw new BaseException("该游戏已存在创角配置");
+        }
+        GameUserConfig gameUserConfig = new GameUserConfig();
+        gameUserConfig.setSourceSystem("ZX_ONE");
+        gameUserConfig.setGameId(dto.getGameId());
+        gameUserConfig.setRoleLevel(dto.getRoleLevel());
+        gameUserConfig.setCreateTime(LocalDateTime.now());
+        gameUserConfig.setUpdateTime(LocalDateTime.now());
+        dao.insert(gameUserConfig);
+        return true;
+    }
+
+    @Override
+    public Boolean delete(Long id) {
+        dao.delete(GameUserConfig.class, id);
+        return true;
+    }
+
+    @Override
+    public Boolean update(GameUserConfigCreateOrUpdateDTO dto) {
+        if(dto.getId()==null){
+            throw new BaseException("id不能为空");
+        }
+        int count = dao.count(GameUserConfig.class, Cnd.where("game_id", "=", dto.getGameId()).and("id", "!=", dto.getId()));
+        if (count > 0) {
+            throw new BaseException("该游戏已存在创角配置");
+        }
+        GameUserConfig old = dao.fetch(GameUserConfig.class, Cnd.where("id", "=", dto.getId()));
+        if (old == null) {
+            throw new BaseException("创角配置不存在");
+        }
+        old.setUpdateTime(LocalDateTime.now());
+        old.setGameId(dto.getGameId());
+        old.setRoleLevel(dto.getRoleLevel());
+        dao.update(old, FieldFilter.create(GameUserConfig.class, "gameId|roleLevel|updateTime"));
+        return true;
+    }
+
     public String getGameUserConfigSql(Criteria criA) {
         String sql = """
                 select 

+ 0 - 1
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/IWebVisitLogServiceImpl.java

@@ -3,7 +3,6 @@ package com.zanxiang.game.data.serve.service.impl;
 import com.alibaba.fastjson2.JSON;
 import com.zanxiang.game.data.serve.pojo.dto.WebLogDTO;
 import com.zanxiang.game.data.serve.service.IWebVisitLogService;
-import com.zanxiang.module.util.JsonUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.kafka.clients.producer.Producer;
 import org.apache.kafka.clients.producer.ProducerRecord;

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

@@ -4,7 +4,10 @@ import com.google.common.base.CaseFormat;
 import com.google.gson.Gson;
 import com.zanxiang.game.data.serve.component.DataPowerComponent;
 import com.zanxiang.game.data.serve.pojo.dto.*;
-import com.zanxiang.game.data.serve.pojo.entity.*;
+import com.zanxiang.game.data.serve.pojo.entity.AdsPitcherDay;
+import com.zanxiang.game.data.serve.pojo.entity.AdsPitcherDayParent;
+import com.zanxiang.game.data.serve.pojo.entity.AdsPitcherDayn;
+import com.zanxiang.game.data.serve.pojo.entity.AdsPitcherGameDayn;
 import com.zanxiang.game.data.serve.pojo.enums.OrderByEnum;
 import com.zanxiang.game.data.serve.pojo.vo.*;
 import com.zanxiang.game.data.serve.service.IPitcherDataService;

+ 3 - 7
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/RoleManageServiceImpl.java

@@ -1,14 +1,11 @@
 package com.zanxiang.game.data.serve.service.impl;
 
 import com.alibaba.fastjson2.JSON;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.zanxiang.erp.base.ErpServer;
 import com.zanxiang.erp.base.rpc.ISysUserRpc;
 import com.zanxiang.erp.security.util.SecurityUtil;
 import com.zanxiang.game.data.serve.pojo.dto.*;
 import com.zanxiang.game.data.serve.pojo.enums.OrderByEnum;
-import com.zanxiang.game.data.serve.pojo.vo.GameMediaDataDayVO;
-import com.zanxiang.game.data.serve.pojo.vo.GameUserConfigListVO;
 import com.zanxiang.game.data.serve.service.IRoleManageService;
 import com.zanxiang.game.data.serve.utils.Page;
 import com.zanxiang.game.module.base.ServerInfo;
@@ -34,7 +31,6 @@ import org.nutz.dao.sql.Sql;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StopWatch;
-import reactor.util.function.Tuple2;
 
 import java.util.*;
 import java.util.function.Function;
@@ -1678,7 +1674,7 @@ public class RoleManageServiceImpl implements IRoleManageService {
                                     server_id,
                                     server_name
                                 FROM dm_game_order.t_game_server_merge
-                                WHERE is_merge = 0 AND is_delete = 0
+                                WHERE is_source_server = 0  AND is_delete = 0
                             ) r on a.source_system = r.source_system AND a.server_id = r.source_server_ids AND d.super_game_id = r.game_id
                             LEFT JOIN (
                                 -- 玩家信息
@@ -2973,8 +2969,8 @@ public class RoleManageServiceImpl implements IRoleManageService {
                 		MAX(super_game_name) as super_game_name , -- 超父游戏名
                 		server_id, -- 区服ID
                 		IFNULL(MAX(i.server_name), MAX(a.server_name)) as server_name, -- 区服名
-                		-- MIN(dt) as dt, -- 开服日期
-                		MAX(merge_time) as dt, -- 开服日期
+                		MIN(dt) as dt, -- 开服日期
+                		-- MAX(merge_time) as dt, -- 开服日期
                 		TIMESTAMPDIFF(DAY, DATE(MIN(dt)), DATE_ADD(Date(NOW()),1)) start_day, -- 开服天数
                 		boss_server_id, -- 合服ID
                 		MAX(boss_server_name) as boss_server_name, -- 合服名

+ 7 - 4
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/task/GameMonitorAlarmTask.java

@@ -2,20 +2,23 @@ package com.zanxiang.game.data.serve.task;
 
 import com.zanxiang.game.data.serve.pojo.properties.SmsProperties;
 import com.zanxiang.game.data.serve.service.IGameMonitorAlarmService;
-import com.zanxiang.module.sms.pojo.SendResult;
 import com.zanxiang.module.sms.service.impl.AliSmsService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.cloud.context.config.annotation.RefreshScope;
 import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
 import java.text.SimpleDateFormat;
-import java.util.*;
-import java.util.concurrent.*;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
 
 /**
  * @author tianhua

+ 0 - 1
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/task/OrderCostMonitorAlarmTask.java

@@ -4,7 +4,6 @@ import com.zanxiang.game.data.serve.service.IOrderCostMonitorAlarmService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;

+ 1 - 1
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/ManageApplication.java

@@ -23,7 +23,7 @@ public class ManageApplication {
 
     public static void main(String[] args) {
         SpringApplication.run(ManageApplication.class, args);
-        System.out.println("赞象Manage服务启动成功 < (客服消息已读状态在结束房间的时候更新´・・)ノ(._.`) \n" +
+        System.out.println("赞象Manage服务启动成功 < (CP接口修改03´・・)ノ(._.`) \n" +
                 "___  ___  ___   _   _   ___  _____  _____ \n" +
                 "|  \\/  | / _ \\ | \\ | | / _ \\|  __ \\|  ___|\n" +
                 "| .  . |/ /_\\ \\|  \\| |/ /_\\ \\ |  \\/| |__  \n" +

+ 46 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/controller/api/CpServerApi.java

@@ -0,0 +1,46 @@
+package com.zanxiang.game.module.manage.controller.api;
+
+import com.zanxiang.game.module.manage.pojo.params.ChatSubmitParam;
+import com.zanxiang.game.module.manage.pojo.params.OpenGameServerParam;
+import com.zanxiang.game.module.manage.service.api.CpServerApiService;
+import com.zanxiang.module.util.pojo.ResultVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+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;
+
+/**
+ * @author : lingfeng
+ * @time : 2024-04-25
+ * @description : Cp服务端接口
+ */
+@Api(tags = {"Cp服务端接口"})
+@RestController
+@RequestMapping("/api")
+@Slf4j
+public class CpServerApi {
+
+    @Autowired
+    private CpServerApiService cpServerApiService;
+
+    @ApiOperation(value = "cp提交游戏聊天记录")
+    @PostMapping(value = "/chat/msg/submit")
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = Boolean.class)})
+    public ResultVO<Boolean> chatMsgSubmit(@Validated @RequestBody ChatSubmitParam param) {
+        return ResultVO.ok(cpServerApiService.chatMsgSubmit(param));
+    }
+
+    @ApiOperation(value = "CP开服通知")
+    @PostMapping(value = "/open/game/server")
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = Boolean.class)})
+    public ResultVO<Boolean> list(@Validated @RequestBody OpenGameServerParam param) {
+        return ResultVO.ok(cpServerApiService.openGameServer(param));
+    }
+}

+ 53 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/params/ChatSubmitParam.java

@@ -0,0 +1,53 @@
+package com.zanxiang.game.module.manage.pojo.params;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.Map;
+
+/**
+ * @author : lingfeng
+ * @time : 2024-04-25
+ * @description : 游戏聊天内容提交
+ */
+@Data
+public class ChatSubmitParam {
+
+    /**
+     * 加密标识
+     */
+    @NotNull(message = "加密标识不可为空")
+    @ApiModelProperty(notes = "加密标识")
+    private String sign;
+
+    /**
+     * 请求时间
+     */
+    @NotNull(message = "请求时间不可为空")
+    @ApiModelProperty(notes = "请求时间, 时间戳 : 13位")
+    private Long signTime;
+
+    /**
+     * 超父游戏id
+     */
+    @NotNull(message = "超父游戏id不可为空")
+    @ApiModelProperty(notes = "超父游戏id")
+    private Long gameId;
+
+    /**
+     * 区服id
+     */
+    @NotBlank(message = "区服id不可为空")
+    @ApiModelProperty(notes = "区服id, 必传")
+    private String serverId;
+
+    /**
+     * 聊天内容
+     */
+    @NotEmpty(message = "聊天内容不可为空")
+    @ApiModelProperty(notes = "聊天内容, 必传")
+    private Map<String, Object> chatContentMap;
+}

+ 65 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/params/OpenGameServerParam.java

@@ -0,0 +1,65 @@
+package com.zanxiang.game.module.manage.pojo.params;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.time.LocalDateTime;
+
+/**
+ * @author : lingfeng
+ * @time : 2024-04-25
+ * @description : 开服参数
+ */
+@Data
+public class OpenGameServerParam {
+
+    /**
+     * 加密标识
+     */
+    @NotNull(message = "加密标识不可为空")
+    @ApiModelProperty(notes = "加密标识")
+    private String sign;
+
+    /**
+     * 请求时间
+     */
+    @NotNull(message = "请求时间不可为空")
+    @ApiModelProperty(notes = "请求时间, 时间戳 : 13位")
+    private Long signTime;
+
+    /**
+     * 超父游戏id
+     */
+    @NotNull(message = "超父游戏id不可为空")
+    @ApiModelProperty(notes = "超父游戏id")
+    private Long gameId;
+
+    /**
+     * 区服id
+     */
+    @NotBlank(message = "区服id不可为空")
+    @ApiModelProperty(notes = "区服id, 必传")
+    private String serverId;
+
+    /**
+     * 区服名称
+     */
+    @NotBlank(message = "区服名称不可为空")
+    @ApiModelProperty(notes = "区服名称, 必传")
+    private String serverName;
+
+    /**
+     * 开服时间
+     */
+    @NotNull(message = "开服时间不可为空")
+    @ApiModelProperty(notes = "开服时间, 必传")
+    private LocalDateTime startTime;
+
+    /**
+     * 区服冠名
+     */
+    @ApiModelProperty(notes = "区服冠名, 非必传")
+    private String nickName;
+}

+ 4 - 17
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/rpc/impl/PayBoxRpcImpl.java

@@ -1,36 +1,23 @@
 package com.zanxiang.game.module.manage.rpc.impl;
 
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.zanxiang.game.module.base.rpc.IPayBoxRpc;
-import com.zanxiang.game.module.manage.service.IAppletCheckService;
-import com.zanxiang.game.module.manage.service.IPayApplicationService;
-import com.zanxiang.game.module.mybatis.entity.PayApplication;
 import com.zanxiang.module.util.pojo.ResultVO;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.dubbo.config.annotation.DubboService;
-import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * @author : lingfeng
  * @time : 2024-01-16
  * @description : 支付盒子
  */
+@Slf4j
 @DubboService
 public class PayBoxRpcImpl implements IPayBoxRpc {
 
-    @Autowired
-    private IAppletCheckService appletCheckService;
-
-    @Autowired
-    private IPayApplicationService payApplicationService;
-
     @Override
     public ResultVO<Boolean> payBoxBan(String appId) {
-        PayApplication payApplication = payApplicationService.getOne(new LambdaQueryWrapper<PayApplication>()
-                .eq(PayApplication::getAppId, appId));
-        if (payApplication == null) {
-            return ResultVO.ok(Boolean.FALSE);
-        }
-        appletCheckService.payApplicationCheck(payApplication);
+        log.error("监测到的 appId : {}", appId);
         return ResultVO.ok(Boolean.TRUE);
     }
+
 }

+ 0 - 23
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IAppletCheckService.java

@@ -1,23 +0,0 @@
-package com.zanxiang.game.module.manage.service;
-
-import com.zanxiang.game.module.mybatis.entity.PayApplication;
-
-/**
- * @author : lingfeng
- * @time : 2024-01-20
- * @description : 小程序检查
- */
-public interface IAppletCheckService {
-
-    /**
-     * 小程序检查
-     */
-    void payApplicationCheck();
-
-    /**
-     * 小程序更新且通知
-     *
-     * @param payApplication : 支付应用
-     */
-    void payApplicationCheck(PayApplication payApplication);
-}

+ 18 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IListenCallService.java

@@ -10,4 +10,22 @@ import com.zanxiang.game.module.mybatis.entity.ListenCall;
  */
 public interface IListenCallService extends IService<ListenCall> {
 
+    /**
+     * 监测异常发送钉钉通知
+     *
+     * @param gameId  : 游戏id
+     * @param isSuper : 是否超父
+     * @param content : 通知内容
+     */
+    void sendDingTalkMsg(Long gameId, boolean isSuper, String content);
+
+    /**
+     * 监测异常电话通知
+     *
+     * @param gameId     : 游戏id
+     * @param isSuper    : 是否超父
+     * @param listenName : 模块名称
+     */
+    void sendPhoneTalkMsg(Long gameId, boolean isSuper, String listenName);
+
 }

+ 129 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/api/CpServerApiService.java

@@ -0,0 +1,129 @@
+package com.zanxiang.game.module.manage.service.api;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.zanxiang.game.module.base.pojo.enums.DeleteEnum;
+import com.zanxiang.game.module.manage.pojo.params.ChatSubmitParam;
+import com.zanxiang.game.module.manage.pojo.params.OpenGameServerParam;
+import com.zanxiang.game.module.manage.service.IGameServerService;
+import com.zanxiang.game.module.manage.service.IGameSupperService;
+import com.zanxiang.game.module.manage.service.IListenCallService;
+import com.zanxiang.game.module.mybatis.entity.GameServer;
+import com.zanxiang.game.module.mybatis.entity.GameSupper;
+import com.zanxiang.module.util.JsonUtil;
+import com.zanxiang.module.util.exception.BaseException;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.time.LocalDateTime;
+import java.util.Objects;
+
+/**
+ * @author : lingfeng
+ * @time : 2024-04-25
+ * @description : cp服务端交互
+ */
+@Slf4j
+@Service
+public class CpServerApiService {
+
+    @Autowired
+    private IGameServerService gameServerService;
+
+    @Autowired
+    private IGameSupperService gameSupperService;
+
+    @Autowired
+    private IListenCallService listenCallService;
+
+    public boolean chatMsgSubmit(ChatSubmitParam param) {
+        GameSupper gameSupper = gameSupperService.getById(param.getGameId());
+        if (gameSupper == null) {
+            throw new BaseException("参数错误");
+        }
+        this.signCheck(gameSupper.getCpServerKey(), param.getGameId(), param.getServerId(),
+                param.getSignTime(), param.getSign());
+        log.error("接收到推送的聊天消息, param : {}", JsonUtil.toString(param));
+        //调武哥接口发送过去
+        return Boolean.TRUE;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    public boolean openGameServer(OpenGameServerParam param) {
+        GameSupper gameSupper = gameSupperService.getById(param.getGameId());
+        if (gameSupper == null) {
+            throw new BaseException("参数错误");
+        }
+        this.signCheck(gameSupper.getCpServerKey(), param.getGameId(), param.getServerId(),
+                param.getSignTime(), param.getSign());
+        //查询区服id
+        GameServer gameServer = gameServerService.getOne(new LambdaQueryWrapper<GameServer>()
+                .eq(GameServer::getGameId, param.getGameId())
+                .eq(GameServer::getServerId, param.getServerId())
+        );
+        GameServer transform = this.transform(param);
+        if (gameServer == null) {
+            gameServer = transform;
+        } else {
+            gameServer.setGameId(transform.getGameId());
+            gameServer.setServerId(transform.getServerId());
+            gameServer.setServerName(transform.getServerName());
+            gameServer.setNickName(transform.getNickName());
+            gameServer.setStartTime(transform.getStartTime());
+            gameServer.setUpdateTime(LocalDateTime.now());
+        }
+        //区服添加或者更新
+        gameServerService.saveOrUpdate(gameServer);
+        //钉钉通知
+        String content = LocalDateTime.now().toString() + "游戏开服通知\n游戏名称 : " + gameSupper.getName()
+                + "\n区服名称:" + param.getServerName() + "\n开服时间:" + param.getStartTime().toString();
+        listenCallService.sendDingTalkMsg(param.getGameId(), Boolean.TRUE, content);
+        return Boolean.TRUE;
+    }
+
+    private GameServer transform(OpenGameServerParam param) {
+        return GameServer.builder()
+                .gameId(param.getGameId())
+                .serverId(param.getServerId())
+                .serverName(param.getServerName())
+                .nickName(param.getNickName())
+                .startTime(param.getStartTime())
+                .isDelete(DeleteEnum.NO.getCode())
+                .createBy(0L)
+                .createTime(LocalDateTime.now())
+                .isSourceServer(Boolean.TRUE)
+                .isMerge(Boolean.FALSE)
+                .updateBy(0L)
+                .updateTime(LocalDateTime.now())
+                .build();
+    }
+
+    private void signCheck(String cpServerKey, Long gameId, String serverId, Long signTime, String sign) {
+        String signStr = "cpServerKey=" + cpServerKey + "gameId=" + gameId
+                + "serverId=" + serverId + "signTime=" + signTime;
+        log.error("请求加密字符串 signStr : {}", signStr);
+        String mySign = this.md5(signStr);
+        if (Objects.equals(mySign, sign)) {
+            log.error("加密验证失败, sign : {}, mySign : {}", sign, mySign);
+            throw new BaseException("加密标识错误");
+        }
+    }
+
+    private String md5(String data) {
+        try {
+            java.security.MessageDigest md = MessageDigest.getInstance("MD5");
+            byte[] array = md.digest(data.getBytes(StandardCharsets.UTF_8));
+            StringBuilder sb = new StringBuilder();
+            for (byte item : array) {
+                sb.append(Integer.toHexString((item & 0xFF) | 0x100), 1, 3);
+            }
+            return sb.toString().toUpperCase();
+        } catch (Exception e) {
+            log.error("MD5加密异常, data : {}", data);
+            throw new BaseException("MD5加密异常");
+        }
+    }
+}

+ 0 - 289
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/AppletCheckServiceImpl.java

@@ -1,289 +0,0 @@
-package com.zanxiang.game.module.manage.service.impl;
-
-import cn.hutool.http.ContentType;
-import cn.hutool.http.HttpUtil;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
-import com.zanxiang.erp.base.ErpServer;
-import com.zanxiang.erp.base.rpc.IDingTalkMsgRpc;
-import com.zanxiang.game.module.base.ServerInfo;
-import com.zanxiang.game.module.base.pojo.enums.PayApplicationTypeEnum;
-import com.zanxiang.game.module.base.pojo.enums.StatusEnum;
-import com.zanxiang.game.module.base.rpc.IWxApiServiceRpc;
-import com.zanxiang.game.module.manage.constant.RedisKeyConstant;
-import com.zanxiang.game.module.manage.enums.ExpireTimeEnum;
-import com.zanxiang.game.module.manage.service.*;
-import com.zanxiang.game.module.manage.utils.RedisUtil;
-import com.zanxiang.game.module.mybatis.entity.GamePayWay;
-import com.zanxiang.game.module.mybatis.entity.ListenCall;
-import com.zanxiang.game.module.mybatis.entity.PayApplication;
-import com.zanxiang.game.module.mybatis.entity.PayBox;
-import com.zanxiang.module.redis.service.IDistributedLockComponent;
-import com.zanxiang.module.util.JsonUtil;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.dubbo.config.annotation.DubboReference;
-import org.apache.logging.log4j.util.Strings;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpEntity;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Service;
-import org.springframework.util.LinkedMultiValueMap;
-import org.springframework.util.MultiValueMap;
-import org.springframework.web.client.RestTemplate;
-
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.util.*;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
-/**
- * @author : lingfeng
- * @time : 2024-01-20
- * @description : 小程序检查
- */
-@Slf4j
-@Service
-public class AppletCheckServiceImpl implements IAppletCheckService {
-
-    @DubboReference(providedBy = ErpServer.SERVER_DUBBO_NAME)
-    private IDingTalkMsgRpc dingTalkMsgRpc;
-
-    @DubboReference(providedBy = ServerInfo.SERVER_SDK_DUBBO_NAME)
-    private IWxApiServiceRpc wxApiServiceRpc;
-
-    @Autowired
-    private RedisUtil<Integer> redisUtil;
-
-    @Autowired
-    private IPayBoxService payBoxService;
-
-    @Autowired
-    private IGamePayWayService gamePayWayService;
-
-    @Autowired
-    private IListenCallService listenCallService;
-
-    @Autowired
-    private IPayApplicationService payApplicationService;
-
-    @Autowired
-    private IDistributedLockComponent distributedLockComponent;
-
-    @Override
-    public void payApplicationCheck() {
-        List<PayApplication> payApplicationList = payApplicationService.list(new LambdaQueryWrapper<PayApplication>()
-                .eq(PayApplication::getStatus, StatusEnum.YES.getCode())
-                .eq(PayApplication::getType, PayApplicationTypeEnum.WX_MINI_APP.getType()));
-        if (CollectionUtils.isEmpty(payApplicationList)) {
-            return;
-        }
-        payApplicationList.forEach(payApplication -> {
-            String accessToken = null;
-            try {
-                accessToken = wxApiServiceRpc.getAccessToken(payApplication.getAppId(), payApplication.getAppSecret());
-            } catch (Exception e) {
-                log.error("获取小程序token异常, appName : {}, e : {}", payApplication.getAppName(), e.getMessage());
-            }
-            if (Strings.isBlank(accessToken) || !this.appletCheck(accessToken, payApplication.getAppName())) {
-                log.error("小程序判定封停或者禁用, appName : {}, accessToken : {}", payApplication.getAppName(), accessToken);
-                this.payApplicationCheck(payApplication);
-            }
-        });
-    }
-
-    @Override
-    public void payApplicationCheck(PayApplication payApplication) {
-        //异常计数器, 返回false的时候过滤
-        if (!this.countUpdate(payApplication.getAppId())) {
-            return;
-        }
-        //连续三次报警, 进行通知
-        try {
-            //更新游戏支付
-            this.gamePayUpdate(payApplication);
-        } catch (Exception e) {
-            log.error("支付应用异常更新游戏支付盒子失败, appName : {}, e : {}", payApplication.getAppName(), e.getMessage());
-        }
-        try {
-            //钉钉通知
-            this.sendDingTalkMsg(payApplication);
-        } catch (Exception e) {
-            log.error("支付应用异常钉钉通知失败, appName : {}, e : {}", payApplication.getAppName(), e.getMessage());
-        }
-        try {
-            //电话通知
-            this.sendPhoneTalkMsg(payApplication);
-        } catch (Exception e) {
-            log.error("支付应用异常电话通知失败, appName : {}, e : {}", payApplication.getAppName(), e.getMessage());
-        }
-    }
-
-    private boolean countUpdate(String appId) {
-        String key = RedisKeyConstant.APPLET_ERROR_COUNT + appId;
-        Integer count = redisUtil.getCache(key);
-        if (count != null && count >= 2) {
-            redisUtil.deleteCache(key);
-            return Boolean.TRUE;
-        }
-        if (count == null) {
-            count = 1;
-        } else {
-            count += 1;
-        }
-        redisUtil.setCache(key, count, ExpireTimeEnum.HALF_HOUR.getTime());
-        return Boolean.FALSE;
-    }
-
-    private void gamePayUpdate(PayApplication payApplication) {
-        //修改支付应用状态
-        log.error("支付应用异常 - 修改支付应用状态, appName : {}", payApplication.getAppName());
-        payApplicationService.update(new LambdaUpdateWrapper<PayApplication>()
-                .eq(PayApplication::getAppId, payApplication.getAppId())
-                .set(PayApplication::getStatus, StatusEnum.NO.getCode())
-                .set(PayApplication::getUpdateTime, LocalDateTime.now()));
-        //查询支付应用对应的盒子
-        List<PayBox> payBoxList = payBoxService.list(new LambdaQueryWrapper<PayBox>()
-                .eq(PayBox::getAppId, payApplication.getAppId())
-                .eq(PayBox::getStatus, StatusEnum.YES.getCode()));
-        if (CollectionUtils.isEmpty(payBoxList)) {
-            log.error("支付应用异常 - 支付应用不存在相关支付盒子, appName : {}", payApplication.getAppName());
-            return;
-        }
-        Set<Integer> payBoxIdList = payBoxList.stream().map(PayBox::getId).collect(Collectors.toSet());
-        //修改支付应用相关支付盒子状态
-        log.error("支付应用异常 - 修改支付盒子状态, appName : {}, payBoxIdList : {}", payApplication.getAppName(), payBoxIdList);
-        payBoxService.update(new LambdaUpdateWrapper<PayBox>()
-                .in(PayBox::getId, payBoxIdList)
-                .set(PayBox::getStatus, StatusEnum.NO.getCode())
-                .set(PayBox::getUpdateTime, LocalDateTime.now()));
-        //游戏支付应用修改
-//        this.gamePayWayUpdate(payApplication, payBoxIdList);
-    }
-
-    private void gamePayWayUpdate(PayApplication payApplication, Set<Integer> payBoxIdList) {
-        //查询相关盒子被使用到的游戏
-        List<GamePayWay> gamePayWayList = gamePayWayService.list(new LambdaQueryWrapper<GamePayWay>()
-                .in(GamePayWay::getPayBoxId, payBoxIdList));
-        if (CollectionUtils.isEmpty(gamePayWayList)) {
-            log.error("支付应用异常 - 支付应用不存在相关联游戏支付配置, appName : {}", payApplication.getAppName());
-            return;
-        }
-        //获取一个能用的支付盒子
-        PayBox payBox = payBoxService.getOne(new LambdaQueryWrapper<PayBox>()
-                .eq(PayBox::getType, payApplication.getType())
-                .eq(PayBox::getStatus, StatusEnum.YES.getCode())
-                .last("limit 1"));
-        if (payBox == null) {
-            log.error("支付应用异常 - 不存在正常可用的支付盒子, appName : {}", payApplication.getAppName());
-            return;
-        }
-        //相关游戏支付配置id列表
-        Set<Long> gamePayWayIdSet = gamePayWayList.stream().map(GamePayWay::getId).collect(Collectors.toSet());
-        //修改游戏支付配置
-        log.error("支付应用异常 - 修改游戏支付配置, appName : {}, gamePayWayIdSet : {}, payBoxId : {}", payApplication.getAppName(),
-                gamePayWayIdSet, payBox.getId());
-        gamePayWayService.update(new LambdaUpdateWrapper<GamePayWay>()
-                .in(GamePayWay::getId, gamePayWayIdSet)
-                .set(GamePayWay::getPayBoxId, payBox.getId())
-                .set(GamePayWay::getUpdateTime, LocalDateTime.now()));
-    }
-
-    private void sendDingTalkMsg(PayApplication payApplication) {
-        List<ListenCall> listenCallList = this.callListenUser();
-        if (CollectionUtils.isEmpty(listenCallList)) {
-            return;
-        }
-        String content = System.currentTimeMillis() + " 小程序 : <" + payApplication.getAppName() + "> 可能被封停或者禁用, 请注意验证";
-        Set<Long> userIdSet = listenCallList.stream().map(ListenCall::getUserId).collect(Collectors.toSet());
-        userIdSet.forEach(userId -> dingTalkMsgRpc.sendByUserId(userId, content));
-    }
-
-    private void sendPhoneTalkMsg(PayApplication payApplication) {
-        List<ListenCall> listenCallList = this.callListenUser();
-        if (CollectionUtils.isEmpty(listenCallList)) {
-            return;
-        }
-        String content = payApplication.getAppName() + "监测异常";
-        Set<String> phoneNumSet = listenCallList.stream().map(ListenCall::getPhoneNum).collect(Collectors.toSet());
-        phoneNumSet.forEach(phoneNum -> {
-            String lockKey = RedisKeyConstant.PHONE_CALL_LOCK + phoneNum;
-            if (!distributedLockComponent.doLock(lockKey, 0L, 1L, TimeUnit.MINUTES)) {
-                return;
-            }
-            this.phoneCall(content, phoneNum);
-        });
-    }
-
-    private List<ListenCall> callListenUser() {
-        List<ListenCall> listenCallList = listenCallService.list(new LambdaQueryWrapper<ListenCall>()
-                .eq(ListenCall::getStatus, StatusEnum.YES.getCode()));
-        if (CollectionUtils.isEmpty(listenCallList)) {
-            return Collections.emptyList();
-        }
-        Collection<ListenCall> collection = listenCallList.stream()
-                .collect(Collectors.toMap(ListenCall::getUserId, Function.identity(), (existing, replacement) -> existing))
-                .values();
-        return new ArrayList<>(collection);
-    }
-
-    private boolean appletCheck(String token, String appName) {
-        //参数对象
-        String dayTime = LocalDate.now().minusDays(3).toString();
-        Map<String, String> paramMap = new HashMap<>(2);
-        paramMap.put("begin_date", dayTime);
-        paramMap.put("end_date", dayTime);
-        String host = "https://api.weixin.qq.com/datacube/getweanalysisappiddailyretaininfo?access_token=" + token;
-        try {
-            // 带参POST请求
-            String result = HttpUtil.post(host, JsonUtil.toString(paramMap));
-            //结果为空, 判定腾讯接口返回错误, 不判定为封禁
-            if (Strings.isBlank(result)) {
-                return Boolean.TRUE;
-            }
-            //没有报错
-            if (!result.contains("errcode")) {
-                return Boolean.TRUE;
-            }
-            //结果返回错误
-            Map<String, Object> resultMap = JsonUtil.toMap(result, Map.class, Object.class);
-            //排除计算中的特殊报错
-            if (Objects.equals(resultMap.get("errcode").toString(), "61503")) {
-                return Boolean.TRUE;
-            }
-            log.error("小程序封停监测结果, appName : {}, result : {}", appName, result);
-        } catch (Exception e) {
-            log.error("小程序封停监测异常, appName : {},  e : {}", appName, e.getMessage());
-            return Boolean.FALSE;
-        }
-        return Boolean.FALSE;
-    }
-
-    private void phoneCall(String param, String mobile) {
-        RestTemplate restTemplate = new RestTemplate();
-        String appCode = "f395b1587fc04a49a975f908660fb1e9";
-        String host = "https://jumfixed.market.alicloudapi.com/voice-notify/send";
-        HttpHeaders headers = new HttpHeaders();
-        headers.set("Authorization", "APPCODE " + appCode);
-        headers.set("Content-Type", ContentType.FORM_URLENCODED.getValue());
-        //参数
-        MultiValueMap<String, String> requestParams = new LinkedMultiValueMap<>();
-        requestParams.add("mobile", mobile);
-        requestParams.add("templateId", "JMJNAWUQOJP9");
-        requestParams.add("param", param);
-        String result = null;
-        try {
-            ResponseEntity<String> responseEntity = restTemplate.exchange(host, HttpMethod.POST,
-                    new HttpEntity<>(requestParams, headers), String.class);
-            result = responseEntity.getBody();
-        } catch (Exception e) {
-            log.error("阿里语音呼叫失败, requestParams : {}, e : {}", JsonUtil.toString(requestParams), e.getMessage());
-        }
-        log.error("阿里语音呼叫结果, result : {}", result);
-    }
-
-}

+ 109 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/ListenCallServiceImpl.java

@@ -1,11 +1,37 @@
 package com.zanxiang.game.module.manage.service.impl;
 
+import cn.hutool.http.ContentType;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zanxiang.erp.base.ErpServer;
+import com.zanxiang.erp.base.rpc.IDingTalkMsgRpc;
+import com.zanxiang.game.module.base.pojo.enums.StatusEnum;
+import com.zanxiang.game.module.manage.constant.RedisKeyConstant;
+import com.zanxiang.game.module.manage.service.IGameService;
 import com.zanxiang.game.module.manage.service.IListenCallService;
+import com.zanxiang.game.module.mybatis.entity.Game;
 import com.zanxiang.game.module.mybatis.entity.ListenCall;
 import com.zanxiang.game.module.mybatis.mapper.ListenCallMapper;
+import com.zanxiang.module.redis.service.IDistributedLockComponent;
+import com.zanxiang.module.util.JsonUtil;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.apache.logging.log4j.util.Strings;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 /**
  * @author : lingfeng
@@ -15,4 +41,87 @@ import org.springframework.stereotype.Service;
 @Slf4j
 @Service
 public class ListenCallServiceImpl extends ServiceImpl<ListenCallMapper, ListenCall> implements IListenCallService {
+
+    @DubboReference(providedBy = ErpServer.SERVER_DUBBO_NAME)
+    private IDingTalkMsgRpc dingTalkMsgRpc;
+
+    @Autowired
+    private IDistributedLockComponent distributedLockComponent;
+
+    @Autowired
+    private IGameService gameService;
+
+    @Override
+    public void sendDingTalkMsg(Long gameId, boolean isSuper, String content) {
+        List<ListenCall> listenCallList = this.callListenUser(gameId, isSuper);
+        if (CollectionUtils.isEmpty(listenCallList)) {
+            return;
+        }
+        Set<Long> userIdSet = listenCallList.stream()
+                .filter(listenCall -> Strings.isNotBlank(listenCall.getDingTalkNum()))
+                .map(ListenCall::getUserId).collect(Collectors.toSet());
+        userIdSet.forEach(userId -> dingTalkMsgRpc.sendByUserId(userId, content));
+    }
+
+    @Override
+    public void sendPhoneTalkMsg(Long gameId, boolean isSuper, String listenName) {
+        List<ListenCall> listenCallList = this.callListenUser(gameId, isSuper);
+        if (CollectionUtils.isEmpty(listenCallList)) {
+            return;
+        }
+        String content = listenName + "监测异常";
+        Set<String> phoneNumSet = listenCallList.stream()
+                .filter(listenCall -> Strings.isNotBlank(listenCall.getPhoneNum()))
+                .map(ListenCall::getPhoneNum).collect(Collectors.toSet());
+        phoneNumSet.forEach(phoneNum -> {
+            String lockKey = RedisKeyConstant.PHONE_CALL_LOCK + phoneNum;
+            if (!distributedLockComponent.doLock(lockKey, 0L, 1L, TimeUnit.MINUTES)) {
+                return;
+            }
+            this.phoneCall(content, phoneNum);
+        });
+    }
+
+    private List<ListenCall> callListenUser(Long gameId, boolean isSuper) {
+        List<Long> gameIdList = new ArrayList<>();
+        if (isSuper) {
+            gameIdList = gameService.list(new LambdaQueryWrapper<Game>()
+                    .eq(Game::getSuperGameId, gameId)
+            ).stream().map(Game::getId).collect(Collectors.toList());
+        }
+        List<ListenCall> listenCallList = super.list(new LambdaQueryWrapper<ListenCall>()
+                .eq(!isSuper, ListenCall::getGameId, gameId)
+                .in(isSuper && CollectionUtils.isNotEmpty(gameIdList), ListenCall::getGameId, gameIdList)
+                .eq(ListenCall::getStatus, StatusEnum.YES.getCode()));
+        if (CollectionUtils.isEmpty(listenCallList)) {
+            return Collections.emptyList();
+        }
+        Collection<ListenCall> collection = listenCallList.stream()
+                .collect(Collectors.toMap(ListenCall::getUserId, Function.identity(), (existing, replacement) -> existing))
+                .values();
+        return new ArrayList<>(collection);
+    }
+
+    private void phoneCall(String param, String mobile) {
+        RestTemplate restTemplate = new RestTemplate();
+        String appCode = "f395b1587fc04a49a975f908660fb1e9";
+        String host = "https://jumfixed.market.alicloudapi.com/voice-notify/send";
+        HttpHeaders headers = new HttpHeaders();
+        headers.set("Authorization", "APPCODE " + appCode);
+        headers.set("Content-Type", ContentType.FORM_URLENCODED.getValue());
+        //参数
+        MultiValueMap<String, String> requestParams = new LinkedMultiValueMap<>();
+        requestParams.add("mobile", mobile);
+        requestParams.add("templateId", "JMJNAWUQOJP9");
+        requestParams.add("param", param);
+        String result = null;
+        try {
+            ResponseEntity<String> responseEntity = restTemplate.exchange(host, HttpMethod.POST,
+                    new HttpEntity<>(requestParams, headers), String.class);
+            result = responseEntity.getBody();
+        } catch (Exception e) {
+            log.error("阿里语音呼叫失败, requestParams : {}, e : {}", JsonUtil.toString(requestParams), e.getMessage());
+        }
+        log.error("阿里语音呼叫结果, result : {}", result);
+    }
 }

+ 0 - 61
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/task/PayApplicationTask.java

@@ -1,61 +0,0 @@
-package com.zanxiang.game.module.manage.task;
-
-import com.zanxiang.game.module.manage.constant.RedisKeyConstant;
-import com.zanxiang.game.module.manage.service.IAppletCheckService;
-import com.zanxiang.module.redis.service.IDistributedLockComponent;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.stereotype.Component;
-
-import java.time.LocalDateTime;
-import java.util.concurrent.TimeUnit;
-
-/**
- * @author : lingfeng
- * @time : 2024-01-20
- * @description : 支付应用任务
- */
-@Slf4j
-@Component
-public class PayApplicationTask {
-
-    @Autowired
-    private IDistributedLockComponent distributedLockComponent;
-
-    @Autowired
-    private IAppletCheckService appletCheckService;
-
-    /**
-     * 服务器域名
-     */
-    @Value("${taskRun}")
-    private Boolean taskRun;
-
-    /**
-     * 小程序每10分钟检查
-     */
-    @Scheduled(cron = "0 0/10 * * * ?")
-    public void payApplicationCheck() {
-        if (!taskRun) {
-            return;
-        }
-        //上锁
-        if (!distributedLockComponent.doLock(RedisKeyConstant.PAY_APP_CHECK_LOCK, 0L, 15L, TimeUnit.MINUTES)) {
-            return;
-        }
-        log.error("小程序每10分钟封停监控定时器开始执行, startTime : {}", LocalDateTime.now().toString());
-        try {
-            //执行检测
-            appletCheckService.payApplicationCheck();
-        } catch (Exception e) {
-            log.error("小程序每10分钟封停监控异常, e : {}", e.getMessage());
-        } finally {
-            //释放锁
-            distributedLockComponent.unlock(RedisKeyConstant.PAY_APP_CHECK_LOCK);
-        }
-        log.error("小程序每10分钟封停监控定时器执行结束 , endTime  : {}", LocalDateTime.now().toString());
-    }
-
-}

+ 5 - 0
game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/entity/GameSupper.java

@@ -50,6 +50,11 @@ public class GameSupper implements Serializable {
      */
     private String cpSendMsgKey;
 
+    /**
+     * CP服务端交互密钥
+     */
+    private String cpServerKey;
+
     /**
      * 1 删除  0 正常
      */