재화 통계

This commit is contained in:
2025-11-24 17:44:30 +09:00
parent aa120b8927
commit 6c110212f6
6 changed files with 229 additions and 37 deletions

View File

@@ -0,0 +1,111 @@
package com.caliverse.admin.Indicators.Indicatorsservice.aggregationservice;
import com.caliverse.admin.Indicators.Indicatordomain.IndicatorsLog;
import com.caliverse.admin.Indicators.Indicatorsservice.base.IndicatorsLogLoadServiceBase;
import com.caliverse.admin.global.common.constants.AdminConstants;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
@Service
public class IndicatorsCurrencyStatsLoadService extends IndicatorsLogLoadServiceBase {
public IndicatorsCurrencyStatsLoadService(
@Qualifier("mongoIndicatorTemplate") MongoTemplate mongoTemplate
) {
super(mongoTemplate);
}
@Override
public <T extends IndicatorsLog> List<T> getIndicatorsLogData(String startTime, String endTime, Class<T> clazz) {
Criteria criteria = makeCriteria(startTime, endTime, "logDay");
GroupOperation groupOperation = Aggregation.group("logDay")
.sum("gold").as("gold")
.sum("sapphire").as("sapphire")
.sum("calium").as("calium")
.sum("ruby").as("ruby");
AggregationOperation lookupOp = context -> new Document("$lookup", new Document()
.append("from", "currency")
.append("let", new Document("currentLogDay", "$_id"))
.append("pipeline", Arrays.asList(
new Document("$match", new Document("$expr", new Document("$and", Arrays.asList(
new Document("$eq", Arrays.asList("$logDay", "$$currentLogDay")),
new Document("$gte", Arrays.asList("$logDay", "2025-05-01")),
new Document("$lte", Arrays.asList("$logDay", "2025-06-31"))
)))),
new Document("$group", new Document()
.append("_id", "$logDay")
.append("sapphireAcquired", new Document("$sum", "$sapphireAcquired"))
.append("sapphireConsumed", new Document("$sum", "$sapphireConsumed"))
.append("goldAcquired", new Document("$sum", "$goldAcquired"))
.append("goldConsumed", new Document("$sum", "$goldConsumed"))
.append("caliumAcquired", new Document("$sum", "$caliumAcquired"))
.append("caliumConsumed", new Document("$sum", "$caliumConsumed"))
.append("rubyAcquired", new Document("$sum", "$rubyAcquired"))
.append("rubyConsumed", new Document("$sum", "$rubyConsumed"))
),
new Document("$project", new Document()
.append("_id", 0)
.append("sapphireAcquired", 1)
.append("sapphireConsumed", 1)
.append("goldAcquired", 1)
.append("goldConsumed", 1)
.append("caliumAcquired", 1)
.append("caliumConsumed", 1)
.append("rubyAcquired", 1)
.append("rubyConsumed", 1)
)
))
.append("as", "currencyData")
);
AddFieldsOperation addFieldsOp = Aggregation.addFields()
.addField("currencyData")
.withValue(ArrayOperators.ArrayElemAt.arrayOf("currencyData").elementAt(0))
.build();
ProjectionOperation projection = Aggregation.project()
.andExclude("_id")
.and("_id").as("logDay")
.and("sapphire").as("sapphire")
.and("ruby").as("ruby")
.and("gold").as("gold")
.and("calium").as("calium")
.and(ConditionalOperators.ifNull("currencyData.sapphireAcquired").then(0)).as("sapphireAcquired")
.and(ConditionalOperators.ifNull("currencyData.sapphireConsumed").then(0)).as("sapphireConsumed")
.and(ConditionalOperators.ifNull("currencyData.goldAcquired").then(0)).as("goldAcquired")
.and(ConditionalOperators.ifNull("currencyData.goldConsumed").then(0)).as("goldConsumed")
.and(ConditionalOperators.ifNull("currencyData.caliumAcquired").then(0)).as("caliumAcquired")
.and(ConditionalOperators.ifNull("currencyData.caliumConsumed").then(0)).as("caliumConsumed")
.and(ConditionalOperators.ifNull("currencyData.rubyAcquired").then(0)).as("rubyAcquired")
.and(ConditionalOperators.ifNull("currencyData.rubyConsumed").then(0)).as("rubyConsumed");
List<AggregationOperation> operations = List.of(
Aggregation.match(criteria),
groupOperation,
lookupOp,
addFieldsOp,
projection,
Aggregation.sort(Sort.Direction.ASC, AdminConstants.MONGO_DB_KEY_LOGDAY)
);
Aggregation aggregation = Aggregation.newAggregation(operations);
return mongoTemplate.aggregate(
aggregation.withOptions(AggregationOptions.builder().allowDiskUse(true).build())
, AdminConstants.MONGO_DB_COLLECTION_ASSETS
, clazz
).getMappedResults();
}
}

View File

@@ -0,0 +1,54 @@
package com.caliverse.admin.Indicators.entity;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class CurrencyStatsInfo extends LogInfoBase{
private String logDay;
private Double sapphire;
private Double ruby;
private Double gold;
private Double calium;
private Double sapphireAcquired;
private Double sapphireConsumed;
private Double goldAcquired;
private Double goldConsumed;
private Double caliumAcquired;
private Double caliumConsumed;
private Double rubyAcquired;
private Double rubyConsumed;
public CurrencyStatsInfo(String logDay,
Double sapphire,
Double ruby,
Double gold,
Double calium,
Double sapphireAcquired,
Double sapphireConsumed,
Double goldAcquired,
Double goldConsumed,
Double caliumAcquired,
Double caliumConsumed,
Double rubyAcquired,
Double rubyConsumed
) {
super(StatisticsType.SNAPSHOT);
this.logDay = logDay;
this.sapphire = sapphire;
this.ruby = ruby;
this.gold = gold;
this.calium = calium;
this.sapphireAcquired = sapphireAcquired;
this.sapphireConsumed = sapphireConsumed;
this.goldAcquired = goldAcquired;
this.goldConsumed = goldConsumed;
this.caliumAcquired = caliumAcquired;
this.caliumConsumed = caliumConsumed;
this.rubyAcquired = rubyAcquired;
this.rubyConsumed = rubyConsumed;
}
}

View File

@@ -70,6 +70,13 @@ public class IndicatorsController {
return ResponseEntity.ok().body( indicatorsService.getAssetsList(requestParams));
}
// 통계 지표
@GetMapping("/currency/stats/list")
public ResponseEntity<IndicatorsResponse> currencyStats(
@RequestParam Map<String, String> requestParams){
return ResponseEntity.ok().body( indicatorsService.currencyStatsList(requestParams));
}
// 인스턴스 지표
@GetMapping("/currency/instance")
public ResponseEntity<IndicatorsResponse> instance(

View File

@@ -1,9 +1,6 @@
package com.caliverse.admin.domain.response;
import com.caliverse.admin.Indicators.entity.AssetsIndicatorInfo;
import com.caliverse.admin.Indicators.entity.CurrencyIndicatorInfo;
import com.caliverse.admin.Indicators.entity.DauLogInfo;
import com.caliverse.admin.Indicators.entity.ItemIndicatorInfo;
import com.caliverse.admin.Indicators.entity.*;
import com.caliverse.admin.domain.entity.Currencys;
import com.caliverse.admin.domain.entity.Distinct;
import com.fasterxml.jackson.annotation.JsonInclude;
@@ -49,6 +46,8 @@ public class IndicatorsResponse {
private List<Retention> retentionList;
@JsonProperty("currency_list")
private List<CurrencyIndicatorInfo> currencyList;
@JsonProperty("currency_stats_list")
private List<CurrencyStatsInfo> currencyStatsList;
@JsonProperty("item_list")
private List<ItemIndicatorInfo> itemList;
@JsonProperty("assets_list")

View File

@@ -50,6 +50,7 @@ public class IndicatorsService {
private final IndicatorsCurrencyLoadService indicatorsCurrencyLoadService;
private final IndicatorsItemLoadService indicatorsItemLoadService;
private final IndicatorsAssetsLoadService indicatorsAssetsLoadService;
private final IndicatorsCurrencyStatsLoadService indicatorsCurrencyStatsLoadService;
private final IndicatorsDauService dauService;
private final IndicatorsNruService indicatorsNruService;
@@ -309,6 +310,26 @@ public class IndicatorsService {
}
// 재화 통계 지표
@RequestLog
public IndicatorsResponse currencyStatsList(Map<String, String> requestParams){
LocalDateTime startDt = DateUtils.stringISOToLocalDateTime(requestParams.get("start_dt"));
LocalDateTime endDt = DateUtils.stringISOToLocalDateTime(requestParams.get("end_dt"));
List<CurrencyStatsInfo> currencyList = indicatorsCurrencyStatsLoadService.getIndicatorsLogData(
startDt.toString().substring(0, 10),
endDt.toString().substring(0, 10),
CurrencyStatsInfo.class);
return IndicatorsResponse.builder()
.resultData(IndicatorsResponse.ResultData.builder()
.currencyStatsList(currencyList)
.build())
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.build();
}
public List<IndicatorsResponse.DailyGoods> getDailyGoodsList(String currencyType, List<Currencys> dailyList
, List<Currencys> totalList){
List<IndicatorsResponse.DailyGoods> resList = dailyList.stream()

View File

@@ -56,17 +56,18 @@ public class OneTimeSchedule implements CommandLineRunner {
log.info("=== OneTimeSchedule starting ===");
try{
LocalDate startDate = LocalDate.of(2024, 8, 28);
// LocalDate startDate = LocalDate.of(2025, 7, 1);
// LocalDate currentDate = LocalDate.of(2025, 5, 1);
LocalDate currentDate = LocalDate.now();
// LocalDate startDate = LocalDate.of(2024, 8, 28);
LocalDate startDate = LocalDate.of(2025, 8, 26);
LocalDate currentDate = LocalDate.of(2025, 8, 27);
// LocalDate currentDate = LocalDate.now();
//
log.info("Processing dates from {} to {}", startDate, currentDate);
LocalDate processDate = startDate;
int processedDates = 0;
migrationService.migrationHistory();
//마이그레이션
// migrationService.migrationHistory();
// while (!processDate.isAfter(currentDate)) {
// LocalDate chunkEndDate = processDate.plusDays(chunkSize - 1);
@@ -106,7 +107,7 @@ public class OneTimeSchedule implements CommandLineRunner {
//
// log.info("Date: {}, StartTime: {}, EndTime: {}", date, dayStartEndTime.getStartTime(), dayStartEndTime.getEndTime());
//
// snapshotService.collectSnapshot(dayStartEndTime.getStartTime(), dayStartEndTime.getEndTime());
//// snapshotService.collectSnapshot(dayStartEndTime.getStartTime(), dayStartEndTime.getEndTime());
//// itemService.collectItem(dayStartEndTime.getStartTime(), dayStartEndTime.getEndTime());
//// userCreateService.collectUserCreate(dayStartEndTime.getStartTime(), dayStartEndTime.getEndTime());
//// userLoginService.collectUserLogin(dayStartEndTime.getStartTime(), dayStartEndTime.getEndTime());
@@ -139,15 +140,32 @@ public class OneTimeSchedule implements CommandLineRunner {
log.info("Date: {}, StartTime: {}, EndTime: {}", date, dayStartEndTime.getStartTime(), dayStartEndTime.getEndTime());
// 1. 가장 부하가 적은 서비스부터 실행
// 아이템 DW
executeWithDelay(() -> {
try {
itemService.collectItem(dayStartEndTime.getStartTime(), dayStartEndTime.getEndTime());
} catch (Exception e) {
log.error("Error in itemService for date: {}", date, e);
}
}, "itemService");
// executeWithDelay(() -> {
// try {
// itemService.collectItem(dayStartEndTime.getStartTime(), dayStartEndTime.getEndTime());
// } catch (Exception e) {
// log.error("Error in itemService for date: {}", date, e);
// }
// }, "itemService");
//
// // 유저 생성 DW
// executeWithDelay(() -> {
// try {
// userCreateService.collectUserCreate(dayStartEndTime.getStartTime(), dayStartEndTime.getEndTime());
// } catch (Exception e) {
// log.error("Error in userCreateService for date: {}", date, e);
// }
// }, "userCreateService");
//
// // 유저 로그인 DW
// executeWithDelay(() -> {
// try {
// userLoginService.collectUserLogin(dayStartEndTime.getStartTime(), dayStartEndTime.getEndTime());
// } catch (Exception e) {
// log.error("Error in userLoginService for date: {}", date, e);
// }
// }, "userLoginService");
// 자산 DW
executeWithDelay(() -> {
@@ -158,24 +176,6 @@ public class OneTimeSchedule implements CommandLineRunner {
}
}, "snapshotService");
// 유저 생성 DW
executeWithDelay(() -> {
try {
userCreateService.collectUserCreate(dayStartEndTime.getStartTime(), dayStartEndTime.getEndTime());
} catch (Exception e) {
log.error("Error in userCreateService for date: {}", date, e);
}
}, "userCreateService");
// 유저 로그인 DW
executeWithDelay(() -> {
try {
userLoginService.collectUserLogin(dayStartEndTime.getStartTime(), dayStartEndTime.getEndTime());
} catch (Exception e) {
log.error("Error in userLoginService for date: {}", date, e);
}
}, "userLoginService");
// 재화 DW
// executeWithDelay(() -> {
// try {