运营游戏数据查询

gamedata
This commit is contained in:
2025-07-21 14:49:29 +08:00
parent 6228b1d795
commit a192250488
20 changed files with 256 additions and 10 deletions

View File

@@ -8,11 +8,17 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static com.accompany.common.constant.Constant.SysConfId.*;
@Api(tags = "游戏配置", value = "游戏配置")
@RestController
@RequestMapping("/admin/game")
@@ -42,4 +48,46 @@ public class GameAdminController extends BaseController {
}
return BusiResult.success(configGameList);
}
@ApiOperation(value = "游戏列表", httpMethod = "GET")
@GetMapping("/allList")
public BusiResult<List<GameConfigVO>> allList() {
List<GameConfigVO> resultList = new ArrayList<>();
GameConfigVO gameConfigVO = new GameConfigVO();
gameConfigVO.setGameChannel(GameService.ALL);
gameConfigVO.setGameId(GameService.ALL);
gameConfigVO.setGameName(GameService.ALL);
resultList.add(gameConfigVO);
List<GameConfigVO> joyPlayList = gameService.getAllConfigGameList(JOY_PLAY_GAME);
if (CollectionUtils.isNotEmpty(joyPlayList)) {
for (GameConfigVO configVO : joyPlayList) {
if (gameConfigVO.getGameName().trim().contains("全部")) {
continue;
}
resultList.add(configVO);
}
}
List<GameConfigVO> leaderccList = gameService.getAllConfigGameList(LEADERCC_GAME);
if (CollectionUtils.isNotEmpty(leaderccList)) {
for (GameConfigVO configVO : leaderccList) {
if (gameConfigVO.getGameName().trim().contains("全部")) {
continue;
}
resultList.add(configVO);
}
}
List<GameConfigVO> baishunList = gameService.getAllConfigGameList(BAISHUN_GAME);
if (CollectionUtils.isNotEmpty(baishunList)) {
for (GameConfigVO configVO : baishunList) {
if (gameConfigVO.getGameName().trim().contains("全部")) {
continue;
}
resultList.add(configVO);
}
}
return BusiResult.success(resultList);
}
}

View File

@@ -1,5 +1,7 @@
package com.accompany.admin.controller.game;
import com.accompany.admin.controller.BaseController;
import com.accompany.admin.service.system.AdminPartitionService;
import com.accompany.business.param.BasePageParams;
import com.accompany.business.service.game.GameDayStatDataService;
import com.accompany.common.result.BusiResult;
@@ -29,11 +31,14 @@ import java.util.List;
@Api(tags = "游戏数据汇总", value = "游戏数据汇总")
@RestController
@RequestMapping("/admin/gamedata")
public class GameDataAdminController {
public class GameDataAdminController extends BaseController {
@Autowired
private GameDayStatDataService gameDayStatDataService;
@Autowired
private AdminPartitionService adminPartitionService;
@ApiOperation(value = "Game汇总", httpMethod = "GET")
@ApiImplicitParams({
@ApiImplicitParam(name = "channel", value = "第三方名称,LEADERCC-灵BAISHUN-百顺", required = true),
@@ -70,8 +75,8 @@ public class GameDataAdminController {
@ApiImplicitParam(name = "gameId", value = "游戏id", required = false),
})
@GetMapping("/user/total")
public BusiResult<PageResult<GameUserDataDetailVo>> userList(String erbanNoStr, String channel, String gameId, BasePageParams params) {
PageResult<GameUserDataDetailVo> gameUserDataDetailVoPageResult = gameDayStatDataService.userList(erbanNoStr, channel, gameId, params.getStartTime(), params.getEndTime(),
public BusiResult<PageResult<GameUserDataDetailVo>> userTotal(String erbanNoStr, String channel, String gameId, BasePageParams params) {
PageResult<GameUserDataDetailVo> gameUserDataDetailVoPageResult = gameDayStatDataService.userTotal(erbanNoStr, channel, gameId, params.getStartTime(), params.getEndTime(),
params.getPartitionId(), params.getPageNo(), params.getPageSize());
return BusiResult.success(gameUserDataDetailVoPageResult);
}
@@ -98,7 +103,7 @@ public class GameDataAdminController {
@PostMapping("/user/export")
public void userExport(HttpServletResponse response, String erbanNoStr, String channel, String gameId, BasePageParams params) throws IOException {
params.setPageSize(100000);
PageResult<GameUserDataDetailVo> gameDataTotalVoPageResult = gameDayStatDataService.userList(erbanNoStr, channel, gameId, params.getStartTime(), params.getEndTime(),
PageResult<GameUserDataDetailVo> gameDataTotalVoPageResult = gameDayStatDataService.userTotal(erbanNoStr, channel, gameId, params.getStartTime(), params.getEndTime(),
params.getPartitionId(), 0, -1);
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
@@ -137,4 +142,20 @@ public class GameDataAdminController {
response.setHeader("Content-disposition", "attachment;filename=" + excelName + ExcelTypeEnum.XLSX.getValue());
EasyExcel.write(response.getOutputStream(), GameDetailVo.class).sheet("游戏明细").doWrite(data.getRows());
}
@ApiOperation(value = "运营游戏数据(单用户汇总)", httpMethod = "GET")
@ApiImplicitParams({
@ApiImplicitParam(name = "erbanNo", value = "用户id", required = true),
@ApiImplicitParam(name = "channel", value = "第三方名称,LEADERCC-灵BAISHUN-百顺,JOYPLAY-游玩", required = false),
@ApiImplicitParam(name = "gameId", value = "游戏id", required = false),
@ApiImplicitParam(name = "startDate", value = "开始时间yyyy-MM-dd", required = false),
@ApiImplicitParam(name = "endDate", value = "结束时间yyyy-MM-dd", required = false),
})
@GetMapping("/userTotalALL")
public BusiResult<GameUserDataDetailVo> userTotalALL(Long erbanNo, String channel, String gameId, String startDate, String endDate) {
List<Integer> rolePartitionIds = adminPartitionService.getAllPartitionId(getAdminId());
GameUserDataDetailVo gameUserDataDetailVoPageResult = gameDayStatDataService.userTotalALL(erbanNo, channel, gameId, startDate, endDate, rolePartitionIds);
return BusiResult.success(gameUserDataDetailVoPageResult);
}
}

View File

@@ -1,5 +1,6 @@
package com.accompany.sharding.vo;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@@ -60,4 +61,8 @@ public class GameUserDataDetailVo {
@ApiModelProperty("比例")
private BigDecimal betRate;
@ExcelIgnore
@ApiModelProperty("充值等级")
private String chargeLevel;
}

View File

@@ -236,7 +236,7 @@ public class ShardingSphereConfig {
}
private AlgorithmConfiguration getGameGoldLogShardingAlgorithmConfiguration() {
AlgorithmConfiguration algorithmConfiguration = getMonthShardingAlgorithmConfiguration();
AlgorithmConfiguration algorithmConfiguration = getMonthShardingAlgorithmConfigurationV2();
return algorithmConfiguration;
}
@@ -245,7 +245,7 @@ public class ShardingSphereConfig {
}
private AlgorithmConfiguration getBaiShunGameRecordShardingAlgorithmConfiguration() {
return getMonthShardingAlgorithmConfiguration();
return getMonthShardingAlgorithmConfigurationV2();
}
private AlgorithmConfiguration getFamilyMemberRoomMicRecordShardingAlgorithmConfiguration() {

View File

@@ -24,4 +24,7 @@ public interface BaiShunGameRecordMapper extends BaseMapper<BaiShunGameRecord> {
IPage<GameDetailVo> gameDetail(IPage<GameDetailVo> iPage, @Param("gameId") String gameId,
@Param("beginTime") Date beginTime, @Param("endTime") Date endTime, @Param("partitionId") Integer partitionId);
GameUserDataDetailVo userTotalALL(@Param("uid") Long uid, @Param("gameId") String gameId,
@Param("beginTime") Date beginTime, @Param("endTime") Date endTime);
}

View File

@@ -20,4 +20,7 @@ public interface GameGoldLogMapper extends BaseMapper<GameGoldLog> {
IPage<GameDetailVo> gameDetail(IPage<GameDetailVo> iPage, @Param("gameId") String gameId,
@Param("beginTime") Date beginTime, @Param("endTime") Date endTime, @Param("partitionId") Integer partitionId);
GameUserDataDetailVo userTotalALL(@Param("uid") Long uid, @Param("gameId") String gameId,
@Param("beginTime") Date beginTime, @Param("endTime") Date endTime);
}

View File

@@ -26,4 +26,7 @@ public interface JoyGameRecordMapper extends BaseMapper<JoyGameRecord> {
IPage<GameDetailVo> gameDetail(IPage<GameDetailVo> iPage, @Param("gameId") String gameId,
@Param("beginTime") Date beginTime, @Param("endTime") Date endTime, @Param("partitionId") Integer partitionId);
GameUserDataDetailVo userTotalALL(@Param("uid") Long uid, @Param("gameId") String gameId,
@Param("beginTime") Date beginTime, @Param("endTime") Date endTime);
}

View File

@@ -82,4 +82,26 @@
group by statDate,gr.game_id
order by statDate desc
</select>
<select id="userTotalALL" resultType="com.accompany.sharding.vo.GameUserDataDetailVo">
SELECT
SUM(payGold) AS payGold,
SUM(winGold) AS winGold,
COUNT(1) AS playNum
FROM (
SELECT
round_id,
uid,
abs(sum(if(gr.currency_diff &lt; 0, gr.`currency_diff`, 0))) payGold,
sum(if(gr.currency_diff > 0, gr.`currency_diff`, 0)) winGold
FROM game_gold_log
WHERE create_time >= #{beginTime}
AND create_time &lt;= #{endTime}
AND uid = #{uid}
<if test="gameId != null and gameId !='' and 'All' != gameId">
AND game_id = #{gameId}
</if>
GROUP BY round_id,uid
) AS round_summary
</select>
</mapper>

View File

@@ -85,4 +85,26 @@
group by statDate,gr.game_id
order by statDate desc
</select>
</mapper>
<select id="userTotalALL" resultType="com.accompany.sharding.vo.GameUserDataDetailVo">
SELECT
SUM(payGold) AS payGold,
SUM(winGold) AS winGold,
COUNT(1) AS playNum
FROM (
SELECT
round_id,
uid,
SUM(IF(type = 1, coin, 0)) AS payGold,
SUM(IF(type = 2, coin, 0)) AS winGold
FROM game_gold_log
WHERE create_time >= #{beginTime}
AND create_time &lt;= #{endTime}
AND uid = #{uid}
<if test="gameId != null and gameId !='' and 'All' != gameId">
AND game_id = #{gameId}
</if>
GROUP BY round_id, uid
) AS round_summary
</select>
</mapper>

View File

@@ -71,4 +71,19 @@
group by statDate,gr.game_id
order by statDate desc
</select>
<select id="userTotalALL" resultType="com.accompany.sharding.vo.GameUserDataDetailVo">
select
sum(gr.`bet`) payGold,
sum(gr.`pay`) winGold,
sum(if(gr.`type` = 1, 1, 0)) playNum
from joy_game_record gr
where gr.create_time >= #{beginTime}
and gr.create_time &lt;= #{endTime}
and gr.uid = #{uid}
<if test="gameId != null and gameId !='' and 'All' != gameId">
and gr.game_id = #{gameId}
</if>
</select>
</mapper>

View File

@@ -4,6 +4,7 @@ import lombok.Data;
@Data
public class GameConfigVO {
private String gameChannel;
private String gameName;
private String gameId;
}

View File

@@ -18,4 +18,7 @@ public interface BaiShunGameRecordService extends IService<BaiShunGameRecord> {
IPage<GameUserDataDetailVo> userTotalList(IPage<GameUserDataDetailVo> iPage, List<Long> uids, String gameId, Date beginTime, Date endTime, Integer partitionId);
GameUserDataDetailVo userTotalStat(List<Long> uids, String gameId, Date beginTime, Date endTime, Integer partitionId);
IPage<GameDetailVo> gameDetail(IPage<GameDetailVo> iPage, String gameId, Date beginTime, Date endTime, Integer partitionId);
GameUserDataDetailVo userTotalALL(Long uid, String gameId, Date beginTime, Date endTime);
}

View File

@@ -38,4 +38,9 @@ public class BaiShunGameRecordServiceImpl extends ServiceImpl<BaiShunGameRecordM
return baseMapper.gameDetail(iPage, gameId, beginTime, endTime, partitionId);
}
@Override
public GameUserDataDetailVo userTotalALL(Long uid, String gameId, Date beginTime, Date endTime) {
return baseMapper.userTotalALL(uid, gameId, beginTime, endTime);
}
}

View File

@@ -22,7 +22,7 @@ public interface GameDayStatDataService extends IService<GameDayStatData> {
PageResult<GameDataTotalVo> totalList(
String channel, String gameId, String startDate, String endDate, Integer partitionId, Integer pageNo, Integer pageSize);
PageResult<GameUserDataDetailVo> userList(String erbanNoStr,
PageResult<GameUserDataDetailVo> userTotal(String erbanNoStr,
String channel, String gameId, String startDate, String endDate, Integer partitionId, Integer pageNo, Integer pageSize);
List<GameUserDataDetailVo> userListOffset7and14(String erbanNoStr,
@@ -39,4 +39,5 @@ public interface GameDayStatDataService extends IService<GameDayStatData> {
*/
void statDayList(String channel, Date statTime);
GameUserDataDetailVo userTotalALL(Long erbanNo, String channel, String gameId, String startDate, String endDate, List<Integer> rolePartitionIds);
}

View File

@@ -17,4 +17,6 @@ public interface GameGoldLogService extends IService<GameGoldLog> {
GameUserDataDetailVo userTotalStat(List<Long> uids, String gameId, Date beginTime, Date endTime, Integer partitionId);
IPage<GameDetailVo> gameDetail(IPage<GameDetailVo> iPage, String gameId, Date beginTime, Date endTime, Integer partitionId);
GameUserDataDetailVo userTotalALL(Long uid, String gameId, Date beginTime, Date endTime);
}

View File

@@ -41,4 +41,9 @@ public class GameGoldLogServiceImpl extends ServiceImpl<GameGoldLogMapper, GameG
public IPage<GameDetailVo> gameDetail(IPage<GameDetailVo> iPage, String gameId, Date beginTime, Date endTime, Integer partitionId) {
return baseMapper.gameDetail(iPage, gameId, beginTime, endTime, partitionId);
}
@Override
public GameUserDataDetailVo userTotalALL(Long uid, String gameId, Date beginTime, Date endTime) {
return baseMapper.userTotalALL(uid, gameId, beginTime, endTime);
}
}

View File

@@ -281,6 +281,7 @@ public class GameService {
}
for (GameConfigVO gameConfigVO : gameConfigVOS) {
GameConstant.GameChannel byChannel = GameConstant.GameChannel.getByChannel(channel);
gameConfigVO.setGameChannel(byChannel.name());
gameConfigVO.setGameName(byChannel.getDesc() + "-" + gameConfigVO.getGameName());
}
return gameConfigVOS;

View File

@@ -22,4 +22,6 @@ public interface JoyGameRecordService extends IService<JoyGameRecord> {
IPage<GameDetailVo> gameDetail(IPage<GameDetailVo> iPage, String gameId, Date beginTime, Date endTime, Integer partitionId);
GameUserDataDetailVo userTotalALL(Long uid, String gameId, Date beginTime, Date endTime);
}

View File

@@ -12,6 +12,7 @@ import com.accompany.common.constant.GameConstant;
import com.accompany.common.result.PageResult;
import com.accompany.core.exception.AdminServiceException;
import com.accompany.core.model.Users;
import com.accompany.payment.service.UserRechargeLevelService;
import com.accompany.sharding.vo.GameDataTotalVo;
import com.accompany.sharding.vo.GameDetailVo;
import com.accompany.sharding.vo.GameUserDataDetailVo;
@@ -33,6 +34,7 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Collectors;
/**
@@ -64,6 +66,10 @@ public class GameDayStatDataServiceImpl extends ServiceImpl<GameDayStatDataMappe
@Autowired
private JoyGameRecordService joyGameRecordService;
@Autowired
private UserRechargeLevelService userRechargeLevelService;
@Override
public void statDayList(String channel, Date statTime) {
log.info("GameDayStatDataServiceImpl.statDayList-begin channel:{}, statTime:{}", channel, statTime);
@@ -203,7 +209,7 @@ public class GameDayStatDataServiceImpl extends ServiceImpl<GameDayStatDataMappe
}
@Override
public PageResult<GameUserDataDetailVo> userList(String erbanNoStr, String channel, String gameId, String startDate, String endDate, Integer partitionId, Integer pageNo, Integer pageSize) {
public PageResult<GameUserDataDetailVo> userTotal(String erbanNoStr, String channel, String gameId, String startDate, String endDate, Integer partitionId, Integer pageNo, Integer pageSize) {
GameConstant.GameChannel byChannel = GameConstant.GameChannel.getByChannel(channel);
if (byChannel == null) {
throw new AdminServiceException("请选择第三方名称");
@@ -491,4 +497,77 @@ public class GameDayStatDataServiceImpl extends ServiceImpl<GameDayStatDataMappe
}
return null;
}
@Override
public GameUserDataDetailVo userTotalALL(Long erbanNo, String channel, String gameId, String startDate, String endDate, List<Integer> rolePartitionIds) {
if (erbanNo == null) {
throw new AdminServiceException("请输入用户ID");
}
if (StringUtils.isEmpty(startDate) || StringUtils.isEmpty(endDate)) {
throw new AdminServiceException("请选择时间范围");
}
Users user = usersService.getUserByErbanNo(erbanNo);
if (user == null) {
throw new AdminServiceException(erbanNo + " 用户不存在");
}
if (!rolePartitionIds.contains(user.getPartitionId())) {
return null;
}
Date beginTime, endTime;
Date now = new Date();
if (StringUtils.isNotEmpty(startDate) && StringUtils.isNotEmpty(endDate)) {
beginTime = DateUtil.parseDate(startDate);
endTime = DateUtil.endOfDay(DateUtil.parseDate(endDate));
} else {
endTime = DateUtil.endOfDay(now);
beginTime = DateUtil.offsetDay(DateUtil.beginOfDay(endTime), -7);
}
Long uid = user.getUid();
GameUserDataDetailVo gameUserDataDetailVo = new GameUserDataDetailVo();
gameUserDataDetailVo.setUid(uid);
gameUserDataDetailVo.setErbanNo(erbanNo);
gameUserDataDetailVo.setChargeLevel(userRechargeLevelService.getLevelByUid(uid));
gameUserDataDetailVo.setNick(user.getNick());
List<GameUserDataDetailVo> gameUserDataDetailVos = new ArrayList<>();
Map<String, Supplier<GameUserDataDetailVo>> channelServiceMap = new HashMap<>();
channelServiceMap.put(GameConstant.GameChannel.LEADERCC.name(),
() -> gameGoldLogService.userTotalALL(uid, gameId, beginTime, endTime));
channelServiceMap.put(GameConstant.GameChannel.BAISHUN.name(),
() -> baiShunGameRecordService.userTotalALL(uid, gameId, beginTime, endTime));
channelServiceMap.put(GameConstant.GameChannel.JOYPLAY.name(),
() -> joyGameRecordService.userTotalALL(uid, gameId, beginTime, endTime));
// 处理特定渠道或默认情况
if (channelServiceMap.containsKey(channel)) {
Optional.ofNullable(channelServiceMap.get(channel).get())
.ifPresent(gameUserDataDetailVos::add);
} else {
channelServiceMap.values().stream()
.map(Supplier::get)
.filter(Objects::nonNull)
.forEach(gameUserDataDetailVos::add);
}
if (CollectionUtils.isNotEmpty(gameUserDataDetailVos)) {
gameUserDataDetailVo.setPayGold(gameUserDataDetailVos.stream().map(GameUserDataDetailVo::getPayGold)
.filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add));
gameUserDataDetailVo.setPlayNum(gameUserDataDetailVos.stream().mapToInt(GameUserDataDetailVo::getPlayNum)
.filter(Objects::nonNull).sum());
gameUserDataDetailVo.setWinGold(gameUserDataDetailVos.stream().filter(Objects::nonNull).map(GameUserDataDetailVo::getWinGold)
.filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add));
} else {
gameUserDataDetailVo.setPlayNum(0);
gameUserDataDetailVo.setPayGold(BigDecimal.ZERO);
gameUserDataDetailVo.setWinGold(BigDecimal.ZERO);
}
gameUserDataDetailVo.setTotalRemain(gameUserDataDetailVo.getPayGold().subtract(gameUserDataDetailVo.getWinGold()));
if (gameUserDataDetailVo.getPayGold().compareTo(BigDecimal.ZERO) > 0) {
gameUserDataDetailVo.setBetRate(gameUserDataDetailVo.getWinGold().divide(gameUserDataDetailVo.getPayGold(), 4, RoundingMode.DOWN));
} else {
gameUserDataDetailVo.setBetRate(BigDecimal.ZERO);
}
return gameUserDataDetailVo;
}
}

View File

@@ -37,4 +37,9 @@ public class JoyGameRecordServiceImpl extends ServiceImpl<JoyGameRecordMapper, J
public IPage<GameDetailVo> gameDetail(IPage<GameDetailVo> iPage, String gameId, Date beginTime, Date endTime, Integer partitionId) {
return baseMapper.gameDetail(iPage, gameId, beginTime, endTime, partitionId);
}
@Override
public GameUserDataDetailVo userTotalALL(Long uid, String gameId, Date beginTime, Date endTime) {
return baseMapper.userTotalALL(uid, gameId, beginTime, endTime);
}
}