Browse Source

new: 留存用户接口定义

lwh 3 weeks ago
parent
commit
0d135b6cd2

+ 118 - 0
pig-statistics/pig-statistics-api/src/main/java/com/pig4cloud/pig/statistics/api/dto/retention/GetRetentionTrendDTO.java

@@ -0,0 +1,118 @@
+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
+@Schema(description = "查询留存趋势入参")
+public class GetRetentionTrendDTO 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;
+
+	/**
+	 * 校验规则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;
+	}
+}

+ 131 - 0
pig-statistics/pig-statistics-api/src/main/java/com/pig4cloud/pig/statistics/api/dto/retention/PageQueryRetentionDTO.java

@@ -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;
+	}
+}

+ 33 - 0
pig-statistics/pig-statistics-api/src/main/java/com/pig4cloud/pig/statistics/api/vo/retention/GetRetentionTrendVO.java

@@ -0,0 +1,33 @@
+package com.pig4cloud.pig.statistics.api.vo.retention;
+
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author: lwh
+ * @date: 2025-08-25
+ * @description: 查询留存趋势出参
+ */
+@Data
+@Schema(description = "查询留存趋势出参")
+public class GetRetentionTrendVO implements Serializable {
+
+	@Serial
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 日期
+	 */
+	@Schema(description = "日期")
+	private List<String> dates;
+
+	/**
+	 * 留存数据列表
+	 */
+	private List<RetentionTrendItemsVO> items;
+}

+ 47 - 0
pig-statistics/pig-statistics-api/src/main/java/com/pig4cloud/pig/statistics/api/vo/retention/PageQueryRetentionVO.java

@@ -0,0 +1,47 @@
+package com.pig4cloud.pig.statistics.api.vo.retention;
+
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * @author: lwh
+ * @date: 2025-08-25
+ * @description: TODO
+ */
+
+@Data
+@Schema(description = "分页查询留存用户详情出参")
+public class PageQueryRetentionVO implements Serializable {
+	@Serial
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 日期
+	 */
+	@Schema(description = "日期")
+	private String date;
+
+	/**
+	 * 新增用户数
+	 */
+	@Schema(description = "新增用户数,type=newUser时存在")
+	private Integer newUser;
+
+	/**
+	 * 活跃用户数
+	 */
+	@Schema(description = "活跃用户数,type=activeUser时存在")
+	private Integer activeUser;
+
+	/**
+	 * 留存率
+	 */
+	@Schema(description = "留存率")
+	private List<BigDecimal> retention;
+}

+ 37 - 0
pig-statistics/pig-statistics-api/src/main/java/com/pig4cloud/pig/statistics/api/vo/retention/RetentionTrendItemsVO.java

@@ -0,0 +1,37 @@
+package com.pig4cloud.pig.statistics.api.vo.retention;
+
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * @author: lwh
+ * @date: 2025-08-25
+ * @description: TODO
+ */
+
+@Data
+@Schema(description = "留存趋势详情")
+public class RetentionTrendItemsVO {
+
+	/**
+	 * 数据值
+	 */
+	@Schema(description = "数据值")
+	private List<BigDecimal> data;
+
+	/**
+	 * 数据名称
+	 */
+	@Schema(description = "数据名称")
+	private String name;
+
+	/**
+	 * 数据key
+	 */
+	@Schema(description = "数据key")
+	private String key;
+}

+ 31 - 0
pig-statistics/pig-statistics-biz/src/main/java/com/pig4cloud/pig/statistics/controller/RetentionAnalyseController.java

@@ -1,11 +1,21 @@
 package com.pig4cloud.pig.statistics.controller;
 
 
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.pig4cloud.pig.common.core.util.R;
+import com.pig4cloud.pig.statistics.api.dto.retention.GetRetentionTrendDTO;
+import com.pig4cloud.pig.statistics.api.dto.retention.PageQueryRetentionDTO;
+import com.pig4cloud.pig.statistics.api.vo.retention.GetRetentionTrendVO;
+import com.pig4cloud.pig.statistics.api.vo.retention.PageQueryRetentionVO;
 import com.pig4cloud.pig.statistics.service.RetentionAnalyseService;
+import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.security.SecurityRequirement;
 import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
 import lombok.AllArgsConstructor;
 import org.springframework.http.HttpHeaders;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
@@ -22,4 +32,25 @@ import org.springframework.web.bind.annotation.RestController;
 public class RetentionAnalyseController
 {
 	private final RetentionAnalyseService retentionAnalyseService;
+
+/***************************************** 留存用户 *****************************************/
+
+	@PostMapping("/view")
+	@Operation(summary = "分页查询留存详情")
+	public R<Page<PageQueryRetentionVO>> pageRetentionDetail(@Valid @RequestBody PageQueryRetentionDTO reqDto) {
+		Page<PageQueryRetentionVO> page = retentionAnalyseService.pageRetentionDetail(reqDto);
+		return R.ok(page);
+	}
+
+	@PostMapping("/trend")
+	@Operation(summary = "查询留存趋势")
+	public R<GetRetentionTrendVO> getRetentionTrend(@Valid @RequestBody GetRetentionTrendDTO reqDto) {
+		return R.ok();
+	}
+
+	@PostMapping("/view/export")
+	@Operation(summary = "导出留存详情")
+	public R exportRetentionDetail(@Valid @RequestBody GetRetentionTrendDTO reqDto) {
+		return R.ok();
+	}
 }

+ 12 - 0
pig-statistics/pig-statistics-biz/src/main/java/com/pig4cloud/pig/statistics/service/RetentionAnalyseService.java

@@ -1,6 +1,11 @@
 package com.pig4cloud.pig.statistics.service;
 
 
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.pig4cloud.pig.statistics.api.dto.retention.PageQueryRetentionDTO;
+import com.pig4cloud.pig.statistics.api.vo.retention.PageQueryRetentionVO;
+import jakarta.validation.Valid;
+
 /**
  * @author: lwh
  * @date: 2025-08-22
@@ -8,4 +13,11 @@ package com.pig4cloud.pig.statistics.service;
  */
 
 public interface RetentionAnalyseService {
+
+	/**
+	 * 分页查询留存详情
+	 * @param reqDto 分页参数
+	 * @return 分页数据
+	 */
+	Page<PageQueryRetentionVO> pageRetentionDetail(@Valid PageQueryRetentionDTO reqDto);
 }

+ 18 - 0
pig-statistics/pig-statistics-biz/src/main/java/com/pig4cloud/pig/statistics/service/impl/RetentionAnalyseServiceImpl.java

@@ -1,6 +1,11 @@
 package com.pig4cloud.pig.statistics.service.impl;
 
 
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.pig4cloud.pig.statistics.api.dto.retention.PageQueryRetentionDTO;
+import com.pig4cloud.pig.statistics.api.vo.retention.PageQueryRetentionVO;
+import com.pig4cloud.pig.statistics.mapper.MktStatActiveUserMapper;
+import com.pig4cloud.pig.statistics.mapper.MktStatNewUserMapper;
 import com.pig4cloud.pig.statistics.service.RetentionAnalyseService;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -16,4 +21,17 @@ import org.springframework.stereotype.Service;
 @AllArgsConstructor
 public class RetentionAnalyseServiceImpl implements RetentionAnalyseService {
 
+	private final MktStatNewUserMapper newUserMapper;
+
+	private final MktStatActiveUserMapper activeUserMapper;
+
+	/**
+	 * 分页查询留存用户详情
+	 * @param reqDto 分页参数
+	 * @return Page<PageQueryRetentionVO>
+	 */
+	@Override
+	public Page<PageQueryRetentionVO> pageRetentionDetail(PageQueryRetentionDTO reqDto) {
+		return null;
+	}
 }