用户统计
产品原型
所谓用户统计,实际上统计的是用户的数量。通过折线图来展示,上面这根蓝色线代表的是用户总量,下边这根绿色线代表的是新增用户数量,是具体到每一天。所以说用户统计主要统计两个数据 ,一个是总的用户数量 ,另外一个是新增用户数量。
业务规则:
- 基于可视化报表的折线图展示用户数据,X轴为日期,Y轴为用户数
- 根据时间选择区间,展示每天的用户总量和新增用户量数据
3.2 代码开发
3.2.1 VO设计
根据用户统计接口的返回结果设计VO:
在sky-pojo模块,UserReportVO.java已定义
java
package com.sky.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserReportVO implements Serializable {
//日期,以逗号分隔,例如:2022-10-01,2022-10-02,2022-10-03
private String dateList;
//用户总量,以逗号分隔,例如:200,210,220
private String totalUserList;
//新增用户,以逗号分隔,例如:20,21,10
private String newUserList;
}
3.2.2 Controller层
根据接口定义,在ReportController中创建userStatistics方法:
java
/**
* 用户数据统计
* @param begin
* @param end
* @return
*/
@GetMapping("/userStatistics")
@ApiOperation("用户数据统计")
public Result<UserReportVO> userStatistics(
@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,
@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end){
return Result.success(reportService.getUserStatistics(begin,end));
}
3.2.3 Service层接口
在ReportService接口中声明getUserStatistics方法:
java
/**
* 根据时间区间统计用户数量
* @param begin
* @param end
* @return
*/
UserReportVO getUserStatistics(LocalDate begin, LocalDate end);
3.2.4 Service层实现类
在ReportServiceImpl实现类中实现getUserStatistics方法:
java
@Override
public UserReportVO getUserStatistics(LocalDate begin, LocalDate end) {
List<LocalDate> dateList = new ArrayList<>();
dateList.add(begin);
while (!begin.equals(end)){
begin = begin.plusDays(1);
dateList.add(begin);
}
List<Integer> newUserList = new ArrayList<>(); //新增用户数
List<Integer> totalUserList = new ArrayList<>(); //总用户数
for (LocalDate date : dateList) {
LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
//新增用户数量 select count(id) from user where create_time > ? and create_time < ?
Integer newUser = getUserCount(beginTime, endTime);
//总用户数量 select count(id) from user where create_time < ?
Integer totalUser = getUserCount(null, endTime);
newUserList.add(newUser);
totalUserList.add(totalUser);
}
return UserReportVO.builder()
.dateList(StringUtils.join(dateList,","))
.newUserList(StringUtils.join(newUserList,","))
.totalUserList(StringUtils.join(totalUserList,","))
.build();
}
在ReportServiceImpl实现类中创建私有方法getUserCount:
java
/**
* 根据时间区间统计用户数量
* @param beginTime
* @param endTime
* @return
*/
private Integer getUserCount(LocalDateTime beginTime, LocalDateTime endTime) {
Map map = new HashMap();
map.put("begin",beginTime);
map.put("end", endTime);
return userMapper.countByMap(map);
}
3.2.5 Mapper层
在UserMapper接口中声明countByMap方法:
java
/**
* 根据动态条件统计用户数量
* @param map
* @return
*/
Integer countByMap(Map map);
在UserMapper.xml文件中编写动态SQL:
java
<select id="countByMap" resultType="java.lang.Integer">
select count(id) from user
<where>
<if test="begin != null">
and create_time >= #{begin}
</if>
<if test="end != null">
and create_time <= #{end}
</if>
</where>
</select>