feat(console): add game summary country ranking
This commit is contained in:
parent
b1e68f00e8
commit
83b61e94dd
@ -73,6 +73,18 @@ public class DatavRestController extends BaseController {
|
||||
return countryDashboardGameMetricService.pageGameMetrics(cmd);
|
||||
}
|
||||
|
||||
@GetMapping("/country-dashboard/game-metrics/games")
|
||||
public PageResult<CountryDashboardGameMetricCO> countryDashboardGameMetricGames(
|
||||
CountryDashboardGameMetricQryCmd cmd) {
|
||||
return countryDashboardGameMetricService.pageGameSummaries(cmd);
|
||||
}
|
||||
|
||||
@GetMapping("/country-dashboard/game-metrics/country-rank")
|
||||
public List<CountryDashboardGameMetricCO> countryDashboardGameMetricCountryRanks(
|
||||
CountryDashboardGameMetricQryCmd cmd) {
|
||||
return countryDashboardGameMetricService.listGameCountryRanks(cmd);
|
||||
}
|
||||
|
||||
@PostMapping("/country-dashboard/backfill")
|
||||
public Map<String, Object> backfillCountryDashboard(
|
||||
@RequestParam String startDate,
|
||||
|
||||
@ -83,10 +83,7 @@ public class CountryDashboardGameMetricServiceImpl implements CountryDashboardGa
|
||||
SortSpec sortSpec = normalizeSort(cmd == null ? null : cmd.getSortField(),
|
||||
cmd == null ? null : cmd.getSortOrder());
|
||||
String countryCodes = normalizeCsv(cmd == null ? null : cmd.getCountryCodes());
|
||||
String gameProvider = trimToNull(cmd == null ? null : cmd.getGameProvider());
|
||||
if (gameProvider != null) {
|
||||
gameProvider = gameProvider.toUpperCase(Locale.ROOT);
|
||||
}
|
||||
String gameProvider = normalizeGameProvider(cmd == null ? null : cmd.getGameProvider());
|
||||
String gameKeyword = trimToNull(cmd == null ? null : cmd.getGameKeyword());
|
||||
|
||||
Long total = countryDashboardDAO.countGamePeriodMetrics(
|
||||
@ -108,6 +105,76 @@ public class CountryDashboardGameMetricServiceImpl implements CountryDashboardGa
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<CountryDashboardGameMetricCO> pageGameSummaries(
|
||||
CountryDashboardGameMetricQryCmd cmd) {
|
||||
ensureMetricSchema();
|
||||
QueryCondition condition = QueryCondition.of(cmd);
|
||||
int cursor = Math.max(1, cmd == null || cmd.getCursor() == null ? 1 : cmd.getCursor());
|
||||
int limit = Math.max(1, cmd == null || cmd.getLimit() == null ? 50 : cmd.getLimit());
|
||||
limit = Math.min(200, limit);
|
||||
int offset = (cursor - 1) * limit;
|
||||
|
||||
PageResult<CountryDashboardGameMetricCO> result = new PageResult<>();
|
||||
result.setCurrent(cursor);
|
||||
result.setSize(limit);
|
||||
if (!hasText(condition.sysOrigin)) {
|
||||
result.setTotal(0L);
|
||||
result.setRecords(List.of());
|
||||
return result;
|
||||
}
|
||||
|
||||
SortSpec sortSpec = normalizeSummarySort(cmd == null ? null : cmd.getSortField(),
|
||||
cmd == null ? null : cmd.getSortOrder());
|
||||
String countryCodes = normalizeCsv(cmd == null ? null : cmd.getCountryCodes());
|
||||
String gameProvider = normalizeGameProvider(cmd == null ? null : cmd.getGameProvider());
|
||||
String gameKeyword = trimToNull(cmd == null ? null : cmd.getGameKeyword());
|
||||
|
||||
Long total = countryDashboardDAO.countGameSummaryMetrics(
|
||||
condition.periodType, condition.startTime, condition.endTime,
|
||||
PERIOD_ALL.equals(condition.periodType) ? PERIOD_ALL : null,
|
||||
condition.statTimezone, condition.countryKeyword, countryCodes, gameProvider, gameKeyword,
|
||||
condition.sysOrigin);
|
||||
List<CountryDashboardGameMetricCO> records = countryDashboardDAO.listGameSummaryMetrics(
|
||||
condition.periodType, condition.startTime, condition.endTime,
|
||||
PERIOD_ALL.equals(condition.periodType) ? PERIOD_ALL : null,
|
||||
condition.statTimezone, condition.countryKeyword, countryCodes, gameProvider, gameKeyword,
|
||||
condition.sysOrigin, sortSpec.column(), sortSpec.direction(), offset, limit)
|
||||
.stream()
|
||||
.map(this::toCO)
|
||||
.toList();
|
||||
|
||||
result.setTotal(total == null ? 0L : total);
|
||||
result.setRecords(records);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CountryDashboardGameMetricCO> listGameCountryRanks(
|
||||
CountryDashboardGameMetricQryCmd cmd) {
|
||||
ensureMetricSchema();
|
||||
QueryCondition condition = QueryCondition.of(cmd);
|
||||
if (!hasText(condition.sysOrigin)) {
|
||||
return List.of();
|
||||
}
|
||||
String gameProvider = normalizeGameProvider(cmd == null ? null : cmd.getGameProvider());
|
||||
String gameId = trimToNull(cmd == null ? null : cmd.getGameId());
|
||||
if (gameProvider == null || gameId == null) {
|
||||
return List.of();
|
||||
}
|
||||
int limit = Math.max(1, cmd.getRankLimit() == null ? 100 : cmd.getRankLimit());
|
||||
limit = Math.min(500, limit);
|
||||
String countryCodes = normalizeCsv(cmd.getCountryCodes());
|
||||
return countryDashboardDAO.listGameCountryRankMetrics(
|
||||
condition.periodType, condition.startTime, condition.endTime,
|
||||
PERIOD_ALL.equals(condition.periodType) ? PERIOD_ALL : null,
|
||||
condition.statTimezone, condition.countryKeyword, countryCodes, gameProvider, null,
|
||||
gameId, condition.sysOrigin, limit)
|
||||
.stream()
|
||||
.map(this::toCO)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshRecentDays(int days) {
|
||||
ensureMetricSchema();
|
||||
@ -457,6 +524,24 @@ public class CountryDashboardGameMetricServiceImpl implements CountryDashboardGa
|
||||
return new SortSpec(column, direction);
|
||||
}
|
||||
|
||||
private static SortSpec normalizeSummarySort(String sortField, String sortOrder) {
|
||||
String column = switch (Objects.toString(sortField, "")) {
|
||||
case "payoutAmount" -> "payoutAmount";
|
||||
case "profitAmount" -> "profitAmount";
|
||||
case "userCount" -> "userCount";
|
||||
case "orderCount" -> "orderCount";
|
||||
case "consumeAmount" -> "consumeAmount";
|
||||
default -> null;
|
||||
};
|
||||
String direction = "ascend".equalsIgnoreCase(sortOrder) ? "ASC" : "DESC";
|
||||
return new SortSpec(column, direction);
|
||||
}
|
||||
|
||||
private static String normalizeGameProvider(String gameProvider) {
|
||||
String value = trimToNull(gameProvider);
|
||||
return value == null ? null : value.toUpperCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
private static StatTimezone normalizeStatTimezone(String statTimezone) {
|
||||
String value = trimToNull(statTimezone);
|
||||
if (value == null) {
|
||||
|
||||
@ -36,11 +36,21 @@ public class CountryDashboardGameMetricQryCmd extends CountryDashboardQryCmd {
|
||||
*/
|
||||
private String gameProvider;
|
||||
|
||||
/**
|
||||
* 游戏 ID.
|
||||
*/
|
||||
private String gameId;
|
||||
|
||||
/**
|
||||
* 游戏 ID 或名称关键字.
|
||||
*/
|
||||
private String gameKeyword;
|
||||
|
||||
/**
|
||||
* 国家排名返回条数.
|
||||
*/
|
||||
private Integer rankLimit;
|
||||
|
||||
/**
|
||||
* 排序字段.
|
||||
*/
|
||||
|
||||
@ -13,6 +13,10 @@ public interface CountryDashboardGameMetricService {
|
||||
|
||||
PageResult<CountryDashboardGameMetricCO> pageGameMetrics(CountryDashboardGameMetricQryCmd cmd);
|
||||
|
||||
PageResult<CountryDashboardGameMetricCO> pageGameSummaries(CountryDashboardGameMetricQryCmd cmd);
|
||||
|
||||
List<CountryDashboardGameMetricCO> listGameCountryRanks(CountryDashboardGameMetricQryCmd cmd);
|
||||
|
||||
void refreshRecentDays(int days);
|
||||
|
||||
List<String> refreshRange(LocalDate startDate, LocalDate endDate, String sysOrigin,
|
||||
|
||||
@ -364,4 +364,46 @@ public interface CountryDashboardDAO extends BaseDAO<IUserBaseInfo> {
|
||||
@Param("sortDirection") String sortDirection,
|
||||
@Param("offset") int offset,
|
||||
@Param("limit") int limit);
|
||||
|
||||
Long countGameSummaryMetrics(
|
||||
@Param("periodType") String periodType,
|
||||
@Param("startTime") LocalDateTime startTime,
|
||||
@Param("endTime") LocalDateTime endTime,
|
||||
@Param("periodKey") String periodKey,
|
||||
@Param("statTimezone") String statTimezone,
|
||||
@Param("countryKeyword") String countryKeyword,
|
||||
@Param("countryCodes") String countryCodes,
|
||||
@Param("gameProvider") String gameProvider,
|
||||
@Param("gameKeyword") String gameKeyword,
|
||||
@Param("sysOrigin") String sysOrigin);
|
||||
|
||||
List<CountryDashboardGameMetricDTO> listGameSummaryMetrics(
|
||||
@Param("periodType") String periodType,
|
||||
@Param("startTime") LocalDateTime startTime,
|
||||
@Param("endTime") LocalDateTime endTime,
|
||||
@Param("periodKey") String periodKey,
|
||||
@Param("statTimezone") String statTimezone,
|
||||
@Param("countryKeyword") String countryKeyword,
|
||||
@Param("countryCodes") String countryCodes,
|
||||
@Param("gameProvider") String gameProvider,
|
||||
@Param("gameKeyword") String gameKeyword,
|
||||
@Param("sysOrigin") String sysOrigin,
|
||||
@Param("sortColumn") String sortColumn,
|
||||
@Param("sortDirection") String sortDirection,
|
||||
@Param("offset") int offset,
|
||||
@Param("limit") int limit);
|
||||
|
||||
List<CountryDashboardGameMetricDTO> listGameCountryRankMetrics(
|
||||
@Param("periodType") String periodType,
|
||||
@Param("startTime") LocalDateTime startTime,
|
||||
@Param("endTime") LocalDateTime endTime,
|
||||
@Param("periodKey") String periodKey,
|
||||
@Param("statTimezone") String statTimezone,
|
||||
@Param("countryKeyword") String countryKeyword,
|
||||
@Param("countryCodes") String countryCodes,
|
||||
@Param("gameProvider") String gameProvider,
|
||||
@Param("gameKeyword") String gameKeyword,
|
||||
@Param("gameId") String gameId,
|
||||
@Param("sysOrigin") String sysOrigin,
|
||||
@Param("limit") int limit);
|
||||
}
|
||||
|
||||
@ -1846,6 +1846,71 @@
|
||||
LIMIT #{limit} OFFSET #{offset}
|
||||
</select>
|
||||
|
||||
<select id="countGameSummaryMetrics" resultType="java.lang.Long">
|
||||
SELECT COUNT(1)
|
||||
FROM (
|
||||
SELECT 1
|
||||
FROM country_dashboard_game_period_metric t
|
||||
<include refid="GameMetricFilterWhere"/>
|
||||
GROUP BY t.game_provider, t.game_id
|
||||
) summary
|
||||
</select>
|
||||
|
||||
<select id="listGameSummaryMetrics"
|
||||
resultType="com.red.circle.console.infra.database.rds.dto.datav.CountryDashboardGameMetricDTO">
|
||||
SELECT
|
||||
MAX(t.period_key) AS periodKey,
|
||||
MAX(t.period_name) AS periodName,
|
||||
MAX(t.stat_timezone) AS statTimezone,
|
||||
MAX(t.game_provider) AS gameProvider,
|
||||
t.game_id AS gameId,
|
||||
MAX(t.game_name) AS gameName,
|
||||
COALESCE(SUM(t.consume_amount), 0) AS consumeAmount,
|
||||
COALESCE(SUM(t.payout_amount), 0) AS payoutAmount,
|
||||
COALESCE(SUM(t.profit_amount), 0) AS profitAmount,
|
||||
COALESCE(SUM(t.user_count), 0) AS userCount,
|
||||
COALESCE(SUM(t.order_count), 0) AS orderCount,
|
||||
MAX(t.refreshed_at) AS refreshedAt
|
||||
FROM country_dashboard_game_period_metric t
|
||||
<include refid="GameMetricFilterWhere"/>
|
||||
GROUP BY t.game_provider, t.game_id
|
||||
<choose>
|
||||
<when test="sortColumn != null and sortColumn != ''">
|
||||
ORDER BY ${sortColumn} ${sortDirection}, gameProvider ASC, gameId ASC
|
||||
</when>
|
||||
<otherwise>
|
||||
ORDER BY consumeAmount DESC, gameProvider ASC, gameId ASC
|
||||
</otherwise>
|
||||
</choose>
|
||||
LIMIT #{limit} OFFSET #{offset}
|
||||
</select>
|
||||
|
||||
<select id="listGameCountryRankMetrics"
|
||||
resultType="com.red.circle.console.infra.database.rds.dto.datav.CountryDashboardGameMetricDTO">
|
||||
SELECT
|
||||
MAX(t.period_key) AS periodKey,
|
||||
MAX(t.period_name) AS periodName,
|
||||
MAX(t.stat_timezone) AS statTimezone,
|
||||
t.country_code AS countryCode,
|
||||
MAX(t.country_name) AS countryName,
|
||||
MAX(t.game_provider) AS gameProvider,
|
||||
MAX(t.game_id) AS gameId,
|
||||
MAX(t.game_name) AS gameName,
|
||||
COALESCE(SUM(t.consume_amount), 0) AS consumeAmount,
|
||||
COALESCE(SUM(t.payout_amount), 0) AS payoutAmount,
|
||||
COALESCE(SUM(t.profit_amount), 0) AS profitAmount,
|
||||
COALESCE(SUM(t.user_count), 0) AS userCount,
|
||||
COALESCE(SUM(t.order_count), 0) AS orderCount,
|
||||
MAX(t.refreshed_at) AS refreshedAt
|
||||
FROM country_dashboard_game_period_metric t
|
||||
<include refid="GameMetricFilterWhere"/>
|
||||
AND t.game_provider = #{gameProvider}
|
||||
AND t.game_id = #{gameId}
|
||||
GROUP BY t.country_code
|
||||
ORDER BY consumeAmount DESC, countryCode ASC
|
||||
LIMIT #{limit}
|
||||
</select>
|
||||
|
||||
<select id="listNewUserCohorts"
|
||||
resultType="com.red.circle.console.infra.database.rds.dto.datav.CountryDashboardRetentionUserDTO">
|
||||
SELECT
|
||||
|
||||
@ -75,4 +75,6 @@ red-circle:
|
||||
- /console/datav/country-dashboard
|
||||
- /console/datav/country-dashboard/recharge-details
|
||||
- /console/datav/country-dashboard/game-metrics
|
||||
- /console/datav/country-dashboard/game-metrics/games
|
||||
- /console/datav/country-dashboard/game-metrics/country-rank
|
||||
- /console/user/base/info/im/sig
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user