diff --git a/rc-service/rc-service-console/console-application/src/main/java/com/red/circle/console/app/service/app/datav/CountryDashboardDailyMetricService.java b/rc-service/rc-service-console/console-application/src/main/java/com/red/circle/console/app/service/app/datav/CountryDashboardDailyMetricService.java index 4ed4d81e..87c984ba 100644 --- a/rc-service/rc-service-console/console-application/src/main/java/com/red/circle/console/app/service/app/datav/CountryDashboardDailyMetricService.java +++ b/rc-service/rc-service-console/console-application/src/main/java/com/red/circle/console/app/service/app/datav/CountryDashboardDailyMetricService.java @@ -6,7 +6,9 @@ import com.red.circle.console.infra.database.rds.dto.datav.CountryDashboardDaily import com.red.circle.console.infra.database.rds.dto.datav.CountryDashboardMetricDTO; import com.red.circle.console.infra.database.rds.dto.datav.CountryDashboardPeriodMetricDTO; import com.red.circle.console.infra.database.rds.dto.datav.CountryDashboardRetentionUserDTO; +import com.red.circle.console.infra.database.rds.dto.datav.CountryDashboardUserCountryDTO; import java.math.BigDecimal; +import java.sql.Timestamp; import java.time.DayOfWeek; import java.time.Instant; import java.time.LocalDate; @@ -26,9 +28,11 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.function.BiConsumer; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.bson.Document; +import org.bson.types.Decimal128; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.aggregation.Aggregation; @@ -58,6 +62,7 @@ public class CountryDashboardDailyMetricService { private static final String STORAGE_TIMEZONE = "Asia/Riyadh"; private static final String STORAGE_TIMEZONE_OFFSET = "+03:00"; private static final String COLLECTION_USER_DAILY_ACTIVE_LOG = "user_daily_active_log"; + private static final String COLLECTION_GIFT_GIVE_RUNNING_WATER = "gift_give_running_water"; private static final int USER_BATCH_SIZE = 1000; private final CountryDashboardDAO countryDashboardDAO; @@ -171,6 +176,7 @@ public class CountryDashboardDailyMetricService { countryDashboardDAO.createPeriodUserMetricTable(); countryDashboardDAO.ensurePeriodMetricTimezoneSchema(); countryDashboardDAO.ensurePeriodMetricUserColumnsSchema(); + countryDashboardDAO.ensureMetricValueColumnsSchema(); metricSchemaEnsured = true; log.info("country dashboard metric tables ensured"); } @@ -227,6 +233,14 @@ public class CountryDashboardDailyMetricService { PERIOD_DAY, startTime, endTime, startTimeMillis, endTimeMillis, null, sysOrigin, STORAGE_TIMEZONE_OFFSET, STORAGE_TIMEZONE_OFFSET), statDate, sysOrigin); + TimeWindow timeWindow = new TimeWindow(startTime, endTime, startTimeMillis, endTimeMillis, + statDate.atStartOfDay(STORAGE_ZONE_ID).toInstant(), + statDate.plusDays(1).atStartOfDay(STORAGE_ZONE_ID).toInstant()); + mergeDailyMongo(rows, listGiftConsume(timeWindow, sysOrigin, STORAGE_TIMEZONE), + (row, amount) -> row.setGiftConsume(add(row.getGiftConsume(), amount)), statDate, sysOrigin); + mergeDailyMongo(rows, listLuckyGiftAnchorShare(timeWindow, sysOrigin, STORAGE_TIMEZONE), + (row, amount) -> row.setLuckyGiftAnchorShare(add(row.getLuckyGiftAnchorShare(), amount)), + statDate, sysOrigin); List metrics = new ArrayList<>(rows.values()); RefreshWriteResult writeResult = transactionTemplate.execute(status -> { @@ -296,6 +310,12 @@ public class CountryDashboardDailyMetricService { mergePeriodAmounts(rows, countryDashboardDAO.listLuckyBoxGame( window.periodType(), startTime, endTime, null, sysOrigin, STORAGE_TIMEZONE_OFFSET, statTimezone.offset()), window, sysOrigin, statTimezone); + mergePeriodMongo(rows, listGiftConsume(timeWindow, sysOrigin, statTimezone.id()), + (row, amount) -> row.setGiftConsume(add(row.getGiftConsume(), amount)), + window, sysOrigin, statTimezone); + mergePeriodMongo(rows, listLuckyGiftAnchorShare(timeWindow, sysOrigin, statTimezone.id()), + (row, amount) -> row.setLuckyGiftAnchorShare(add(row.getLuckyGiftAnchorShare(), amount)), + window, sysOrigin, statTimezone); mergePeriodDailyActive(rows, listDailyActive(window, sysOrigin), window, sysOrigin, statTimezone); mergePeriodRetention(rows, window, sysOrigin, statTimezone, startTime, endTime); @@ -373,9 +393,11 @@ public class CountryDashboardDailyMetricService { row.setGoogleRecharge(add(row.getGoogleRecharge(), metric.getGoogleRecharge())); row.setDealerRecharge(add(row.getDealerRecharge(), metric.getDealerRecharge())); row.setSalaryExchange(add(row.getSalaryExchange(), metric.getSalaryExchange())); + row.setGiftConsume(add(row.getGiftConsume(), metric.getGiftConsume())); row.setLuckyGiftTotalFlow(add(row.getLuckyGiftTotalFlow(), metric.getLuckyGiftTotalFlow())); row.setLuckyGiftUser(safeLong(row.getLuckyGiftUser()) + safeLong(metric.getLuckyGiftUser())); row.setLuckyGiftPayout(add(row.getLuckyGiftPayout(), metric.getLuckyGiftPayout())); + row.setLuckyGiftAnchorShare(add(row.getLuckyGiftAnchorShare(), metric.getLuckyGiftAnchorShare())); row.setGameTotalFlow(add(row.getGameTotalFlow(), metric.getGameTotalFlow())); row.setGameUser(safeLong(row.getGameUser()) + safeLong(metric.getGameUser())); row.setGamePayout(add(row.getGamePayout(), metric.getGamePayout())); @@ -397,8 +419,10 @@ public class CountryDashboardDailyMetricService { row.setGoogleRecharge(add(row.getGoogleRecharge(), metric.getGoogleRecharge())); row.setDealerRecharge(add(row.getDealerRecharge(), metric.getDealerRecharge())); row.setSalaryExchange(add(row.getSalaryExchange(), metric.getSalaryExchange())); + row.setGiftConsume(add(row.getGiftConsume(), metric.getGiftConsume())); row.setLuckyGiftTotalFlow(add(row.getLuckyGiftTotalFlow(), metric.getLuckyGiftTotalFlow())); row.setLuckyGiftPayout(add(row.getLuckyGiftPayout(), metric.getLuckyGiftPayout())); + row.setLuckyGiftAnchorShare(add(row.getLuckyGiftAnchorShare(), metric.getLuckyGiftAnchorShare())); row.setGameTotalFlow(add(row.getGameTotalFlow(), metric.getGameTotalFlow())); row.setGamePayout(add(row.getGamePayout(), metric.getGamePayout())); } @@ -432,11 +456,62 @@ public class CountryDashboardDailyMetricService { } } + private void mergeDailyMongo(Map rows, + List metrics, BiConsumer merger, + LocalDate statDate, String sysOrigin) { + if (metrics == null || metrics.isEmpty()) { + return; + } + Map countryMap = mapUserCountries( + metrics.stream().map(MongoMetric::userId).filter(Objects::nonNull).distinct().toList()); + for (MongoMetric metric : metrics) { + CountryDashboardUserCountryDTO country = countryMap.get(metric.userId()); + if (country == null) { + continue; + } + CountryDashboardMetricDTO rowKey = new CountryDashboardMetricDTO() + .setCountryCode(country.getCountryCode()) + .setCountryName(country.getCountryName()); + merger.accept(getRow(rows, rowKey, statDate, sysOrigin), metric.amount()); + } + } + + private void mergePeriodMongo(Map rows, + List metrics, BiConsumer merger, + PeriodWindow window, String sysOrigin, StatTimezone statTimezone) { + if (metrics == null || metrics.isEmpty()) { + return; + } + Map countryMap = mapUserCountries( + metrics.stream().map(MongoMetric::userId).filter(Objects::nonNull).distinct().toList()); + for (MongoMetric metric : metrics) { + CountryDashboardUserCountryDTO country = countryMap.get(metric.userId()); + if (country == null) { + continue; + } + CountryDashboardMetricDTO rowKey = new CountryDashboardMetricDTO() + .setCountryCode(country.getCountryCode()) + .setCountryName(country.getCountryName()); + merger.accept(getPeriodRow(rows, rowKey, window, sysOrigin, statTimezone), metric.amount()); + } + } + private void mergePeriodRetention(Map rows, PeriodWindow window, String sysOrigin, StatTimezone statTimezone, LocalDateTime startTime, LocalDateTime endTime) { + mergePeriodRetentionDays(rows, window, sysOrigin, statTimezone, startTime.minusDays(1), + endTime.minusDays(1), 1); + mergePeriodRetentionDays(rows, window, sysOrigin, statTimezone, startTime.minusDays(7), + endTime.minusDays(7), 7); + mergePeriodRetentionDays(rows, window, sysOrigin, statTimezone, startTime.minusDays(30), + endTime.minusDays(30), 30); + } + + private void mergePeriodRetentionDays(Map rows, + PeriodWindow window, String sysOrigin, StatTimezone statTimezone, LocalDateTime cohortStartTime, + LocalDateTime cohortEndTime, int retentionDays) { List cohorts = countryDashboardDAO.listNewUserCohorts( - window.periodType(), startTime, endTime, null, sysOrigin, + window.periodType(), cohortStartTime, cohortEndTime, null, sysOrigin, STORAGE_TIMEZONE_OFFSET, statTimezone.offset()); if (cohorts == null || cohorts.isEmpty()) { return; @@ -450,9 +525,7 @@ public class CountryDashboardDailyMetricService { continue; } userIds.add(cohort.getUserId()); - collectRetentionActiveDate(activeDates, cohort.getRegisterDate(), 1, today); - collectRetentionActiveDate(activeDates, cohort.getRegisterDate(), 7, today); - collectRetentionActiveDate(activeDates, cohort.getRegisterDate(), 30, today); + collectRetentionActiveDate(activeDates, cohort.getRegisterDate(), retentionDays, today); } Set activeUserDates = listActiveUserDateSet(userIds, activeDates, sysOrigin); @@ -465,11 +538,7 @@ public class CountryDashboardDailyMetricService { .setCountryName(cohort.getCountryName()); CountryDashboardPeriodMetricDTO row = getPeriodRow(rows, metric, window, sysOrigin, statTimezone); - mergeRetentionDay(row, cohort.getUserId(), cohort.getRegisterDate(), 1, today, - activeUserDates); - mergeRetentionDay(row, cohort.getUserId(), cohort.getRegisterDate(), 7, today, - activeUserDates); - mergeRetentionDay(row, cohort.getUserId(), cohort.getRegisterDate(), 30, today, + mergeRetentionDay(row, cohort.getUserId(), cohort.getRegisterDate(), retentionDays, today, activeUserDates); } } @@ -512,6 +581,77 @@ public class CountryDashboardDailyMetricService { .setDailyActiveUser(dailyActiveUser); } + private List listGiftConsume(TimeWindow timeWindow, String sysOrigin, + String statTimezone) { + List criteria = baseGiftCriteria(timeWindow, sysOrigin); + criteria.add(Criteria.where("luckyGift").ne(Boolean.TRUE)); + criteria.add(Criteria.where("originId").regex("^\\d+$")); + criteria.add(new Criteria().orOperator( + Criteria.where("dynamicContentId").exists(false), + Criteria.where("dynamicContentId").is(null), + Criteria.where("dynamicContentId").is("") + )); + return aggregateGiftAmount(criteria, "$giftValue.actualAmount", false, statTimezone); + } + + private List listLuckyGiftAnchorShare(TimeWindow timeWindow, String sysOrigin, + String statTimezone) { + List criteria = baseGiftCriteria(timeWindow, sysOrigin); + criteria.add(Criteria.where("luckyGift").is(Boolean.TRUE)); + return aggregateGiftAmount(criteria, "$acceptUsers.targetAmount", true, statTimezone); + } + + private List baseGiftCriteria(TimeWindow timeWindow, String sysOrigin) { + List criteria = new ArrayList<>(); + criteria.add(Criteria.where("refunded").ne(Boolean.TRUE)); + criteria.add(Criteria.where("userId").ne(null)); + criteria.add(Criteria.where("createTime").gte(Timestamp.from(timeWindow.startInstant()))); + criteria.add(Criteria.where("createTime").lt(Timestamp.from(timeWindow.endInstant()))); + if (hasText(sysOrigin)) { + criteria.add(Criteria.where("sysOrigin").is(sysOrigin)); + } + return criteria; + } + + private List aggregateGiftAmount(List criteria, String amountPath, + boolean unwindAcceptUsers, String statTimezone) { + List operations = new ArrayList<>(); + operations.add(Aggregation.match(new Criteria().andOperator(criteria.toArray(new Criteria[0])))); + if (unwindAcceptUsers) { + operations.add(Aggregation.unwind("acceptUsers")); + } + operations.add(context -> new Document("$project", + new Document("userId", "$userId") + .append("amount", amountPath) + .append("day", new Document("$dateToString", + new Document("format", "%Y-%m-%d") + .append("date", "$createTime") + .append("timezone", statTimezone))))); + operations.add(Aggregation.group("userId", "day").sum("amount").as("amount")); + + return mongoTemplate.aggregate(Aggregation.newAggregation(operations), + COLLECTION_GIFT_GIVE_RUNNING_WATER, Document.class) + .getMappedResults() + .stream() + .map(this::toMongoMetric) + .filter(Objects::nonNull) + .toList(); + } + + private MongoMetric toMongoMetric(Document document) { + Object id = document.get("_id"); + if (!(id instanceof Document idDoc)) { + return null; + } + Long userId = toLong(idDoc.get("userId")); + String day = Objects.toString(idDoc.get("day"), null); + BigDecimal amount = toBigDecimal(document.get("amount")); + if (userId == null || !hasText(day) || amount == null) { + return null; + } + return new MongoMetric(userId, day, amount); + } + private void collectRetentionActiveDate(Set activeDates, String registerDate, int retentionDays, LocalDate today) { LocalDate targetDate = LocalDate.parse(registerDate, DATE_FORMATTER).plusDays(retentionDays); @@ -572,6 +712,27 @@ public class CountryDashboardDailyMetricService { return result; } + private Map mapUserCountries(List userIds) { + Map result = new LinkedHashMap<>(); + if (userIds == null || userIds.isEmpty()) { + return result; + } + for (int start = 0; start < userIds.size(); start += USER_BATCH_SIZE) { + int end = Math.min(start + USER_BATCH_SIZE, userIds.size()); + List batch = countryDashboardDAO.listUserCountryByIds( + userIds.subList(start, end)); + if (batch == null) { + continue; + } + for (CountryDashboardUserCountryDTO item : batch) { + if (item.getUserId() != null) { + result.put(item.getUserId(), item); + } + } + } + return result; + } + private CountryDashboardDailyMetricDTO getRow(Map rows, CountryDashboardMetricDTO metric, LocalDate statDate, String sysOrigin) { String countryCode = hasText(metric.getCountryCode()) ? metric.getCountryCode() : "UNKNOWN"; @@ -645,7 +806,9 @@ public class CountryDashboardDailyMetricService { LocalDateTime.ofInstant(startInstant, STORAGE_ZONE_ID), LocalDateTime.ofInstant(endInstant, STORAGE_ZONE_ID), startInstant.toEpochMilli(), - endInstant.toEpochMilli()); + endInstant.toEpochMilli(), + startInstant, + endInstant); } private List resolveStatTimezones(String statTimezonesValue) { @@ -737,6 +900,22 @@ public class CountryDashboardDailyMetricService { return Long.valueOf(Objects.toString(value)); } + private static BigDecimal toBigDecimal(Object value) { + if (value == null) { + return BigDecimal.ZERO; + } + if (value instanceof BigDecimal bigDecimal) { + return bigDecimal; + } + if (value instanceof Decimal128 decimal128) { + return decimal128.bigDecimalValue(); + } + if (value instanceof Number number) { + return new BigDecimal(number.toString()); + } + return new BigDecimal(Objects.toString(value, "0")); + } + private static String normalizeCountryCode(Object value) { String countryCode = Objects.toString(value, "").trim(); return countryCode.isEmpty() ? "UNKNOWN" : countryCode; @@ -762,9 +941,12 @@ public class CountryDashboardDailyMetricService { } private record TimeWindow(LocalDateTime startTime, LocalDateTime endTime, - Long startTimeMillis, Long endTimeMillis) { + Long startTimeMillis, Long endTimeMillis, Instant startInstant, Instant endInstant) { } private record RefreshWriteResult(int deleted, int inserted, int userRows) { } + + private record MongoMetric(Long userId, String day, BigDecimal amount) { + } } diff --git a/rc-service/rc-service-console/console-application/src/main/java/com/red/circle/console/app/service/app/datav/CountryDashboardServiceImpl.java b/rc-service/rc-service-console/console-application/src/main/java/com/red/circle/console/app/service/app/datav/CountryDashboardServiceImpl.java index 0202d9c4..adba3488 100644 --- a/rc-service/rc-service-console/console-application/src/main/java/com/red/circle/console/app/service/app/datav/CountryDashboardServiceImpl.java +++ b/rc-service/rc-service-console/console-application/src/main/java/com/red/circle/console/app/service/app/datav/CountryDashboardServiceImpl.java @@ -337,6 +337,7 @@ public class CountryDashboardServiceImpl implements CountryDashboardService { } countryDashboardDAO.createPeriodMetricTable(); countryDashboardDAO.ensurePeriodMetricUserColumnsSchema(); + countryDashboardDAO.ensureMetricValueColumnsSchema(); periodMetricSchemaEnsured = true; } } @@ -374,9 +375,11 @@ public class CountryDashboardServiceImpl implements CountryDashboardService { row.setGoogleRecharge(add(row.getGoogleRecharge(), metric.getGoogleRecharge())); row.setDealerRecharge(add(row.getDealerRecharge(), metric.getDealerRecharge())); row.setSalaryExchange(add(row.getSalaryExchange(), metric.getSalaryExchange())); + row.setGiftConsume(add(row.getGiftConsume(), metric.getGiftConsume())); row.setLuckyGiftTotalFlow(add(row.getLuckyGiftTotalFlow(), metric.getLuckyGiftTotalFlow())); row.setLuckyGiftUser(row.getLuckyGiftUser() + safeLong(metric.getLuckyGiftUser())); row.setLuckyGiftPayout(add(row.getLuckyGiftPayout(), metric.getLuckyGiftPayout())); + row.setLuckyGiftAnchorShare(add(row.getLuckyGiftAnchorShare(), metric.getLuckyGiftAnchorShare())); row.setGameTotalFlow(add(row.getGameTotalFlow(), metric.getGameTotalFlow())); row.setGameUser(row.getGameUser() + safeLong(metric.getGameUser())); row.setGamePayout(add(row.getGamePayout(), metric.getGamePayout())); diff --git a/rc-service/rc-service-console/console-infrastructure/src/main/java/com/red/circle/console/infra/database/rds/dao/datav/CountryDashboardDAO.java b/rc-service/rc-service-console/console-infrastructure/src/main/java/com/red/circle/console/infra/database/rds/dao/datav/CountryDashboardDAO.java index 1e04fac0..b126cb80 100644 --- a/rc-service/rc-service-console/console-infrastructure/src/main/java/com/red/circle/console/infra/database/rds/dao/datav/CountryDashboardDAO.java +++ b/rc-service/rc-service-console/console-infrastructure/src/main/java/com/red/circle/console/infra/database/rds/dao/datav/CountryDashboardDAO.java @@ -36,6 +36,8 @@ public interface CountryDashboardDAO extends BaseDAO { int ensurePeriodMetricUserColumnsSchema(); + int ensureMetricValueColumnsSchema(); + Integer getDashboardBackfillLock( @Param("lockName") String lockName, @Param("timeoutSeconds") Integer timeoutSeconds); diff --git a/rc-service/rc-service-console/console-infrastructure/src/main/java/com/red/circle/console/infra/database/rds/dto/datav/CountryDashboardDailyMetricDTO.java b/rc-service/rc-service-console/console-infrastructure/src/main/java/com/red/circle/console/infra/database/rds/dto/datav/CountryDashboardDailyMetricDTO.java index df124c4c..b789bcc5 100644 --- a/rc-service/rc-service-console/console-infrastructure/src/main/java/com/red/circle/console/infra/database/rds/dto/datav/CountryDashboardDailyMetricDTO.java +++ b/rc-service/rc-service-console/console-infrastructure/src/main/java/com/red/circle/console/infra/database/rds/dto/datav/CountryDashboardDailyMetricDTO.java @@ -36,12 +36,16 @@ public class CountryDashboardDailyMetricDTO { private BigDecimal salaryExchange; + private BigDecimal giftConsume; + private BigDecimal luckyGiftTotalFlow; private Long luckyGiftUser; private BigDecimal luckyGiftPayout; + private BigDecimal luckyGiftAnchorShare; + private BigDecimal gameTotalFlow; private Long gameUser; diff --git a/rc-service/rc-service-console/console-infrastructure/src/main/java/com/red/circle/console/infra/database/rds/dto/datav/CountryDashboardMetricDTO.java b/rc-service/rc-service-console/console-infrastructure/src/main/java/com/red/circle/console/infra/database/rds/dto/datav/CountryDashboardMetricDTO.java index 65652d6e..8a56e47e 100644 --- a/rc-service/rc-service-console/console-infrastructure/src/main/java/com/red/circle/console/infra/database/rds/dto/datav/CountryDashboardMetricDTO.java +++ b/rc-service/rc-service-console/console-infrastructure/src/main/java/com/red/circle/console/infra/database/rds/dto/datav/CountryDashboardMetricDTO.java @@ -35,12 +35,16 @@ public class CountryDashboardMetricDTO { private BigDecimal salaryExchange; + private BigDecimal giftConsume; + private BigDecimal luckyGiftTotalFlow; private Long luckyGiftUser; private BigDecimal luckyGiftPayout; + private BigDecimal luckyGiftAnchorShare; + private BigDecimal gameTotalFlow; private Long gameUser; diff --git a/rc-service/rc-service-console/console-infrastructure/src/main/java/com/red/circle/console/infra/database/rds/dto/datav/CountryDashboardPeriodMetricDTO.java b/rc-service/rc-service-console/console-infrastructure/src/main/java/com/red/circle/console/infra/database/rds/dto/datav/CountryDashboardPeriodMetricDTO.java index 7f272971..cd6d88ed 100644 --- a/rc-service/rc-service-console/console-infrastructure/src/main/java/com/red/circle/console/infra/database/rds/dto/datav/CountryDashboardPeriodMetricDTO.java +++ b/rc-service/rc-service-console/console-infrastructure/src/main/java/com/red/circle/console/infra/database/rds/dto/datav/CountryDashboardPeriodMetricDTO.java @@ -46,12 +46,16 @@ public class CountryDashboardPeriodMetricDTO { private BigDecimal salaryExchange; + private BigDecimal giftConsume; + private BigDecimal luckyGiftTotalFlow; private Long luckyGiftUser; private BigDecimal luckyGiftPayout; + private BigDecimal luckyGiftAnchorShare; + private BigDecimal gameTotalFlow; private Long gameUser; diff --git a/rc-service/rc-service-console/console-infrastructure/src/main/resources/dao/datav/CountryDashboardDAO.xml b/rc-service/rc-service-console/console-infrastructure/src/main/resources/dao/datav/CountryDashboardDAO.xml index 2f6355b4..7fa8e8bf 100644 --- a/rc-service/rc-service-console/console-infrastructure/src/main/resources/dao/datav/CountryDashboardDAO.xml +++ b/rc-service/rc-service-console/console-infrastructure/src/main/resources/dao/datav/CountryDashboardDAO.xml @@ -26,9 +26,11 @@ `google_recharge` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT 'Google充值', `dealer_recharge` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT '代理充值', `salary_exchange` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT '工资兑换', + `gift_consume` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT '礼物消耗', `lucky_gift_total_flow` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT '幸运礼物流水', `lucky_gift_user` bigint NOT NULL DEFAULT 0 COMMENT '幸运礼物用户数', `lucky_gift_payout` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT '幸运礼物返奖', + `lucky_gift_anchor_share` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT '幸运礼物主播分成', `game_total_flow` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT '游戏流水', `game_user` bigint NOT NULL DEFAULT 0 COMMENT '游戏用户数', `game_payout` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT '游戏返奖', @@ -62,9 +64,11 @@ `google_recharge` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT 'Google充值', `dealer_recharge` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT '代理充值', `salary_exchange` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT '工资兑换', + `gift_consume` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT '礼物消耗', `lucky_gift_total_flow` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT '幸运礼物流水', `lucky_gift_user` bigint NOT NULL DEFAULT 0 COMMENT '幸运礼物用户数', `lucky_gift_payout` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT '幸运礼物返奖', + `lucky_gift_anchor_share` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT '幸运礼物主播分成', `game_total_flow` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT '游戏流水', `game_user` bigint NOT NULL DEFAULT 0 COMMENT '游戏用户数', `game_payout` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT '游戏返奖', @@ -573,6 +577,73 @@ DO IF(@country_dashboard_user_columns_schema_lock = 1, RELEASE_LOCK('country_dashboard_period_user_columns_schema'), 0); + + SET @country_dashboard_value_columns_schema_lock = GET_LOCK('country_dashboard_value_columns_schema', 60); + SET @current_schema = DATABASE(); + + SET @ddl = IF( + @country_dashboard_value_columns_schema_lock = 1 + AND NOT EXISTS ( + SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS + WHERE TABLE_SCHEMA = @current_schema + AND TABLE_NAME = 'country_dashboard_daily_metric' + AND COLUMN_NAME = 'gift_consume' + ), + 'ALTER TABLE `country_dashboard_daily_metric` ADD COLUMN `gift_consume` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT ''礼物消耗'' AFTER `salary_exchange`', + 'SELECT 1' + ); + PREPARE stmt FROM @ddl; + EXECUTE stmt; + DEALLOCATE PREPARE stmt; + + SET @ddl = IF( + @country_dashboard_value_columns_schema_lock = 1 + AND NOT EXISTS ( + SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS + WHERE TABLE_SCHEMA = @current_schema + AND TABLE_NAME = 'country_dashboard_daily_metric' + AND COLUMN_NAME = 'lucky_gift_anchor_share' + ), + 'ALTER TABLE `country_dashboard_daily_metric` ADD COLUMN `lucky_gift_anchor_share` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT ''幸运礼物主播分成'' AFTER `lucky_gift_payout`', + 'SELECT 1' + ); + PREPARE stmt FROM @ddl; + EXECUTE stmt; + DEALLOCATE PREPARE stmt; + + SET @ddl = IF( + @country_dashboard_value_columns_schema_lock = 1 + AND NOT EXISTS ( + SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS + WHERE TABLE_SCHEMA = @current_schema + AND TABLE_NAME = 'country_dashboard_period_metric' + AND COLUMN_NAME = 'gift_consume' + ), + 'ALTER TABLE `country_dashboard_period_metric` ADD COLUMN `gift_consume` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT ''礼物消耗'' AFTER `salary_exchange`', + 'SELECT 1' + ); + PREPARE stmt FROM @ddl; + EXECUTE stmt; + DEALLOCATE PREPARE stmt; + + SET @ddl = IF( + @country_dashboard_value_columns_schema_lock = 1 + AND NOT EXISTS ( + SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS + WHERE TABLE_SCHEMA = @current_schema + AND TABLE_NAME = 'country_dashboard_period_metric' + AND COLUMN_NAME = 'lucky_gift_anchor_share' + ), + 'ALTER TABLE `country_dashboard_period_metric` ADD COLUMN `lucky_gift_anchor_share` decimal(20,2) NOT NULL DEFAULT 0.00 COMMENT ''幸运礼物主播分成'' AFTER `lucky_gift_payout`', + 'SELECT 1' + ); + PREPARE stmt FROM @ddl; + EXECUTE stmt; + DEALLOCATE PREPARE stmt; + + DO IF(@country_dashboard_value_columns_schema_lock = 1, RELEASE_LOCK('country_dashboard_value_columns_schema'), 0); + + NULLIF(u.country_code, '') AS countryCode, NULLIF(u.country_name, '') AS countryName @@ -987,9 +1058,11 @@ IFNULL(SUM(t.google_recharge), 0) AS googleRecharge, IFNULL(SUM(t.dealer_recharge), 0) AS dealerRecharge, IFNULL(SUM(t.salary_exchange), 0) AS salaryExchange, + IFNULL(SUM(t.gift_consume), 0) AS giftConsume, IFNULL(SUM(t.lucky_gift_total_flow), 0) AS luckyGiftTotalFlow, IFNULL(SUM(t.lucky_gift_user), 0) AS luckyGiftUser, IFNULL(SUM(t.lucky_gift_payout), 0) AS luckyGiftPayout, + IFNULL(SUM(t.lucky_gift_anchor_share), 0) AS luckyGiftAnchorShare, IFNULL(SUM(t.game_total_flow), 0) AS gameTotalFlow, IFNULL(SUM(t.game_user), 0) AS gameUser, IFNULL(SUM(t.game_payout), 0) AS gamePayout @@ -1043,9 +1116,11 @@ IFNULL(SUM(t.google_recharge), 0) AS googleRecharge, IFNULL(SUM(t.dealer_recharge), 0) AS dealerRecharge, IFNULL(SUM(t.salary_exchange), 0) AS salaryExchange, + IFNULL(SUM(t.gift_consume), 0) AS giftConsume, IFNULL(SUM(t.lucky_gift_total_flow), 0) AS luckyGiftTotalFlow, IFNULL(SUM(t.lucky_gift_user), 0) AS luckyGiftUser, IFNULL(SUM(t.lucky_gift_payout), 0) AS luckyGiftPayout, + IFNULL(SUM(t.lucky_gift_anchor_share), 0) AS luckyGiftAnchorShare, IFNULL(SUM(t.game_total_flow), 0) AS gameTotalFlow, IFNULL(SUM(t.game_user), 0) AS gameUser, IFNULL(SUM(t.game_payout), 0) AS gamePayout, @@ -1125,9 +1200,11 @@ google_recharge, dealer_recharge, salary_exchange, + gift_consume, lucky_gift_total_flow, lucky_gift_user, lucky_gift_payout, + lucky_gift_anchor_share, game_total_flow, game_user, game_payout, @@ -1148,9 +1225,11 @@ IFNULL(#{item.googleRecharge}, 0), IFNULL(#{item.dealerRecharge}, 0), IFNULL(#{item.salaryExchange}, 0), + IFNULL(#{item.giftConsume}, 0), IFNULL(#{item.luckyGiftTotalFlow}, 0), IFNULL(#{item.luckyGiftUser}, 0), IFNULL(#{item.luckyGiftPayout}, 0), + IFNULL(#{item.luckyGiftAnchorShare}, 0), IFNULL(#{item.gameTotalFlow}, 0), IFNULL(#{item.gameUser}, 0), IFNULL(#{item.gamePayout}, 0), @@ -1166,9 +1245,11 @@ google_recharge = VALUES(google_recharge), dealer_recharge = VALUES(dealer_recharge), salary_exchange = VALUES(salary_exchange), + gift_consume = VALUES(gift_consume), lucky_gift_total_flow = VALUES(lucky_gift_total_flow), lucky_gift_user = VALUES(lucky_gift_user), lucky_gift_payout = VALUES(lucky_gift_payout), + lucky_gift_anchor_share = VALUES(lucky_gift_anchor_share), game_total_flow = VALUES(game_total_flow), game_user = VALUES(game_user), game_payout = VALUES(game_payout), @@ -1204,9 +1285,11 @@ google_recharge, dealer_recharge, salary_exchange, + gift_consume, lucky_gift_total_flow, lucky_gift_user, lucky_gift_payout, + lucky_gift_anchor_share, game_total_flow, game_user, game_payout, @@ -1238,9 +1321,11 @@ IFNULL(#{item.googleRecharge}, 0), IFNULL(#{item.dealerRecharge}, 0), IFNULL(#{item.salaryExchange}, 0), + IFNULL(#{item.giftConsume}, 0), IFNULL(#{item.luckyGiftTotalFlow}, 0), IFNULL(#{item.luckyGiftUser}, 0), IFNULL(#{item.luckyGiftPayout}, 0), + IFNULL(#{item.luckyGiftAnchorShare}, 0), IFNULL(#{item.gameTotalFlow}, 0), IFNULL(#{item.gameUser}, 0), IFNULL(#{item.gamePayout}, 0), @@ -1266,9 +1351,11 @@ google_recharge = VALUES(google_recharge), dealer_recharge = VALUES(dealer_recharge), salary_exchange = VALUES(salary_exchange), + gift_consume = VALUES(gift_consume), lucky_gift_total_flow = VALUES(lucky_gift_total_flow), lucky_gift_user = VALUES(lucky_gift_user), lucky_gift_payout = VALUES(lucky_gift_payout), + lucky_gift_anchor_share = VALUES(lucky_gift_anchor_share), game_total_flow = VALUES(game_total_flow), game_user = VALUES(game_user), game_payout = VALUES(game_payout), @@ -1479,8 +1566,10 @@ IFNULL(SUM(t.google_recharge), 0) AS googleRecharge, IFNULL(SUM(t.dealer_recharge), 0) AS dealerRecharge, IFNULL(SUM(t.salary_exchange), 0) AS salaryExchange, + IFNULL(SUM(t.gift_consume), 0) AS giftConsume, IFNULL(SUM(t.lucky_gift_total_flow), 0) AS luckyGiftTotalFlow, IFNULL(SUM(t.lucky_gift_payout), 0) AS luckyGiftPayout, + IFNULL(SUM(t.lucky_gift_anchor_share), 0) AS luckyGiftAnchorShare, IFNULL(SUM(t.game_total_flow), 0) AS gameTotalFlow, IFNULL(SUM(t.game_payout), 0) AS gamePayout, IFNULL(SUM(t.d1_retention_user), 0) AS d1RetentionUser,