|
@@ -0,0 +1,131 @@
|
|
|
+package com.pig4cloud.pig.statistics.api.dto.retention;
|
|
|
+
|
|
|
+
|
|
|
+import io.swagger.v3.oas.annotations.media.Schema;
|
|
|
+import jakarta.validation.constraints.AssertTrue;
|
|
|
+import jakarta.validation.constraints.NotBlank;
|
|
|
+import jakarta.validation.constraints.NotNull;
|
|
|
+import lombok.Data;
|
|
|
+
|
|
|
+import java.io.Serial;
|
|
|
+import java.io.Serializable;
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.temporal.ChronoUnit;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author: lwh
|
|
|
+ * @date: 2025-08-25
|
|
|
+ * @description: 留存分析分页查询条件
|
|
|
+ */
|
|
|
+@Data
|
|
|
+public class PageQueryRetentionDTO implements Serializable {
|
|
|
+
|
|
|
+ @Serial
|
|
|
+ private static final long serialVersionUID = 1L;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 应用ID
|
|
|
+ */
|
|
|
+ @NotBlank(message = "应用ID不能为空")
|
|
|
+ @Schema(description = "应用ID", example = "Fqs2CL9CUn7U1AqilSFXgb")
|
|
|
+ private String appId;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 渠道
|
|
|
+ */
|
|
|
+ @Schema(description = "渠道", example = "[\"App Store\"]")
|
|
|
+ private List<String> channel;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 开始时间
|
|
|
+ */
|
|
|
+ @NotNull(message = "开始时间不能为空")
|
|
|
+ @Schema(description = "开始时间", example = "2025-07-29")
|
|
|
+ private LocalDate fromDate;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 结束时间
|
|
|
+ */
|
|
|
+ @NotNull(message = "结束时间不能为空")
|
|
|
+ @Schema(description = "结束时间", example = "2025-08-05")
|
|
|
+ private LocalDate toDate;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 时间单位
|
|
|
+ */
|
|
|
+ @NotBlank(message = "时间单位不能为空")
|
|
|
+ @Schema(description = "时间单位,day-天,week-周,month-月", example = "day")
|
|
|
+ private String timeUnit;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 版本
|
|
|
+ */
|
|
|
+ @Schema(description = "版本", example = "[\"1.0.0\"]")
|
|
|
+ private List<String> version;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 类型
|
|
|
+ */
|
|
|
+ @NotBlank(message = "类型不能为空")
|
|
|
+ @Schema(description = "类型,newUser-新用户,activeUser-活跃用户", example = "newUser")
|
|
|
+ private String type;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 每页显示条数,默认 10
|
|
|
+ */
|
|
|
+ @Schema(description = "每页显示条数", example = "10")
|
|
|
+ private long size = 10;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 当前页
|
|
|
+ */
|
|
|
+ @Schema(description = "当前页",example = "1")
|
|
|
+ private long current = 1;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 校验规则1:fromDate不能大于toDate,只能小于等于
|
|
|
+ */
|
|
|
+ @Schema(hidden = true)
|
|
|
+ @AssertTrue(message = "开始时间不能晚于结束时间")
|
|
|
+ public boolean isFromDateLessThanOrEqualToToDate() {
|
|
|
+ if (fromDate == null || toDate == null) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return !fromDate.isAfter(toDate);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 校验规则2:如果timeUnit为week,则跨度不能小于一周
|
|
|
+ */
|
|
|
+ @Schema(hidden = true)
|
|
|
+ @AssertTrue(message = "周维度查询时间跨度不能小于7天")
|
|
|
+ public boolean isWeekTimeUnitAtLeastOneWeek() {
|
|
|
+ if (fromDate == null || toDate == null || timeUnit == null) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if ("week".equals(timeUnit)) {
|
|
|
+ long days = ChronoUnit.DAYS.between(fromDate, toDate);
|
|
|
+ return days >= 7;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 校验规则3:月维度查询时间跨度不能小于30天
|
|
|
+ */
|
|
|
+ @Schema(hidden = true)
|
|
|
+ @AssertTrue(message = "月维度查询时间跨度不能小于30天")
|
|
|
+ public boolean isMonthTimeUnitAtLeastMonth() {
|
|
|
+ if (fromDate == null || toDate == null || timeUnit == null) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if ("month".equals(timeUnit)) {
|
|
|
+ long days = ChronoUnit.DAYS.between(fromDate, toDate);
|
|
|
+ return days >= 30;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+}
|