|
|
@@ -105,33 +105,59 @@ public class AnalyticsService {
|
|
|
|
|
|
// ==================== 概览数字 ====================
|
|
|
|
|
|
- public Map<String, Object> queryOverview(String range) {
|
|
|
- String today = LocalDate.now().toString();
|
|
|
- Instant todayStart = parseDate(today);
|
|
|
- Instant todayEnd = LocalDate.parse(today).plusDays(1).atStartOfDay(ZoneOffset.UTC).toInstant();
|
|
|
+ /**
|
|
|
+ * 统计概览
|
|
|
+ * @param range today | yesterday | week | total | custom
|
|
|
+ * @param startDate custom 的起始日期(yyyy-MM-dd),仅 range=custom 时生效
|
|
|
+ * @param endDate custom 的结束日期(yyyy-MM-dd),仅 range=custom 时生效
|
|
|
+ */
|
|
|
+ public Map<String, Object> queryOverview(String range, String startDate, String endDate) {
|
|
|
+ if (range == null || range.isBlank()) {
|
|
|
+ range = "total";
|
|
|
+ }
|
|
|
+ Instant todayStart = parseDate(LocalDate.now().toString());
|
|
|
+ Instant todayEnd = LocalDate.now().plusDays(1).atStartOfDay(ZoneOffset.UTC).toInstant();
|
|
|
|
|
|
Instant startTime;
|
|
|
Instant endTime;
|
|
|
String label;
|
|
|
|
|
|
- if ("today".equals(range)) {
|
|
|
- startTime = todayStart;
|
|
|
- endTime = todayEnd;
|
|
|
- label = "today";
|
|
|
- } else if ("week".equals(range)) {
|
|
|
- startTime = todayStart.minus(6, java.time.temporal.ChronoUnit.DAYS);
|
|
|
- endTime = todayEnd;
|
|
|
- label = "week";
|
|
|
- } else {
|
|
|
- startTime = Instant.EPOCH;
|
|
|
- endTime = FAR_FUTURE;
|
|
|
- label = "total";
|
|
|
+ switch (range) {
|
|
|
+ case "today":
|
|
|
+ startTime = todayStart;
|
|
|
+ endTime = todayEnd;
|
|
|
+ label = "today";
|
|
|
+ break;
|
|
|
+ case "yesterday":
|
|
|
+ startTime = todayStart.minus(1, java.time.temporal.ChronoUnit.DAYS);
|
|
|
+ endTime = todayStart;
|
|
|
+ label = "yesterday";
|
|
|
+ break;
|
|
|
+ case "week":
|
|
|
+ startTime = todayStart.minus(6, java.time.temporal.ChronoUnit.DAYS);
|
|
|
+ endTime = todayEnd;
|
|
|
+ label = "week";
|
|
|
+ break;
|
|
|
+ case "custom":
|
|
|
+ Instant customStart = startDate != null ? parseDate(startDate) : Instant.EPOCH;
|
|
|
+ Instant customEnd = endDate != null
|
|
|
+ ? LocalDate.parse(endDate).plusDays(1).atStartOfDay(ZoneOffset.UTC).toInstant()
|
|
|
+ : FAR_FUTURE;
|
|
|
+ startTime = customStart != null ? customStart : Instant.EPOCH;
|
|
|
+ endTime = customEnd;
|
|
|
+ label = "custom";
|
|
|
+ break;
|
|
|
+ default: // "total"
|
|
|
+ startTime = Instant.EPOCH;
|
|
|
+ endTime = FAR_FUTURE;
|
|
|
+ label = "total";
|
|
|
}
|
|
|
|
|
|
Map<String, Object> overview = new LinkedHashMap<>();
|
|
|
overview.put("range", label);
|
|
|
overview.put("total_events", repo.countTotal(startTime, endTime));
|
|
|
overview.put("active_users", repo.countDistinctUsers(startTime, endTime));
|
|
|
+ overview.put("unique_ips", repo.countDistinctIps(startTime, endTime));
|
|
|
overview.put("page_views", repo.countByType("page_view", startTime, endTime));
|
|
|
overview.put("searches", repo.countByType("search", startTime, endTime));
|
|
|
overview.put("ai_qa", repo.countByType("chat", startTime, endTime));
|