Просмотр исходного кода

【feat】【v3】
1.增加数据统计查询逻辑

ChenYL 10 месяцев назад
Родитель
Сommit
ea5a01cf64

+ 12 - 0
src/main/java/com/punchsettle/server/atomic/service/IStatNewUserService.java

@@ -1,5 +1,10 @@
 package com.punchsettle.server.atomic.service;
 
+import com.punchsettle.server.atomic.entity.StatNewUser;
+import com.punchsettle.server.pojo.stat.StatNewUserQuery;
+
+import java.util.List;
+
 /**
  * @author tyuio
  * @version 1.0.0
@@ -7,4 +12,11 @@ package com.punchsettle.server.atomic.service;
  * @description 新用户数据统计 service
  */
 public interface IStatNewUserService {
+
+    /**
+     * 按条件查询
+     * @param query
+     * @return
+     */
+    List<StatNewUser> queryByCondition(StatNewUserQuery query);
 }

+ 12 - 0
src/main/java/com/punchsettle/server/atomic/service/IStatPointsService.java

@@ -1,5 +1,10 @@
 package com.punchsettle.server.atomic.service;
 
+import com.punchsettle.server.atomic.entity.StatPoints;
+import com.punchsettle.server.pojo.stat.StatPointsQuery;
+
+import java.util.List;
+
 /**
  * @author tyuio
  * @version 1.0.0
@@ -7,4 +12,11 @@ package com.punchsettle.server.atomic.service;
  * @description 积分数据统计 service
  */
 public interface IStatPointsService {
+
+    /**
+     * 按条件查询
+     * @param query
+     * @return
+     */
+    List<StatPoints> queryByCondition(StatPointsQuery query);
 }

+ 29 - 1
src/main/java/com/punchsettle/server/atomic/service/impl/StatNewUserServiceImpl.java

@@ -1,7 +1,20 @@
 package com.punchsettle.server.atomic.service.impl;
 
-import com.punchsettle.server.atomic.service.IStatNewUserService;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import com.punchsettle.server.atomic.entity.StatNewUser;
+import com.punchsettle.server.atomic.mapper.StatNewUserMapper;
+import com.punchsettle.server.atomic.service.IStatNewUserService;
+import com.punchsettle.server.common.utils.Assert;
+import com.punchsettle.server.pojo.stat.StatNewUserQuery;
+import com.punchsettle.server.utiis.WeekendUtils;
+
+import tk.mybatis.mapper.weekend.Weekend;
+import tk.mybatis.mapper.weekend.WeekendCriteria;
 
 /**
  * @author tyuio
@@ -11,4 +24,19 @@ import org.springframework.stereotype.Service;
  */
 @Service
 public class StatNewUserServiceImpl implements IStatNewUserService {
+
+    @Autowired
+    private StatNewUserMapper statNewUserMapper;
+
+    @Override
+    public List<StatNewUser> queryByCondition(StatNewUserQuery query) {
+        Assert.isNull(query);
+
+        Weekend<StatNewUser> weekend = WeekendUtils.createExcludeAuditFields(StatNewUser.class);
+        WeekendCriteria<StatNewUser, Object> criteria = weekend.weekendCriteria();
+        if (StringUtils.hasText(query.getStatStartTime()) && StringUtils.hasText(query.getStatEndTime())) {
+            criteria.andBetween(StatNewUser::getStatTime, query.getStatStartTime(), query.getStatEndTime());
+        }
+        return statNewUserMapper.selectByExample(weekend);
+    }
 }

+ 30 - 0
src/main/java/com/punchsettle/server/atomic/service/impl/StatPointsServiceImpl.java

@@ -1,7 +1,19 @@
 package com.punchsettle.server.atomic.service.impl;
 
+import com.punchsettle.server.atomic.entity.StatPoints;
+import com.punchsettle.server.atomic.mapper.StatPointsMapper;
 import com.punchsettle.server.atomic.service.IStatPointsService;
+import com.punchsettle.server.common.utils.Assert;
+import com.punchsettle.server.pojo.stat.StatPointsQuery;
+import com.punchsettle.server.utiis.WeekendUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+import tk.mybatis.mapper.weekend.Weekend;
+import tk.mybatis.mapper.weekend.WeekendCriteria;
+
+import java.util.List;
+import java.util.Objects;
 
 /**
  * @author tyuio
@@ -11,4 +23,22 @@ import org.springframework.stereotype.Service;
  */
 @Service
 public class StatPointsServiceImpl implements IStatPointsService {
+
+    @Autowired
+    private StatPointsMapper statPointsMapper;
+
+    @Override
+    public List<StatPoints> queryByCondition(StatPointsQuery query) {
+        Assert.isNull(query);
+
+        Weekend<StatPoints> weekend = WeekendUtils.createExcludeAuditFields(StatPoints.class);
+        WeekendCriteria<StatPoints, Object> criteria = weekend.weekendCriteria();
+        if (Objects.nonNull(query.getUserId())) {
+            criteria.andEqualTo(StatPoints::getUserId, query.getUserId());
+        }
+        if (StringUtils.hasText(query.getStatStartTime()) && StringUtils.hasText(query.getStatEndTime())) {
+            criteria.andBetween(StatPoints::getStatTime, query.getStatStartTime(), query.getStatEndTime());
+        }
+        return statPointsMapper.selectByExample(weekend);
+    }
 }

+ 5 - 0
src/main/java/com/punchsettle/server/core/config/BizProperties.java

@@ -25,4 +25,9 @@ public class BizProperties {
      * token过期时间
      */
     private Integer tokenExpire;
+
+    /**
+     * 统计折线图数据数量
+     */
+    private Integer lineItemCount;
 }

+ 23 - 0
src/main/java/com/punchsettle/server/pojo/stat/StatNewUserQuery.java

@@ -0,0 +1,23 @@
+package com.punchsettle.server.pojo.stat;
+
+import lombok.Data;
+
+/**
+ * @author myou
+ * @version 1.0.0
+ * @date 2025/5/3 15:03
+ * @description 新用户数据统计 查询
+ */
+@Data
+public class StatNewUserQuery {
+
+    /**
+     * 统计开始时间
+     */
+    private String statStartTime;
+
+    /**
+     * 统计结束时间
+     */
+    private String statEndTime;
+}

+ 28 - 0
src/main/java/com/punchsettle/server/pojo/stat/StatPointsQuery.java

@@ -0,0 +1,28 @@
+package com.punchsettle.server.pojo.stat;
+
+import lombok.Data;
+
+/**
+ * @author myou
+ * @version 1.0.0
+ * @date 2025/5/3 9:40
+ * @description 积分数据统计 查询类
+ */
+@Data
+public class StatPointsQuery {
+
+    /**
+     * 统计开始时间
+     */
+    private String statStartTime;
+
+    /**
+     * 统计结束时间
+     */
+    private String statEndTime;
+
+    /**
+     * 用户ID
+     */
+    private Long userId;
+}

+ 7 - 5
src/main/java/com/punchsettle/server/service/controller/PunchInController.java

@@ -2,6 +2,7 @@ package com.punchsettle.server.service.controller;
 
 import java.util.List;
 
+import com.punchsettle.server.pojo.punchIn.PiTaskHistoryStatVO;
 import com.punchsettle.server.pojo.punchIn.PiTaskRequest;
 import com.punchsettle.server.pojo.punchIn.PiTaskStatQuery;
 import com.punchsettle.server.pojo.punchIn.PiTaskStatVO;
@@ -126,11 +127,12 @@ public class PunchInController {
     }
 
     /**
-     * 查询历史打卡数据
-     * @param query
+     * 查询打卡记录历史
+     * @param punchInDate
+     * @return
      */
-    @PostMapping("/queryPunchInData")
-    public PunchInDataVO queryPunchInData(@RequestBody @Validated PunchInDataQuery query) {
-        return punchInManager.queryPunchInData(query);
+    @GetMapping("/queryPunchInHistory")
+    public List<PiTaskHistoryStatVO> queryPunchInHistory(@NotNull(message = "打卡日期不能为空") String punchInDate) {
+        return punchInManager.queryPunchInHistory(punchInDate);
     }
 }

+ 49 - 0
src/main/java/com/punchsettle/server/service/controller/StatController.java

@@ -0,0 +1,49 @@
+package com.punchsettle.server.service.controller;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.punchsettle.server.pojo.ucharts.LineVO;
+import com.punchsettle.server.service.manager.IStatManager;
+
+/**
+ * @author myou
+ * @version 1.0.0
+ * @date 2025/5/3 20:27
+ * @description 数据统计
+ */
+@RestController
+@RequestMapping("/stat")
+public class StatController {
+
+    @Autowired
+    private IStatManager statManager;
+
+    /**
+     * 查询积分折线图
+     * @return
+     */
+    @RequestMapping("/queryStatPointsLine")
+    public LineVO queryStatPointsLine() {
+        return statManager.queryStatPointsLine();
+    }
+
+    /**
+     * 查询新用户折线图
+     * @return
+     */
+    @RequestMapping("/queryStatNewUserLine")
+    public LineVO queryStatNewUserLine() {
+        return statManager.queryStatNewUserLine();
+    }
+
+    /**
+     * 查询任务折线图
+     * @return
+     */
+    @RequestMapping("/queryStatTaskLine")
+    public LineVO queryStatTaskLine() {
+        return statManager.queryStatTaskLine();
+    }
+}

+ 6 - 0
src/main/java/com/punchsettle/server/service/manager/IPunchInManager.java

@@ -2,6 +2,7 @@ package com.punchsettle.server.service.manager;
 
 import java.util.List;
 
+import com.punchsettle.server.pojo.punchIn.PiTaskHistoryStatVO;
 import com.punchsettle.server.pojo.punchIn.PiTaskRequest;
 import com.punchsettle.server.pojo.punchIn.PiTaskSimpleVO;
 import com.punchsettle.server.pojo.punchIn.PiTaskStatQuery;
@@ -89,4 +90,9 @@ public interface IPunchInManager {
      * @return
      */
     PunchInDataVO queryPunchInData(PunchInDataQuery query);
+
+    /**
+     * 查询打卡历史
+     */
+    List<PiTaskHistoryStatVO> queryPunchInHistory(String punchInDate);
 }

+ 30 - 0
src/main/java/com/punchsettle/server/service/manager/IStatManager.java

@@ -0,0 +1,30 @@
+package com.punchsettle.server.service.manager;
+
+import com.punchsettle.server.pojo.ucharts.LineVO;
+
+/**
+ * @author myou
+ * @version 1.0.0
+ * @date 2025/5/3 9:29
+ * @description 统计数据 服务类
+ */
+public interface IStatManager {
+
+    /**
+     * 查询积分折线图
+     * @return
+     */
+    LineVO queryStatPointsLine();
+
+    /**
+     * 查询新用户折线图
+     * @return
+     */
+    LineVO queryStatNewUserLine();
+
+    /**
+     * 查询任务折线图
+     * @return
+     */
+    LineVO queryStatTaskLine();
+}

+ 20 - 0
src/main/java/com/punchsettle/server/service/manager/impl/PunchInManagerImpl.java

@@ -684,4 +684,24 @@ public class PunchInManagerImpl implements IPunchInManager {
         piTask.setTaskVersion(Optional.ofNullable(oldPiTask.getTaskVersion()).orElse(0) + 1);
         return piTask;
     }
+
+    @Override
+    public List<PiTaskHistoryStatVO> queryPunchInHistory(String punchInDate) {
+        Assert.isNullInBusiness(punchInDate, "打卡日期不能为空");
+
+        // 查询打卡记录
+        PiTaskHistoryQuery piTaskHistoryQuery = new PiTaskHistoryQuery();
+        piTaskHistoryQuery.setUserIds(Arrays.asList(UserUtils.getCurrentUserId()));
+        piTaskHistoryQuery.setPunchInDate(punchInDate);
+        List<PiTaskHistory> piTaskHistories = piTaskHistoryService.queryByCondition(piTaskHistoryQuery);
+        if (CollectionUtils.isEmpty(piTaskHistories)) {
+            return List.of();
+        }
+
+        return piTaskHistories.stream().map(piTaskHistory -> {
+            PiTaskHistoryStatVO piTaskHistoryStatVO = new PiTaskHistoryStatVO();
+            BeanUtils.copyProperties(piTaskHistory, piTaskHistoryStatVO);
+            return piTaskHistoryStatVO;
+        }).collect(Collectors.toList());
+    }
 }

+ 191 - 0
src/main/java/com/punchsettle/server/service/manager/impl/StatManagerImpl.java

@@ -0,0 +1,191 @@
+package com.punchsettle.server.service.manager.impl;
+
+import com.punchsettle.server.atomic.entity.PiTaskHistory;
+import com.punchsettle.server.atomic.entity.StatNewUser;
+import com.punchsettle.server.atomic.entity.StatPoints;
+import com.punchsettle.server.atomic.service.IPiTaskHistoryService;
+import com.punchsettle.server.atomic.service.IStatNewUserService;
+import com.punchsettle.server.atomic.service.IStatPointsService;
+import com.punchsettle.server.constant.PunchInResultEnum;
+import com.punchsettle.server.core.config.BizProperties;
+import com.punchsettle.server.pojo.punchIn.PiTaskHistoryQuery;
+import com.punchsettle.server.pojo.stat.StatNewUserQuery;
+import com.punchsettle.server.pojo.stat.StatPointsQuery;
+import com.punchsettle.server.pojo.ucharts.LineSeriesVO;
+import com.punchsettle.server.pojo.ucharts.LineVO;
+import com.punchsettle.server.service.manager.IStatManager;
+import com.punchsettle.server.utiis.DateUtils;
+import com.punchsettle.server.utiis.UserUtils;
+import lombok.Data;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * @author myou
+ * @version 1.0.0
+ * @date 2025/5/3 9:32
+ * @description 统计数据服务类
+ */
+@Component
+public class StatManagerImpl implements IStatManager {
+
+    @Autowired
+    private IStatPointsService statPointsService;
+
+    @Autowired
+    private IStatNewUserService statNewUserService;
+
+    @Autowired
+    private IPiTaskHistoryService piTaskHistoryService;
+
+    @Autowired
+    private BizProperties bizProperties;
+
+    @Override
+    public LineVO queryStatPointsLine() {
+        LocalDate endDate = LocalDate.now();
+        LocalDate startDate = endDate.minusDays(bizProperties.getLineItemCount());
+
+        // 获取折线图时间范围
+        List<LocalDate> dateRange = DateUtils.getDateRange(startDate, endDate);
+        String[] lineCategories = dateRange.stream().map(LocalDate::toString).toArray(String[]::new);
+
+        StatPointsQuery statPointsQuery = new StatPointsQuery();
+        statPointsQuery.setUserId(UserUtils.getCurrentUserId());
+        statPointsQuery.setStatStartTime(startDate.toString());
+        statPointsQuery.setStatEndTime(endDate.toString());
+        List<StatPoints> statPointsList = statPointsService.queryByCondition(statPointsQuery);
+        Map<String, StatPoints> statPointsMap = statPointsList.stream().collect(Collectors.toMap(StatPoints::getStatTime, Function.identity(), (v1, v2) -> v1));
+
+        List<Integer> settlePointsList = new ArrayList<>(lineCategories.length);
+        List<Integer> consumePointsList = new ArrayList<>(lineCategories.length);
+        List<Integer> totalPointsList = new ArrayList<>(lineCategories.length);
+        for (String lineCategory : lineCategories) {
+            StatPoints statPoints = statPointsMap.get(lineCategory);
+            if (Objects.isNull(statPoints)) {
+                settlePointsList.add(null);
+                consumePointsList.add(null);
+                totalPointsList.add(null);
+                continue;
+            }
+            settlePointsList.add(statPoints.getSettlePoints());
+            consumePointsList.add(statPoints.getConsumePoints());
+            totalPointsList.add(statPoints.getTotalPoints());
+        }
+
+        LineSeriesVO settlePointsLineSeriesVO = new LineSeriesVO();
+        settlePointsLineSeriesVO.setName("结算积分");
+        settlePointsLineSeriesVO.setData(settlePointsList.toArray(Integer[]::new));
+
+        LineSeriesVO consumePointsLineSeriesVO = new LineSeriesVO();
+        consumePointsLineSeriesVO.setName("消耗积分");
+        consumePointsLineSeriesVO.setData(consumePointsList.toArray(Integer[]::new));
+
+        LineSeriesVO totalPointsLineSeriesVO = new LineSeriesVO();
+        totalPointsLineSeriesVO.setName("总积分");
+        totalPointsLineSeriesVO.setData(totalPointsList.toArray(Integer[]::new));
+
+        LineVO lineVO = new LineVO();
+        lineVO.setCategories(lineCategories);
+        lineVO.setSeries(Arrays.asList(settlePointsLineSeriesVO, consumePointsLineSeriesVO, totalPointsLineSeriesVO));
+        return lineVO;
+    }
+
+    @Override
+    public LineVO queryStatNewUserLine() {
+        LocalDate endDate = LocalDate.now();
+        LocalDate startDate = endDate.minusDays(bizProperties.getLineItemCount());
+
+        // 获取折线图时间范围
+        List<LocalDate> dateRange = DateUtils.getDateRange(startDate, endDate);
+        String[] lineCategories = dateRange.stream().map(LocalDate::toString).toArray(String[]::new);
+
+        StatNewUserQuery statNewUserQuery = new StatNewUserQuery();
+        statNewUserQuery.setStatStartTime(startDate.toString());
+        statNewUserQuery.setStatEndTime(endDate.toString());
+        List<StatNewUser> statNewUserList = statNewUserService.queryByCondition(statNewUserQuery);
+        Map<String, Integer> statNewUserMap = statNewUserList.stream().collect(Collectors.toMap(StatNewUser::getStatTime, StatNewUser::getNewUserCount, (v1, v2) -> v1));
+
+        List<Integer> newUserCountList = new ArrayList<>(lineCategories.length);
+        for (String lineCategory : lineCategories) {
+            Integer newUserCount = Optional.ofNullable(statNewUserMap.get(lineCategory)).orElse(0);
+            newUserCountList.add(newUserCount);
+        }
+
+        LineSeriesVO newUserLineSeriesVO = new LineSeriesVO();
+        newUserLineSeriesVO.setName("新增用户数");
+        newUserLineSeriesVO.setData(newUserCountList.toArray(Integer[]::new));
+
+        LineVO lineVO = new LineVO();
+        lineVO.setCategories(lineCategories);
+        lineVO.setSeries(Arrays.asList(newUserLineSeriesVO));
+        return lineVO;
+    }
+
+    @Override
+    public LineVO queryStatTaskLine() {
+        LocalDate endDate = LocalDate.now();
+        LocalDate startDate = endDate.minusDays(bizProperties.getLineItemCount());
+
+        // 获取折线图时间范围
+        List<LocalDate> dateRange = DateUtils.getDateRange(startDate, endDate);
+        String[] lineCategories = dateRange.stream().map(LocalDate::toString).toArray(String[]::new);
+
+        PiTaskHistoryQuery piTaskHistoryQuery = new PiTaskHistoryQuery();
+        piTaskHistoryQuery.setPunchInDateFrom(startDate.toString());
+        piTaskHistoryQuery.setPunchInDateTo(endDate.toString());
+        List<PiTaskHistory> piTaskHistoryList = piTaskHistoryService.queryByCondition(piTaskHistoryQuery);
+        Map<String, List<PiTaskHistory>> piTaskHistoryMap = piTaskHistoryList.stream().collect(Collectors.groupingBy(PiTaskHistory::getPunchInDate));
+
+        // 总任务数
+        List<Integer> totalTaskCountList = new ArrayList<>(lineCategories.length);
+        // 打卡任务数
+        List<Integer> punchInTaskCountList = new ArrayList<>(lineCategories.length);
+        // 完成打卡任务数
+        List<Integer> doneTaskCountList = new ArrayList<>(lineCategories.length);
+        for (String lineCategory : lineCategories) {
+            List<PiTaskHistory> piTaskHistories = piTaskHistoryMap.get(lineCategory);
+            if (CollectionUtils.isEmpty(piTaskHistories)) {
+                totalTaskCountList.add(0);
+                punchInTaskCountList.add(0);
+                doneTaskCountList.add(0);
+                continue;
+            }
+            // 总任数
+            totalTaskCountList.add(piTaskHistories.size());
+            // TODO 这里要单独弄一个统计表,不然无法计算
+            punchInTaskCountList.add(piTaskHistories.size());
+            // 任务完成数
+            doneTaskCountList.add(piTaskHistories.stream().filter(piTaskHistory -> piTaskHistory.getPunchInResult().equals(PunchInResultEnum.DONE)).collect(Collectors.toList()).size());
+        }
+
+        LineSeriesVO totalTaskCountLineSeriesVO = new LineSeriesVO();
+        totalTaskCountLineSeriesVO.setName("总任务数");
+        totalTaskCountLineSeriesVO.setData(totalTaskCountList.toArray(Integer[]::new));
+
+        LineSeriesVO punchInTaskCountLineSeriesVO = new LineSeriesVO();
+        punchInTaskCountLineSeriesVO.setName("打卡数量");
+        punchInTaskCountLineSeriesVO.setData(punchInTaskCountList.toArray(Integer[]::new));
+
+        LineSeriesVO doneTaskCountLineSeriesVO = new LineSeriesVO();
+        doneTaskCountLineSeriesVO.setName("完成数量");
+        doneTaskCountLineSeriesVO.setData(doneTaskCountList.toArray(Integer[]::new));
+
+        LineVO lineVO = new LineVO();
+        lineVO.setCategories(lineCategories);
+        lineVO.setSeries(Arrays.asList(totalTaskCountLineSeriesVO, punchInTaskCountLineSeriesVO, doneTaskCountLineSeriesVO));
+        return lineVO;
+    }
+}

+ 1 - 1
src/main/resources/application-prod.yaml

@@ -26,4 +26,4 @@ biz:
   # Json Token 密码
   tokenPassword: ENC(nEvMwnWzB6W9pEmq9sSP4oHzIA9VkMmCsp67MZbyeaDv4awBEGOsyA==)
   # Json Token过期时间,单位:天
-  tokenExpire: 7
+  tokenExpire: 15

+ 5 - 0
src/main/resources/application.yaml

@@ -19,3 +19,8 @@ jasypt:
 # one-api接口平台
 one-api:
   url: https://oneapi.coderbox.cn/openapi
+
+# 系统相关配置
+biz:
+  # 折线图数据数量
+  lineItemCount: 30