瀏覽代碼

Merge branch 'master' of http://1.14.104.71:10880/root/ylrz_scrm_java

caoliqin 3 天之前
父節點
當前提交
588072cc61
共有 21 個文件被更改,包括 506 次插入41 次删除
  1. 2 0
      fs-admin/src/main/java/com/fs/FSAdminApplication.java
  2. 36 9
      fs-admin/src/main/java/com/fs/api/controller/IndexStatisticsController.java
  3. 1 0
      fs-common/src/main/java/com/fs/common/core/redis/RedisCache.java
  4. 2 2
      fs-company-app/src/main/java/com/fs/app/controller/FsUserCourseVideoController.java
  5. 3 3
      fs-service-system/src/main/java/com/fs/course/mapper/FsCourseAnswerLogsMapper.java
  6. 3 3
      fs-service-system/src/main/java/com/fs/course/mapper/FsCourseWatchLogMapper.java
  7. 5 5
      fs-service-system/src/main/java/com/fs/course/service/impl/FsUserCourseServiceImpl.java
  8. 6 5
      fs-service-system/src/main/java/com/fs/course/vo/FsUserCourseParticipationRecordVO.java
  9. 64 0
      fs-service-system/src/main/java/com/fs/statis/StatisticsRedisConstant.java
  10. 1 0
      fs-service-system/src/main/java/com/fs/statis/cache/IStatisticsCacheService.java
  11. 6 1
      fs-service-system/src/main/java/com/fs/statis/cache/impl/StatisticsCacheServiceImpl.java
  12. 4 1
      fs-service-system/src/main/java/com/fs/statis/dto/AnalysisPreviewQueryDTO.java
  13. 4 3
      fs-service-system/src/main/java/com/fs/statis/dto/ConsumptionBalanceDataDTO.java
  14. 2 0
      fs-service-system/src/main/java/com/fs/statis/dto/RewardMoneyTopTenDTO.java
  15. 2 0
      fs-service-system/src/main/java/com/fs/statis/dto/RewardMoneyTrendDTO.java
  16. 10 0
      fs-service-system/src/main/java/com/fs/statis/mapper/ConsumptionBalanceMapper.java
  17. 27 0
      fs-service-system/src/main/java/com/fs/statis/service/IStatisticsService.java
  18. 192 1
      fs-service-system/src/main/java/com/fs/statis/service/impl/StatisticsServiceImpl.java
  19. 75 0
      fs-service-system/src/main/java/com/fs/statis/service/utils/TrendDataFiller.java
  20. 7 6
      fs-service-system/src/main/resources/mapper/course/FsUserCourseMapper.xml
  21. 54 2
      fs-service-system/src/main/resources/mapper/statis/ConsumptionBalanceMapper.xml

+ 2 - 0
fs-admin/src/main/java/com/fs/FSAdminApplication.java

@@ -8,6 +8,7 @@ import org.springframework.cache.annotation.EnableCaching;
 import org.springframework.context.annotation.Bean;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.transaction.annotation.EnableTransactionManagement;
 import org.springframework.web.multipart.commons.CommonsMultipartResolver;
 
@@ -23,6 +24,7 @@ import java.util.Date;
 @EnableTransactionManagement
 @EnableAsync
 @EnableCaching
+@EnableScheduling
 public class FSAdminApplication
 {
     public static void main(String[] args)

+ 36 - 9
fs-admin/src/main/java/com/fs/api/controller/IndexStatisticsController.java

@@ -1,5 +1,7 @@
 package com.fs.api.controller;
 
+import com.fs.common.core.redis.RedisCache;
+import com.fs.statis.StatisticsRedisConstant;
 import com.fs.statis.cache.IStatisticsCacheService;
 import com.fs.statis.dto.*;
 import com.fs.statis.service.IStatisticsService;
@@ -10,6 +12,8 @@ import com.fs.common.core.domain.R;
 
 import java.util.List;
 
+import static com.fs.statis.StatisticsRedisConstant.DATA_OVERVIEW_DEALER_CHARTS;
+
 /**
  * 首页-统计
  */
@@ -20,12 +24,30 @@ public class IndexStatisticsController {
     private IStatisticsCacheService statisticsService;
     @Autowired
     private IStatisticsService statisticsService1;
+    @Autowired
+    private RedisCache redisCache;
     /**
      * 分析概览
      */
     @PostMapping("/analysisPreview")
     public R analysisPreview(@RequestBody AnalysisPreviewQueryDTO param){
-        AnalysisPreviewDTO analysisPreviewDTO = statisticsService1.analysisPreview(param);
+        AnalysisPreviewDTO analysisPreviewDTO = null;
+        Integer type = param.getType();
+        if(type == null) {
+            type = 0;
+        }
+
+        if(0 == type){
+            analysisPreviewDTO = redisCache.getCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_ANALYSISPREVIEW_TODAY);
+        } else if(1 == type){
+            analysisPreviewDTO = redisCache.getCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_ANALYSISPREVIEW_YESTODAY);
+        } else if(2 == type) {
+            analysisPreviewDTO = redisCache.getCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_ANALYSISPREVIEW_THIS_WEEEK);
+        } else if(3 == type) {
+            analysisPreviewDTO = redisCache.getCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_ANALYSISPREVIEW_THIS_MONTH);
+        } else if(4 == type) {
+            analysisPreviewDTO = redisCache.getCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_ANALYSISPREVIEW_BEFORE_MONTH);
+        }
         return R.ok().put("data",analysisPreviewDTO);
     }
 
@@ -34,7 +56,8 @@ public class IndexStatisticsController {
      */
     @GetMapping("/rechargeComsumption")
     public R rechargeComsumption(){
-        ConsumptionBalanceDataDTO consumptionBalanceDataDTO = statisticsService.rechargeConsumption();
+        ConsumptionBalanceDataDTO consumptionBalanceDataDTO = redisCache.getCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_BALANCE);
+
         return R.ok().put("data", consumptionBalanceDataDTO);
     }
 
@@ -43,8 +66,9 @@ public class IndexStatisticsController {
      */
     @PostMapping("/watchEndPlayTrend")
     public R watchEndPlayTrend(@RequestBody AnalysisPreviewQueryDTO param){
-        List<WatchEndPlayTrendDTO> watchEndPlayTrendDTOS = statisticsService.watchEndPlayTrend(param);
-        return R.ok().put("data", watchEndPlayTrendDTOS);
+        String key = String.format("%s::%d", DATA_OVERVIEW_DEALER_CHARTS, param.getType());
+        List<DeaMemberTopTenDTO> deaMemberTopTenDTOS = redisCache.getCacheObject(key);
+        return R.ok().put("data", deaMemberTopTenDTOS);
     }
 
     /**
@@ -59,7 +83,7 @@ public class IndexStatisticsController {
     /**
      * 奖励金额top10
      */
-    @GetMapping("/rewardMoneyTopTen")
+    @PostMapping("/rewardMoneyTopTen")
     public R rewardMoneyTopTen(@RequestBody AnalysisPreviewQueryDTO param){
         List<RewardMoneyTopTenDTO> rewardMoneyTopTenDTOS = statisticsService1.rewardMoneyTopTen(param);
         return R.ok().put("data", rewardMoneyTopTenDTOS);
@@ -68,7 +92,7 @@ public class IndexStatisticsController {
     /**
      * 答题红包金额趋势图
      */
-    @GetMapping("/rewardMoneyTrend")
+    @PostMapping("/rewardMoneyTrend")
     public R rewardMoneyTrend(@RequestBody AnalysisPreviewQueryDTO param){
         List<RewardMoneyTrendDTO> rewardMoneyTrendDTOS = statisticsService1.rewardMoneyTrendDTO(param);
         return R.ok().put("data", rewardMoneyTrendDTOS);
@@ -88,7 +112,8 @@ public class IndexStatisticsController {
      */
     @GetMapping("/dealerAggregated")
     public R dealerAggregated(){
-        DealerAggregatedDTO dealerAggregatedDTO = statisticsService.dealerAggregated();
+        DealerAggregatedDTO dealerAggregatedDTO = redisCache.getCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_AGGREGATED);
+
         return R.ok().put("data",dealerAggregatedDTO);
     }
 
@@ -97,7 +122,8 @@ public class IndexStatisticsController {
      */
     @GetMapping("/smsBalance")
     public R smsBalance(){
-        Long smsBalance = statisticsService1.smsBalance();
+        Long smsBalance = redisCache.getCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_SMS_BALANCE);
+
         return R.ok().put("data", smsBalance);
     }
 
@@ -107,7 +133,8 @@ public class IndexStatisticsController {
      */
     @GetMapping("/authorizationInfo")
     public R authorizationInfo(){
-        AuthorizationInfoDTO authorizationInfoDTO = statisticsService1.authorizationInfo();
+        AuthorizationInfoDTO authorizationInfoDTO = redisCache.getCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_AUTHORIZATION_INFO);
+
         return R.ok().put("data", authorizationInfoDTO);
     }
 }

+ 1 - 0
fs-common/src/main/java/com/fs/common/core/redis/RedisCache.java

@@ -128,6 +128,7 @@ public class RedisCache
         return count == null ? 0 : count;
     }
 
+
     /**
      * 获得缓存的list对象
      *

+ 2 - 2
fs-company-app/src/main/java/com/fs/app/controller/FsUserCourseVideoController.java

@@ -94,14 +94,14 @@ public class FsUserCourseVideoController extends AppBaseController {
     @Login
     @ApiOperation("参与记录")
     @GetMapping("/participationRecord")
-    public ResponseResult<Object> participationRecord(@RequestParam Long courseId,
+    public ResponseResult<Object> participationRecord(@RequestParam Long videoId,
                                                       @RequestParam Integer type,
                                                       @RequestParam(required = false) String keyword,
                                                       @RequestParam(required = false, defaultValue = "1") Integer pageNum,
                                                       @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
         log.debug("参与记录 keyword: {}, pageNum: {}, pageSize: {}", keyword, pageNum, pageSize);
         Map<String, Object> params = new HashMap<>();
-        params.put("courseId", courseId);
+        params.put("videoId", videoId);
         params.put("type", type);
         params.put("keyword", keyword);
 

+ 3 - 3
fs-service-system/src/main/java/com/fs/course/mapper/FsCourseAnswerLogsMapper.java

@@ -134,9 +134,9 @@ public interface FsCourseAnswerLogsMapper
      * 查询领取次数
      *
      * @param userId   用户ID
-     * @param courseId 课程ID
+     * @param videoId  小节ID
      * @return count
      */
-    @Select("select count(log_id) from fs_course_red_packet_log where user_id = #{userId} and course_id = #{courseId}")
-    Long selectRedStatus(@Param("userId") Long userId, @Param("courseId") Long courseId);
+    @Select("select count(log_id) from fs_course_red_packet_log where user_id = #{userId} and video_id = #{videoId}")
+    Long selectRedStatus(@Param("userId") Long userId, @Param("videoId") Long videoId);
 }

+ 3 - 3
fs-service-system/src/main/java/com/fs/course/mapper/FsCourseWatchLogMapper.java

@@ -309,9 +309,9 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
      * 聚合查询
      *
      * @param userId   用户ID
-     * @param courseId 课程ID
+     * @param videoId  小节ID
      * @return map
      */
-    @Select("select count(log_id) AS watchCount, count(case when log_type = 2 then log_id end) AS finishCount, sum(duration) AS watchTime from fs_course_watch_log where user_id = #{userId} and course_id = #{courseId}")
-    Map<String, Long> selectSumByUserIdAndCourseId(@Param("userId") Long userId, @Param("courseId") Long courseId);
+    @Select("select count(log_id) AS watchCount, count(case when log_type = 2 then log_id end) AS finishCount, sum(duration) AS watchTime from fs_course_watch_log where user_id = #{userId} and video_id = #{videoId}")
+    Map<String, Object> selectSumByUserIdAndVideoId(@Param("userId") Long userId, @Param("videoId") Long videoId);
 }

+ 5 - 5
fs-service-system/src/main/java/com/fs/course/service/impl/FsUserCourseServiceImpl.java

@@ -417,18 +417,18 @@ public class FsUserCourseServiceImpl implements IFsUserCourseService
             List<CompanyTag> companyTags = companyTagMapper.selectCompanyTagListByUserId(recordVO.getUserId());
             recordVO.setTags(companyTags);
 
-            Map<String, Long> sumMap = fsCourseWatchLogMapper.selectSumByUserIdAndCourseId(recordVO.getUserId(), recordVO.getCourseId());
+            Map<String, Object> sumMap = fsCourseWatchLogMapper.selectSumByUserIdAndVideoId(recordVO.getUserId(), recordVO.getVideoId());
             // 观看次数
-            recordVO.setWatchCount(sumMap.getOrDefault("watchCount", 0L).intValue());
+            recordVO.setWatchCount((Long) sumMap.getOrDefault("watchCount", 0L));
 
             // 完播次数
-            recordVO.setFinishCount(sumMap.getOrDefault("finishCount", 0L).intValue());
+            recordVO.setFinishCount((Long) sumMap.getOrDefault("finishCount", 0L));
 
             // 观看时长
-            recordVO.setWatchTime(sumMap.getOrDefault("watchTime", 0L).intValue());
+            recordVO.setWatchTime((BigDecimal) sumMap.getOrDefault("watchTime", BigDecimal.ZERO));
 
             // 领取状态
-            Long count = fsCourseAnswerLogsMapper.selectRedStatus(recordVO.getUserId(), recordVO.getCourseId());
+            Long count = fsCourseAnswerLogsMapper.selectRedStatus(recordVO.getUserId(), recordVO.getVideoId());
             if (Objects.nonNull(count) && count > 0) {
                 recordVO.setRedStatus(1);
             } else {

+ 6 - 5
fs-service-system/src/main/java/com/fs/course/vo/FsUserCourseParticipationRecordVO.java

@@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fs.company.domain.CompanyTag;
 import lombok.Data;
 
+import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.util.List;
 
@@ -14,9 +15,9 @@ public class FsUserCourseParticipationRecordVO {
      */
     private Long userId;
     /**
-     * 课程ID
+     * 小节D
      */
-    private Long courseId;
+    private Long videoId;
     /**
      * 用户昵称
      */
@@ -41,15 +42,15 @@ public class FsUserCourseParticipationRecordVO {
     /**
      * 观看次数
      */
-    private Integer watchCount;
+    private Long watchCount;
     /**
      * 完播次数
      */
-    private Integer finishCount;
+    private Long finishCount;
     /**
      * 累计时长
      */
-    private Integer watchTime;
+    private BigDecimal watchTime;
     /**
      * 红包领取状态
      */

+ 64 - 0
fs-service-system/src/main/java/com/fs/statis/StatisticsRedisConstant.java

@@ -0,0 +1,64 @@
+package com.fs.statis;
+
+/**
+ * 统计redis常量
+ */
+public class StatisticsRedisConstant {
+    /**
+     * 经销商统计
+     */
+    public static final String DATA_OVERVIEW_DEALER_AGGREGATED = "statistics::data::overview::DealerAggregatedDTO";
+    /**
+     * 短信余额
+     */
+    public static final String DATA_OVERVIEW_DEALER_SMS_BALANCE = "statistics::data::overview::SMS::BALANCE";
+    /**
+     * 余额类
+     */
+    public static final String DATA_OVERVIEW_DEALER_BALANCE = "statistics::data::overview::balance";
+    /**
+     * 平台统计类信息
+     */
+    public static final String DATA_OVERVIEW_DEALER_AUTHORIZATION_INFO = "statistics::data::overview::authorizationInfo";
+
+    /**
+     * 分析概览-今日
+     */
+    public static final String DATA_OVERVIEW_DEALER_ANALYSISPREVIEW_TODAY = "statistics::data::overview::AnalysisPreviewDTO::0";
+    /**
+     * 分析概览-昨日
+     */
+    public static final String DATA_OVERVIEW_DEALER_ANALYSISPREVIEW_YESTODAY = "statistics::data::overview::AnalysisPreviewDTO::1";
+
+    /**
+     * 分析概览-本周
+     */
+    public static final String DATA_OVERVIEW_DEALER_ANALYSISPREVIEW_THIS_WEEEK = "statistics::data::overview::AnalysisPreviewDTO::2";
+
+    /**
+     * 分析概览-本月
+     */
+    public static final String DATA_OVERVIEW_DEALER_ANALYSISPREVIEW_THIS_MONTH = "statistics::data::overview::AnalysisPreviewDTO::3";
+    /**
+     * 分析概览-上月
+     */
+    public static final String DATA_OVERVIEW_DEALER_ANALYSISPREVIEW_BEFORE_MONTH = "statistics::data::overview::AnalysisPreviewDTO::4";
+
+
+    /**
+     * 会员观看、完播人数趋势图
+     */
+    public static final String DATA_OVERVIEW_DEALER_CHARTS = "statistics::data::charts::dealer::charts";
+
+
+    /**
+     * 经销商会员观看TOP10 - 按观看人数
+     */
+    public static final String CHARTS_MEMBER_TOP_TEN_WATCH = "statistics::data::charts::memeber::top10::watch::user::count";
+    /**
+     * 经销商会员观看TOP10 - 按完播人数
+     */
+    public static final String CHARTS_MEMBER_TOP_TEN_COMPLETED = "statistics::data:charts::memeber::top10::watch::completed::user::count";
+
+
+}

+ 1 - 0
fs-service-system/src/main/java/com/fs/statis/cache/IStatisticsCacheService.java

@@ -27,6 +27,7 @@ public interface IStatisticsCacheService {
      * @return 会员观看、完播人数趋势图
      */
     List<WatchEndPlayTrendDTO> watchEndPlayTrend(AnalysisPreviewQueryDTO param);
+    void setWatchEndPlayTrend(Integer type,List<WatchEndPlayTrendDTO> data);
 
     /**
      * 经销商会员观看TOP10

+ 6 - 1
fs-service-system/src/main/java/com/fs/statis/cache/impl/StatisticsCacheServiceImpl.java

@@ -34,7 +34,6 @@ public class StatisticsCacheServiceImpl implements IStatisticsCacheService {
 
     private static final Cache<Integer, List<WatchEndPlayTrendDTO>> WATCH_END_PLAY_TREND = Caffeine.newBuilder()
             .maximumSize(1000)
-            .expireAfterWrite(10, TimeUnit.MINUTES)
             .build();
 
     private static final Cache<Integer, List<DeaMemberTopTenDTO>> DEA_MEMBER_TOP_TEN = Caffeine.newBuilder()
@@ -70,6 +69,12 @@ public class StatisticsCacheServiceImpl implements IStatisticsCacheService {
         });
     }
 
+    @Override
+    public void setWatchEndPlayTrend(Integer type,List<WatchEndPlayTrendDTO> data) {
+        WATCH_END_PLAY_TREND.put(type,data);
+    }
+
+
     @Override
     public List<DeaMemberTopTenDTO> deaMemberTopTen(AnalysisPreviewQueryDTO param) {
         return DEA_MEMBER_TOP_TEN.get(param.getType(),e->{

+ 4 - 1
fs-service-system/src/main/java/com/fs/statis/dto/AnalysisPreviewQueryDTO.java

@@ -32,6 +32,9 @@ public class AnalysisPreviewQueryDTO implements Serializable {
      */
     private String sort;
 
-    private Integer dateType;
+    /**
+     * 0 按公司统计 1 按课程统计
+     */
+    private Integer dataType;
 
 }

+ 4 - 3
fs-service-system/src/main/java/com/fs/statis/dto/ConsumptionBalanceDataDTO.java

@@ -3,6 +3,7 @@ package com.fs.statis.dto;
 import lombok.Data;
 
 import java.io.Serializable;
+import java.math.BigDecimal;
 
 /**
  * 消费余额
@@ -13,16 +14,16 @@ public class ConsumptionBalanceDataDTO implements Serializable {
      * 当前账户余额。
      * 数值表示,单位可能是分或其他约定单位。
      */
-    private Long balance;
+    private BigDecimal balance;
     /**
      * 今日消费金额。
      * 当天的总消费数额。
      */
-    private Integer todayComsumption;
+    private BigDecimal todayComsumption;
     /**
      * 昨日消费金额。
      * 昨天的总消费数额。
      */
-    private Integer yesterdayComsumption;
+    private BigDecimal yesterdayComsumption;
 
 }

+ 2 - 0
fs-service-system/src/main/java/com/fs/statis/dto/RewardMoneyTopTenDTO.java

@@ -7,6 +7,8 @@ import java.math.BigDecimal;
 
 @Data
 public class RewardMoneyTopTenDTO implements Serializable {
+    private Long courseId;
+    private String courseName;
     private Long companyId;
     private String companyName;
     private BigDecimal rewardMoney;

+ 2 - 0
fs-service-system/src/main/java/com/fs/statis/dto/RewardMoneyTrendDTO.java

@@ -8,4 +8,6 @@ import java.math.BigDecimal;
 @Data
 public class RewardMoneyTrendDTO implements Serializable {
     private BigDecimal rewardMoney;
+    private String x;
+    private String startDate;
 }

+ 10 - 0
fs-service-system/src/main/java/com/fs/statis/mapper/ConsumptionBalanceMapper.java

@@ -105,7 +105,17 @@ public interface ConsumptionBalanceMapper {
      */
     List<CourseStatsDTO> watchCourseTopTen(AnalysisPreviewQueryDTO param);
 
+    /**
+     * 奖励金额TOP10
+     * @param param 请求参数
+     * @return TOP10
+     */
     List<RewardMoneyTopTenDTO> rewardMoneyTopTen(AnalysisPreviewQueryDTO param);
 
+    /**
+     * 奖励金额趋势
+     * @param param 请求参数
+     * @return 趋势
+     */
     List<RewardMoneyTrendDTO> rewardMoneyTrendDTO(AnalysisPreviewQueryDTO param);
 }

+ 27 - 0
fs-service-system/src/main/java/com/fs/statis/service/IStatisticsService.java

@@ -8,6 +8,33 @@ import java.util.List;
  * 统计接口
  */
 public interface IStatisticsService {
+
+    /**
+     * 数据概览定时任务
+     */
+    void dataOverviewTask();
+
+    /**
+     * 分析概览定时任务
+     */
+    void analysisPreviewTask(Integer type);
+
+
+    /**
+     * 会员观看、完播人数趋势图
+     */
+    void watchEndPlayTrendTask(Integer type);
+
+    /**
+     * 课程观看TOP10
+     */
+    void watchCourseTopTenTask();
+
+    /**
+     * 答题红包金额TOP10
+     */
+    void rewardMoneyTopTenTask();
+
     /**
      * 分析概览 - 经销商统计
      */

+ 192 - 1
fs-service-system/src/main/java/com/fs/statis/service/impl/StatisticsServiceImpl.java

@@ -1,6 +1,9 @@
 package com.fs.statis.service.impl;
 
+import com.fs.common.core.redis.RedisCache;
 import com.fs.company.cache.ICompanyCacheService;
+import com.fs.statis.StatisticsRedisConstant;
+import com.fs.statis.cache.IStatisticsCacheService;
 import com.fs.statis.dto.*;
 import com.fs.statis.mapper.ConsumptionBalanceMapper;
 import com.fs.statis.service.IStatisticsService;
@@ -9,13 +12,20 @@ import com.fs.store.service.cache.IFsUserCourseCacheService;
 import com.hc.openapi.tool.util.ObjectUtils;
 import com.hc.openapi.tool.util.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
-import java.util.Collections;
+import java.time.DayOfWeek;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.TemporalAdjusters;
 import java.util.List;
 
+import static com.fs.statis.StatisticsRedisConstant.DATA_OVERVIEW_DEALER_CHARTS;
+
 @Service
 public class StatisticsServiceImpl implements IStatisticsService {
     @Autowired
@@ -26,6 +36,166 @@ public class StatisticsServiceImpl implements IStatisticsService {
 
     @Autowired
     private ICompanyCacheService companyCacheService;
+
+    @Autowired
+    private RedisCache redisCache;
+
+
+    @Override
+    @Scheduled(cron = "0 0 * * * *")
+    public void dataOverviewTask() {
+        DealerAggregatedDTO dealerAggregatedDTO = this.dealerAggregated();
+        ConsumptionBalanceDataDTO consumptionBalanceDataDTO = this.rechargeConsumption();
+        AuthorizationInfoDTO authorizationInfoDTO = authorizationInfo();
+        Long smsBalance = this.smsBalance();
+
+        redisCache.setCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_AGGREGATED, dealerAggregatedDTO);
+        redisCache.setCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_BALANCE, consumptionBalanceDataDTO);
+        redisCache.setCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_AUTHORIZATION_INFO, authorizationInfoDTO);
+        redisCache.setCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_SMS_BALANCE, smsBalance);
+    }
+
+
+    @Scheduled(cron = "0 0/15 * * * *")
+    public void analysisPreviewTask0(){
+        analysisPreviewTask(0);
+    }
+
+    @Scheduled(cron = "0 0 1 * * *")
+    public void analysisPreviewTask1(){
+        analysisPreviewTask(0);
+        analysisPreviewTask(1);
+        analysisPreviewTask(2);
+        analysisPreviewTask(3);
+        analysisPreviewTask(4);
+    }
+
+
+    @Override
+    public void analysisPreviewTask(Integer type) {
+        // 根据type计算出时间范围
+        String startDate = "";
+        String endDate = "";
+
+        LocalDate now = LocalDate.now();
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+
+
+        if(0 == type){
+            startDate = now.format(formatter);
+            endDate = now.format(formatter);
+        } else if(1 == type){
+            LocalDate yesterday = now.minusDays(1);
+            startDate = yesterday.format(formatter);
+            endDate = yesterday.format(formatter);
+        } else if(2 == type) {
+            LocalDate startOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
+            startDate = startOfWeek.format(formatter);
+            endDate = now.format(formatter);
+        } else if(3 == type) {
+            LocalDate startOfMonth = now.withDayOfMonth(1);
+            startDate = startOfMonth.format(formatter);
+            endDate = now.format(formatter);
+        } else if(4 == type) {
+            LocalDate firstDayOfPreviousMonth = now.minusMonths(1).withDayOfMonth(1);
+            LocalDate lastDayOfPreviousMonth = now.withDayOfMonth(1).minusDays(1);
+            startDate = firstDayOfPreviousMonth.format(formatter);
+            endDate = lastDayOfPreviousMonth.format(formatter);
+        }
+
+        AnalysisPreviewQueryDTO param = new AnalysisPreviewQueryDTO();
+        param.setStartTime(startDate);
+        param.setEndTime(endDate);
+        param.setType(type);
+
+        AnalysisPreviewDTO analysisPreviewDTO = this.analysisPreview(param);
+
+        if(0 == type){
+            redisCache.setCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_ANALYSISPREVIEW_TODAY, analysisPreviewDTO);
+        } else if(1 == type){
+            redisCache.setCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_ANALYSISPREVIEW_YESTODAY, analysisPreviewDTO);
+        } else if(2 == type) {
+            redisCache.setCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_ANALYSISPREVIEW_THIS_WEEEK, analysisPreviewDTO);
+        } else if(3 == type) {
+            redisCache.setCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_ANALYSISPREVIEW_THIS_MONTH, analysisPreviewDTO);
+        } else if(4 == type) {
+            redisCache.setCacheObject(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_ANALYSISPREVIEW_BEFORE_MONTH, analysisPreviewDTO);
+        }
+
+    }
+
+    @Scheduled(cron = "0 0/15 * * * *")
+    public void watchEndPlayTrendTask0(){
+        this.watchEndPlayTrendTask(0);
+        this.watchEndPlayTrendTask(1);
+        this.watchEndPlayTrendTask(2);
+        this.watchEndPlayTrendTask(3);
+        this.watchEndPlayTrendTask(4);
+    }
+
+    @Scheduled(cron = "0 0 1 * * *")
+    public void watchEndPlayTrendTask1(){
+        this.watchEndPlayTrendTask(1);
+        this.watchEndPlayTrendTask(2);
+        this.watchEndPlayTrendTask(3);
+        this.watchEndPlayTrendTask(4);
+    }
+
+
+    @Override
+    public void watchEndPlayTrendTask(Integer type) {
+        // 根据type计算出时间范围
+        String startDate = "";
+        String endDate = "";
+
+        LocalDateTime now = LocalDateTime.now();
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+
+        if(0 == type){
+            startDate = now.format(formatter);
+            endDate = now.format(formatter);
+        } else if(1 == type){
+            LocalDateTime yesterday = now.minusDays(1);
+            startDate = yesterday.format(formatter);
+            endDate = yesterday.format(formatter);
+        } else if(2 == type) {
+            LocalDateTime startOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
+            startDate = startOfWeek.format(formatter);
+            endDate = now.format(formatter);
+        } else if(3 == type) {
+            LocalDateTime startOfMonth = now.withDayOfMonth(1);
+            startDate = startOfMonth.format(formatter);
+            endDate = now.format(formatter);
+        } else if(4 == type) {
+            LocalDateTime firstDayOfPreviousMonth = now.minusMonths(1).withDayOfMonth(1);
+            LocalDateTime lastDayOfPreviousMonth = now.withDayOfMonth(1).minusDays(1);
+            startDate = firstDayOfPreviousMonth.format(formatter);
+            endDate = lastDayOfPreviousMonth.format(formatter);
+        }
+
+        AnalysisPreviewQueryDTO param = new AnalysisPreviewQueryDTO();
+        param.setStartTime(startDate);
+        param.setEndTime(endDate);
+        param.setType(type);
+
+        List<WatchEndPlayTrendDTO> watchEndPlayTrendDTOS = this.watchEndPlayTrend(param);
+
+        redisCache.setCacheObject(String.format("%s::%d",DATA_OVERVIEW_DEALER_CHARTS,type),watchEndPlayTrendDTOS);
+
+    }
+
+    @Override
+    public void watchCourseTopTenTask() {
+
+    }
+
+    @Override
+    public void rewardMoneyTopTenTask() {
+
+    }
+
+
     @Override
     public DealerAggregatedDTO dealerAggregated() {
         return consumptionBalanceMapper.dealerAggregated();
@@ -182,12 +352,33 @@ public class StatisticsServiceImpl implements IStatisticsService {
     @Override
     public List<RewardMoneyTopTenDTO> rewardMoneyTopTen(AnalysisPreviewQueryDTO param) {
         List<RewardMoneyTopTenDTO> rewardMoneyTopTenDTOS = consumptionBalanceMapper.rewardMoneyTopTen(param);
+        for (RewardMoneyTopTenDTO dto : rewardMoneyTopTenDTOS) {
+            if(dto.getCompanyId() != null) {
+                String companyName = companyCacheService.selectCompanyNameById(dto.getCompanyId());
+                dto.setCompanyName(companyName);
+            }
+            if(dto.getCourseId() != null){
+                String courseName = fsUserCourseCacheService.selectCourseNameByCourseId(dto.getCourseId());
+                dto.setCourseName(courseName);
+            }
+
+        }
         return rewardMoneyTopTenDTOS;
     }
 
     @Override
     public List<RewardMoneyTrendDTO> rewardMoneyTrendDTO(AnalysisPreviewQueryDTO param) {
         List<RewardMoneyTrendDTO> rewardMoneyTrendDTOS = consumptionBalanceMapper.rewardMoneyTrendDTO(param);
+
+        // 今日,昨日 格式为24小时
+        if(ObjectUtils.equals(param.getType(),0) || ObjectUtils.equals(param.getType(),1)){
+            rewardMoneyTrendDTOS = TrendDataFiller.fillRewardHourData(rewardMoneyTrendDTOS);
+            // 否则都是按天为维度的时间范围
+        } else {
+            rewardMoneyTrendDTOS = TrendDataFiller.fillRewardDateSegmentData(rewardMoneyTrendDTOS, param.getStartTime(), param.getEndTime());
+        }
+
+
         return rewardMoneyTrendDTOS;
     }
 }

+ 75 - 0
fs-service-system/src/main/java/com/fs/statis/service/utils/TrendDataFiller.java

@@ -1,7 +1,9 @@
 package com.fs.statis.service.utils;
 
+import com.fs.statis.dto.RewardMoneyTrendDTO;
 import com.fs.statis.dto.WatchEndPlayTrendDTO;
 
+import java.math.BigDecimal;
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
 import java.util.Collections;
@@ -12,6 +14,79 @@ import java.util.List;
  * 时序数据补全工具类
  */
 public class TrendDataFiller {
+    public static List<RewardMoneyTrendDTO> fillRewardHourData(List<RewardMoneyTrendDTO> data){
+
+        boolean[] hourExists = new boolean[24];
+
+        for (RewardMoneyTrendDTO dto : data) {
+            int hour = Integer.parseInt(dto.getStartDate());
+            if (hour >= 0 && hour < 24) {
+                hourExists[hour] = true;
+                dto.setX(String.valueOf(hour));
+            }
+        }
+
+        // 填充不存在的小时数据
+        for (int i = 0; i < 24; i++) {
+            if (!hourExists[i]) {
+                RewardMoneyTrendDTO dto = new RewardMoneyTrendDTO();
+                dto.setX(String.valueOf(i));
+                dto.setRewardMoney(BigDecimal.ZERO);
+                data.add(dto);
+            }
+        }
+
+        data.sort((a, b) -> {
+            int intA = Integer.parseInt(a.getX());
+            int intB = Integer.parseInt(b.getX());
+            return Integer.compare(intA, intB);
+        });
+        return data;
+    }
+
+    /**
+     * 填充日期段数据
+     * @param data
+     * @return
+     */
+    public static List<RewardMoneyTrendDTO> fillRewardDateSegmentData(List<RewardMoneyTrendDTO> data,String startDate,String endDate){
+        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        LocalDate start = LocalDate.parse(startDate, dateTimeFormatter);
+        LocalDate end = LocalDate.parse(endDate, dateTimeFormatter);
+
+        LocalDate current = start;
+        while (!current.isAfter(end)) {
+            String dateStr = current.format(dateFormatter);
+            boolean found = false;
+
+            for (RewardMoneyTrendDTO dto : data) {
+                if (dateStr.equals(dto.getStartDate())) {
+                    found = true;
+                    dto.setX(dateStr);
+                    break;
+                }
+            }
+
+            if (!found) {
+                RewardMoneyTrendDTO dto = new RewardMoneyTrendDTO();
+                dto.setStartDate(dateStr);
+                dto.setX(dateStr);
+                dto.setRewardMoney(BigDecimal.ZERO);
+                data.add(dto);
+            }
+
+            current = current.plusDays(1);
+        }
+
+        data.sort((a, b) -> {
+            LocalDate dateA = LocalDate.parse(a.getX(), dateFormatter);
+            LocalDate dateB = LocalDate.parse(b.getX(), dateFormatter);
+            return dateA.compareTo(dateB);
+        });
+
+        return data;
+    }
 
     /**
      * 填充24小时类数据

+ 7 - 6
fs-service-system/src/main/resources/mapper/course/FsUserCourseMapper.xml

@@ -256,19 +256,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
     <!-- 查询用户参与记录 -->
     <select id="getParticipationRecordByMap" resultType="com.fs.course.vo.FsUserCourseParticipationRecordVO">
-        select distinct
+        select
             fu.user_id,
-            fuc.course_id,
+            fucv.video_id,
             fu.nickname as nickName,
             fu.username as userName,
             fu.avatar,
             fu.phone as phoneNumber,
             fu.create_time,
             max(fcwl.create_time) as watchDate
-        from fs_user_course fuc
-        inner join fs_course_watch_log fcwl on fcwl.course_id = fuc.course_id
+        from fs_user_course_video fucv
+        inner join fs_course_watch_log fcwl on fcwl.video_id = fucv.video_id
         inner join fs_user fu on fu.user_id = fcwl.user_id
-        where fuc.course_id = #{params.courseId}
+        where fucv.video_id = #{params.videoId}
         <if test="params.keyword != null and params.keyword != ''">
             and (
                 fu.user_id = #{params.keyword}
@@ -282,7 +282,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                 and (
                     select count(log_id) as count
                     from fs_course_answer_logs
-                    where user_id = fu.user_id and course_id = fuc.course_id and is_right = 1
+                    where user_id = fu.user_id and fcwl.video_id = fucv.video_id and is_right = 1
                 ) > 0
             </when>
             <when test="params.type == 1">
@@ -295,6 +295,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                 and fcwl.log_type = 3
             </otherwise>
         </choose>
+        group by fu.user_id, fucv.video_id, fu.nickname, fu.username, fu.avatar, fu.phone, fu.create_time
     </select>
     <select id="selectFsUserCourseListCompanyPVO" resultType="com.fs.course.vo.FsUserCourseListPVO">
         select c.*,cc.cate_name,ucc.cate_name as sub_cate_name from fs_user_course  c

+ 54 - 2
fs-service-system/src/main/resources/mapper/statis/ConsumptionBalanceMapper.xml

@@ -157,10 +157,62 @@
         LIMIT 10
     </select>
     <select id="rewardMoneyTopTen" resultType="com.fs.statis.dto.RewardMoneyTopTenDTO">
-
+        SELECT
+            -- 按公司
+            <if test="dataType == 0">
+                company_id,
+            </if>
+            -- 按课程
+            <if test="dataType == 1">
+                course_id,
+            </if>
+            SUM(money) as rewardMoney
+        FROM
+            company_red_package_logs
+        <where>
+            operate_type = 1
+            AND status = 1
+            <if test="startTime != null">
+                AND create_time <![CDATA[>=]]> #{startTime}
+            </if>
+            <if test="endTime != null">
+                AND create_time <![CDATA[<]]> #{endTime}
+            </if>
+        </where>
+        GROUP BY
+            <if test="dataType == 0">
+                company_id
+            </if>
+            <if test="dataType == 1">
+                course_id
+            </if>
+        ORDER BY
+            rewardMoney DESC
+            LIMIT 10
     </select>
     <select id="rewardMoneyTrendDTO" resultType="com.fs.statis.dto.RewardMoneyTrendDTO">
-
+        select
+        --             今日/昨日 小时
+        <if test="type == 0 or type == 1">
+            DATE_FORMAT(create_time, '%H') AS start_date,
+        </if>
+        --                 本周/本月/上月 天
+        <if test="type == 2 or type == 3 or type == 4">
+            DATE_FORMAT(create_time, '%Y-%m-%d') AS start_date,
+        </if>
+               SUM(money) as rewardMoney
+        from company_red_package_logs
+        <where>
+            <if test="startTime != null">
+                create_time <![CDATA[>=]]> #{startTime}
+            </if>
+            <if test="endTime != null">
+                AND create_time <![CDATA[<]]> #{endTime}
+            </if>
+            AND operate_type = 1
+            AND status = 1
+        </where>
+        group by start_date
     </select>
 
 </mapper>