fix: complete country dashboard derived metrics
This commit is contained in:
parent
4112160656
commit
74fd42330e
@ -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<CountryDashboardDailyMetricDTO> 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<String, CountryDashboardDailyMetricDTO> rows,
|
||||
List<MongoMetric> metrics, BiConsumer<CountryDashboardDailyMetricDTO, BigDecimal> merger,
|
||||
LocalDate statDate, String sysOrigin) {
|
||||
if (metrics == null || metrics.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Map<Long, CountryDashboardUserCountryDTO> 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<String, CountryDashboardPeriodMetricDTO> rows,
|
||||
List<MongoMetric> metrics, BiConsumer<CountryDashboardPeriodMetricDTO, BigDecimal> merger,
|
||||
PeriodWindow window, String sysOrigin, StatTimezone statTimezone) {
|
||||
if (metrics == null || metrics.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Map<Long, CountryDashboardUserCountryDTO> 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<String, CountryDashboardPeriodMetricDTO> 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<String, CountryDashboardPeriodMetricDTO> rows,
|
||||
PeriodWindow window, String sysOrigin, StatTimezone statTimezone, LocalDateTime cohortStartTime,
|
||||
LocalDateTime cohortEndTime, int retentionDays) {
|
||||
List<CountryDashboardRetentionUserDTO> 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<String> 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<MongoMetric> listGiftConsume(TimeWindow timeWindow, String sysOrigin,
|
||||
String statTimezone) {
|
||||
List<Criteria> 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<MongoMetric> listLuckyGiftAnchorShare(TimeWindow timeWindow, String sysOrigin,
|
||||
String statTimezone) {
|
||||
List<Criteria> criteria = baseGiftCriteria(timeWindow, sysOrigin);
|
||||
criteria.add(Criteria.where("luckyGift").is(Boolean.TRUE));
|
||||
return aggregateGiftAmount(criteria, "$acceptUsers.targetAmount", true, statTimezone);
|
||||
}
|
||||
|
||||
private List<Criteria> baseGiftCriteria(TimeWindow timeWindow, String sysOrigin) {
|
||||
List<Criteria> 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<MongoMetric> aggregateGiftAmount(List<Criteria> criteria, String amountPath,
|
||||
boolean unwindAcceptUsers, String statTimezone) {
|
||||
List<AggregationOperation> 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<String> 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<Long, CountryDashboardUserCountryDTO> mapUserCountries(List<Long> userIds) {
|
||||
Map<Long, CountryDashboardUserCountryDTO> 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<CountryDashboardUserCountryDTO> 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<String, CountryDashboardDailyMetricDTO> 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<StatTimezone> 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) {
|
||||
}
|
||||
}
|
||||
|
||||
@ -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()));
|
||||
|
||||
@ -36,6 +36,8 @@ public interface CountryDashboardDAO extends BaseDAO<IUserBaseInfo> {
|
||||
|
||||
int ensurePeriodMetricUserColumnsSchema();
|
||||
|
||||
int ensureMetricValueColumnsSchema();
|
||||
|
||||
Integer getDashboardBackfillLock(
|
||||
@Param("lockName") String lockName,
|
||||
@Param("timeoutSeconds") Integer timeoutSeconds);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
</update>
|
||||
|
||||
<update id="ensureMetricValueColumnsSchema">
|
||||
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);
|
||||
</update>
|
||||
|
||||
<sql id="CountryColumns">
|
||||
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,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user