后台-sud小游戏时长统计

This commit is contained in:
2025-08-25 18:21:33 +08:00
parent 8873022807
commit e433b4dfde
6 changed files with 399 additions and 0 deletions

View File

@@ -0,0 +1,45 @@
package com.accompany.admin.vo.miniGame;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel("休闲游戏时长明细VO")
public class MiniGameForSudAdminDetailVo {
/**
* 游戏ID
*/
@ApiModelProperty("游戏ID")
private Long gameId;
/**
* 游戏名称
*/
@ApiModelProperty("游戏名称")
private String gameName;
/**
* 房间ID
*/
@ApiModelProperty("房间ID")
private Long roomUid;
@ApiModelProperty("房间编号")
private Long erbanNo;
/**
* 分区ID
*/
@ApiModelProperty("分区ID")
private Long partitionId;
@ApiModelProperty("分区描述")
private String partitionDesc;
/**
* 游戏时长(秒)
*/
@ApiModelProperty("游戏时长(秒)")
private Integer duration;
}

View File

@@ -0,0 +1,63 @@
package com.accompany.admin.vo.miniGame;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel("休闲游戏时长统计VO")
public class MiniGameForSudAdminStatsVo {
/**
* 游戏ID
*/
@ApiModelProperty("游戏ID")
private Long gameId;
/**
* 游戏名称
*/
@ApiModelProperty("游戏名称")
private String gameName;
/**
* 统计月份
*/
@ApiModelProperty("统计月份")
private String statMonth;
/**
* 总时长(秒)
*/
@ApiModelProperty("总时长(秒)")
private Long totalDuration;
/**
* 英文区时长(秒)
*/
@ApiModelProperty("英文区时长(秒)")
private Long enDuration;
/**
* 阿拉伯语区时长(秒)
*/
@ApiModelProperty("阿拉伯语区时长(秒)")
private Long arDuration;
/**
* 中文区时长(秒)
*/
@ApiModelProperty("中文区时长(秒)")
private Long zhDuration;
/**
* 土耳其语区时长(秒)
*/
@ApiModelProperty("土耳其语区时长(秒)")
private Long trDuration;
/**
* 英文2区时长(秒)
*/
@ApiModelProperty("英文2区时长(秒)")
private Long en2Duration;
}

View File

@@ -0,0 +1,40 @@
package com.accompany.admin.mapper.miniGame;
import com.accompany.admin.vo.miniGame.MiniGameForSudAdminDetailVo;
import com.accompany.admin.vo.miniGame.MiniGameForSudAdminStatsVo;
import com.accompany.business.model.miniGame.MiniGameRound;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface MiniGameForSudAdminMapper extends BaseMapper<MiniGameRound> {
/**
* 按月份统计游戏总时长
*
* @param gameId 游戏ID
* @param startTime 开始时间戳
* @param endTime 结束时间戳
* @return 统计结果
*/
List<MiniGameForSudAdminStatsVo> statGameDurationByMonth(@Param("gameId") Long gameId,
@Param("startTime") Long startTime,
@Param("endTime") Long endTime);
/**
* 按月份统计游戏总时长
*
* @param gameId 游戏ID
* @param startTime 开始时间戳
* @param endTime 结束时间戳
* @return 统计结果
*/
List<MiniGameForSudAdminDetailVo> pageGameRoundDetail(Page<MiniGameForSudAdminDetailVo> page,
@Param("gameId") Long gameId,
@Param("startTime") Long startTime,
@Param("endTime") Long endTime);
}

View File

@@ -0,0 +1,121 @@
package com.accompany.admin.service.miniGame;
import com.accompany.admin.vo.miniGame.MiniGameForSudAdminDetailVo;
import com.accompany.admin.vo.miniGame.MiniGameForSudAdminStatsVo;
import com.accompany.business.model.miniGame.MiniGame;
import com.accompany.business.model.miniGame.MiniGameRound;
import com.accompany.admin.mapper.miniGame.MiniGameForSudAdminMapper;
import com.accompany.business.service.miniGame.MiniGameService;
import com.accompany.common.status.BusiStatus;
import com.accompany.common.utils.DateTimeUtil;
import com.accompany.core.exception.AdminServiceException;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.servlet.http.HttpServletResponse;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Slf4j
@Service
public class MiniGameForSudAdminService extends ServiceImpl<MiniGameForSudAdminMapper, MiniGameRound> {
@Autowired
private MiniGameForSudAdminMapper miniGameForSudAdminMapper;
@Autowired
private MiniGameService miniGameService;
/**
* 获取游戏时长统计列表
* @param gameId 游戏ID
* @param month 月份 (格式: yyyy-MM)
* @return 统计列表
*/
public List<MiniGameForSudAdminStatsVo> listStat(Long gameId, String month) {
// 获取所有游戏信息
List<MiniGame> miniGameList = null == gameId? miniGameService.miniGameAllList(null):
Collections.singletonList(miniGameService.queryMiniGameByMgId(gameId));
if (CollectionUtils.isEmpty(miniGameList)){
return Collections.emptyList();
}
// 计算查询时间范围
Date monthDateTime = DateTimeUtil.convertStrToDate(month, DateTimeUtil.DEFAULT_DATE_PATTERN_YEAR_MONTH);
long startTime = DateTimeUtil.getBeginTimeOfMonth(monthDateTime).getTime();
long endTime = DateTimeUtil.getEndTimeOfMonth(monthDateTime).getTime();
// 查询统计数据
List<MiniGameForSudAdminStatsVo> statList = miniGameForSudAdminMapper.statGameDurationByMonth(gameId, startTime, endTime);
if (CollectionUtils.isEmpty(statList)){
return Collections.emptyList();
}
Map<Long, MiniGameForSudAdminStatsVo> statMap = statList.stream().collect(Collectors.toMap(MiniGameForSudAdminStatsVo::getGameId, vo -> vo));
return miniGameList.stream().map(game -> {
MiniGameForSudAdminStatsVo vo = statMap.get(game.getMgId());
if (vo == null){
vo = new MiniGameForSudAdminStatsVo();
vo.setGameId(game.getMgId());
vo.setGameName(game.getName());
vo.setStatMonth(month);
vo.setTotalDuration(0L);
vo.setEnDuration(0L);
vo.setArDuration(0L);
vo.setZhDuration(0L);
vo.setTrDuration(0L);
vo.setEn2Duration(0L);
}
vo.setGameName(game.getName());
return vo;
}).toList();
}
/**
* 获取游戏时长明细列表
* @param gameId 游戏ID
* @param month 月份 (格式: yyyy-MM)
* @param page 页码
* @param size 每页大小
* @return 明细列表
*/
public Page<MiniGameForSudAdminDetailVo> pageDetail(Long gameId, String month, Integer page, Integer size) {
// 获取所有游戏信息
MiniGame miniGame = miniGameService.queryMiniGameByMgId(gameId);
if (null == miniGame) {
throw new AdminServiceException(BusiStatus.PARAMERROR);
}
Page<MiniGameForSudAdminDetailVo> voPage = new Page<>(page, size);
// 计算查询时间范围
Date monthDateTime = DateTimeUtil.convertStrToDate(month, DateTimeUtil.DEFAULT_DATE_PATTERN_YEAR_MONTH);
long startTime = DateTimeUtil.getBeginTimeOfMonth(monthDateTime).getTime();
long endTime = DateTimeUtil.getEndTimeOfMonth(monthDateTime).getTime();
miniGameForSudAdminMapper.pageGameRoundDetail(voPage, gameId, startTime, endTime);
return voPage;
}
/**
* 导出游戏时长明细
* @param gameId 游戏ID
* @param month 月份 (格式: yyyy-MM)
* @param response HTTP响应
*/
public void exportDetail(Long gameId, String month, HttpServletResponse response) {
// 实现导出逻辑
// 这里可以使用Apache POI或其他库来生成Excel文件
// 为简化起见,此处仅提供方法框架
log.info("导出游戏时长明细: gameId={}, month={}", gameId, month);
}
}

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.accompany.admin.mapper.miniGame.MiniGameForSudAdminMapper">
<select id="statGameDurationByMonth"
resultType="com.accompany.admin.vo.miniGame.MiniGameForSudAdminStatsVo">
SELECT
mg_id as gameId,
SUM(battle_duration) as totalDuration,
SUM(CASE WHEN u.partition_id = 1 THEN battle_duration ELSE 0 END) AS enDuration,
SUM(CASE WHEN u.partition_id = 2 THEN battle_duration ELSE 0 END) AS arDuration,
SUM(CASE WHEN u.partition_id = 4 THEN battle_duration ELSE 0 END) AS zhDuration,
SUM(CASE WHEN u.partition_id = 8 THEN battle_duration ELSE 0 END) AS trDuration,
SUM(CASE WHEN u.partition_id = 16 THEN battle_duration ELSE 0 END) AS en2Duration
FROM mini_game_round
JOIN users u ON room_uid = u.uid
WHERE
battle_start_at between #{startTime} and #{endTime}
<if test="gameId != null">
AND mg_id = #{gameId}
</if>
and state = 2
GROUP BY mg_id
</select>
<select id="pageGameRoundDetail" resultType="com.accompany.admin.vo.miniGame.MiniGameForSudAdminDetailVo">
select mgr.gameId, mg.gameName, mgr.room_uid, u.erban_no, u.partition_id, pi.partition_desc, mgr.battle_duration as duration
from mini_game_round mgr
inner join mini_game mg on mgr.mg_id = mg.mg_id
left join users u on mgr.room_uid = u.uid
left join partition_info pi on u.partition_id = pi.partition_id
where
battle_start_at between #{startTime} and #{endTime}
<if test="gameId != null">
and mg_id = #{gameId}
</if>
and state = 2
order by mgr.update_time desc
</select>
</mapper>

View File

@@ -0,0 +1,89 @@
package com.accompany.admin.controller.miniGame;
import com.accompany.admin.service.miniGame.MiniGameForSudAdminService;
import com.accompany.admin.vo.miniGame.MiniGameForSudAdminDetailVo;
import com.accompany.admin.vo.miniGame.MiniGameForSudAdminStatsVo;
import com.accompany.common.result.BusiResult;
import com.accompany.common.status.BusiStatus;
import com.accompany.core.exception.AdminServiceException;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.List;
@Slf4j
@Api(tags = "休闲游戏时长统计")
@RestController
@RequestMapping("/admin/minigame/sud/stat")
public class MiniGameForSudAdminController {
@Autowired
private MiniGameForSudAdminService miniGameForSudAdminService;
@ApiOperation("获取休闲游戏时长统计列表")
@ApiImplicitParams({
@ApiImplicitParam(name = "gameId", value = "游戏ID", required = false, dataType = "Long", paramType = "query"),
@ApiImplicitParam(name = "month", value = "月份(格式: yyyy-MM)", required = true, dataType = "String", paramType = "query")
})
@GetMapping("/listStat")
public BusiResult<List<MiniGameForSudAdminStatsVo>> listStat(
Long gameId,
String month) {
if (!StringUtils.hasText(month)){
throw new AdminServiceException(BusiStatus.PARAMERROR);
}
List<MiniGameForSudAdminStatsVo> result = miniGameForSudAdminService.listStat(gameId, month);
return BusiResult.success(result);
}
@ApiOperation("获取休闲游戏时长明细列表")
@ApiImplicitParams({
@ApiImplicitParam(name = "gameId", value = "游戏ID", required = true, dataType = "Long", paramType = "query"),
@ApiImplicitParam(name = "month", value = "月份(格式: yyyy-MM)", required = true, dataType = "String", paramType = "query"),
@ApiImplicitParam(name = "page", value = "页码", required = true, dataType = "Integer", paramType = "query"),
@ApiImplicitParam(name = "size", value = "每页大小", required = true, dataType = "Integer", paramType = "query")
})
@GetMapping("/pageDetail")
public BusiResult<Page<MiniGameForSudAdminDetailVo>> pageDetail(
Long gameId,
String month,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer size) {
Page<MiniGameForSudAdminDetailVo> result = miniGameForSudAdminService.pageDetail(gameId, month, page, size);
return BusiResult.success(result);
}
@SneakyThrows
@ApiOperation("导出休闲游戏时长明细")
@ApiImplicitParams({
@ApiImplicitParam(name = "gameId", value = "游戏ID", required = true, dataType = "Long", paramType = "query"),
@ApiImplicitParam(name = "month", value = "月份(格式: yyyy-MM)", required = true, dataType = "String", paramType = "query")
})
@GetMapping("/exportDetail")
public void exportDetail(
Long gameId,
String month,
HttpServletResponse response) {
if (null == gameId || !StringUtils.hasText(month)) {
throw new AdminServiceException(BusiStatus.PARAMERROR);
}
Page<MiniGameForSudAdminDetailVo> page = miniGameForSudAdminService.pageDetail(gameId, month, 1, -1);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
String fileName = URLEncoder.encode("休闲游戏时长明细", "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
EasyExcel.write(response.getOutputStream(), MiniGameForSudAdminDetailVo.class).sheet("休闲游戏时长明细").doWrite(page.getRecords());
}
}