Quellcode durchsuchen

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

dongdong.xiang vor 1 Monat
Ursprung
Commit
10b0de5c71
67 geänderte Dateien mit 3090 neuen und 247 gelöschten Zeilen
  1. 30 25
      fs-admin/src/main/java/com/fs/company/controller/CompanyController.java
  2. 28 11
      fs-admin/src/main/java/com/fs/company/controller/CompanyUserController.java
  3. 9 0
      fs-admin/src/main/java/com/fs/core/exception/FSExceptionHandler.java
  4. 37 22
      fs-admin/src/main/java/com/fs/course/controller/FsUserCoursePeriodController.java
  5. 14 1
      fs-admin/src/main/java/com/fs/course/controller/FsUserCourseTrainingCampController.java
  6. 20 0
      fs-admin/src/main/java/com/fs/course/controller/FsUserCourseVideoController.java
  7. 1 0
      fs-admin/src/main/java/com/fs/course/controller/FsUserVideoController.java
  8. 62 0
      fs-admin/src/main/java/com/fs/stats/FsStatsMemberController.java
  9. 31 10
      fs-admin/src/main/java/com/fs/store/controller/FsUserController.java
  10. 18 0
      fs-admin/src/main/java/com/fs/task/stats/FsStatsMemberDailyTask.java
  11. 25 1
      fs-admin/src/main/java/com/fs/user/FsUserAdminController.java
  12. 242 0
      fs-company/src/main/java/com/fs/company/controller/IndexStatisticsController.java
  13. 11 2
      fs-service-system/src/main/java/com/fs/company/mapper/CompanyMapper.java
  14. 8 0
      fs-service-system/src/main/java/com/fs/company/mapper/CompanyUserMapper.java
  15. 12 5
      fs-service-system/src/main/java/com/fs/company/service/ICompanyService.java
  16. 8 1
      fs-service-system/src/main/java/com/fs/company/service/ICompanyUserService.java
  17. 17 5
      fs-service-system/src/main/java/com/fs/company/service/impl/CompanyServiceImpl.java
  18. 15 2
      fs-service-system/src/main/java/com/fs/company/service/impl/CompanyUserServiceImpl.java
  19. 4 0
      fs-service-system/src/main/java/com/fs/course/domain/FsUserCoursePeriod.java
  20. 3 0
      fs-service-system/src/main/java/com/fs/course/mapper/FsCourseTrafficLogMapper.java
  21. 3 3
      fs-service-system/src/main/java/com/fs/course/mapper/FsUserCourseMapper.java
  22. 17 4
      fs-service-system/src/main/java/com/fs/course/mapper/FsUserCoursePeriodDaysMapper.java
  23. 11 4
      fs-service-system/src/main/java/com/fs/course/mapper/FsUserCoursePeriodMapper.java
  24. 8 0
      fs-service-system/src/main/java/com/fs/course/mapper/FsUserCourseTrainingCampMapper.java
  25. 11 4
      fs-service-system/src/main/java/com/fs/course/mapper/FsUserCourseVideoMapper.java
  26. 21 2
      fs-service-system/src/main/java/com/fs/course/service/IFsUserCoursePeriodDaysService.java
  27. 5 5
      fs-service-system/src/main/java/com/fs/course/service/IFsUserCourseService.java
  28. 8 1
      fs-service-system/src/main/java/com/fs/course/service/IFsUserCourseTrainingCampService.java
  29. 10 2
      fs-service-system/src/main/java/com/fs/course/service/IFsUserCourseVideoService.java
  30. 1 1
      fs-service-system/src/main/java/com/fs/course/service/impl/FsCourseWatchLogServiceImpl.java
  31. 64 8
      fs-service-system/src/main/java/com/fs/course/service/impl/FsUserCoursePeriodDaysServiceImpl.java
  32. 32 7
      fs-service-system/src/main/java/com/fs/course/service/impl/FsUserCourseTrainingCampServiceImpl.java
  33. 24 13
      fs-service-system/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java
  34. 2 2
      fs-service-system/src/main/java/com/fs/course/service/impl/TencentCloudCosService.java
  35. 3 0
      fs-service-system/src/main/java/com/fs/course/vo/FsUserCoursePeriodVO.java
  36. 39 48
      fs-service-system/src/main/java/com/fs/sop/service/impl/QwSopTempServiceImpl.java
  37. 149 0
      fs-service-system/src/main/java/com/fs/statis/domain/FsStatsMemberDaily.java
  38. 5 0
      fs-service-system/src/main/java/com/fs/statis/dto/AnalysisPreviewQueryDTO.java
  39. 4 0
      fs-service-system/src/main/java/com/fs/statis/mapper/ConsumptionBalanceMapper.java
  40. 26 0
      fs-service-system/src/main/java/com/fs/statis/mapper/FsStatsMemberDailyMapper.java
  41. 23 0
      fs-service-system/src/main/java/com/fs/statis/service/IFsStatsMemberDailyService.java
  42. 108 0
      fs-service-system/src/main/java/com/fs/statis/service/IStatisticsCompanyService.java
  43. 36 0
      fs-service-system/src/main/java/com/fs/statis/service/impl/FsStatsMemberDailyServiceImpl.java
  44. 1077 0
      fs-service-system/src/main/java/com/fs/statis/service/impl/StatisticsCompanyServiceImpl.java
  45. 82 0
      fs-service-system/src/main/java/com/fs/statis/vo/FsStatsMemberDailyVO.java
  46. 12 0
      fs-service-system/src/main/java/com/fs/store/mapper/FsStoreProductMapper.java
  47. 10 6
      fs-service-system/src/main/java/com/fs/store/mapper/FsUserMapper.java
  48. 1 0
      fs-service-system/src/main/java/com/fs/store/service/IFsStoreProductService.java
  49. 8 7
      fs-service-system/src/main/java/com/fs/store/service/IFsUserService.java
  50. 5 0
      fs-service-system/src/main/java/com/fs/store/service/impl/FsStoreProductServiceImpl.java
  51. 23 18
      fs-service-system/src/main/java/com/fs/store/service/impl/FsUserServiceImpl.java
  52. 12 0
      fs-service-system/src/main/resources/mapper/company/CompanyMapper.xml
  53. 15 0
      fs-service-system/src/main/resources/mapper/company/CompanyUserMapper.xml
  54. 40 1
      fs-service-system/src/main/resources/mapper/course/FsCourseTrafficLogMapper.xml
  55. 38 0
      fs-service-system/src/main/resources/mapper/course/FsUserCoursePeriodDaysMapper.xml
  56. 15 0
      fs-service-system/src/main/resources/mapper/course/FsUserCoursePeriodMapper.xml
  57. 12 0
      fs-service-system/src/main/resources/mapper/course/FsUserCourseTrainingCampMapper.xml
  58. 16 0
      fs-service-system/src/main/resources/mapper/course/FsUserCourseVideoMapper.xml
  59. 88 0
      fs-service-system/src/main/resources/mapper/statis/ConsumptionBalanceMapper.xml
  60. 161 0
      fs-service-system/src/main/resources/mapper/statis/FsStatsMemberDailyMapper.xml
  61. 13 12
      fs-service-system/src/main/resources/mapper/store/FsStoreOrderMapper.xml
  62. 13 13
      fs-service-system/src/main/resources/mapper/store/FsStorePaymentMapper.xml
  63. 12 0
      fs-service-system/src/main/resources/mapper/store/FsUserMapper.xml
  64. 5 0
      fs-user-app/src/main/java/com/fs/app/controller/CourseH5Controller.java
  65. 192 0
      fs-user-app/src/main/java/com/fs/app/controller/WxCompanyUserController.java
  66. 34 0
      fs-user-app/src/main/java/com/fs/app/param/LoginMaWxParam.java
  67. 1 1
      fs-user-app/src/main/resources/application.yml

+ 30 - 25
fs-admin/src/main/java/com/fs/company/controller/CompanyController.java

@@ -1,18 +1,16 @@
 package com.fs.company.controller;
 
-import java.math.BigDecimal;
-import java.sql.Timestamp;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.List;
-
 import cn.hutool.core.util.IdUtil;
+import com.fs.common.annotation.Log;
 import com.fs.common.annotation.RepeatSubmit;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
-import com.fs.common.utils.OrderUtils;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.ParseUtils;
 import com.fs.common.utils.ServletUtils;
+import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.common.utils.sign.Md5Utils;
 import com.fs.company.domain.*;
 import com.fs.company.param.CompanyDeductParam;
@@ -27,26 +25,17 @@ import com.fs.core.security.LoginUser;
 import com.fs.core.security.SecurityUtils;
 import com.fs.core.web.service.TokenService;
 import com.fs.his.vo.OptionsVO;
-import lombok.Synchronized;
-import org.springframework.security.access.prepost.PreAuthorize;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-import com.fs.common.annotation.Log;
-import com.fs.common.core.controller.BaseController;
-import com.fs.common.core.domain.AjaxResult;
-import com.fs.common.enums.BusinessType;
-import com.fs.common.utils.poi.ExcelUtil;
-import com.fs.common.core.page.TableDataInfo;
+import org.springframework.web.bind.annotation.*;
 
-import javax.swing.*;
+import java.text.ParseException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 /**
  * 企业Controller
@@ -257,5 +246,21 @@ public class CompanyController extends BaseController
         return getDataTable(list);
     }
 
+    /**
+     * 根据公司名称模糊查询
+     * @param name  名称
+     * @return  list
+     */
+    @GetMapping("/getCompanyListLikeName")
+    public R getCompanyUserListLikeName(@RequestParam(required = false) String name,
+                                        @RequestParam(required = false, defaultValue = "1") Integer pageNum,
+                                        @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
+        Map<String,Object> params = new HashMap<>();
+        params.put("companyName", name);
+
+        PageHelper.startPage(pageNum, pageSize);
+        List<OptionsVO> companyUserList = companyService.selectCompanyListByMap(params);
+        return R.ok().put("data", new PageInfo<>(companyUserList));
+    }
 
 }

+ 28 - 11
fs-admin/src/main/java/com/fs/company/controller/CompanyUserController.java

@@ -1,22 +1,25 @@
 package com.fs.company.controller;
 
-import java.util.List;
-
-import com.fs.common.constant.UserConstants;
-import com.fs.common.core.domain.R;
-import com.fs.common.utils.ServletUtils;
-import com.fs.core.security.LoginUser;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
 import com.fs.common.annotation.Log;
+import com.fs.common.constant.UserConstants;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.company.domain.CompanyUser;
 import com.fs.company.service.ICompanyUserService;
-import com.fs.common.utils.poi.ExcelUtil;
-import com.fs.common.core.page.TableDataInfo;
+import com.fs.his.vo.OptionsVO;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 /**
  * 企业员工信息Controller
@@ -163,4 +166,18 @@ public class CompanyUserController extends BaseController
         return toAjax(companyUserService.changeCompanyUser(userIds, companyUserId, companyId));
     }
 
+
+    @GetMapping("/getCompanyUserListLikeName")
+    public R getCompanyUserListLikeName(@RequestParam(required = false) String name,
+                                        @RequestParam(required = false) Long companyId,
+                                        @RequestParam(required = false, defaultValue = "1") Integer pageNum,
+                                        @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
+        Map<String,Object> params = new HashMap<>();
+        params.put("companyUserName", name);
+        params.put("companyId", companyId);
+
+        PageHelper.startPage(pageNum, pageSize);
+        List<OptionsVO> companyUserList = companyUserService.selectCompanyUserListByMap(params);
+        return R.ok().put("data", new PageInfo<>(companyUserList));
+    }
 }

+ 9 - 0
fs-admin/src/main/java/com/fs/core/exception/FSExceptionHandler.java

@@ -5,6 +5,7 @@ package com.fs.core.exception;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
 import com.fs.common.exception.CustomException;
+import com.fs.common.exception.ServiceException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.dao.DuplicateKeyException;
@@ -34,6 +35,14 @@ public class FSExceptionHandler {
 		return r;
 	}
 
+	@ExceptionHandler(ServiceException.class)
+	public R handleServiceException(ServiceException e){
+		R r = new R();
+		r.put("code", e.getCode());
+		r.put("msg", e.getMessage());
+		return r;
+	}
+
 	@ExceptionHandler(NoHandlerFoundException.class)
 	public R handlerNoFoundException(Exception e) {
 		logger.error(e.getMessage(), e);

+ 37 - 22
fs-admin/src/main/java/com/fs/course/controller/FsUserCoursePeriodController.java

@@ -1,43 +1,37 @@
 package com.fs.course.controller;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.course.domain.FsUserCoursePeriod;
 import com.fs.course.domain.FsUserCoursePeriodDays;
 import com.fs.course.domain.FsUserCourseVideoRedPackage;
 import com.fs.course.param.CompanyRedPacketParam;
 import com.fs.course.param.FsBatchPeriodRedPackageParam;
 import com.fs.course.param.PeriodCountParam;
-import com.fs.course.vo.PeriodRedPacketVO;
 import com.fs.course.service.IFsUserCoursePeriodDaysService;
+import com.fs.course.service.IFsUserCoursePeriodService;
 import com.fs.course.service.IFsUserCourseVideoRedPackageService;
 import com.fs.course.vo.FsPeriodCountVO;
 import com.fs.course.vo.FsUserCoursePeriodVO;
-import com.fs.store.vo.h5.FsUserPageListVO;
+import com.fs.course.vo.PeriodRedPacketVO;
+import com.fs.his.vo.OptionsVO;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-import com.fs.common.annotation.Log;
-import com.fs.common.core.controller.BaseController;
-import com.fs.common.core.domain.AjaxResult;
-import com.fs.common.enums.BusinessType;
-import com.fs.course.domain.FsUserCoursePeriod;
-import com.fs.course.service.IFsUserCoursePeriodService;
-import com.fs.common.utils.poi.ExcelUtil;
-import com.fs.common.core.page.TableDataInfo;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 
 /**
  * 会员营期Controller
@@ -203,4 +197,25 @@ public class FsUserCoursePeriodController extends BaseController {
         return R.ok(result);
     }
 
+    @GetMapping("/getPeriodListLikeName")
+    public R getPeriodListLikeName(@RequestParam(required = false) String name,
+                                   @RequestParam(required = false) Long campId,
+                                   @RequestParam(required = false, defaultValue = "1") Integer pageNum,
+                                   @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
+        Map<String,Object> params = new HashMap<>();
+        params.put("name", name);
+        params.put("campId", campId);
+
+        PageHelper.startPage(pageNum, pageSize);
+        List<OptionsVO> periodList = fsUserCoursePeriodDaysService.selectPeriodListByMap(params);
+        return R.ok().put("data", new PageInfo<>(periodList));
+    }
+
+    @ApiOperation("营期课程-上移/下移")
+    @PutMapping("/courseMove")
+    public R periodCourseMove(Long id, Long targetId) {
+        return fsUserCoursePeriodDaysService.periodCourseMove(id, targetId);
+    }
+
+
 }

+ 14 - 1
fs-admin/src/main/java/com/fs/course/controller/FsUserCourseTrainingCampController.java

@@ -2,6 +2,7 @@ package com.fs.course.controller;
 
 import com.fs.common.annotation.Log;
 import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
 import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.SortUtils;
 import com.fs.course.domain.FsUserCourseTrainingCamp;
@@ -9,10 +10,10 @@ import com.fs.course.dto.FsUserCourseTrainingCampDTO;
 import com.fs.course.dto.FsUserCourseTrainingCampUpdateDTO;
 import com.fs.course.service.IFsUserCourseTrainingCampService;
 import com.fs.course.vo.FsUserCourseTrainingCampVO;
+import com.fs.his.vo.OptionsVO;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
 import lombok.AllArgsConstructor;
-import org.assertj.core.util.Arrays;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
@@ -106,4 +107,16 @@ public class FsUserCourseTrainingCampController {
         return AjaxResult.success();
     }
 
+    @GetMapping("/getCampListLikeName")
+    public R getCampListLikeName(@RequestParam(required = false) String name,
+                                 @RequestParam(required = false, defaultValue = "1") Integer pageNum,
+                                 @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
+        Map<String,Object> params = new HashMap<>();
+        params.put("name", name);
+
+        PageHelper.startPage(pageNum, pageSize);
+        List<OptionsVO> campList = fsUserCourseTrainingCampService.selectCampListByMap(params);
+        return R.ok().put("data", new PageInfo<>(campList));
+    }
+
 }

+ 20 - 0
fs-admin/src/main/java/com/fs/course/controller/FsUserCourseVideoController.java

@@ -13,11 +13,16 @@ import com.fs.course.param.BatchRedUpdate;
 import com.fs.course.param.BatchVideoSvae;
 import com.fs.course.param.CourseVideoUpdates;
 import com.fs.course.service.IFsUserCourseVideoService;
+import com.fs.his.vo.OptionsVO;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 课堂视频Controller
@@ -137,4 +142,19 @@ public class FsUserCourseVideoController extends BaseController
         fsUserCourseVideoService.batchUpdateRed(list);
         return R.ok();
     }
+
+
+    @GetMapping("/getVideoListLikeName")
+    public R getVideoListLikeName(@RequestParam(required = false) String name,
+                                   @RequestParam(required = false) String periodId,
+                                   @RequestParam(required = false, defaultValue = "1") Integer pageNum,
+                                   @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
+        Map<String,Object> params = new HashMap<>();
+        params.put("name", name);
+        params.put("periodId", periodId);
+
+        PageHelper.startPage(pageNum, pageSize);
+        List<OptionsVO> periodList = fsUserCourseVideoService.selectVideoListByMap(params);
+        return R.ok().put("data", new PageInfo<>(periodList));
+    }
 }

+ 1 - 0
fs-admin/src/main/java/com/fs/course/controller/FsUserVideoController.java

@@ -277,4 +277,5 @@ public class FsUserVideoController extends BaseController
             throw new RuntimeException("FFmpeg 执行失败,退出代码:" + exitCode);
         }
     }
+
 }

+ 62 - 0
fs-admin/src/main/java/com/fs/stats/FsStatsMemberController.java

@@ -0,0 +1,62 @@
+package com.fs.stats;
+
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.statis.service.IFsStatsMemberDailyService;
+import com.fs.statis.vo.FsStatsMemberDailyVO;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.LocalDate;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/stats/member")
+@AllArgsConstructor
+public class FsStatsMemberController {
+
+    private final IFsStatsMemberDailyService statsMemberDailyService;
+
+    @GetMapping("/dailyData")
+    public AjaxResult dailyData(@RequestParam String startDate,
+                                @RequestParam String endDate,
+                                @RequestParam Integer type,
+                                @RequestParam(required = false) Long companyId,
+                                @RequestParam(required = false) Long companyUserId,
+                                @RequestParam(required = false) Long userId,
+                                @RequestParam(required = false) String phone,
+                                @RequestParam(required = false) Long trainCampId,
+                                @RequestParam(required = false) Long periodId,
+                                @RequestParam(required = false) Long courseId,
+                                @RequestParam(required = false) Long videoId,
+                                @RequestParam(required = false, defaultValue = "1") Integer pageNum,
+                                @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
+        Map<String, Object> params = new HashMap<>();
+        params.put("companyId", companyId);
+        params.put("companyUserId", companyUserId);
+        params.put("userId", userId);
+        params.put("phone", phone);
+        params.put("trainCampId", trainCampId);
+        params.put("periodId", periodId);
+        params.put("courseId", courseId);
+        params.put("videoId", videoId);
+
+        if (type == 1) {
+            params.put("startDate", LocalDate.parse(startDate));
+            params.put("endDate", LocalDate.parse(endDate).plusDays(1));
+        } else {
+            params.put("startDate", LocalDate.parse(startDate).withDayOfMonth(1));
+            params.put("endDate", LocalDate.parse(endDate).withDayOfMonth(1).plusMonths(1));
+        }
+
+        PageHelper.startPage(pageNum, pageSize);
+        List<FsStatsMemberDailyVO> list = statsMemberDailyService.selectDailyData(params);
+        return AjaxResult.success(new PageInfo<>(list));
+    }
+}

+ 31 - 10
fs-admin/src/main/java/com/fs/store/controller/FsUserController.java

@@ -1,21 +1,25 @@
 package com.fs.store.controller;
 
-import java.util.List;
-
-import com.fs.common.core.domain.R;
-import com.fs.common.utils.ParseUtils;
-import com.fs.store.vo.FSUserVO;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.domain.ResponseResult;
+import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.ParseUtils;
+import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.store.domain.FsUser;
+import com.fs.store.param.h5.FsUserPageListParam;
 import com.fs.store.service.IFsUserService;
-import com.fs.common.utils.poi.ExcelUtil;
-import com.fs.common.core.page.TableDataInfo;
+import com.fs.store.vo.FSUserVO;
+import com.fs.store.vo.h5.FsUserPageListVO;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
 
 /**
  * 用户Controller
@@ -145,4 +149,21 @@ public class FsUserController extends BaseController
         List<FsUser> list = fsUserService.selectFsUserList(user);
         return R.ok().put("data",list);
     }
+
+    @PreAuthorize("@ss.hasPermi('store:user:darkRoomList')")
+    @GetMapping("/darkRoomList")
+    @ApiOperation("小黑屋")
+    public TableDataInfo darkRoomList(FsUserPageListParam param) {
+        startPage();
+        List<FsUserPageListVO> list = fsUserService.selectFsUserPageList(param);
+        return getDataTable(list);
+    }
+
+    @PreAuthorize("@ss.hasPermi('store:user:darkRoomList')")
+    @PostMapping("/enabledUsers")
+    @ApiOperation("批量启用会员")
+    public ResponseResult<Boolean> enabledUsers(@RequestBody String[] ids) {
+        Boolean r = fsUserService.disabledUser(ids, true);
+        return ResponseResult.ok(r);
+    }
 }

+ 18 - 0
fs-admin/src/main/java/com/fs/task/stats/FsStatsMemberDailyTask.java

@@ -0,0 +1,18 @@
+package com.fs.task.stats;
+
+import com.fs.statis.service.IFsStatsMemberDailyService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Slf4j
+@Component
+public class FsStatsMemberDailyTask {
+
+    @Autowired
+    private IFsStatsMemberDailyService fsStatsMemberDailyService;
+
+    public void refreshMemberDailyData() {
+        fsStatsMemberDailyService.refreshMemberDailyData();
+    }
+}

+ 25 - 1
fs-admin/src/main/java/com/fs/user/FsUserAdminController.java

@@ -2,18 +2,27 @@ package com.fs.user;
 
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.R;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.his.vo.OptionsVO;
 import com.fs.store.param.h5.FsUserPageListParam;
 import com.fs.store.service.IFsUserService;
 import com.fs.store.vo.h5.*;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
+import com.fs.store.vo.h5.FsUserPageListVO;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
-import java.util.*;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 @Api(tags = "会员管理接口")
 @RestController
@@ -37,5 +46,20 @@ public class FsUserAdminController extends BaseController {
         return R.ok(result);
     }
 
+    /**
+     * 根据会员名称模糊查询
+     * @param name  名称
+     * @return  list
+     */
+    @GetMapping("/getUserListLikeName")
+    public R getUserListLikeName(@RequestParam(required = false) String name,
+                                 @RequestParam(required = false, defaultValue = "1") Integer pageNum,
+                                 @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
+        Map<String,Object> params = new HashMap<>();
+        params.put("nickName", name);
 
+        PageHelper.startPage(pageNum, pageSize);
+        List<OptionsVO> userList = fsUserService.selectUserListByMap(params);
+        return R.ok().put("data", new PageInfo<>(userList));
+    }
 }

+ 242 - 0
fs-company/src/main/java/com/fs/company/controller/IndexStatisticsController.java

@@ -0,0 +1,242 @@
+package com.fs.company.controller;
+
+import com.fs.common.core.domain.R;
+import com.fs.common.core.redis.RedisCache;
+import com.fs.common.utils.ServletUtils;
+import com.fs.core.security.LoginUser;
+import com.fs.core.web.service.TokenService;
+import com.fs.statis.StatisticsRedisConstant;
+import com.fs.statis.dto.*;
+import io.jsonwebtoken.lang.Assert;
+import org.apache.http.util.Asserts;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.fs.statis.StatisticsRedisConstant.*;
+
+/**
+ * 首页-统计
+ */
+@RestController
+@RequestMapping("/index/statistics")
+public class IndexStatisticsController {
+    @Autowired
+    private RedisCache redisCache;
+
+    @Autowired
+    private TokenService tokenService;
+    /**
+     * 分析概览
+     */
+    @PostMapping("/analysisPreview")
+    public R analysisPreview(@RequestBody AnalysisPreviewQueryDTO param){
+        AnalysisPreviewDTO analysisPreviewDTO = null;
+        Integer type = param.getType();
+        Integer userType = param.getUserType();
+
+        if(type == null) {
+            type = 0;
+        }
+
+        if(userType == null) {
+            userType = 0;
+        }
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        param.setCompanyId(loginUser.getCompany().getCompanyId());
+        analysisPreviewDTO = redisCache.getCacheObject(String.format("%s:%d:%d:%d",DATA_OVERVIEW_DEALER_ANALYSISPREVIEW,type,userType,param.getCompanyId()));
+
+        return R.ok().put("data",analysisPreviewDTO);
+    }
+
+
+    /**
+     * 消费余额
+     */
+    @GetMapping("/rechargeComsumption")
+    public R rechargeComsumption(){
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        Long companyId = loginUser.getCompany().getCompanyId();
+
+        ConsumptionBalanceDataDTO consumptionBalanceDataDTO = redisCache.getCacheObject(String.format("%s:%d",StatisticsRedisConstant.DATA_OVERVIEW_DEALER_BALANCE,companyId));
+        return R.ok().put("data", consumptionBalanceDataDTO);
+    }
+
+    /**
+     * 获取统计流量
+     * @return
+     */
+    @GetMapping("/trafficLog")
+    public R getTrafficLog(){
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        Long companyId = loginUser.getCompany().getCompanyId();
+        TrafficLogDTO trafficLogDTO = redisCache.getCacheObject(String.format("%s:%d",DATA_OVERVIEW_TRAFFIC_LOG,companyId));
+        return R.ok().put("data",trafficLogDTO);
+    }
+
+    /**
+     * 观看趋势
+     */
+    @PostMapping("/watchEndPlayTrend")
+    public R watchEndPlayTrend(@RequestBody AnalysisPreviewQueryDTO param){
+        Integer type = param.getType();
+        Integer userType = param.getUserType();
+
+        if(type == null) {
+            type = 0;
+        }
+        if(userType == null){
+            userType = 0;
+        }
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        Long companyId = loginUser.getCompany().getCompanyId();
+        param.setCompanyId(companyId);
+
+        String key = String.format("%s:%d:%d:%d", DATA_OVERVIEW_DEALER_CHARTS, type,userType,param.getCompanyId());
+        List<DeaMemberTopTenDTO> deaMemberTopTenDTOS = redisCache.getCacheObject(key);
+        return R.ok().put("data", deaMemberTopTenDTOS);
+    }
+
+    /**
+     * 经销商会员观看
+     */
+    @PostMapping("/deaMemberTopTen")
+    public R deaMemberTopTen(@RequestBody AnalysisPreviewQueryDTO param){
+        Integer type = param.getType();
+        Integer statisticalType = param.getStatisticalType();
+        Integer userType = param.getUserType();
+
+        if(type == null) {
+            type = 0;
+        }
+        if(userType == null){
+            userType = 0;
+        }
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        Long companyId = loginUser.getCompany().getCompanyId();
+        param.setCompanyId(companyId);
+
+        List<DeaMemberTopTenDTO> deaMemberTopTenDTOS = redisCache.getCacheObject(String.format("%s:%d:%d:%d:%d", CHARTS_MEMBER_TOP_TEN_WATCH, type, statisticalType,userType,param.getCompanyId()));
+        if(deaMemberTopTenDTOS == null){
+            deaMemberTopTenDTOS = new ArrayList<>();
+        }
+        return R.ok().put("data", deaMemberTopTenDTOS);
+    }
+
+    /**
+     * 奖励金额top10
+     */
+    @PostMapping("/rewardMoneyTopTen")
+    public R rewardMoneyTopTen(@RequestBody AnalysisPreviewQueryDTO param){
+        Integer type = param.getType();
+        Integer dataType = param.getDataType();
+        Integer userType = param.getUserType();
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        Long companyId = loginUser.getCompany().getCompanyId();
+        param.setCompanyId(companyId);
+
+        List<RewardMoneyTopTenDTO> rewardMoneyTopTenDTOS = redisCache.getCacheObject( String.format("%s:%d:%d:%d:%d", CHARTS_REWARD_MONEY_TOP_TEN, type,dataType,userType,param.getCompanyId()));
+        return R.ok().put("data", rewardMoneyTopTenDTOS);
+    }
+
+    /**
+     * 答题红包金额趋势图
+     */
+    @PostMapping("/rewardMoneyTrend")
+    public R rewardMoneyTrend(@RequestBody AnalysisPreviewQueryDTO param){
+        Integer type = param.getType();
+        Integer userType = param.getUserType();
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        Long companyId = loginUser.getCompany().getCompanyId();
+        param.setCompanyId(companyId);
+
+        List<RewardMoneyTrendDTO> rewardMoneyTrendDTOS = redisCache.getCacheObject( String.format("%s:%d:%d:%d", CHARTS_REWARD_MONEY_TREND, type,userType,param.getCompanyId()));
+        return R.ok().put("data", rewardMoneyTrendDTOS);
+    }
+
+    /**
+     * 课程观看top10
+     */
+    @PostMapping("/watchCourseTopTen")
+    public R watchCourseTopTen(@RequestBody AnalysisPreviewQueryDTO param){
+        Integer type = param.getType();
+        String sort = param.getSort();
+        Integer statisticalType = param.getStatisticalType();
+        Integer userType = param.getUserType();
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        Long companyId = loginUser.getCompany().getCompanyId();
+        param.setCompanyId(companyId);
+
+        List<CourseStatsDTO> courseStatsDTOS = redisCache.getCacheObject(String.format("%s:%d:%d:%d:%s:%d", CHARTS_WATCH_TOP_TEN, type,statisticalType,userType,sort,param.getCompanyId()));
+        return R.ok().put("data", courseStatsDTOS);
+    }
+
+    /**
+     * 数据概览
+     */
+    @GetMapping("/dealerAggregated")
+    public R dealerAggregated(){
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        Long companyId = loginUser.getCompany().getCompanyId();
+
+        DealerAggregatedDTO dealerAggregatedDTO = redisCache.getCacheObject(String.format("%s:%d",StatisticsRedisConstant.DATA_OVERVIEW_DEALER_AGGREGATED,companyId));
+
+        return R.ok().put("data",dealerAggregatedDTO);
+    }
+
+    /**
+     * 短信余额
+     */
+    @GetMapping("/smsBalance")
+    public R smsBalance(){
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        Long companyId = loginUser.getCompany().getCompanyId();
+
+        Long smsBalance = redisCache.getCacheObject(String.format("%s:%d",StatisticsRedisConstant.DATA_OVERVIEW_DEALER_SMS_BALANCE,companyId));
+
+        return R.ok().put("data", smsBalance);
+    }
+
+
+    /**
+     * 授权信息
+     */
+    @GetMapping("/authorizationInfo")
+    public R authorizationInfo(){
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        Long companyId = loginUser.getCompany().getCompanyId();
+
+        AuthorizationInfoDTO authorizationInfoDTO = redisCache.getCacheObject(String.format("%s:%d",StatisticsRedisConstant.DATA_OVERVIEW_DEALER_AUTHORIZATION_INFO,companyId));
+
+        return R.ok().put("data", authorizationInfoDTO);
+    }
+
+
+    /**
+     * 当月订单数统计
+     * @return
+     */
+    @GetMapping("/thisMonthOrderCount")
+    public R thisMonthOrderCount(){
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        Long companyId = loginUser.getCompany().getCompanyId();
+
+        R result = redisCache.getCacheObject(String.format("%s:%d",StatisticsRedisConstant.THIS_MONTH_ORDER_COUNT,companyId));
+        return result;
+    }
+
+    /**
+     * 当月收益统计
+     * @return
+     */
+    @GetMapping("/thisMonthRecvCount")
+    public R thisMonthRecvCount(){
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        Long companyId = loginUser.getCompany().getCompanyId();
+
+        R result = redisCache.getCacheObject(String.format("%s:%d",StatisticsRedisConstant.THIS_MONTH_RECV_COUNT,companyId));
+        return result;
+    }
+}

+ 11 - 2
fs-service-system/src/main/java/com/fs/company/mapper/CompanyMapper.java

@@ -1,7 +1,5 @@
 package com.fs.company.mapper;
 
-import java.math.BigDecimal;
-import java.util.List;
 import com.fs.company.domain.Company;
 import com.fs.company.param.CompanyParam;
 import com.fs.company.vo.CompanyCrmVO;
@@ -12,6 +10,10 @@ import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
 import org.apache.ibatis.annotations.Update;
 
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
+
 /**
  * 企业Mapper接口
  *
@@ -146,4 +148,11 @@ public interface CompanyMapper
     List<OptionsVO> selectAllCompanyList();
 
     void updateMoney(@Param("id") Long id, @Param("money") BigDecimal money);
+
+    /**
+     * 根据条件查询公司选项列表
+     * @param params    参数
+     * @return list
+     */
+    List<OptionsVO> selectCompanyListByMap(@Param("params") Map<String, Object> params);
 }

+ 8 - 0
fs-service-system/src/main/java/com/fs/company/mapper/CompanyUserMapper.java

@@ -7,6 +7,7 @@ import com.fs.company.vo.CompanyQwUserByIdsVo;
 import com.fs.company.vo.CompanyUserQwListVO;
 import com.fs.company.vo.CompanyUserVO;
 import com.fs.company.vo.DocCompanyUserVO;
+import com.fs.his.vo.OptionsVO;
 import com.fs.qw.param.QwWatchLogStatisticsListParam;
 import com.fs.qw.vo.CompanyUserQwVO;
 import com.fs.qw.vo.QwUserVO;
@@ -16,6 +17,7 @@ import org.apache.ibatis.annotations.Select;
 import org.apache.ibatis.annotations.Update;
 
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -279,4 +281,10 @@ public interface CompanyUserMapper
     @Select("select * from company_user where phonenumber = #{phoneNumber}")
     CompanyUser getCompanyUserByPhone(String phoneNumber);
 
+    /**
+     * 查询销售选项列表
+     * @param params    参数
+     * @return  list
+     */
+    List<OptionsVO> selectCompanyUserListByMap(@Param("params") Map<String, Object> params);
 }

+ 12 - 5
fs-service-system/src/main/java/com/fs/company/service/ICompanyService.java

@@ -1,18 +1,18 @@
 package com.fs.company.service;
 
-import java.math.BigDecimal;
-import java.util.List;
-import java.util.Map;
-
 import com.fs.common.core.domain.R;
 import com.fs.company.domain.Company;
 import com.fs.company.param.CompanyParam;
 import com.fs.company.vo.CompanyCrmVO;
 import com.fs.company.vo.CompanyNameVO;
 import com.fs.company.vo.CompanyVO;
+import com.fs.his.vo.OptionsVO;
 import com.fs.store.domain.FsStoreOrder;
 import com.fs.store.domain.FsStorePayment;
-import com.fs.his.vo.OptionsVO;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
 
 /**
  * 企业Service接口
@@ -107,4 +107,11 @@ public interface ICompanyService
     void updateMoney(Long companyId, BigDecimal money);
 
     void configUserCheck(Long companyId, Integer userIsDefaultBlack);
+
+    /**
+     * 根据条件查询公司选项列表
+     * @param params    参数
+     * @return list
+     */
+    List<OptionsVO> selectCompanyListByMap(Map<String, Object> params);
 }

+ 8 - 1
fs-service-system/src/main/java/com/fs/company/service/ICompanyUserService.java

@@ -9,9 +9,9 @@ import com.fs.company.vo.CompanyUserQwListVO;
 import com.fs.company.vo.CompanyUserVO;
 import com.fs.company.vo.DocCompanyUserVO;
 import com.fs.his.vo.CitysAreaVO;
+import com.fs.his.vo.OptionsVO;
 import com.fs.qw.vo.CompanyUserQwVO;
 import com.fs.qw.vo.QwUserVO;
-import com.fs.his.vo.OptionsVO;
 
 import java.util.List;
 import java.util.Map;
@@ -181,4 +181,11 @@ public interface ICompanyUserService {
      * @return
      */
     int changeCompanyUser(List<Long> userIds, Long companyUserId, Long companyId);
+
+    /**
+     * 查询销售选项列表
+     * @param params    参数
+     * @return  list
+     */
+    List<OptionsVO> selectCompanyUserListByMap(Map<String, Object> params);
 }

+ 17 - 5
fs-service-system/src/main/java/com/fs/company/service/impl/CompanyServiceImpl.java

@@ -1,32 +1,34 @@
 package com.fs.company.service.impl;
 
-import java.math.BigDecimal;
-import java.util.*;
-
 import cn.hutool.json.JSONUtil;
 import com.fs.common.core.domain.R;
 import com.fs.common.utils.DateUtils;
 import com.fs.company.domain.*;
 import com.fs.company.mapper.*;
 import com.fs.company.param.CompanyParam;
+import com.fs.company.service.ICompanyService;
 import com.fs.company.vo.CompanyCrmVO;
 import com.fs.company.vo.CompanyNameVO;
 import com.fs.company.vo.CompanyVO;
 import com.fs.course.mapper.FsCourseRedPacketLogMapper;
+import com.fs.his.vo.OptionsVO;
 import com.fs.store.config.StoreConfig;
 import com.fs.store.domain.FsStoreOrder;
 import com.fs.store.domain.FsStorePayment;
 import com.fs.store.mapper.FsStoreOrderMapper;
-import com.fs.his.vo.OptionsVO;
 import com.fs.system.service.ISysConfigService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
-import com.fs.company.service.ICompanyService;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
 /**
  * 企业Service业务层处理
  *
@@ -447,4 +449,14 @@ public class CompanyServiceImpl implements ICompanyService
             companyMapper.updateCompany(company);
         }
     }
+
+    /**
+     * 根据条件查询公司选项列表
+     * @param params    参数
+     * @return list
+     */
+    @Override
+    public List<OptionsVO> selectCompanyListByMap(Map<String, Object> params) {
+        return companyMapper.selectCompanyListByMap(params);
+    }
 }

+ 15 - 2
fs-service-system/src/main/java/com/fs/company/service/impl/CompanyUserServiceImpl.java

@@ -11,10 +11,13 @@ import com.fs.company.domain.*;
 import com.fs.company.mapper.*;
 import com.fs.company.param.CompanyUserAreaParam;
 import com.fs.company.param.CompanyUserQwParam;
-import com.fs.company.param.CompanyVoiceCallerParam;
 import com.fs.company.service.ICompanyUserService;
-import com.fs.company.vo.*;
+import com.fs.company.vo.CompanyQwUserByIdsVo;
+import com.fs.company.vo.CompanyUserQwListVO;
+import com.fs.company.vo.CompanyUserVO;
+import com.fs.company.vo.DocCompanyUserVO;
 import com.fs.his.vo.CitysAreaVO;
+import com.fs.his.vo.OptionsVO;
 import com.fs.qw.vo.CompanyUserQwVO;
 import com.fs.qw.vo.QwUserVO;
 import com.fs.his.vo.OptionsVO;
@@ -461,6 +464,16 @@ public class CompanyUserServiceImpl implements ICompanyUserService
        return fsUserMapper.batchUpdateUserCompanyUser(userIds, companyUserId, companyId);
     }
 
+    /**
+     * 查询销售选项列表
+     * @param params    参数
+     * @return  list
+     */
+    @Override
+    public List<OptionsVO> selectCompanyUserListByMap(Map<String, Object> params) {
+        return companyUserMapper.selectCompanyUserListByMap(params);
+    }
+
     /**
      * 批量审核用户
      * @param userIds 用户ID集合

+ 4 - 0
fs-service-system/src/main/java/com/fs/course/domain/FsUserCoursePeriod.java

@@ -78,6 +78,10 @@ public class FsUserCoursePeriod
     @Excel(name = "开营日期-结束时间", width = 30, dateFormat = "yyyy-MM-dd")
     private LocalDate periodEndTime;
 
+    /** 营期状态,1-未开始,2-进行中,3-已结束 */
+    @Excel(name = "营期状态,1-未开始,2-进行中,3-已结束")
+    private Long periodStatus;
+
     @TableField(exist = false)
     private List<Long> companyIdList;
 }

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

@@ -80,17 +80,20 @@ public interface FsCourseTrafficLogMapper
      * @return Long
      */
     Long getTodayTrafficLog();
+    Long getTodayTrafficLogCompanyId(@Param("companyId") Long companyId);
 
     /**
      * 获取当月统计流量
      * @return Long
      */
     Long getMonthTrafficLog();
+    Long getMonthTrafficLogCompanyId(@Param("companyId") Long companyId);
 
     /**
      * 昨天
      * @return Long
      */
     Long getYesterdayTrafficLog();
+    Long getYesterdayTrafficLogCompanyId(@Param("companyId") Long companyId);
 
 }

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

@@ -1,8 +1,5 @@
 package com.fs.course.mapper;
 
-import java.util.List;
-import java.util.Map;
-
 import com.fs.course.domain.FsUserCourse;
 import com.fs.course.param.FsUserCourseAddStudyCourseParam;
 import com.fs.course.param.FsUserCourseListUParam;
@@ -15,6 +12,9 @@ import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
 import org.apache.ibatis.annotations.Update;
 
+import java.util.List;
+import java.util.Map;
+
 /**
  * 课程Mapper接口
  *

+ 17 - 4
fs-service-system/src/main/java/com/fs/course/mapper/FsUserCoursePeriodDaysMapper.java

@@ -1,12 +1,13 @@
 package com.fs.course.mapper;
 
-import java.util.List;
-import java.util.Set;
-
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.fs.course.domain.FsUserCoursePeriodDays;
+import com.fs.his.vo.OptionsVO;
 import org.apache.ibatis.annotations.Param;
-import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * 营期课程Mapper接口
@@ -70,4 +71,16 @@ public interface FsUserCoursePeriodDaysMapper extends BaseMapper<FsUserCoursePer
      */
     List<FsUserCoursePeriodDays> selectCourseVideoList(@Param("periodIds") Set<Long> periodIds);
 
+    /**
+     * 查询营期选项列表
+     * @param params    参数
+     * @return  list
+     */
+    List<OptionsVO> selectPeriodListByMap(@Param("params") Map<String, Object> params);
+    /**
+     * 批量修改
+     * @param fsUserCoursePeriodDaysList
+     */
+    void batchUpdateCoursePeriodDays(List<FsUserCoursePeriodDays> fsUserCoursePeriodDaysList);
+
 }

+ 11 - 4
fs-service-system/src/main/java/com/fs/course/mapper/FsUserCoursePeriodMapper.java

@@ -1,15 +1,16 @@
 package com.fs.course.mapper;
 
-import java.util.List;
-import java.util.Set;
-
 import com.fs.course.domain.FsUserCoursePeriod;
 import com.fs.course.param.CompanyRedPacketParam;
-import com.fs.course.vo.PeriodRedPacketVO;
 import com.fs.course.vo.FsUserCoursePeriodVO;
+import com.fs.course.vo.PeriodRedPacketVO;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
 
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 /**
  * 会员营期Mapper接口
  *
@@ -104,4 +105,10 @@ public interface FsUserCoursePeriodMapper
      */
     List<FsUserCoursePeriod> selectFsUserCoursePeriodsByIds(@Param("periodIds") Set<Long> periodIds);
 
+    /**
+     * 查询训练营进行中的营期条数
+     * @param params    参数
+     * @return  count
+     */
+    int countPeriodByCampIds(@Param("params") Map<String, Object> params);
 }

+ 8 - 0
fs-service-system/src/main/java/com/fs/course/mapper/FsUserCourseTrainingCampMapper.java

@@ -4,6 +4,7 @@ package com.fs.course.mapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.fs.course.domain.FsUserCourseTrainingCamp;
 import com.fs.course.vo.FsUserCourseTrainingCampVO;
+import com.fs.his.vo.OptionsVO;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
 
@@ -32,4 +33,11 @@ public interface FsUserCourseTrainingCampMapper extends BaseMapper<FsUserCourseT
      */
     @Select("select ifnull(max(order_number), 0) + 1 from fs_user_course_training_camp")
     Long getOrderNumber();
+
+    /**
+     * 查询训练营选项列表
+     * @param params    参数
+     * @return  list
+     */
+    List<OptionsVO> selectCampListByMap(@Param("params") Map<String, Object> params);
 }

+ 11 - 4
fs-service-system/src/main/java/com/fs/course/mapper/FsUserCourseVideoMapper.java

@@ -1,9 +1,5 @@
 package com.fs.course.mapper;
 
-import java.math.BigDecimal;
-import java.util.List;
-import java.util.Map;
-
 import com.fs.course.domain.FsUserCourseVideo;
 import com.fs.course.param.CourseVideoUpdates;
 import com.fs.course.param.FsUserCourseVideoListUParam;
@@ -16,6 +12,10 @@ import com.fs.his.vo.OptionsVO;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
 
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
+
 /**
  * 课堂视频Mapper接口
  *
@@ -173,4 +173,11 @@ public interface FsUserCourseVideoMapper
     void insertBatchFsUserCourseVideo(@Param("collect") List<FsUserCourseVideo> collect);
 
     void updateRedPacketMoney(@Param("videoId") Long videoId, @Param("redPacketMoney") BigDecimal redPacketMoney);
+
+    /**
+     * 获取选项列表
+     * @param params    参数
+     * @return  list
+     */
+    List<OptionsVO> selectVideoListByMap(@Param("params") Map<String, Object> params);
 }

+ 21 - 2
fs-service-system/src/main/java/com/fs/course/service/IFsUserCoursePeriodDaysService.java

@@ -1,13 +1,16 @@
 package com.fs.course.service;
 
-import java.util.List;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.fs.common.core.domain.R;
 import com.fs.course.domain.FsUserCoursePeriodDays;
 import com.fs.course.param.CompanyRedPacketParam;
 import com.fs.course.param.PeriodCountParam;
-import com.fs.course.vo.PeriodRedPacketVO;
 import com.fs.course.vo.FsPeriodCountVO;
+import com.fs.course.vo.PeriodRedPacketVO;
+import com.fs.his.vo.OptionsVO;
+
+import java.util.List;
+import java.util.Map;
 
 /**
  * 营期课程Service接口
@@ -90,4 +93,20 @@ public interface IFsUserCoursePeriodDaysService extends IService<FsUserCoursePer
      * @return
      */
     List<FsPeriodCountVO> periodCourseCount(PeriodCountParam param);
+
+    /**
+     * 查询营期选项列表
+     * @param params    参数
+     * @return  list
+     */
+    List<OptionsVO> selectPeriodListByMap(Map<String, Object> params);
+
+    /**
+     * 上移/下移(调整课程的营期时间)
+     * @param id 当前数据
+     * @param targetId 需要移动到的数据
+     * @return
+     */
+    R periodCourseMove(Long id, Long targetId);
+
 }

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

@@ -1,10 +1,5 @@
 package com.fs.course.service;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.List;
-import java.util.Map;
-
 import com.fs.common.core.domain.R;
 import com.fs.course.domain.FsUserCourse;
 import com.fs.course.param.*;
@@ -13,6 +8,11 @@ import com.fs.course.vo.*;
 import com.fs.course.vo.newfs.FsUserCourseListVO;
 import com.fs.his.vo.OptionsVO;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+
 /**
  * 课程Service接口
  *

+ 8 - 1
fs-service-system/src/main/java/com/fs/course/service/IFsUserCourseTrainingCampService.java

@@ -5,8 +5,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.fs.course.domain.FsUserCourseTrainingCamp;
 import com.fs.course.dto.FsUserCourseTrainingCampDTO;
 import com.fs.course.vo.FsUserCourseTrainingCampVO;
+import com.fs.his.vo.OptionsVO;
 
-import javax.validation.Valid;
 import java.util.List;
 import java.util.Map;
 
@@ -43,4 +43,11 @@ public interface IFsUserCourseTrainingCampService extends IService<FsUserCourseT
      * @param id    id
      */
     void copy(Long id);
+
+    /**
+     * 查询训练营选项列表
+     * @param params    参数
+     * @return  list
+     */
+    List<OptionsVO> selectCampListByMap(Map<String, Object> params);
 }

+ 10 - 2
fs-service-system/src/main/java/com/fs/course/service/IFsUserCourseVideoService.java

@@ -9,12 +9,13 @@ import com.fs.course.param.newfs.FsUserCourseVideoLinkParam;
 import com.fs.course.param.newfs.FsUserCourseVideoUParam;
 import com.fs.course.param.newfs.UserCourseVideoPageParam;
 import com.fs.course.vo.FsUserCourseVideoListUVO;
+import com.fs.course.vo.FsUserCourseVideoQVO;
+import com.fs.course.vo.FsUserCourseVideoVO;
 import com.fs.course.vo.newfs.FsUserCourseVideoDetailsVO;
 import com.fs.course.vo.newfs.FsUserCourseVideoLinkDetailsVO;
 import com.fs.course.vo.newfs.FsUserCourseVideoPageListVO;
-import com.fs.course.vo.FsUserCourseVideoQVO;
-import com.fs.course.vo.FsUserCourseVideoVO;
 import com.fs.course.vo.newfs.FsUserVideoListVO;
+import com.fs.his.vo.OptionsVO;
 
 import java.util.List;
 import java.util.Map;
@@ -149,4 +150,11 @@ public interface IFsUserCourseVideoService
     void batchSaveVideo(BatchVideoSvae vo);
 
     void batchUpdateRed(List<BatchRedUpdate> list);
+
+    /**
+     * 获取选项列表
+     * @param params    参数
+     * @return  list
+     */
+    List<OptionsVO> selectVideoListByMap(Map<String, Object> params);
 }

+ 1 - 1
fs-service-system/src/main/java/com/fs/course/service/impl/FsCourseWatchLogServiceImpl.java

@@ -890,7 +890,7 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
                 //判断是否完课
                 long percentage = (duration * 100 / videoDuration);
                 if (percentage >= config.getAnswerRate()) {
-                    watchLog.setLogType(2); // 设置状态为“已完成”
+                    watchLog.setLogType(2); // 设置状态为“已完成”checkFsUserWatchStatus
                     watchLog.setFinishTime(new Date());
                     String heartbeatKey ="h5wxuser:watch:heartbeat:" + userId+ ":" + videoId + ":" + companyUserId;
                     // 完课删除心跳记录

+ 64 - 8
fs-service-system/src/main/java/com/fs/course/service/impl/FsUserCoursePeriodDaysServiceImpl.java

@@ -2,34 +2,45 @@ package com.fs.course.service.impl;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
+import java.sql.Wrapper;
+import java.time.LocalDate;
+import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fs.common.core.domain.R;
 import com.fs.common.utils.DateUtils;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fs.common.utils.date.DateUtil;
 import com.fs.common.utils.date.TimeTypeEnum;
 import com.fs.course.domain.FsUserCoursePeriod;
+import com.fs.course.domain.FsUserCoursePeriodDays;
+import com.fs.course.mapper.FsUserCoursePeriodDaysMapper;
 import com.fs.course.mapper.FsUserCoursePeriodMapper;
 import com.fs.course.param.CompanyRedPacketParam;
 import com.fs.course.param.PeriodCountParam;
-import com.fs.course.vo.PeriodRedPacketVO;
+import com.fs.course.service.IFsUserCoursePeriodDaysService;
 import com.fs.course.vo.FsPeriodCountVO;
+import com.fs.course.vo.PeriodRedPacketVO;
 import com.fs.course.vo.newfs.FsCourseAnalysisCountVO;
+import com.fs.his.vo.OptionsVO;
 import com.fs.store.mapper.FsUserMapper;
 import com.fs.store.param.h5.CourseAnalysisParam;
 import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
-import com.fs.course.mapper.FsUserCoursePeriodDaysMapper;
-import com.fs.course.domain.FsUserCoursePeriodDays;
-import com.fs.course.service.IFsUserCoursePeriodDaysService;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 /**
  * 营期课程Service业务层处理
@@ -39,12 +50,15 @@ import com.fs.course.service.IFsUserCoursePeriodDaysService;
  */
 @Service
 @AllArgsConstructor
+@Slf4j
 public class FsUserCoursePeriodDaysServiceImpl extends ServiceImpl<FsUserCoursePeriodDaysMapper, FsUserCoursePeriodDays> implements IFsUserCoursePeriodDaysService {
 
     private final FsUserCoursePeriodMapper fsUserCoursePeriodMapper;
 
     private final FsUserMapper  fsUserMapper;
 
+    private final FsUserCoursePeriodDaysMapper fsUserCoursePeriodDaysMapper;
+
     /**
      * 查询营期课程
      *
@@ -218,6 +232,38 @@ public class FsUserCoursePeriodDaysServiceImpl extends ServiceImpl<FsUserCourseP
         }).collect(Collectors.toList());
     }
 
+    @Override
+    public R periodCourseMove(Long id, Long targetId) {
+        List<Long> idList = new ArrayList<>();
+        idList.add(id);
+        idList.add(targetId);
+        List<FsUserCoursePeriodDays> fsUserCoursePeriodDays = baseMapper.selectBatchIds(idList);
+        if(fsUserCoursePeriodDays.isEmpty()){
+            return R.error(404, "当前数据或者移动的目标数据不存在");
+        }
+
+        List<FsUserCoursePeriodDays> list = new ArrayList<>();
+        FsUserCoursePeriodDays periodDays = fsUserCoursePeriodDays.get(0);
+        LocalDate currentDayDate = periodDays.getDayDate();
+        Integer lesson = periodDays.getLesson();
+
+        FsUserCoursePeriodDays periodDaysTarget = fsUserCoursePeriodDays.get(1);
+        periodDays.setDayDate(periodDaysTarget.getDayDate());
+        periodDays.setLesson(periodDaysTarget.getLesson());
+        list.add(periodDays);
+
+        periodDaysTarget.setDayDate(currentDayDate);
+        periodDaysTarget.setLesson(lesson);
+        list.add(periodDaysTarget);
+        try {
+            fsUserCoursePeriodDaysMapper.batchUpdateCoursePeriodDays(list);
+        } catch (RuntimeException e) {
+            log.error("上移/下移异常,当前id:{}, 目标id:{}", id, targetId);
+            return R.error();
+        }
+        return R.ok();
+    }
+
     private static FsCourseAnalysisCountVO getCourseAnalysisCountVO(FsUserCoursePeriodDays v, Map<Long, FsCourseAnalysisCountVO> courseMap, Map<Long, FsCourseAnalysisCountVO> redPacketMap, Map<Long, FsCourseAnalysisCountVO> answerMap) {
         FsCourseAnalysisCountVO countVO = new FsCourseAnalysisCountVO();
         FsCourseAnalysisCountVO courseVO = courseMap.getOrDefault(v.getVideoId(), countVO);
@@ -234,4 +280,14 @@ public class FsUserCoursePeriodDaysServiceImpl extends ServiceImpl<FsUserCourseP
                 .setAnswerTimes(answerVO.getAnswerTimes()).setAnswerRightTimes(answerVO.getAnswerRightTimes());
         return countVO;
     }
+
+    /**
+     * 查询营期选项列表
+     * @param params    参数
+     * @return  list
+     */
+    @Override
+    public List<OptionsVO> selectPeriodListByMap(Map<String, Object> params) {
+        return baseMapper.selectPeriodListByMap(params);
+    }
 }

+ 32 - 7
fs-service-system/src/main/java/com/fs/course/service/impl/FsUserCourseTrainingCampServiceImpl.java

@@ -2,27 +2,25 @@ package com.fs.course.service.impl;
 
 
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fs.common.exception.ServiceException;
-import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.bean.BeanUtils;
 import com.fs.course.domain.FsUserCoursePeriod;
 import com.fs.course.domain.FsUserCoursePeriodDays;
+import com.fs.course.domain.FsUserCourseTrainingCamp;
 import com.fs.course.dto.FsUserCourseTrainingCampDTO;
-import com.fs.course.mapper.FsUserCoursePeriodDaysMapper;
 import com.fs.course.mapper.FsUserCoursePeriodMapper;
+import com.fs.course.mapper.FsUserCourseTrainingCampMapper;
 import com.fs.course.service.IFsUserCoursePeriodDaysService;
+import com.fs.course.service.IFsUserCourseTrainingCampService;
 import com.fs.course.vo.FsUserCourseTrainingCampVO;
-import com.fs.store.service.IFsUserService;
+import com.fs.his.vo.OptionsVO;
 import lombok.AllArgsConstructor;
 import org.springframework.stereotype.Service;
-import com.fs.course.mapper.FsUserCourseTrainingCampMapper;
-import com.fs.course.domain.FsUserCourseTrainingCamp;
-import com.fs.course.service.IFsUserCourseTrainingCampService;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.util.*;
 import java.util.stream.Collectors;
@@ -68,11 +66,28 @@ public class FsUserCourseTrainingCampServiceImpl extends ServiceImpl<FsUserCours
      * 删除训练营
      * @param ids   ids
      */
+    @Transactional(rollbackFor = Exception.class)
     @Override
     public void del(Long[] ids) {
+        // 检查是否存在进行中的营期
+        if (checkPeriodStatus(ids)) {
+            throw new ServiceException("存在进行中的营期,请营期结束后再操作");
+        }
+
         baseMapper.deleteBatchIds(Arrays.asList(ids));
     }
 
+    /**
+     * 检查是否存在进行中的营期
+     * @param ids 训练营ID集合
+     */
+    private boolean checkPeriodStatus(Long[] ids) {
+        Map<String, Object> params = new HashMap<>();
+        params.put("ids", ids);
+        params.put("date", LocalDate.now());
+        return fsUserCoursePeriodMapper.countPeriodByCampIds(params) > 0;
+    }
+
     /**
      * 复制训练营
      * @param id    id
@@ -114,4 +129,14 @@ public class FsUserCourseTrainingCampServiceImpl extends ServiceImpl<FsUserCours
             }
         });
     }
+
+    /**
+     * 查询训练营选项列表
+     * @param params    参数
+     * @return  list
+     */
+    @Override
+    public List<OptionsVO> selectCampListByMap(Map<String, Object> params) {
+        return baseMapper.selectCampListByMap(params);
+    }
 }

+ 24 - 13
fs-service-system/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -27,13 +27,7 @@ import com.fs.course.vo.FsUserCourseVideoQVO;
 import com.fs.course.vo.FsUserCourseVideoVO;
 import com.fs.course.vo.newfs.*;
 import com.fs.his.param.WxSendRedPacketParam;
-import com.fs.sop.mapper.SopUserLogsInfoMapper;
-import com.fs.store.domain.FsUser;
-import com.fs.store.domain.FsUserIntegralLogs;
-import com.fs.store.mapper.FsUserIntegralLogsMapper;
-import com.fs.store.mapper.FsUserMapper;
-import com.fs.store.service.IFsStorePaymentService;
-import com.fs.store.service.IFsUserService;
+import com.fs.his.vo.OptionsVO;
 import com.fs.qw.domain.QwExternalContact;
 import com.fs.qw.domain.QwUser;
 import com.fs.qw.mapper.QwExternalContactMapper;
@@ -42,26 +36,29 @@ import com.fs.qwApi.Result.QwAddContactWayResult;
 import com.fs.qwApi.param.QwAddContactWayParam;
 import com.fs.qwApi.service.QwApiService;
 import com.fs.sop.mapper.QwSopLogsMapper;
+import com.fs.sop.mapper.SopUserLogsInfoMapper;
+import com.fs.store.domain.FsUser;
+import com.fs.store.domain.FsUserIntegralLogs;
+import com.fs.store.mapper.FsUserIntegralLogsMapper;
+import com.fs.store.mapper.FsUserMapper;
+import com.fs.store.service.IFsStorePaymentService;
+import com.fs.store.service.IFsUserService;
 import com.fs.store.service.cache.IFsUserCourseCacheService;
 import com.fs.system.service.ISysConfigService;
 import com.github.binarywang.wxpay.bean.transfer.TransferBillsResult;
+import lombok.extern.slf4j.Slf4j;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.util.CollectionUtils;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.time.LocalDateTime;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.stream.Collectors;
 
@@ -71,6 +68,7 @@ import java.util.stream.Collectors;
  * @author fs
  * @date 2024-05-17
  */
+@Slf4j
 @Service
 public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
 {
@@ -308,6 +306,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
 
         // 从Redis中获取观看时长
         String redisKey = "h5user:watch:duration:" + param.getQwUserId()+ ":" + param.getQwExternalId() + ":" + param.getVideoId();
+        log.info("看课redis-key:{}", redisKey);
         try {
             String durationStr = redisCache.getCacheObject(redisKey);
             Long duration = durationStr != null ? Long.parseLong(durationStr) : 0L;
@@ -1021,8 +1020,10 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
 
         // 从Redis中获取观看时长
         String redisKey = "h5wxuser:watch:duration:" + param.getUserId() + ":" + param.getVideoId() + ":" + param.getCompanyUserId();
+        log.info("看课redis缓存key:{}", redisKey);
         try {
             String durationStr = redisCache.getCacheObject(redisKey);
+            log.info("看课记录:{}", durationStr);
             long duration = durationStr != null ? Long.parseLong(durationStr) : 0L;
 
             // 更新Redis中的观看时长
@@ -1085,6 +1086,16 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         });
     }
 
+    /**
+     * 获取选项列表
+     * @param params    参数
+     * @return  list
+     */
+    @Override
+    public List<OptionsVO> selectVideoListByMap(Map<String, Object> params) {
+        return fsUserCourseVideoMapper.selectVideoListByMap(params);
+    }
+
     //会员-更新心跳时间
     public void updateHeartbeatWx(FsUserCourseVideoUParam param) {
         String redisKey = "h5wxuser:watch:heartbeat:" + param.getUserId() + ":" + param.getVideoId() + ":" + param.getCompanyUserId();

+ 2 - 2
fs-service-system/src/main/java/com/fs/course/service/impl/TencentCloudCosService.java

@@ -45,10 +45,10 @@ public class TencentCloudCosService implements ITencentCloudCosService {
 
     private static final String YL_SECRET_ID = "AKIDiMq9lDf2EOM9lIfqqfKo7FNgM5meD0sT";
     private static final String YL_SECRET_KEY = "u5SuS80342xzx8FRBukza9lVNHKNMSaB";
-    private static final String YL_BUCKET = "fby-1323137866";
+    private static final String YL_BUCKET = "hylj-1323137866";
     private static final String YL_APP_ID = "1323137866";
     private static final String YL_REGION = "ap-chongqing";
-    private static final String YL_PROXY = "fby";
+    private static final String YL_PROXY = "hylj";
     @Override
     public R getTmpSecretKey() {
         TreeMap<String, Object> config = new TreeMap<String, Object>();

+ 3 - 0
fs-service-system/src/main/java/com/fs/course/vo/FsUserCoursePeriodVO.java

@@ -82,4 +82,7 @@ public class FsUserCoursePeriodVO implements Serializable {
     @Excel(name = "开营日期-结束时间", width = 30, dateFormat = "yyyy-MM-dd")
     private LocalDate periodEndTime;
 
+    @Excel(name = "营期状态")
+    private Long periodStatus;
+
 }

+ 39 - 48
fs-service-system/src/main/java/com/fs/sop/service/impl/QwSopTempServiceImpl.java

@@ -210,55 +210,46 @@ public class QwSopTempServiceImpl implements IQwSopTempService
             day.setName("第" + day.getDayNum() + "天");
             day.setSorts(day.getDayNum());
             day.setList(new ArrayList<>());
-            QwSopTempRules rules = new QwSopTempRules();
-            rules.setTempId(temp.getId());
-            rules.setName(day.getName());
-            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
-            rules.setTime(e.getViewStartTime().format(formatter));
-            rules.setContentType(2);
-            rules.setType(2);
-            rules.setCourseType(0);
-            rules.setCourseId(e.getCourseId());
-            rules.setVideoId(e.getVideoId());
-            rules.setSorts(0);
-            day.getList().add(rules);
-            QwSopTempContent content = new QwSopTempContent();
-            content.setTempId(temp.getId());
-            content.setContentType(3);
-            QwSopTempSetting2.Content.Setting setting = new QwSopTempSetting2.Content.Setting();
-            setting.setLinkTitle(fsUserCourse.getCourseName());
-            setting.setIsBindUrl(1);
-            setting.setLinkDescribe(e.getTitle());
-            setting.setLinkImageUrl(fsUserCourse.getImgUrl());
-            setting.setContentType("3");
-            content.setContent(JSON.toJSONString(setting));
-            content.setIsBindUrl(1);
-            rules.setList(Collections.singletonList(content));
-
-
-
-            if(temp.getTimeList() != null &&  !temp.getTimeList().isEmpty()){
-                AtomicInteger sorts = new AtomicInteger(1);
-                List<QwSopTempRules> rulesList = temp.getTimeList().stream().map(time -> {
-                    QwSopTempRules rulesSub = new QwSopTempRules();
-                    rulesSub.setTempId(temp.getId());
-                    rulesSub.setName(day.getName());
-                    rulesSub.setTime(time);
-                    rulesSub.setContentType(1);
-                    rulesSub.setType(1);
-                    rulesSub.setSorts(sorts.getAndIncrement());
-                    QwSopTempContent contentSbu = new QwSopTempContent();
-                    contentSbu.setTempId(temp.getId());
-                    contentSbu.setContentType(1);
-                    QwSopTempSetting2.Content.Setting settingSub = new QwSopTempSetting2.Content.Setting();
-                    settingSub.setContentType("1");
-                    settingSub.setValue("");
-                    contentSbu.setContent(JSON.toJSONString(settingSub));
-                    rulesSub.setList(Collections.singletonList(contentSbu));
-                    return rulesSub;
-                }).collect(Collectors.toList());
-                day.getList().addAll(rulesList);
+            if(temp.getTimeList() == null){
+                temp.setTimeList(new ArrayList<>());
             }
+            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
+            temp.getTimeList().add(0, e.getViewStartTime().format(formatter));
+            AtomicInteger sorts = new AtomicInteger(0);
+            List<QwSopTempRules> rulesList = temp.getTimeList().stream().map(time -> {
+                QwSopTempRules rules = new QwSopTempRules();
+                rules.setTempId(temp.getId());
+                rules.setName(day.getName());
+                rules.setTime(time);
+                rules.setContentType(2);
+                rules.setType(2);
+                rules.setCourseType(0);
+                rules.setCourseId(e.getCourseId());
+                rules.setVideoId(e.getVideoId());
+                rules.setSorts(sorts.getAndIncrement());
+                // 设置消息类型
+                if(rules.getSorts() == 0){
+                    rules.setCourseType(0);
+                }else if(rules.getSorts() == 1){
+                    rules.setCourseType(1);
+                }else{
+                    rules.setCourseType(4);
+                }
+                QwSopTempContent content = new QwSopTempContent();
+                content.setTempId(temp.getId());
+                content.setContentType(3);
+                QwSopTempSetting2.Content.Setting setting = new QwSopTempSetting2.Content.Setting();
+                setting.setLinkTitle(fsUserCourse.getCourseName());
+                setting.setIsBindUrl(1);
+                setting.setLinkDescribe(e.getTitle());
+                setting.setLinkImageUrl(fsUserCourse.getImgUrl());
+                setting.setContentType("3");
+                content.setContent(JSON.toJSONString(setting));
+                content.setIsBindUrl(1);
+                rules.setList(Collections.singletonList(content));
+                return rules;
+            }).collect(Collectors.toList());
+            day.getList().addAll(rulesList);
             return day;
         }).collect(Collectors.toList());
         qwSopTempDayService.addOrUpdateBatch(collect);

+ 149 - 0
fs-service-system/src/main/java/com/fs/statis/domain/FsStatsMemberDaily.java

@@ -0,0 +1,149 @@
+package com.fs.statis.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.time.LocalDate;
+
+@Data
+@TableName("fs_stats_member_daily")
+public class FsStatsMemberDaily {
+
+    /**
+     * 主键ID
+     */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 统计时间
+     */
+    private LocalDate statDate;
+
+    /**
+     * 用户ID
+     */
+    private Long userId;
+
+    /**
+     * 用户昵称
+     */
+    private String nickName;
+
+    /**
+     * 用户姓名
+     */
+    private String realName;
+
+    /**
+     * 用户手机号
+     */
+    private String phone;
+
+    /**
+     * 用户标签
+     */
+    private String tag;
+
+    /**
+     * 所属经销商分组
+     */
+    private Long companyGroupId;
+
+    /**
+     * 所属经销商
+     */
+    private Long companyId;
+
+    /**
+     * 所属经销商名称
+     */
+    private String companyName;
+
+    /**
+     * 所属群管
+     */
+    private Long companyUserId;
+
+    /**
+     * 所属群管名称
+     */
+    private String companyUserName;
+
+    /**
+     * 所属训练营
+     */
+    private Long trainCampId;
+
+    /**
+     * 所属训练营名称
+     */
+    private String trainCampName;
+
+    /**
+     * 所属营期
+     */
+    private Long periodId;
+
+    /**
+     * 所属营期名称
+     */
+    private String periodName;
+
+    /**
+     * 所属课程
+     */
+    private Long courseId;
+
+    /**
+     * 所属课程名称
+     */
+    private String courseName;
+
+    /**
+     * 所属小节
+     */
+    private Long videoId;
+
+    /**
+     * 所属小节名称
+     */
+    private String videoName;
+
+    /**
+     * 是否完课 0未完课 1已完课
+     */
+    private Integer isOver;
+
+    /**
+     * 观看次数
+     */
+    private Long watchCount;
+
+    /**
+     * 观看时长
+     */
+    private Long watchDuration;
+
+    /**
+     * 答题次数
+     */
+    private Long answerCount;
+
+    /**
+     * 正确次数
+     */
+    private Long answerCorrectCount;
+
+    /**
+     * 答题红包个数
+     */
+    private Long redPacketCount;
+
+    /**
+     * 答题红包金额
+     */
+    private Long redPacketAmount;
+}

+ 5 - 0
fs-service-system/src/main/java/com/fs/statis/dto/AnalysisPreviewQueryDTO.java

@@ -42,4 +42,9 @@ public class AnalysisPreviewQueryDTO implements Serializable {
      */
     private Integer userType;
 
+    /**
+     * 公司id
+     */
+    private Long companyId;
+
 }

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

@@ -1,6 +1,7 @@
 package com.fs.statis.mapper;
 
 import com.fs.statis.dto.*;
+import org.apache.ibatis.annotations.Param;
 
 import java.math.BigDecimal;
 import java.util.List;
@@ -17,6 +18,7 @@ public interface ConsumptionBalanceMapper {
     ConsumptionBalanceDataDTO rechargeConsumption();
 
     DealerAggregatedDTO dealerAggregated();
+    DealerAggregatedDTO dealerAggregatedCompanyId(@Param("companyId") Long companyId);
 
     /**
      * 观看人数
@@ -120,5 +122,7 @@ public interface ConsumptionBalanceMapper {
     List<RewardMoneyTrendDTO> rewardMoneyTrendDTO(AnalysisPreviewQueryDTO param);
 
     BigDecimal getCurrentBalance();
+    BigDecimal getCurrentBalanceCompanyId(@Param("companyId") Long companyId);
 
+    Long smsBalanceCompany(@Param("companyId") Long companyId);
 }

+ 26 - 0
fs-service-system/src/main/java/com/fs/statis/mapper/FsStatsMemberDailyMapper.java

@@ -0,0 +1,26 @@
+package com.fs.statis.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.statis.domain.FsStatsMemberDaily;
+import com.fs.statis.vo.FsStatsMemberDailyVO;
+import org.apache.ibatis.annotations.Param;
+
+import java.time.LocalDate;
+import java.util.List;
+import java.util.Map;
+
+public interface FsStatsMemberDailyMapper extends BaseMapper<FsStatsMemberDaily> {
+
+    /**
+     * 查询会员统计数据
+     * @param params    参数
+     * @return  list
+     */
+    List<FsStatsMemberDailyVO> selectDailyData(@Param("params") Map<String, Object> params);
+
+    /**
+     * 更新统计数据
+     * @param date 日期
+     */
+    void refreshMemberDailyData(@Param("date") LocalDate date);
+}

+ 23 - 0
fs-service-system/src/main/java/com/fs/statis/service/IFsStatsMemberDailyService.java

@@ -0,0 +1,23 @@
+package com.fs.statis.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.statis.domain.FsStatsMemberDaily;
+import com.fs.statis.vo.FsStatsMemberDailyVO;
+
+import java.util.List;
+import java.util.Map;
+
+public interface IFsStatsMemberDailyService extends IService<FsStatsMemberDaily> {
+
+    /**
+     * 查询会员统计数据
+     * @param params    参数
+     * @return  list
+     */
+    List<FsStatsMemberDailyVO> selectDailyData(Map<String, Object> params);
+
+    /**
+     * 更新统计数据
+     */
+    void refreshMemberDailyData();
+}

+ 108 - 0
fs-service-system/src/main/java/com/fs/statis/service/IStatisticsCompanyService.java

@@ -0,0 +1,108 @@
+package com.fs.statis.service;
+
+import com.fs.statis.dto.*;
+
+import java.util.List;
+
+/**
+ * 公司统计接口
+ */
+public interface IStatisticsCompanyService {
+
+    /**
+     * 数据概览定时任务
+     */
+    void dataOverviewTask();
+
+    /**
+     * 分析概览定时任务
+     */
+    void analysisPreviewTask(Integer type,Integer userType,Long companyId);
+
+
+    /**
+     * 会员观看、完播人数趋势图
+     */
+    void watchEndPlayTrendTask(Integer type,Integer userType,Long companyId);
+
+
+    /**
+     * 经销商会员观看TOP10
+     */
+    void companyWatchCourseTopTenTask(Integer type,Integer statisticalType,Integer userType,Long companyId);
+
+    /**
+     * 课程观看TOP10
+     */
+    void watchCourseTopTenTask(Integer type,Integer statisticalType,Integer userType,String sort,Long companyId);
+
+    /**
+     * 答题红包金额TOP10
+     */
+    void rewardMoneyTopTenTask(Integer type,Integer dataType,Integer userType,Long companyId);
+    void rewardMoneyTradeTask(Integer type,Integer userType,Long companyId);
+
+
+
+    DealerAggregatedDTO dealerAggregated(Long companyId);
+
+    /**
+     * 消费余额
+     */
+
+    ConsumptionBalanceDataDTO rechargeConsumption(Long companyId);
+
+    /**
+     * 分析概览
+     */
+    AnalysisPreviewDTO analysisPreview(AnalysisPreviewQueryDTO param);
+
+    Long smsBalance(Long companyId);
+
+    /**
+     * 授权信息
+     * @return
+     */
+    AuthorizationInfoDTO authorizationInfo();
+
+    /**
+     * 会员观看、完播人数趋势图
+     * @param param 请求参数
+     * @return 观看完播趋势
+     */
+    List<WatchEndPlayTrendDTO> watchEndPlayTrend(AnalysisPreviewQueryDTO param);
+
+    /**
+     * 经销商会员观看TOP10
+     * @param param
+     * @return
+     */
+    List<DeaMemberTopTenDTO> deaMemberTopTen(AnalysisPreviewQueryDTO param);
+
+    /**
+     * 课程观看TOP10
+     * @param param
+     * @return
+     */
+    List<CourseStatsDTO> watchCourseTopTen(AnalysisPreviewQueryDTO param);
+
+    List<RewardMoneyTopTenDTO> rewardMoneyTopTen(AnalysisPreviewQueryDTO param);
+
+    List<RewardMoneyTrendDTO> rewardMoneyTrendDTO(AnalysisPreviewQueryDTO param);
+
+    /**
+     * 获取统计流量
+     * @return TrafficLogDTO
+     */
+    TrafficLogDTO getTrafficLog(Long companyId);
+
+    /**
+     * 本月订单数
+     */
+    void thisMonthOrderCount(Long companyId);
+
+    /**
+     * 本月收款数
+     */
+    void thisMonthRecvCount(Long companyId);
+}

+ 36 - 0
fs-service-system/src/main/java/com/fs/statis/service/impl/FsStatsMemberDailyServiceImpl.java

@@ -0,0 +1,36 @@
+package com.fs.statis.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.statis.domain.FsStatsMemberDaily;
+import com.fs.statis.mapper.FsStatsMemberDailyMapper;
+import com.fs.statis.service.IFsStatsMemberDailyService;
+import com.fs.statis.vo.FsStatsMemberDailyVO;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDate;
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class FsStatsMemberDailyServiceImpl extends ServiceImpl<FsStatsMemberDailyMapper, FsStatsMemberDaily> implements IFsStatsMemberDailyService {
+
+    /**
+     * 查询会员统计数据
+     * @param params    参数
+     * @return  list
+     */
+    @Override
+    public List<FsStatsMemberDailyVO> selectDailyData(Map<String, Object> params) {
+        return baseMapper.selectDailyData(params);
+    }
+
+    /**
+     * 更新统计数据
+     */
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void refreshMemberDailyData() {
+        baseMapper.refreshMemberDailyData(LocalDate.now());
+    }
+}

+ 1077 - 0
fs-service-system/src/main/java/com/fs/statis/service/impl/StatisticsCompanyServiceImpl.java

@@ -0,0 +1,1077 @@
+package com.fs.statis.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.redis.RedisCache;
+import com.fs.common.utils.TimeUtils;
+import com.fs.company.cache.ICompanyCacheService;
+import com.fs.company.service.ICompanyService;
+import com.fs.course.mapper.FsCourseTrafficLogMapper;
+import com.fs.his.vo.OptionsVO;
+import com.fs.statis.StatisticsRedisConstant;
+import com.fs.statis.dto.*;
+import com.fs.statis.mapper.ConsumptionBalanceMapper;
+import com.fs.statis.service.IStatisticsCompanyService;
+import com.fs.statis.service.utils.TrendDataFiller;
+import com.fs.store.service.IFsStoreOrderService;
+import com.fs.store.service.IFsStorePaymentService;
+import com.fs.store.service.IFsStoreProductService;
+import com.fs.store.service.IFsUserService;
+import com.fs.store.service.cache.IFsUserCourseCacheService;
+import com.fs.system.domain.SysConfig;
+import com.fs.system.service.ISysConfigService;
+import com.hc.openapi.tool.util.ObjectUtils;
+import com.hc.openapi.tool.util.StringUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.util.Asserts;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.DayOfWeek;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.TemporalAdjusters;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.fs.statis.StatisticsRedisConstant.*;
+
+@Slf4j
+@Service("statisticsCompanyService")
+public class StatisticsCompanyServiceImpl implements IStatisticsCompanyService {
+    @Autowired
+    private ConsumptionBalanceMapper consumptionBalanceMapper;
+
+    @Autowired
+    private IFsUserCourseCacheService fsUserCourseCacheService;
+
+    @Autowired
+    private ICompanyCacheService companyCacheService;
+
+    @Autowired
+    private RedisCache redisCache;
+
+    @Autowired
+    private FsCourseTrafficLogMapper fsCourseTrafficLogMapper;
+    @Autowired
+    private IFsUserService userService;
+
+    @Autowired
+    private IFsStoreOrderService storeOrderService;
+
+    @Autowired
+    private IFsStorePaymentService paymentService;
+
+    @Autowired
+    private IFsStoreProductService productService;
+
+    @Autowired
+    private ISysConfigService configService;
+
+    @Autowired
+    private ICompanyService companyService;
+    @Override
+    public void dataOverviewTask() {
+        List<OptionsVO> optionsVOS = companyService.selectAllCompanyList();
+        for (OptionsVO optionsVO : optionsVOS) {
+            Long companyId = optionsVO.getDictValue();
+            if(companyId == null){
+                continue;
+            }
+            dataOverviewTaskCompany(companyId);
+        }
+    }
+
+    private void dataOverviewTaskCompany(Long companyId){
+        DealerAggregatedDTO dealerAggregatedDTO = this.dealerAggregated(companyId);
+        ConsumptionBalanceDataDTO consumptionBalanceDataDTO = this.rechargeConsumption(companyId);
+        AuthorizationInfoDTO authorizationInfoDTO = authorizationInfo();
+        Long smsBalance = this.smsBalance(companyId);
+        TrafficLogDTO trafficLog = this.getTrafficLog(companyId);
+
+        redisCache.setCacheObject(String.format(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_AGGREGATED+":%d",companyId), dealerAggregatedDTO);
+        redisCache.setCacheObject(String.format(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_BALANCE+":%d",companyId), consumptionBalanceDataDTO);
+        redisCache.setCacheObject(String.format(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_AUTHORIZATION_INFO+":%d",companyId), authorizationInfoDTO);
+        redisCache.setCacheObject(String.format(StatisticsRedisConstant.DATA_OVERVIEW_DEALER_SMS_BALANCE+":%d",companyId), smsBalance);
+        redisCache.setCacheObject(String.format(StatisticsRedisConstant.DATA_OVERVIEW_TRAFFIC_LOG+":%d",companyId),trafficLog);
+    }
+    public void analysisPreviewTask0(){
+        List<OptionsVO> optionsVOS = companyService.selectAllCompanyList();
+        for (OptionsVO optionsVO : optionsVOS) {
+            Long companyId = optionsVO.getDictValue();
+            if (companyId == null) {
+                continue;
+            }
+            analysisPreviewTask(0,1,companyId);
+            analysisPreviewTask(0,2,companyId);
+        }
+
+    }
+
+    public void analysisPreviewTask1(){
+        List<OptionsVO> optionsVOS = companyService.selectAllCompanyList();
+        for (OptionsVO optionsVO : optionsVOS) {
+            Long companyId = optionsVO.getDictValue();
+            if (companyId == null) {
+                continue;
+            }
+
+            analysisPreviewTask(0,1,companyId);
+            analysisPreviewTask(1,1,companyId);
+            analysisPreviewTask(2,1,companyId);
+            analysisPreviewTask(3,1,companyId);
+            analysisPreviewTask(4,1,companyId);
+
+            analysisPreviewTask(0,2,companyId);
+            analysisPreviewTask(1,2,companyId);
+            analysisPreviewTask(2,2,companyId);
+            analysisPreviewTask(3,2,companyId);
+            analysisPreviewTask(4,2,companyId);
+        }
+    }
+    @Override
+    public void analysisPreviewTask(Integer type, Integer userType,Long companyId) {
+        // 根据type计算出时间范围
+        String startDate = "";
+        String endDate = "";
+
+        LocalDateTime now = LocalDateTime.now();
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+        LocalTime startOfDayTime = LocalTime.MIN;
+        LocalTime endOfDayTime = LocalTime.of(23, 59, 59);
+
+        if(0 == type){
+            LocalDateTime startOfDay = now.with(startOfDayTime);
+            LocalDateTime endOfDay = now.with(endOfDayTime);
+            startDate = startOfDay.format(formatter);
+            endDate = endOfDay.format(formatter);
+        } else if(1 == type){
+            LocalDateTime yesterday = now.minusDays(1);
+            LocalDateTime startOfYesterday = yesterday.with(startOfDayTime);
+            LocalDateTime endOfYesterday = yesterday.with(endOfDayTime);
+            startDate = startOfYesterday.format(formatter);
+            endDate = endOfYesterday.format(formatter);
+        } else if(2 == type) {
+            LocalDateTime startOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
+            LocalDateTime startOfStartOfWeek = startOfWeek.with(startOfDayTime);
+            LocalDateTime endOfToday = now.with(endOfDayTime);
+            startDate = startOfStartOfWeek.format(formatter);
+            endDate = endOfToday.format(formatter);
+        } else if(3 == type) {
+            LocalDateTime startOfMonth = now.withDayOfMonth(1);
+            LocalDateTime startOfStartOfMonth = startOfMonth.with(startOfDayTime);
+            LocalDateTime endOfToday = now.with(endOfDayTime);
+            startDate = startOfStartOfMonth.format(formatter);
+            endDate = endOfToday.format(formatter);
+        } else if(4 == type) {
+            LocalDateTime firstDayOfPreviousMonth = now.minusMonths(1).withDayOfMonth(1);
+            LocalDateTime lastDayOfPreviousMonth = now.withDayOfMonth(1).minusDays(1);
+
+            LocalDateTime startOfPrevMonthStart = firstDayOfPreviousMonth.with(startOfDayTime);
+            LocalDateTime endOfPrevMonthEnd = lastDayOfPreviousMonth.with(endOfDayTime);
+
+            startDate = startOfPrevMonthStart.format(formatter);
+            endDate = endOfPrevMonthEnd.format(formatter);
+        }
+
+        AnalysisPreviewQueryDTO param = new AnalysisPreviewQueryDTO();
+        param.setStartTime(startDate);
+        param.setEndTime(endDate);
+        param.setType(type);
+        param.setUserType(userType);
+        param.setCompanyId(companyId);
+
+        AnalysisPreviewDTO analysisPreviewDTO = this.analysisPreview(param);
+
+        redisCache.setCacheObject(String.format("%s:%d:%d:%d",DATA_OVERVIEW_DEALER_ANALYSISPREVIEW,type,userType,companyId), analysisPreviewDTO);
+    }
+
+
+    public void watchEndPlayTrendTask0(){
+        List<OptionsVO> optionsVOS = companyService.selectAllCompanyList();
+        for (OptionsVO optionsVO : optionsVOS) {
+            Long companyId = optionsVO.getDictValue();
+            if(companyId == null){
+                continue;
+            }
+            this.watchEndPlayTrendTask(0,1,companyId);
+            this.watchEndPlayTrendTask(0,2,companyId);
+        }
+
+    }
+
+    public void watchEndPlayTrendTask1(){
+        List<OptionsVO> optionsVOS = companyService.selectAllCompanyList();
+        for (OptionsVO optionsVO : optionsVOS) {
+            Long companyId = optionsVO.getDictValue();
+            if(companyId == null){
+                continue;
+            }
+            this.watchEndPlayTrendTask(1,1,companyId);
+            this.watchEndPlayTrendTask(2,1,companyId);
+            this.watchEndPlayTrendTask(3,1,companyId);
+            this.watchEndPlayTrendTask(4,1,companyId);
+
+            this.watchEndPlayTrendTask(1,2,companyId);
+            this.watchEndPlayTrendTask(2,2,companyId);
+            this.watchEndPlayTrendTask(3,2,companyId);
+            this.watchEndPlayTrendTask(4,2,companyId);
+        }
+
+    }
+    @Override
+    public void watchEndPlayTrendTask(Integer type, Integer userType,Long companyId) {
+        // 根据type计算出时间范围
+        String startDate = "";
+        String endDate = "";
+
+        LocalDateTime now = LocalDateTime.now();
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+        LocalTime startOfDayTime = LocalTime.MIN;
+        LocalTime endOfDayTime = LocalTime.of(23, 59, 59);
+
+        if(0 == type){
+            LocalDateTime startOfDay = now.with(startOfDayTime);
+            LocalDateTime endOfDay = now.with(endOfDayTime);
+            startDate = startOfDay.format(formatter);
+            endDate = endOfDay.format(formatter);
+        } else if(1 == type){
+            LocalDateTime yesterday = now.minusDays(1);
+            LocalDateTime startOfYesterday = yesterday.with(startOfDayTime);
+            LocalDateTime endOfYesterday = yesterday.with(endOfDayTime);
+            startDate = startOfYesterday.format(formatter);
+            endDate = endOfYesterday.format(formatter);
+        } else if(2 == type) {
+            LocalDateTime startOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
+            LocalDateTime startOfStartOfWeek = startOfWeek.with(startOfDayTime);
+            LocalDateTime endOfToday = now.with(endOfDayTime);
+            startDate = startOfStartOfWeek.format(formatter);
+            endDate = endOfToday.format(formatter);
+        } else if(3 == type) {
+            LocalDateTime startOfMonth = now.withDayOfMonth(1);
+            LocalDateTime startOfStartOfMonth = startOfMonth.with(startOfDayTime);
+            LocalDateTime endOfToday = now.with(endOfDayTime);
+            startDate = startOfStartOfMonth.format(formatter);
+            endDate = endOfToday.format(formatter);
+        } else if(4 == type) {
+            LocalDateTime firstDayOfPreviousMonth = now.minusMonths(1).withDayOfMonth(1);
+            LocalDateTime lastDayOfPreviousMonth = now.withDayOfMonth(1).minusDays(1);
+
+            LocalDateTime startOfPrevMonthStart = firstDayOfPreviousMonth.with(startOfDayTime);
+            LocalDateTime endOfPrevMonthEnd = lastDayOfPreviousMonth.with(endOfDayTime);
+
+            startDate = startOfPrevMonthStart.format(formatter);
+            endDate = endOfPrevMonthEnd.format(formatter);
+        }
+
+        AnalysisPreviewQueryDTO param = new AnalysisPreviewQueryDTO();
+        param.setStartTime(startDate);
+        param.setEndTime(endDate);
+        param.setType(type);
+        param.setCompanyId(companyId);
+
+        param.setUserType(userType);
+        List<WatchEndPlayTrendDTO> watchEndPlayTrendDTOS = this.watchEndPlayTrend(param);
+
+        redisCache.setCacheObject(String.format("%s:%d:%d",DATA_OVERVIEW_DEALER_CHARTS,type,userType),watchEndPlayTrendDTOS);
+    }
+
+    @Override
+    public void companyWatchCourseTopTenTask(Integer type, Integer statisticalType, Integer userType,Long companyId) {
+
+        AnalysisPreviewQueryDTO dto = new AnalysisPreviewQueryDTO();
+        dto.setType(type);
+        dto.setStatisticalType(statisticalType);
+
+        String startDate = "";
+        String endDate = "";
+
+        LocalDateTime now = LocalDateTime.now();
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+        LocalTime startOfDayTime = LocalTime.MIN;
+        LocalTime endOfDayTime = LocalTime.of(23, 59, 59);
+
+        if(0 == type){
+            LocalDateTime startOfDay = now.with(startOfDayTime);
+            LocalDateTime endOfDay = now.with(endOfDayTime);
+            startDate = startOfDay.format(formatter);
+            endDate = endOfDay.format(formatter);
+        } else if(1 == type){
+            LocalDateTime yesterday = now.minusDays(1);
+            LocalDateTime startOfYesterday = yesterday.with(startOfDayTime);
+            LocalDateTime endOfYesterday = yesterday.with(endOfDayTime);
+            startDate = startOfYesterday.format(formatter);
+            endDate = endOfYesterday.format(formatter);
+        } else if(2 == type) {
+            LocalDateTime startOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
+            LocalDateTime startOfStartOfWeek = startOfWeek.with(startOfDayTime);
+            LocalDateTime endOfToday = now.with(endOfDayTime);
+            startDate = startOfStartOfWeek.format(formatter);
+            endDate = endOfToday.format(formatter);
+        } else if(3 == type) {
+            LocalDateTime startOfMonth = now.withDayOfMonth(1);
+            LocalDateTime startOfStartOfMonth = startOfMonth.with(startOfDayTime);
+            LocalDateTime endOfToday = now.with(endOfDayTime);
+            startDate = startOfStartOfMonth.format(formatter);
+            endDate = endOfToday.format(formatter);
+        } else if(4 == type) {
+            LocalDateTime firstDayOfPreviousMonth = now.minusMonths(1).withDayOfMonth(1);
+            LocalDateTime lastDayOfPreviousMonth = now.withDayOfMonth(1).minusDays(1);
+
+            LocalDateTime startOfPrevMonthStart = firstDayOfPreviousMonth.with(startOfDayTime);
+            LocalDateTime endOfPrevMonthEnd = lastDayOfPreviousMonth.with(endOfDayTime);
+
+            startDate = startOfPrevMonthStart.format(formatter);
+            endDate = endOfPrevMonthEnd.format(formatter);
+        }
+
+        dto.setStartTime(startDate);
+        dto.setEndTime(endDate);
+        dto.setUserType(userType);
+        dto.setCompanyId(companyId);
+
+        List<DeaMemberTopTenDTO> deaMemberTopTenDTOS = deaMemberTopTen(dto);
+        redisCache.setCacheObject(String.format("%s:%d:%d:%d:%d", CHARTS_MEMBER_TOP_TEN_WATCH, type,statisticalType,userType,companyId), deaMemberTopTenDTOS);
+    }
+
+    public void companyWatchCourseTopTenTask0(){
+        List<OptionsVO> optionsVOS = companyService.selectAllCompanyList();
+        for (OptionsVO optionsVO : optionsVOS) {
+            Long companyId = optionsVO.getDictValue();
+            if (companyId == null) {
+                continue;
+            }
+            companyWatchCourseTopTenTask(0,0,1,companyId);
+            companyWatchCourseTopTenTask(0,1,1,companyId);
+
+
+            companyWatchCourseTopTenTask(0,0,2,companyId);
+            companyWatchCourseTopTenTask(0,1,2,companyId);
+        }
+
+    }
+
+    public void companyWatchCourseTopTenTask1(){
+        List<OptionsVO> optionsVOS = companyService.selectAllCompanyList();
+        for (OptionsVO optionsVO : optionsVOS) {
+            Long companyId = optionsVO.getDictValue();
+            if (companyId == null) {
+                continue;
+            }
+            companyWatchCourseTopTenTask(1,0,1,companyId);
+            companyWatchCourseTopTenTask(1,1,1,companyId);
+            companyWatchCourseTopTenTask(2,0,1,companyId);
+            companyWatchCourseTopTenTask(2,1,1,companyId);
+            companyWatchCourseTopTenTask(3,0,1,companyId);
+            companyWatchCourseTopTenTask(3,1,1,companyId);
+            companyWatchCourseTopTenTask(4,0,1,companyId);
+            companyWatchCourseTopTenTask(4,1,1,companyId);
+
+            companyWatchCourseTopTenTask(1,0,2,companyId);
+            companyWatchCourseTopTenTask(1,1,2,companyId);
+            companyWatchCourseTopTenTask(2,0,2,companyId);
+            companyWatchCourseTopTenTask(2,1,2,companyId);
+            companyWatchCourseTopTenTask(3,0,2,companyId);
+            companyWatchCourseTopTenTask(3,1,2,companyId);
+            companyWatchCourseTopTenTask(4,0,2,companyId);
+            companyWatchCourseTopTenTask(4,1,2,companyId);
+        }
+
+
+
+    }
+
+    @Override
+    public void watchCourseTopTenTask(Integer type, Integer statisticalType, Integer userType, String sort,Long companyId) {
+        AnalysisPreviewQueryDTO dto = new AnalysisPreviewQueryDTO();
+        dto.setType(type);
+        dto.setStatisticalType(statisticalType);
+        dto.setSort(sort);
+
+        String startDate = "";
+        String endDate = "";
+
+        LocalDateTime now = LocalDateTime.now();
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+        LocalTime startOfDayTime = LocalTime.MIN;
+        LocalTime endOfDayTime = LocalTime.of(23, 59, 59);
+
+        if(0 == type){
+            LocalDateTime startOfDay = now.with(startOfDayTime);
+            LocalDateTime endOfDay = now.with(endOfDayTime);
+            startDate = startOfDay.format(formatter);
+            endDate = endOfDay.format(formatter);
+        } else if(1 == type){
+            LocalDateTime yesterday = now.minusDays(1);
+            LocalDateTime startOfYesterday = yesterday.with(startOfDayTime);
+            LocalDateTime endOfYesterday = yesterday.with(endOfDayTime);
+            startDate = startOfYesterday.format(formatter);
+            endDate = endOfYesterday.format(formatter);
+        } else if(2 == type) {
+            LocalDateTime startOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
+            LocalDateTime startOfStartOfWeek = startOfWeek.with(startOfDayTime);
+            LocalDateTime endOfToday = now.with(endOfDayTime);
+            startDate = startOfStartOfWeek.format(formatter);
+            endDate = endOfToday.format(formatter);
+        } else if(3 == type) {
+            LocalDateTime startOfMonth = now.withDayOfMonth(1);
+            LocalDateTime startOfStartOfMonth = startOfMonth.with(startOfDayTime);
+            LocalDateTime endOfToday = now.with(endOfDayTime);
+            startDate = startOfStartOfMonth.format(formatter);
+            endDate = endOfToday.format(formatter);
+        } else if(4 == type) {
+            LocalDateTime firstDayOfPreviousMonth = now.minusMonths(1).withDayOfMonth(1);
+            LocalDateTime lastDayOfPreviousMonth = now.withDayOfMonth(1).minusDays(1);
+
+            LocalDateTime startOfPrevMonthStart = firstDayOfPreviousMonth.with(startOfDayTime);
+            LocalDateTime endOfPrevMonthEnd = lastDayOfPreviousMonth.with(endOfDayTime);
+
+            startDate = startOfPrevMonthStart.format(formatter);
+            endDate = endOfPrevMonthEnd.format(formatter);
+        }
+        dto.setStartTime(startDate);
+        dto.setEndTime(endDate);
+        dto.setUserType(userType);
+        dto.setCompanyId(companyId);
+        List<CourseStatsDTO> courseStatsDTOS = watchCourseTopTen(dto);
+
+        redisCache.setCacheObject( String.format("%s:%d:%d:%d:%s:%d", CHARTS_WATCH_TOP_TEN, type,statisticalType,userType,sort,companyId), courseStatsDTOS);
+
+    }
+
+
+    public void watchCourseTopTenTask0(){
+        List<OptionsVO> optionsVOS = companyService.selectAllCompanyList();
+        for (OptionsVO optionsVO : optionsVOS) {
+            Long companyId = optionsVO.getDictValue();
+            if (companyId == null) {
+                continue;
+            }
+
+            watchCourseTopTenTask(0,0,1,"DESC",companyId);
+            watchCourseTopTenTask(0,0,1,"ASC",companyId);
+            watchCourseTopTenTask(0,1,1,"DESC",companyId);
+            watchCourseTopTenTask(0,1,1,"ASC",companyId);
+            watchCourseTopTenTask(0,2,1,"DESC",companyId);
+            watchCourseTopTenTask(0,2,1,"ASC",companyId);
+            watchCourseTopTenTask(0,3,1,"DESC",companyId);
+            watchCourseTopTenTask(0,3,1,"ASC",companyId);
+
+            watchCourseTopTenTask(0,0,1,"DESC",companyId);
+            watchCourseTopTenTask(0,0,1,"ASC",companyId);
+            watchCourseTopTenTask(0,1,1,"DESC",companyId);
+            watchCourseTopTenTask(0,1,1,"ASC",companyId);
+            watchCourseTopTenTask(0,2,1,"DESC",companyId);
+            watchCourseTopTenTask(0,2,1,"ASC",companyId);
+            watchCourseTopTenTask(0,3,1,"DESC",companyId);
+            watchCourseTopTenTask(0,3,1,"ASC",companyId);
+
+        }
+
+    }
+
+    public void watchCourseTopTenTask1(){
+        List<OptionsVO> optionsVOS = companyService.selectAllCompanyList();
+        for (OptionsVO optionsVO : optionsVOS) {
+            Long companyId = optionsVO.getDictValue();
+            if (companyId == null) {
+                continue;
+            }
+
+            watchCourseTopTenTask(1,0,1,"DESC",companyId);
+            watchCourseTopTenTask(1,0,1,"ASC",companyId);
+
+            watchCourseTopTenTask(1,0,2,"DESC",companyId);
+            watchCourseTopTenTask(1,0,2,"ASC",companyId);
+
+
+            watchCourseTopTenTask(1,1,1,"DESC",companyId);
+            watchCourseTopTenTask(1,1,1,"ASC",companyId);
+
+            watchCourseTopTenTask(1,1,2,"DESC",companyId);
+            watchCourseTopTenTask(1,1,2,"ASC",companyId);
+
+            watchCourseTopTenTask(1,2,1,"DESC",companyId);
+            watchCourseTopTenTask(1,2,1,"ASC",companyId);
+
+            watchCourseTopTenTask(1,2,2,"DESC",companyId);
+            watchCourseTopTenTask(1,2,2,"ASC",companyId);
+
+
+            watchCourseTopTenTask(1,3,1,"DESC",companyId);
+            watchCourseTopTenTask(1,3,1,"ASC",companyId);
+
+            watchCourseTopTenTask(1,3,2,"DESC",companyId);
+            watchCourseTopTenTask(1,3,2,"ASC",companyId);
+
+            watchCourseTopTenTask(2,0,1,"DESC",companyId);
+            watchCourseTopTenTask(2,0,1,"ASC",companyId);
+
+            watchCourseTopTenTask(2,0,2,"DESC",companyId);
+            watchCourseTopTenTask(2,0,2,"ASC",companyId);
+
+            watchCourseTopTenTask(2,1,1,"DESC",companyId);
+            watchCourseTopTenTask(2,1,1,"ASC",companyId);
+
+            watchCourseTopTenTask(2,1,2,"DESC",companyId);
+            watchCourseTopTenTask(2,1,2,"ASC",companyId);
+
+            watchCourseTopTenTask(2,2,1,"DESC",companyId);
+            watchCourseTopTenTask(2,2,1,"ASC",companyId);
+
+            watchCourseTopTenTask(2,2,2,"DESC",companyId);
+            watchCourseTopTenTask(2,2,2,"ASC",companyId);
+
+
+            watchCourseTopTenTask(2,3,1,"DESC",companyId);
+            watchCourseTopTenTask(2,3,1,"ASC",companyId);
+
+            watchCourseTopTenTask(2,3,2,"DESC",companyId);
+            watchCourseTopTenTask(2,3,2,"ASC",companyId);
+
+            watchCourseTopTenTask(3,0,1,"DESC",companyId);
+            watchCourseTopTenTask(3,0,1,"ASC",companyId);
+
+            watchCourseTopTenTask(3,0,2,"DESC",companyId);
+            watchCourseTopTenTask(3,0,2,"ASC",companyId);
+
+            watchCourseTopTenTask(3,1,1,"DESC",companyId);
+            watchCourseTopTenTask(3,1,1,"ASC",companyId);
+
+            watchCourseTopTenTask(3,1,2,"DESC",companyId);
+            watchCourseTopTenTask(3,1,2,"ASC",companyId);
+
+            watchCourseTopTenTask(3,2,1,"DESC",companyId);
+            watchCourseTopTenTask(3,2,1,"ASC",companyId);
+
+            watchCourseTopTenTask(3,2,2,"DESC",companyId);
+            watchCourseTopTenTask(3,2,2,"ASC",companyId);
+
+            watchCourseTopTenTask(3,3,1,"DESC",companyId);
+            watchCourseTopTenTask(3,3,1,"ASC",companyId);
+
+            watchCourseTopTenTask(3,3,2,"DESC",companyId);
+            watchCourseTopTenTask(3,3,2,"ASC",companyId);
+
+            watchCourseTopTenTask(4,0,1,"DESC",companyId);
+            watchCourseTopTenTask(4,0,1,"ASC",companyId);
+
+            watchCourseTopTenTask(4,0,2,"DESC",companyId);
+            watchCourseTopTenTask(4,0,2,"ASC",companyId);
+
+            watchCourseTopTenTask(4,1,1,"DESC",companyId);
+            watchCourseTopTenTask(4,1,1,"ASC",companyId);
+            watchCourseTopTenTask(4,2,1,"DESC",companyId);
+            watchCourseTopTenTask(4,2,1,"ASC",companyId);
+            watchCourseTopTenTask(4,3,1,"DESC",companyId);
+            watchCourseTopTenTask(4,3,1,"ASC",companyId);
+
+            watchCourseTopTenTask(4,1,2,"DESC",companyId);
+            watchCourseTopTenTask(4,1,2,"ASC",companyId);
+            watchCourseTopTenTask(4,2,2,"DESC",companyId);
+            watchCourseTopTenTask(4,2,2,"ASC",companyId);
+            watchCourseTopTenTask(4,3,2,"DESC",companyId);
+            watchCourseTopTenTask(4,3,2,"ASC",companyId);
+        }
+
+    }
+
+
+    @Override
+    public void rewardMoneyTopTenTask(Integer type, Integer dataType, Integer userType,Long companyId) {
+        AnalysisPreviewQueryDTO dto = new AnalysisPreviewQueryDTO();
+        dto.setType(type);
+        dto.setDataType(dataType);
+
+        String startDate = "";
+        String endDate = "";
+
+        LocalDateTime now = LocalDateTime.now();
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+        LocalTime startOfDayTime = LocalTime.MIN;
+        LocalTime endOfDayTime = LocalTime.of(23, 59, 59);
+
+        if(0 == type){
+            LocalDateTime startOfDay = now.with(startOfDayTime);
+            LocalDateTime endOfDay = now.with(endOfDayTime);
+            startDate = startOfDay.format(formatter);
+            endDate = endOfDay.format(formatter);
+        } else if(1 == type){
+            LocalDateTime yesterday = now.minusDays(1);
+            LocalDateTime startOfYesterday = yesterday.with(startOfDayTime);
+            LocalDateTime endOfYesterday = yesterday.with(endOfDayTime);
+            startDate = startOfYesterday.format(formatter);
+            endDate = endOfYesterday.format(formatter);
+        } else if(2 == type) {
+            LocalDateTime startOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
+            LocalDateTime startOfStartOfWeek = startOfWeek.with(startOfDayTime);
+            LocalDateTime endOfToday = now.with(endOfDayTime);
+            startDate = startOfStartOfWeek.format(formatter);
+            endDate = endOfToday.format(formatter);
+        } else if(3 == type) {
+            LocalDateTime startOfMonth = now.withDayOfMonth(1);
+            LocalDateTime startOfStartOfMonth = startOfMonth.with(startOfDayTime);
+            LocalDateTime endOfToday = now.with(endOfDayTime);
+            startDate = startOfStartOfMonth.format(formatter);
+            endDate = endOfToday.format(formatter);
+        } else if(4 == type) {
+            LocalDateTime firstDayOfPreviousMonth = now.minusMonths(1).withDayOfMonth(1);
+            LocalDateTime lastDayOfPreviousMonth = now.withDayOfMonth(1).minusDays(1);
+
+            LocalDateTime startOfPrevMonthStart = firstDayOfPreviousMonth.with(startOfDayTime);
+            LocalDateTime endOfPrevMonthEnd = lastDayOfPreviousMonth.with(endOfDayTime);
+
+            startDate = startOfPrevMonthStart.format(formatter);
+            endDate = endOfPrevMonthEnd.format(formatter);
+        }
+
+        dto.setStartTime(startDate);
+        dto.setEndTime(endDate);
+        dto.setUserType(userType);
+        dto.setCompanyId(companyId);
+
+        List<RewardMoneyTopTenDTO> rewardMoneyTopTenDTOS = rewardMoneyTopTen(dto);
+
+        redisCache.setCacheObject( String.format("%s:%d:%d:%d:%d", CHARTS_REWARD_MONEY_TOP_TEN, type,dataType,userType,companyId), rewardMoneyTopTenDTOS);
+
+    }
+
+    @Override
+    public void rewardMoneyTradeTask(Integer type, Integer userType,Long companyId) {
+        AnalysisPreviewQueryDTO dto = new AnalysisPreviewQueryDTO();
+        dto.setType(type);
+
+        String startDate = "";
+        String endDate = "";
+
+        LocalDateTime now = LocalDateTime.now();
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+        LocalTime startOfDayTime = LocalTime.MIN;
+        LocalTime endOfDayTime = LocalTime.of(23, 59, 59);
+
+        if(0 == type){
+            LocalDateTime startOfDay = now.with(startOfDayTime);
+            LocalDateTime endOfDay = now.with(endOfDayTime);
+            startDate = startOfDay.format(formatter);
+            endDate = endOfDay.format(formatter);
+        } else if(1 == type){
+            LocalDateTime yesterday = now.minusDays(1);
+            LocalDateTime startOfYesterday = yesterday.with(startOfDayTime);
+            LocalDateTime endOfYesterday = yesterday.with(endOfDayTime);
+            startDate = startOfYesterday.format(formatter);
+            endDate = endOfYesterday.format(formatter);
+        } else if(2 == type) {
+            LocalDateTime startOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
+            LocalDateTime startOfStartOfWeek = startOfWeek.with(startOfDayTime);
+            LocalDateTime endOfToday = now.with(endOfDayTime);
+            startDate = startOfStartOfWeek.format(formatter);
+            endDate = endOfToday.format(formatter);
+        } else if(3 == type) {
+            LocalDateTime startOfMonth = now.withDayOfMonth(1);
+            LocalDateTime startOfStartOfMonth = startOfMonth.with(startOfDayTime);
+            LocalDateTime endOfToday = now.with(endOfDayTime);
+            startDate = startOfStartOfMonth.format(formatter);
+            endDate = endOfToday.format(formatter);
+        } else if(4 == type) {
+            LocalDateTime firstDayOfPreviousMonth = now.minusMonths(1).withDayOfMonth(1);
+            LocalDateTime lastDayOfPreviousMonth = now.withDayOfMonth(1).minusDays(1);
+
+            LocalDateTime startOfPrevMonthStart = firstDayOfPreviousMonth.with(startOfDayTime);
+            LocalDateTime endOfPrevMonthEnd = lastDayOfPreviousMonth.with(endOfDayTime);
+
+            startDate = startOfPrevMonthStart.format(formatter);
+            endDate = endOfPrevMonthEnd.format(formatter);
+        }
+
+        dto.setStartTime(startDate);
+        dto.setEndTime(endDate);
+        dto.setUserType(userType);
+        dto.setCompanyId(companyId);
+        List<RewardMoneyTrendDTO> rewardMoneyTrendDTOS = rewardMoneyTrendDTO(dto);
+        redisCache.setCacheObject( String.format("%s:%d:%d", CHARTS_REWARD_MONEY_TREND, type,userType), rewardMoneyTrendDTOS);
+
+    }
+
+
+    public void rewardMoneyTask15Minutes(){
+        List<OptionsVO> optionsVOS = companyService.selectAllCompanyList();
+        for (OptionsVO optionsVO : optionsVOS) {
+            Long companyId = optionsVO.getDictValue();
+            if (companyId == null) {
+                continue;
+            }
+            rewardMoneyTopTenTask(0,0,1,companyId);
+            rewardMoneyTopTenTask(0,1,1,companyId);
+
+            rewardMoneyTradeTask(0,1,companyId);
+
+            rewardMoneyTopTenTask(0,0,2,companyId);
+            rewardMoneyTopTenTask(0,1,2,companyId);
+
+            rewardMoneyTradeTask(0,2,companyId);
+        }
+
+    }
+
+
+    public void rewardMoneyTaskEveryday(){
+        List<OptionsVO> optionsVOS = companyService.selectAllCompanyList();
+        for (OptionsVO optionsVO : optionsVOS) {
+            Long companyId = optionsVO.getDictValue();
+            if (companyId == null) {
+                continue;
+            }
+
+            rewardMoneyTopTenTask(1,0,1,companyId);
+            rewardMoneyTopTenTask(1,1,1,companyId);
+
+
+            rewardMoneyTopTenTask(2,0,1,companyId);
+            rewardMoneyTopTenTask(2,1,1,companyId);
+
+            rewardMoneyTopTenTask(3,0,1,companyId);
+            rewardMoneyTopTenTask(3,1,1,companyId);
+
+            rewardMoneyTopTenTask(4,0,1,companyId);
+            rewardMoneyTopTenTask(4,1,1,companyId);
+
+
+            rewardMoneyTradeTask(1,1,companyId);
+            rewardMoneyTradeTask(2,1,companyId);
+            rewardMoneyTradeTask(3,1,companyId);
+            rewardMoneyTradeTask(4,1,companyId);
+
+
+            rewardMoneyTopTenTask(1,0,2,companyId);
+            rewardMoneyTopTenTask(1,1,2,companyId);
+            rewardMoneyTopTenTask(2,0,2,companyId);
+            rewardMoneyTopTenTask(2,1,2,companyId);
+            rewardMoneyTopTenTask(3,0,2,companyId);
+            rewardMoneyTopTenTask(3,1,2,companyId);
+            rewardMoneyTopTenTask(4,0,2,companyId);
+            rewardMoneyTopTenTask(4,1,2,companyId);
+
+            rewardMoneyTradeTask(1,2,companyId);
+            rewardMoneyTradeTask(2,2,companyId);
+            rewardMoneyTradeTask(3,2,companyId);
+            rewardMoneyTradeTask(4,2,companyId);
+        }
+
+    }
+
+    @Override
+    public DealerAggregatedDTO dealerAggregated(Long companyId) {
+        Long dayUserCount=userService.selectFsUserCount(1,companyId);
+        Long storeOrderCount=storeOrderService.selectFsStoreOrderTotalCount(0,companyId);
+        Long dayStoreOrderCount=storeOrderService.selectFsStoreOrderTotalCount(1,companyId);
+        Long paymentCount=paymentService.selectFsStorePaymentCount(0,companyId);
+        Long dayPaymentCount=paymentService.selectFsStorePaymentCount(1,companyId);
+        Long productCount=productService.selectFsStoreProductCount(0,companyId);
+        Long dayProductCount=productService.selectFsStoreProductCount(1,companyId);
+        DealerAggregatedDTO dealerAggregatedDTO = consumptionBalanceMapper.dealerAggregatedCompanyId(companyId);
+        dealerAggregatedDTO.setTodayIncreaseUserNum(dayUserCount);
+        dealerAggregatedDTO.setOrderTotalNum(storeOrderCount);
+        dealerAggregatedDTO.setTodayOrderNum(dayStoreOrderCount);
+        dealerAggregatedDTO.setRecvTodayNum(paymentCount);
+        dealerAggregatedDTO.setRecvTodayNum(dayPaymentCount);
+        dealerAggregatedDTO.setGoodsTotalNum(productCount);
+        dealerAggregatedDTO.setTodayGoodsNum(dayProductCount);
+        return dealerAggregatedDTO;
+    }
+
+    @Override
+    public ConsumptionBalanceDataDTO rechargeConsumption(Long companyId) {
+        // 获取流量统计数据
+        TrafficLogDTO trafficLog = this.getTrafficLog(companyId);
+
+        // 获取流量价格配置
+        SysConfig config = configService.selectConfigByConfigKey("statis.config");
+        Asserts.notNull(config, "流量价格配置不能为空!");
+        JSONObject jsonObject = JSONObject.parseObject(config.getConfigValue());
+        float trafficPrice = jsonObject.getFloatValue("trafficPrice");
+
+        // 创建消费余额数据对象
+        ConsumptionBalanceDataDTO consumptionBalanceData = new ConsumptionBalanceDataDTO();
+
+        // 计算消费金额(将流量从字节转换为GB,然后乘以每GB价格)
+        BigDecimal todayConsumption = calculateTrafficCost(trafficLog.getToday(), trafficPrice);
+        BigDecimal yesterdayConsumption = calculateTrafficCost(trafficLog.getYesterday(), trafficPrice);
+
+        // 设置消费数据
+        consumptionBalanceData.setTodayComsumption(todayConsumption);
+        consumptionBalanceData.setYesterdayComsumption(yesterdayConsumption);
+
+        // 从数据库获取当前余额
+        BigDecimal currentBalance = consumptionBalanceMapper.getCurrentBalanceCompanyId(companyId);
+        consumptionBalanceData.setBalance(currentBalance);
+
+        return consumptionBalanceData;
+    }
+    /**
+     * 计算流量消费金额
+     * @param trafficBytes 流量字节数
+     * @param pricePerGB 每GB价格
+     * @return 消费金额
+     */
+    private BigDecimal calculateTrafficCost(Long trafficBytes, float pricePerGB) {
+        if (trafficBytes == null || trafficBytes <= 0) {
+            return BigDecimal.ZERO;
+        }
+
+        // 将字节转换为GB (1GB = 1024^3 bytes)
+        BigDecimal trafficGB = new BigDecimal(trafficBytes)
+                .divide(new BigDecimal(1024 * 1024 * 1024), 6, BigDecimal.ROUND_HALF_UP);
+
+        // 计算消费金额
+        return trafficGB.multiply(new BigDecimal(pricePerGB)).setScale(2, BigDecimal.ROUND_HALF_UP);
+    }
+
+
+    @Override
+    public AnalysisPreviewDTO analysisPreview(AnalysisPreviewQueryDTO param) {
+        AnalysisPreviewDTO dto = new AnalysisPreviewDTO();
+
+        Long watchUserCount = consumptionBalanceMapper.queryWatchUserCount(param);
+        Long completedUserCount = consumptionBalanceMapper.queryCompletedUserCount(param);
+
+        if(watchUserCount == null){
+            watchUserCount = 0L;
+        }
+        if(completedUserCount == null){
+            completedUserCount = 0L;
+        }
+
+        // 观看人数
+        dto.setWatchUserCount(watchUserCount);
+        // 完播人数
+        dto.setCompletedUserCount(completedUserCount);
+
+        // 完播率
+        if(!ObjectUtils.equals(watchUserCount,0L)){
+            BigDecimal multiply = (BigDecimal.valueOf(completedUserCount)
+                    .divide(BigDecimal.valueOf(watchUserCount),4,BigDecimal.ROUND_HALF_UP))
+                    .multiply(BigDecimal.valueOf(100));
+
+            dto.setCompletedRate(multiply.setScale(2,BigDecimal.ROUND_HALF_UP).toPlainString());
+        } else {
+            dto.setCompletedRate("0");
+        }
+
+        Long watchCount = consumptionBalanceMapper.queryWatchCount(param);
+        Long completedCount = consumptionBalanceMapper.queryCompletedCount(param);
+
+        if(watchCount == null){
+            watchCount = 0L;
+        }
+        if(completedCount == null){
+            completedCount = 0L;
+        }
+
+        // 观看次数
+        dto.setWatchCount(watchCount);
+        // 完播次数
+        dto.setCompletedCount(completedCount);
+        // 视频完播率
+        if(!ObjectUtils.equals(watchCount, 0L)){
+            BigDecimal multiply = BigDecimal.valueOf(completedCount)
+                    .divide(BigDecimal.valueOf(watchCount),4,BigDecimal.ROUND_HALF_UP)
+                    .multiply(BigDecimal.valueOf(100));
+
+            dto.setWatchRate(multiply.setScale(2,BigDecimal.ROUND_HALF_UP).toPlainString());
+        } else {
+            dto.setWatchRate("0");
+        }
+
+        Long answerMemberCount = consumptionBalanceMapper.queryAnswerMemberCount(param);
+        Long correctUserCount = consumptionBalanceMapper.queryCorrectUserCount(param);
+
+        if(answerMemberCount == null){
+            answerMemberCount = 0L;
+        }
+        if(correctUserCount == null){
+            correctUserCount = 0L;
+        }
+        // 答题人数
+        dto.setAnswerMemberCount(answerMemberCount);
+        // 正确人数
+        dto.setCorrectUserCount(correctUserCount);
+        // 正确比例
+        if(!ObjectUtils.equals(answerMemberCount, 0L)){
+            BigDecimal multiply = BigDecimal.valueOf(correctUserCount)
+                    .divide(BigDecimal.valueOf(answerMemberCount),4,BigDecimal.ROUND_HALF_UP)
+                    .multiply(BigDecimal.valueOf(100));
+
+            dto.setCorrectRate(multiply.setScale(2, RoundingMode.HALF_UP).toPlainString());
+        } else {
+            dto.setCorrectRate("0");
+        }
+        Long rewardCount = consumptionBalanceMapper.queryRewardCount(param);
+        if(rewardCount == null) {
+            rewardCount = 0L;
+        }
+        BigDecimal rewardMoney = consumptionBalanceMapper.queryRewardMoney(param);
+        if(rewardMoney == null) {
+            rewardMoney = BigDecimal.ZERO;
+        }
+        // 答题红包个数
+        dto.setRewardCount(rewardCount);
+        // 答题红包金额
+        dto.setRewardMoney(rewardMoney);
+
+        return dto;
+    }
+
+
+    @Override
+    public Long smsBalance(Long companyId) {
+        Long smsBalance = consumptionBalanceMapper.smsBalanceCompany(companyId);
+        if(smsBalance != null) {
+            smsBalance = 0L;
+        }
+        return smsBalance;
+    }
+
+    @Override
+    public AuthorizationInfoDTO authorizationInfo() {
+        return consumptionBalanceMapper.authorizationInfo();
+    }
+
+    @Override
+    public List<WatchEndPlayTrendDTO> watchEndPlayTrend(AnalysisPreviewQueryDTO param) {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public List<DeaMemberTopTenDTO> deaMemberTopTen(AnalysisPreviewQueryDTO param) {
+        List<DeaMemberTopTenDTO> deaMemberTopTenDTOS = consumptionBalanceMapper.deaMemberTopTen(param);
+        for (DeaMemberTopTenDTO dto : deaMemberTopTenDTOS) {
+            Long companyId = dto.getCompanyId();
+            String companyName = companyCacheService.selectCompanyNameById(companyId);
+            if(StringUtils.isNotBlank(companyName)){
+                dto.setCompanyName(companyName);
+            }
+        }
+        return deaMemberTopTenDTOS;
+    }
+
+    @Override
+    public List<CourseStatsDTO> watchCourseTopTen(AnalysisPreviewQueryDTO param) {
+        List<CourseStatsDTO> courseStatsDTOS = consumptionBalanceMapper.watchCourseTopTen(param);
+        for (CourseStatsDTO courseStatsDTO : courseStatsDTOS) {
+            String courseName = fsUserCourseCacheService.selectCourseNameByCourseId(courseStatsDTO.getCourseId());
+            if(StringUtils.isNotBlank(courseName)){
+                courseStatsDTO.setCourseName(courseName);
+            }
+        }
+        return courseStatsDTOS;
+    }
+
+    @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;
+    }
+
+    @Override
+    public TrafficLogDTO getTrafficLog(Long companyId) {
+        TrafficLogDTO trafficLogDTO = new TrafficLogDTO();
+        Long todayTrafficLog = fsCourseTrafficLogMapper.getTodayTrafficLogCompanyId(companyId);
+        Long yesterdayTrafficLog = fsCourseTrafficLogMapper.getYesterdayTrafficLogCompanyId(companyId);
+        Long monthTrafficLog = fsCourseTrafficLogMapper.getMonthTrafficLogCompanyId(companyId);
+        trafficLogDTO.setToday(todayTrafficLog);
+        trafficLogDTO.setThisMonth(monthTrafficLog);
+        trafficLogDTO.setYesterday(yesterdayTrafficLog);
+        return trafficLogDTO;
+    }
+
+    public void companyThisMonthOrderCount(){
+        List<OptionsVO> optionsVOS = companyService.selectAllCompanyList();
+        for (OptionsVO optionsVO : optionsVOS) {
+            Long companyId = optionsVO.getDictValue();
+            if (companyId == null) {
+                continue;
+            }
+            this.thisMonthOrderCount(companyId);
+            this.thisMonthRecvCount(companyId);
+        }
+    }
+    @Override
+    public void thisMonthOrderCount(Long companyId) {
+        Long[] users=new Long[0];
+        TimeUtils.TimeEntity timeEntity=TimeUtils.parseTime("5",null,null);
+        timeEntity.setUserIds(users);
+        timeEntity.setCompanyId(companyId);
+        Integer cycleNum = timeEntity.getCycleNum();
+        Integer beginTime = timeEntity.getBeginTime();
+        List<Integer> timeList = new ArrayList<>();
+        for (int i = 1; i <= cycleNum; i++) {
+            timeList.add(beginTime);
+            beginTime = TimeUtils.formatTime(beginTime);
+        }
+        List<JSONObject> jsonObjectList = storeOrderService.selectFsStoreOrderCounts(timeEntity.toMap());
+        List<String> dates = jsonObjectList.stream().map(jsonObject -> jsonObject.getString("type")).collect(Collectors.toList());
+        List<Integer> orderCount = jsonObjectList.stream().map(jsonObject -> jsonObject.getInteger("orderCount")).collect(Collectors.toList());
+        List<Integer> payPrice = jsonObjectList.stream().map(jsonObject -> jsonObject.getInteger("payPrice")).collect(Collectors.toList());
+        R result = R.ok().put("dates", dates).put("orderCount", orderCount).put("payPrice", payPrice);
+        redisCache.setCacheObject(String.format(THIS_MONTH_ORDER_COUNT+":%d",companyId),result);
+    }
+
+    @Override
+    public void thisMonthRecvCount(Long companyId) {
+        Long[] users=new Long[0];
+        TimeUtils.TimeEntity timeEntity=TimeUtils.parseTime("5",null,null);
+        timeEntity.setUserIds(users);
+        timeEntity.setCompanyId(companyId);
+        Integer cycleNum = timeEntity.getCycleNum();
+        Integer beginTime = timeEntity.getBeginTime();
+        List<Integer> timeList = new ArrayList<>();
+        for (int i = 1; i <= cycleNum; i++) {
+            timeList.add(beginTime);
+            beginTime = TimeUtils.formatTime(beginTime);
+        }
+        List<JSONObject> jsonObjectList = paymentService.selectFsStorePaymentCounts(timeEntity.toMap());
+        List<String> dates = jsonObjectList.stream().map(jsonObject -> jsonObject.getString("type")).collect(Collectors.toList());
+        List<Integer> orderCount = jsonObjectList.stream().map(jsonObject -> jsonObject.getInteger("orderCount")).collect(Collectors.toList());
+        List<Float> payMoney = jsonObjectList.stream().map(jsonObject -> jsonObject.getFloatValue("payMoney")).collect(Collectors.toList());
+        R result = R.ok().put("dates", dates).put("orderCount", orderCount).put("payMoney", payMoney);
+        redisCache.setCacheObject(String.format(THIS_MONTH_RECV_COUNT+":%d",companyId),result);
+    }
+}

+ 82 - 0
fs-service-system/src/main/java/com/fs/statis/vo/FsStatsMemberDailyVO.java

@@ -0,0 +1,82 @@
+package com.fs.statis.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+
+@Data
+public class FsStatsMemberDailyVO {
+    /**
+     * 统计日期
+     */
+    private LocalDate statDate;
+    /**
+     * 用户ID
+     */
+    private Long userId;
+    /**
+     * 用户昵称
+     */
+    private String nickName;
+    /**
+     * 用户姓名
+     */
+    private String realName;
+    /**
+     * 电话号码
+     */
+    private String phone;
+    /**
+     * 标签
+     */
+    private String tag;
+    /**
+     * 公司ID
+     */
+    private Long companyId;
+    /**
+     * 公司名称
+     */
+    private String companyName;
+    /**
+     * 销售ID
+     */
+    private Long companyUserId;
+    /**
+     * 销售名称
+     */
+    private String companyUserName;
+    /**
+     * 课程数量
+     */
+    private Long count;
+    /**
+     * 完课数量
+     */
+    private Long overCount;
+    /**
+     * 观看次数
+     */
+    private Long watchCount;
+    /**
+     * 观看时长
+     */
+    private Long watchDuration;
+    /**
+     * 答题次数
+     */
+    private Long answerCount;
+    /**
+     * 正确次数
+     */
+    private Long answerCorrectCount;
+    /**
+     * 红包个数
+     */
+    private Long redPacketCount;
+    /**
+     * 红包金额
+     */
+    private BigDecimal redPacketAmount;
+}

+ 12 - 0
fs-service-system/src/main/java/com/fs/store/mapper/FsStoreProductMapper.java

@@ -182,6 +182,18 @@ public interface FsStoreProductMapper
             "</if>" +
             "</script>"})
     Long selectFsStoreProductCount(@Param("type") int type );
+    @Select({"<script> " +
+            "select count(1) from fs_store_product  " +
+            "where 1=1 " +
+            "<if test = 'type != null and  type ==1  '> " +
+            "and  DATE_FORMAT(create_time, '%Y-%m-%d')  = DATE_FORMAT(NOW(), '%Y-%m-%d') " +
+            "</if>" +
+            "<if test = 'companyIds != null and companyIds != \"\" '> " +
+            "and find_in_set(#{companyIds}, company_ids) " +
+            "</if>" +
+            "</script>"})
+    Long selectFsStoreProductCount(@Param("type") int type,@Param("companyIds") Long companyIds);
+
     @Select({"<script> " +
             "select * from fs_store_product where find_in_set(product_id,#{ids})  " +
             "</script>"})

+ 10 - 6
fs-service-system/src/main/java/com/fs/store/mapper/FsUserMapper.java

@@ -1,13 +1,9 @@
 package com.fs.store.mapper;
 
-import java.util.List;
-import java.util.Map;
-
 import com.fs.course.vo.newfs.FsCourseAnalysisCountVO;
+import com.fs.his.vo.OptionsVO;
 import com.fs.qw.param.QwFsUserParam;
 import com.fs.qw.vo.QwFsUserVO;
-import com.fs.qw.vo.newvo.ExternalContactNumVO;
-import com.fs.store.domain.FsStorePayment;
 import com.fs.store.domain.FsUser;
 import com.fs.store.dto.FsUserTransferParamDTO;
 import com.fs.store.param.SelectCusListPageParam;
@@ -15,7 +11,6 @@ import com.fs.store.param.h5.CourseAnalysisParam;
 import com.fs.store.param.h5.FsUserPageListParam;
 import com.fs.store.param.h5.UserStatisticsCommonParam;
 import com.fs.store.vo.FSUserVO;
-
 import com.fs.store.vo.FsCompanyUserListQueryVO;
 import com.fs.store.vo.FsUserTuiVO;
 import com.fs.store.vo.h5.*;
@@ -23,6 +18,9 @@ import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
 import org.apache.ibatis.annotations.Update;
 
+import java.util.List;
+import java.util.Map;
+
 /**
  * 用户Mapper接口
  *
@@ -283,4 +281,10 @@ public interface FsUserMapper
 
     int batchUpdateUserCompanyUser(@Param("userIds") List<Long> userIds, @Param("companyUserId") Long companyUserId, @Param("companyId") Long companyId);
 
+    /**
+     * 查询会员选项列表
+     * @param params    参数
+     * @return  list
+     */
+    List<OptionsVO> selectUserListByMap(@Param("params") Map<String, Object> params);
 }

+ 1 - 0
fs-service-system/src/main/java/com/fs/store/service/IFsStoreProductService.java

@@ -98,6 +98,7 @@ public interface IFsStoreProductService
     List<FsStoreProductListQueryVO> selectFsStoreProductGoodListQuery();
 
     Long selectFsStoreProductCount(int type);
+    Long selectFsStoreProductCount(int type,Long companyId);
 
     List<FsStoreProductActivityListVO> selectFsStoreProductByIds(String productIds);
 

+ 8 - 7
fs-service-system/src/main/java/com/fs/store/service/IFsUserService.java

@@ -1,14 +1,11 @@
 package com.fs.store.service;
 
-import java.util.List;
-import java.util.Map;
-
 import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.ResponseResult;
 import com.fs.common.core.page.TableDataInfo;
-import com.fs.company.vo.CompanyQueryVo;
 import com.fs.course.param.newfs.FsUserCourseBeMemberParam;
 import com.fs.course.vo.newfs.FsCourseAnalysisVO;
+import com.fs.his.vo.OptionsVO;
 import com.fs.qw.param.QwFsUserParam;
 import com.fs.qw.vo.QwFsUserVO;
 import com.fs.store.domain.FsStoreOrder;
@@ -22,12 +19,10 @@ import com.fs.store.param.h5.UserStatisticsCommonParam;
 import com.fs.store.vo.FSUserVO;
 import com.fs.store.vo.FsCompanyUserListQueryVO;
 import com.fs.store.vo.FsUserTuiVO;
-import com.fs.store.vo.h5.FsUserPageListVO;
-import com.fs.store.vo.h5.UserDetailsVO;
-import com.fs.store.vo.h5.UserListPageVO;
 import com.fs.store.vo.h5.*;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * 用户Service接口
@@ -237,4 +232,10 @@ public interface IFsUserService
      */
     ResponseResult<Boolean> becomeMember(FsUserCourseBeMemberParam param);
 
+    /**
+     * 查询会员选项列表
+     * @param params    参数
+     * @return  list
+     */
+    List<OptionsVO> selectUserListByMap(Map<String, Object> params);
 }

+ 5 - 0
fs-service-system/src/main/java/com/fs/store/service/impl/FsStoreProductServiceImpl.java

@@ -654,6 +654,11 @@ public class FsStoreProductServiceImpl implements IFsStoreProductService
         return fsStoreProductMapper.selectFsStoreProductCount(type);
     }
 
+    @Override
+    public Long selectFsStoreProductCount(int type, Long companyId) {
+        return fsStoreProductMapper.selectFsStoreProductCount(type,companyId);
+    }
+
     @Override
     public List<FsStoreProductActivityListVO> selectFsStoreProductByIds(String productIds) {
         return fsStoreProductMapper.selectFsStoreProductByIds(productIds);

+ 23 - 18
fs-service-system/src/main/java/com/fs/store/service/impl/FsUserServiceImpl.java

@@ -1,13 +1,5 @@
 package com.fs.store.service.impl;
 
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.math.RoundingMode;
-import java.util.*;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
-
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
@@ -23,48 +15,51 @@ import com.fs.company.mapper.CompanyMapper;
 import com.fs.company.mapper.CompanyTagUserMapper;
 import com.fs.company.mapper.CompanyUserMapper;
 import com.fs.company.service.ICompanyUserService;
-import com.fs.company.vo.CompanyQueryVo;
 import com.fs.course.mapper.FsUserCourseVideoMapper;
 import com.fs.course.param.newfs.FsUserCourseBeMemberParam;
 import com.fs.course.param.newfs.UserCourseVideoPageParam;
 import com.fs.course.vo.newfs.FsCourseAnalysisCountVO;
 import com.fs.course.vo.newfs.FsCourseAnalysisVO;
 import com.fs.course.vo.newfs.FsUserCourseVideoPageListVO;
+import com.fs.his.vo.OptionsVO;
 import com.fs.qw.param.QwFsUserParam;
 import com.fs.qw.vo.QwFsUserVO;
 import com.fs.store.domain.FsStoreOrder;
 import com.fs.store.domain.FsStoreOrderItem;
+import com.fs.store.domain.FsUser;
 import com.fs.store.domain.FsUserBill;
 import com.fs.store.dto.FsStoreCartDTO;
 import com.fs.store.dto.FsUserTransferParamDTO;
 import com.fs.store.enums.BillDetailEnum;
 import com.fs.store.mapper.FsStoreOrderMapper;
 import com.fs.store.mapper.FsStoreProductAttrValueMapper;
+import com.fs.store.mapper.FsUserMapper;
+import com.fs.store.param.SelectCusListPageParam;
 import com.fs.store.param.h5.CourseAnalysisParam;
 import com.fs.store.param.h5.FsUserPageListParam;
-import com.fs.store.param.SelectCusListPageParam;
 import com.fs.store.param.h5.UserStatisticsCommonParam;
 import com.fs.store.service.IFsUserBillService;
+import com.fs.store.service.IFsUserService;
 import com.fs.store.vo.FSUserVO;
 import com.fs.store.vo.FsCompanyUserListQueryVO;
 import com.fs.store.vo.FsUserTuiVO;
+import com.fs.store.vo.h5.*;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.http.util.Asserts;
-import com.fs.store.vo.h5.FsUserPageListVO;
-import com.fs.store.vo.h5.UserDetailsVO;
-import com.fs.store.vo.h5.UserListCountVO;
-import com.fs.store.vo.h5.UserListPageVO;
-import com.fs.store.vo.h5.*;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
-import com.fs.store.mapper.FsUserMapper;
-import com.fs.store.domain.FsUser;
-import com.fs.store.service.IFsUserService;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.RoundingMode;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
 import static com.fs.store.enums.BillDetailEnum.CATEGORY_1;
 import static com.fs.store.enums.BillDetailEnum.CATEGORY_3;
 
@@ -729,4 +724,14 @@ public class FsUserServiceImpl implements IFsUserService
         }
         return ResponseResult.ok(Boolean.TRUE);
     }
+
+    /**
+     * 查询会员选项列表
+     * @param params    参数
+     * @return  list
+     */
+    @Override
+    public List<OptionsVO> selectUserListByMap(Map<String, Object> params) {
+        return fsUserMapper.selectUserListByMap(params);
+    }
 }

+ 12 - 0
fs-service-system/src/main/resources/mapper/company/CompanyMapper.xml

@@ -51,6 +51,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         where company_id = #{companyId}
     </select>
 
+    <select id="selectCompanyListByMap" resultType="com.fs.his.vo.OptionsVO">
+        select
+            c.company_id dictValue,
+            c.company_name dictLabel
+        from company c
+        <where>
+            <if test="params.companyName != null and params.companyName != ''">
+                company_name like concat('%', #{params.companyName}, '%')
+            </if>
+        </where>
+    </select>
+
     <insert id="insertCompany" parameterType="Company" useGeneratedKeys="true" keyProperty="companyId">
         insert into company
         <trim prefix="(" suffix=")" suffixOverrides=",">

+ 15 - 0
fs-service-system/src/main/resources/mapper/company/CompanyUserMapper.xml

@@ -443,4 +443,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
     </select>
 
+    <select id="selectCompanyUserListByMap" resultType="com.fs.his.vo.OptionsVO">
+        select
+            cu.user_id dictValue,
+            cu.nick_name dictLabel
+        from company_user cu
+        <where>
+            <if test="params.companyUserName != null and params.companyUserName != ''">
+                and cu.nick_name like concat('%', #{params.companyUserName}, '%')
+            </if>
+            <if test="params.companyId != null">
+                and cu.company_id = #{params.companyId}
+            </if>
+        </where>
+    </select>
+
 </mapper>

+ 40 - 1
fs-service-system/src/main/resources/mapper/course/FsCourseTrafficLogMapper.xml

@@ -82,7 +82,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         FROM
             fs_course_traffic_log
         WHERE
-            DATE(create_time) = CURDATE()
+        DATE(create_time) = CURDATE()
     </select>
     <select id="getMonthTrafficLog" resultType="java.lang.Long">
         SELECT
@@ -101,6 +101,45 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         WHERE
             DATE(create_time) = CURDATE() - INTERVAL 1 DAY
     </select>
+    <select id="getTodayTrafficLogCompanyId" resultType="java.lang.Long">
+        SELECT
+            COALESCE(SUM(internet_traffic), 0) AS today_traffic_bytes
+        FROM
+            fs_course_traffic_log
+        <where>
+            DATE(create_time) = CURDATE()
+            <if test="companyId != null">
+                AND company_id = ${companyId}
+            </if>
+        </where>
+
+    </select>
+    <select id="getMonthTrafficLogCompanyId" resultType="java.lang.Long">
+        SELECT
+            COALESCE(SUM(internet_traffic), 0) AS month_traffic_bytes
+        FROM
+            fs_course_traffic_log
+        <where>
+            YEAR(create_time) = YEAR(CURDATE())
+            AND MONTH(create_time) = MONTH(CURDATE())
+            <if test="companyId != null">
+                AND company_id = ${companyId}
+            </if>
+        </where>
+    </select>
+    <select id="getYesterdayTrafficLogCompanyId" resultType="java.lang.Long">
+        SELECT
+            COALESCE(SUM(internet_traffic), 0) AS yesterday_traffic_bytes
+        FROM
+            fs_course_traffic_log
+        <where>
+            DATE(create_time) = CURDATE() - INTERVAL 1 DAY
+            <if test="companyId != null">
+                AND company_id = ${companyId}
+            </if>
+        </where>
+
+    </select>
 
     <insert id="insertFsCourseTrafficLog" parameterType="FsCourseTrafficLog" useGeneratedKeys="true" keyProperty="logId">
         insert into fs_course_traffic_log

+ 38 - 0
fs-service-system/src/main/resources/mapper/course/FsUserCoursePeriodDaysMapper.xml

@@ -40,6 +40,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                 </foreach>
             </if>
         </where>
+        order by a.day_date
     </select>
 
     <select id="selectFsUserCoursePeriodDaysById" parameterType="Long" resultMap="FsUserCoursePeriodDaysResult">
@@ -119,4 +120,41 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </foreach>
 
     </select>
+
+    <select id="selectPeriodListByMap" resultType="com.fs.his.vo.OptionsVO">
+        select
+            ucp.period_id dictValue,
+            ucp.period_name dictLabel
+        from fs_user_course_period ucp
+        <where>
+            <if test="params.name != null and params.name != ''">
+                and ucp.period_name like concat('%', #{params.name}, '%')
+            </if>
+            <if test="params.campId != null">
+                and ucp.training_camp_id = #{params.campId}
+            </if>
+        </where>
+    </select>
+
+    <update id="batchUpdateCoursePeriodDays" parameterType="java.util.List">
+        update fs_user_course_period_days
+        <trim prefix="set" suffixOverrides=",">
+            day_date =
+                <foreach collection="list" item="item" open="case" close=" end,">
+                    <if test="item.dayDate !=null ">
+                        when id=#{item.id} then #{item.dayDate}
+                    </if>
+                </foreach>
+            lesson =
+            <foreach collection="list" item="item" open="case" close=" end,">
+                <if test="item.lesson !=null ">
+                    when id=#{item.id} then #{item.lesson}
+                </if>
+            </foreach>
+        </trim>
+        where id in
+        <foreach collection="list" index="index" item="item" separator="," open="(" close=")">
+            #{item.id}
+        </foreach>
+    </update>
 </mapper>

+ 15 - 0
fs-service-system/src/main/resources/mapper/course/FsUserCoursePeriodMapper.xml

@@ -46,6 +46,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         fs_user_course_period.training_camp_id,
         fs_user_course_period.create_time,
         fs_user_course_period.update_time,
+        fs_user_course_period.period_status,
         course_style,
         live_room_style,
         red_packet_grant_method,
@@ -211,4 +212,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             #{item}
         </foreach>
     </select>
+
+    <select id="countPeriodByCampIds" resultType="java.lang.Integer">
+        select count(ucp.period_id)
+        from fs_user_course_period ucp
+        inner join fs_user_course_training_camp uctc on uctc.training_camp_id = ucp.training_camp_id
+        where uctc.training_camp_id in
+        <foreach collection="params.ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+        <![CDATA[
+        and ucp.period_starting_time <= #{params.date}
+        and ucp.period_end_time >= #{params.date}
+        ]]>
+    </select>
 </mapper>

+ 12 - 0
fs-service-system/src/main/resources/mapper/course/FsUserCourseTrainingCampMapper.xml

@@ -34,4 +34,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             </otherwise>
         </choose>
     </select>
+
+    <select id="selectCampListByMap" resultType="com.fs.his.vo.OptionsVO">
+        select
+            ctc.training_camp_id dictValue,
+            ctc.training_camp_name dictLabel
+        from fs_user_course_training_camp ctc
+        <where>
+            <if test="params.name != null and params.name != ''">
+                ctc.training_camp_name like concat('%', #{params.name}, '%')
+            </if>
+        </where>
+    </select>
 </mapper>

+ 16 - 0
fs-service-system/src/main/resources/mapper/course/FsUserCourseVideoMapper.xml

@@ -253,6 +253,22 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         order by video.course_sort
     </select>
 
+    <select id="selectVideoListByMap" resultType="com.fs.his.vo.OptionsVO">
+        select distinct
+            ucv.video_id dictValue,
+            ucv.title dictLabel
+        from fs_user_course_video ucv
+        left join fs_user_course_period_days ucpd on ucpd.video_id = ucv.video_id
+        <where>
+            <if test="params.name != null and params.name != ''">
+                ucv.title like concat('%', #{params.name}, '%')
+            </if>
+            <if test="params.periodId != null">
+                and ucpd.period_id = #{params.periodId}
+            </if>
+        </where>
+    </select>
+
     <update id="updateRedPacketMoney">
         update fs_user_course_video set red_packet_money = #{redPacketMoney} where video_id = #{videoId}
     </update>

+ 88 - 0
fs-service-system/src/main/resources/mapper/statis/ConsumptionBalanceMapper.xml

@@ -4,6 +4,7 @@
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.fs.statis.mapper.ConsumptionBalanceMapper">
 
+
     <select id="rechargeConsumption" resultType="com.fs.statis.dto.ConsumptionBalanceDataDTO">
         select
             14371277 AS balance,
@@ -46,6 +47,9 @@
             <if test="startTime != null and endTime != null">
                 and create_time between #{startTime} and #{endTime}
             </if>
+            <if test="companyId != null">
+                and company_id = #{companyId}
+            </if>
         </where>
     </select>
     <select id="queryCompletedUserCount" resultType="java.lang.Long">
@@ -58,6 +62,9 @@
             <if test="startTime != null and endTime != null">
                 and create_time between #{startTime} and #{endTime}
             </if>
+            <if test="companyId != null">
+                and company_id = #{companyId}
+            </if>
         </where>
     </select>
     <select id="queryWatchUserCount" resultType="java.lang.Long">
@@ -69,6 +76,9 @@
             <if test="startTime != null and endTime != null">
                 and create_time between #{startTime} and #{endTime}
             </if>
+            <if test="companyId != null">
+                and company_id = #{companyId}
+            </if>
 
         </where>
     </select>
@@ -82,6 +92,9 @@
              <if test="userType != null">
                  and send_type=${userType}
              </if>
+             <if test="companyId != null">
+                 and company_id = #{companyId}
+             </if>
          </where>
     </select>
     <select id="queryAnswerMemberCount" resultType="java.lang.Long">
@@ -90,6 +103,9 @@
            <if test="startTime != null and endTime != null">
                create_time BETWEEN #{startTime} AND #{endTime}
            </if>
+           <if test="companyId != null">
+               and company_id = #{companyId}
+           </if>
        </where>
     </select>
     <select id="queryCorrectUserCount" resultType="java.lang.Long">
@@ -99,6 +115,9 @@
             <if test="startTime != null and endTime != null">
                 and create_time BETWEEN #{startTime} AND #{endTime}
             </if>
+            <if test="companyId != null">
+                and company_id = #{companyId}
+            </if>
         </where>
     </select>
     <select id="queryRewardCount" resultType="java.lang.Long">
@@ -113,6 +132,9 @@
             <if test="userType != null">
                 and log.send_type = ${userType}
             </if>
+            <if test="companyId != null">
+                and log.company_id = #{companyId}
+            </if>
         </where>
     </select>
     <select id="queryRewardMoney" resultType="java.math.BigDecimal">
@@ -127,11 +149,22 @@
             <if test="userType != null">
                 and log.send_type = ${userType}
             </if>
+            <if test="companyId != null">
+                and log.company_id = #{companyId}
+            </if>
         </where>
     </select>
     <select id="smsBalance" resultType="java.lang.Long">
         select sum(remain_sms_count) from company_sms
     </select>
+    <select id="smsBalanceCompany" resultType="java.lang.Long">
+        select sum(remain_sms_count) from company_sms
+        <where>
+            <if test="companyId != null">
+                company_id = #{companyId}
+            </if>
+        </where>
+    </select>
     <select id="authorizationInfo" resultType="com.fs.statis.dto.AuthorizationInfoDTO">
         select version_limit,today_watch_user_count from fs_statistics_index limit 1
     </select>
@@ -186,6 +219,9 @@
             <if test="userType != null">
                 AND send_type = ${userType}
             </if>
+            <if test="companyId != null">
+                AND company_id = ${companyId}
+            </if>
         </where>
         GROUP BY company_id
         limit 10
@@ -211,6 +247,9 @@
             <if test="userType != null">
                 AND send_type = ${userType}
             </if>
+            <if test="companyId != null">
+                AND w.company_id = ${companyId}
+            </if>
         </where>
         GROUP BY
         w.course_id
@@ -258,6 +297,9 @@
             <if test="userType != null">
                 and log.send_type = ${userType}
             </if>
+            <if test="companyId != null">
+                and log.company_id = ${companyId}
+            </if>
         </where>
         GROUP BY
             <if test="dataType == 0">
@@ -294,6 +336,9 @@
             <if test="userType != null">
                 and log.send_type = ${userType}
             </if>
+            <if test="companyId != null">
+                and log.company_id = ${companyId}
+            </if>
             AND rpl.operate_type = 1
             AND rpl.status = 1
         </where>
@@ -302,5 +347,48 @@
     <select id="getCurrentBalance" resultType="java.math.BigDecimal">
         select sum(money) from company
     </select>
+    <select id="dealerAggregatedCompanyId" resultType="com.fs.statis.dto.DealerAggregatedDTO">
+        SELECT
+                1 AS dealder_count,
+                (SELECT COUNT(*) FROM COMPANY_USER
+                                 <where>
+                                     <if test="companyId != null">
+                                         company_id = #{companyId}
+                                     </if>
+                                 </where>
+                                 ) AS group_mgr_count,
+                (SELECT COUNT(*) FROM FS_USER
+                                <where>
+                                    <if test="companyId != null">
+                                        company_id = #{companyId}
+                                    </if>
+                                </where>
+                                ) AS member_count,
+                (SELECT COUNT(*) FROM FS_USER
+                                <where>
+                                    STATUS=1
+                                    <if test="companyId != null">
+                                        AND company_id = #{companyId}
+                                    </if>
+                                </where>
+                                ) AS normal_num,
+                (SELECT COUNT(*) FROM FS_USER
+                                <where>
+                                    STATUS=0
+                                    <if test="companyId != null">
+                                        AND company_id = #{companyId}
+                                    </if>
+                                </where>
+                ) AS black_num,
+                (select COUNT(*) FROM qw_user) AS qw_member_num
+    </select>
+    <select id="getCurrentBalanceCompanyId" resultType="java.math.BigDecimal">
+        select sum(money) from company
+        <where>
+            <if test="companyId != null">
+                company_id = #{companyId}
+            </if>
+        </where>
+    </select>
 
 </mapper>

+ 161 - 0
fs-service-system/src/main/resources/mapper/statis/FsStatsMemberDailyMapper.xml

@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.statis.mapper.FsStatsMemberDailyMapper">
+
+    <update id="refreshMemberDailyData">
+        insert into fs_stats_member_daily
+            (
+            stat_date,user_id,nick_name,real_name,phone,tag,company_group_id,company_id,company_name,company_user_id,company_user_name,
+            train_camp_id,train_camp_name,period_id,period_name,course_id,course_name,video_id,video_name,is_over,watch_count,watch_duration,
+            answer_count,answer_correct_count,red_packet_count,red_packet_amount
+            )
+        select
+            #{date}					    as stat_date,
+            u.user_id				    as user_id,
+            u.nickname				    as nick_name,
+            u.real_name				    as real_name,
+            u.phone					    as phone,
+            concat_ws(',', t.tag) 	    as tag,
+            null					    as company_group_id,
+            c.company_id			    as company_id,
+            c.company_name			    as company_name,
+            cu.user_id				    as company_user_id,
+            cu.nick_name			    as company_user_name,
+            uctc.training_camp_id 	    as train_camp_id,
+            uctc.training_camp_name	    as train_camp_name,
+            ucp.period_id			    as period_id,
+            ucp.period_name			    as period_name,
+            uc.course_id			    as course_id,
+            uc.course_name			    as course_name,
+            ucv.video_id			    as video_id,
+            ucv.title				    as video_name,
+            max(case when cwl.log_type = 2 then 1 else 0 end)
+                                        as is_over,
+            count(cwl.log_id)		    as watch_count,
+            sum(cwl.duration)		    as watch_duration,
+            count(cal.log_id)		    as answer_count,
+            count(case when cal.is_right = 1 then cal.log_id end)
+                                        as answer_correct_count,
+            count(crpl.log_id)		    as red_packet_count,
+            ifnull(sum(crpl.amount),0)	as red_packet_amount
+        from fs_course_watch_log cwl
+        inner join fs_user u 									on u.user_id = cwl.user_id
+        left join company_tag_user ctu 							on ctu.company_id = cwl.company_id and ctu.company_user_id = cwl.company_user_id and ctu.user_id = cwl.user_id
+        left join company_tag t 								on FIND_IN_SET(t.tag_id, ctu.tag_ids)
+        left join fs_user_course_period ucp 				    on ucp.period_id = cwl.period_id
+        left join fs_user_course_training_camp uctc             on uctc.training_camp_id = ucp.training_camp_id
+        left join company c 									on c.company_id = cwl.company_id
+        left join company_user cu 								on cu.company_id = cwl.company_id and cu.user_id = cwl.company_user_id
+        left join fs_user_course uc 							on uc.course_id = cwl.course_id
+        left join fs_user_course_video ucv 					    on ucv.course_id = cwl.course_id and ucv.video_id = cwl.video_id
+        left join fs_course_answer_logs cal 				    on cal.watch_log_id = cwl.log_id
+        left join fs_course_red_packet_log crpl 		        on crpl.watch_log_id = cwl.log_id
+        <![CDATA[
+        where cwl.create_time >= #{date} and cwl.create_time < date_add(#{date}, interval 1 day)
+        ]]>
+        group by
+            cwl.user_id,
+            cwl.company_id,
+            cwl.company_user_id,
+            ucp.training_camp_id,
+            cwl.period_id,
+            cwl.course_id,
+            cwl.video_id
+        on duplicate key update
+            nick_name = values(nick_name),
+            real_name = values(real_name),
+            phone = values(phone),
+            tag = values(tag),
+            company_name = values(company_name),
+            company_user_name = values(company_user_name),
+            train_camp_name = values(train_camp_name),
+            period_name = values(period_name),
+            course_name = values(course_name),
+            video_name = values(video_name),
+            is_over = values(is_over),
+            watch_count = values(watch_count),
+            watch_duration = values(watch_duration),
+            answer_count = values(answer_count),
+            answer_correct_count = values(answer_correct_count),
+            red_packet_count = values(red_packet_count),
+            red_packet_amount = values(red_packet_amount)
+    </update>
+
+    <select id="selectDailyData" resultType="com.fs.statis.vo.FsStatsMemberDailyVO">
+        select
+            <choose>
+                <when test="params.type == 1">
+                    fsmd.stat_date,
+                </when>
+                <otherwise>
+                    date_format(fsmd.stat_date, '%Y-%m') as stat_date,
+                </otherwise>
+            </choose>
+            fsmd.user_id,
+            fsmd.nick_name,
+            fsmd.real_name,
+            fsmd.phone,
+            fsmd.tag,
+            fsmd.company_id,
+            fsmd.company_name,
+            fsmd.company_user_id,
+            fsmd.company_user_name,
+            count(fsmd.id) as count,
+            sum(fsmd.is_over) as overCount,
+            sum(fsmd.watch_count) as watchCount,
+            sum(fsmd.watch_duration) as watchDuration,
+            sum(fsmd.answer_count) as answerCount,
+            sum(fsmd.answer_correct_count) as anserCorrectCount,
+            sum(fsmd.red_packet_count) as redPacketCount,
+            sum(fsmd.red_packet_amount) redPacketAmount
+        from fs_stats_member_daily fsmd
+        <where>
+            <if test="params.startDate != null">
+                and fsmd.stat_date >= #{params.startDate}
+            </if>
+            <if test="params.endDate != null">
+            <![CDATA[
+                and fsmd.stat_date < #{params.endDate}
+            ]]>
+            </if>
+            <if test="params.companyId != null">
+                and fsmd.company_id = #{params.companyId}
+            </if>
+            <if test="params.companyUserId != null">
+                and fsmd.company_user_id = #{params.companyUserId}
+            </if>
+            <if test="params.userId != null">
+                and fsmd.user_id = #{params.userId}
+            </if>
+            <if test="params.phone != null and params.phone != ''">
+                and fsmd.phone like concat('%', #{params.phone}, '%')
+            </if>
+            <if test="params.trainCampId != null">
+                and fsmd.train_camp_id = #{params.trainCampId}
+            </if>
+            <if test="params.periodId != null">
+                and fsmd.period_id = #{params.periodId}
+            </if>
+            <if test="params.courseId != null">
+                and fsmd.course_id = #{params.courseId}
+            </if>
+            <if test="params.videoId != null">
+                and fsmd.video_id = #{params.videoId}
+            </if>
+        </where>
+        group by
+            <choose>
+                <when test="params.type == 1">
+                    stat_date,
+                </when>
+                <otherwise>
+                    date_format(stat_date, '%Y-%m'),
+                </otherwise>
+            </choose>
+            user_id,
+            company_id,
+            company_user_id
+    </select>
+</mapper>

+ 13 - 12
fs-service-system/src/main/resources/mapper/store/FsStoreOrderMapper.xml

@@ -432,18 +432,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         SELECT DATE_FORMAT( o.create_time, #{sqlDateFormat} ) AS type,  o.id,o.pay_price
         FROM
         fs_store_order  AS o
-        WHERE
-        o.status  &gt; 0 and
-        (DATE_FORMAT(o.create_time,#{sqlDateFormat}) between #{beginTime} and #{finalTime})
-        <if test="userIds != null and userIds.length>0">
-            AND o.company_user_id IN
-            <foreach item="item" collection="userIds" open="(" separator="," close=")">
-                #{item}
-            </foreach>
-        </if>
-        <if test="companyId != null  ">
-            AND o.company_id = #{companyId}
-        </if>
+        <where>
+            o.status  &gt; 0 and
+            (DATE_FORMAT(o.create_time,#{sqlDateFormat}) between #{beginTime} and #{finalTime})
+            <if test="userIds != null and userIds.length>0">
+                AND o.company_user_id IN
+                <foreach item="item" collection="userIds" open="(" separator="," close=")">
+                    #{item}
+                </foreach>
+            </if>
+            <if test="companyId != null  ">
+                AND o.company_id = #{companyId}
+            </if>
+        </where>
 
         ) t
         GROUP BY t.type

+ 13 - 13
fs-service-system/src/main/resources/mapper/store/FsStorePaymentMapper.xml

@@ -162,19 +162,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         SELECT DATE_FORMAT( o.create_time, #{sqlDateFormat} ) AS type,  o.payment_id,o.pay_money
         FROM
         fs_store_payment  AS o
-        WHERE
-        o.status=1 and o.business_type=1 and
-        (DATE_FORMAT(o.create_time,#{sqlDateFormat}) between #{beginTime} and #{finalTime})
-        <if test="userIds != null and userIds.length>0">
-            AND o.company_user_id IN
-            <foreach item="item" collection="userIds" open="(" separator="," close=")">
-                #{item}
-            </foreach>
-        </if>
-        <if test="companyId != null  ">
-            AND o.company_id = #{companyId}
-        </if>
-
+        <where>
+            o.status=1 and o.business_type=1 and
+            (DATE_FORMAT(o.create_time,#{sqlDateFormat}) between #{beginTime} and #{finalTime})
+            <if test="userIds != null and userIds.length>0">
+                AND o.company_user_id IN
+                <foreach item="item" collection="userIds" open="(" separator="," close=")">
+                    #{item}
+                </foreach>
+            </if>
+            <if test="companyId != null  ">
+                AND o.company_id = #{companyId}
+            </if>
+        </where>
         ) t
         GROUP BY t.type
     </select>

+ 12 - 0
fs-service-system/src/main/resources/mapper/store/FsUserMapper.xml

@@ -1450,4 +1450,16 @@
         </foreach>
     </update>
 
+    <select id="selectUserListByMap" resultType="com.fs.his.vo.OptionsVO">
+        select
+            u.user_id dictValue,
+            u.nickname dictLabel
+        from fs_user u
+        <where>
+            <if test="params.nickName != null and params.nickName != ''">
+                u.nickname like concat('%', #{params.nickName}, '%')
+            </if>
+        </where>
+    </select>
+
 </mapper>

+ 5 - 0
fs-user-app/src/main/java/com/fs/app/controller/CourseH5Controller.java

@@ -64,6 +64,7 @@ public class CourseH5Controller extends  AppBaseController{
     @GetMapping("/getH5CourseVideoDetails")
     public R getCourseVideoDetails(FsUserCourseVideoFinishUParam param)
     {
+        param.setUserId(Long.parseLong(getUserId()));
         String json = configService.selectConfigByKey("course.config");
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
         FsUserCourseVideoH5DVO course = courseService.selectFsUserCourseVideoH5DVOByVideoId(param.getVideoId());
@@ -128,6 +129,7 @@ public class CourseH5Controller extends  AppBaseController{
     @PostMapping("/updateWatchDuration")
     public R updateWatchDuration(@RequestBody FsUserCourseVideoFinishUParam param)
     {
+        param.setUserId(Long.parseLong(getUserId()));
         return courseVideoService.updateWatchDuration(param);
     }
 
@@ -135,6 +137,7 @@ public class CourseH5Controller extends  AppBaseController{
     @ApiOperation("获取缓冲流量")
     @PostMapping("/getInternetTraffic")
     public R getInternetTraffic(@RequestBody FsUserCourseVideoFinishUParam param) {
+        param.setUserId(Long.parseLong(getUserId()));
         return courseVideoService.getInternetTraffic(param);
     }
 
@@ -142,6 +145,7 @@ public class CourseH5Controller extends  AppBaseController{
     @PostMapping("/courseAnswer")
     public R courseAnswer(@RequestBody FsCourseQuestionAnswerUParam param)
     {
+        param.setUserId(Long.parseLong(getUserId()));
         logger.info("zyp \n【答题】:{}",param.getQuestions());
         if (param.getDuration()==null){
             logger.info("zyp \n【未识别到时长】:{}",param.getUserId());
@@ -154,6 +158,7 @@ public class CourseH5Controller extends  AppBaseController{
     @RepeatSubmit
     public R sendReward(@RequestBody FsCourseSendRewardUParam param)
     {
+        param.setUserId(Long.parseLong(getUserId()));
         logger.info("zyp \n【发放奖励】:{}",param);
         return courseVideoService.sendReward(param);
     }

+ 192 - 0
fs-user-app/src/main/java/com/fs/app/controller/WxCompanyUserController.java

@@ -0,0 +1,192 @@
+package com.fs.app.controller;
+
+import cn.binarywang.wx.miniapp.api.WxMaService;
+import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
+import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
+import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
+import cn.hutool.core.date.DateTime;
+import com.fs.app.annotation.Login;
+import com.fs.app.param.LoginMaWxParam;
+import com.fs.app.utils.JwtUtils;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.redis.RedisCache;
+import com.fs.common.utils.ServletUtils;
+import com.fs.company.domain.CompanyUser;
+import com.fs.company.service.ICompanyDeptService;
+import com.fs.company.service.ICompanyUserService;
+import com.fs.store.domain.FsUser;
+import com.fs.store.service.IFsUserService;
+import com.fs.wx.miniapp.config.WxMaConfiguration;
+import com.fs.wx.miniapp.config.WxMaProperties;
+import io.jsonwebtoken.Claims;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.common.error.WxErrorException;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Date;
+
+@Api("微信小程序相关接口")
+@RestController
+@RequestMapping(value = "/app/wx/miniapp")
+@Slf4j
+public class WxCompanyUserController extends AppBaseController {
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    @Autowired
+    private WxMaProperties maProperties;
+
+    @Autowired
+    JwtUtils jwtUtils;
+
+    @Autowired
+    RedisCache redisCache;
+
+    @Autowired
+    private ICompanyUserService companyUserService;
+
+    @Autowired
+    private ICompanyDeptService companyDeptService;
+
+    @Autowired
+    private IFsUserService userService;
+
+    @ApiOperation("小程序-授权登录")
+    @PostMapping("/loginByMa")
+    public R login(@RequestBody LoginMaWxParam param) {
+        if (StringUtils.isBlank(param.getCode())) {
+            return R.error("code不存在");
+        }
+        //获取第二个小程序配置,序号从0开始
+        final WxMaService wxService = WxMaConfiguration.getMaService(maProperties.getConfigs().get(1).getAppid());
+        try {
+            WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(param.getCode());
+            this.logger.info(session.getSessionKey());
+            this.logger.info(session.getOpenid());
+            // 解密
+            WxMaPhoneNumberInfo phoneNoInfo = wxService.getUserService().getPhoneNoInfo(session.getSessionKey(), param.getEncryptedData(), param.getIv());
+            WxMaUserInfo userInfo = wxService.getUserService().getUserInfo(session.getSessionKey(), param.getEncryptedData(), param.getIv());
+
+            //以下暂时注释,不需要往销售表添加数据
+//            CompanyUser companyUser = companyUserService.getCompanyUserByOpenId(session.getOpenid());
+//            String ip = IpUtil.getRequestIp();
+//
+////            // 如果公司id为空(表示可能是该公司的第一位销售管理员),则需要根据电话号码判断是否存在销售,如果不存在则提示
+////            if (param.getCompanyId() == null) {
+////                if (checkPhone == null) {
+////                    throw new CustomException("由于不是管理员,不能直接登录", 401);
+////                }
+////            }
+//            if (companyUser == null) {
+//                CompanyUser checkPhone = companyUserService.getCompanyUserByPhone(phoneNoInfo.getPhoneNumber());
+//                if (checkPhone != null) {
+//                    if (checkPhone.getMaOpenId() == null) {
+//                        companyUser = checkPhone;
+//                        companyUser.setMaOpenId(session.getOpenid());
+//                        companyUser.setUserId(companyUser.getUserId());
+//                        companyUser.setUpdateTime(new DateTime());
+//                        companyUser.setLoginIp(ip);
+//                        companyUserService.updateUserProfile(companyUser);
+//                    } else {
+//                        throw new CustomException("此手机号用户已存在");
+//                    }
+//                } else {
+//                    //新增
+//                    companyUser = new CompanyUser();
+//                    companyUser.setUserName(phoneNoInfo.getPhoneNumber());
+//                    companyUser.setNickName(userInfo.getNickName() == null ? "微信用户" : userInfo.getNickName());
+//                    companyUser.setPhonenumber(phoneNoInfo.getPhoneNumber());
+//                    companyUser.setSex(userInfo.getGender());
+//                    //密码初始化为123456
+//                    String pw = "123456";
+//                    companyUser.setPassword(SecurityUtils.encryptPassword(param.getPassword() == null ? pw : param.getPassword()));
+//                    companyUser.setCreateTime(new Date());
+//                    companyUser.setCompanyId(param.getCompanyId());
+//                    companyUser.setParentId(param.getParentCompanyUseId());
+//                    companyUser.setMaOpenId(session.getOpenid());
+//
+//                    //部门信息
+//                    CompanyDept dept = companyDeptService.getDefaultCompanyDeptByCompanyId(param.getCompanyId());
+//                    if (Objects.nonNull(dept)) {
+//                        companyUser.setDeptId(dept.getDeptId());
+//                    }
+//                    companyUserService.insertUser(companyUser);
+//                }
+//            } else {
+//                CompanyUser companyUserMp = new CompanyUser();
+//                companyUserMp.setPhonenumber(phoneNoInfo.getPhoneNumber());
+//                companyUserMp.setUserId(companyUser.getUserId());
+//                companyUserMp.setUpdateTime(new DateTime());
+//                companyUserMp.setLoginIp(ip);
+//                companyUserService.updateUserProfile(companyUser);
+//            }
+
+            // 添加会员表数据
+            FsUser user = userService.selectFsUserByMpOpenId(session.getOpenid());
+            if (user != null) {
+                //修改
+                FsUser userMap = new FsUser();
+                userMap.setUserId(user.getUserId());
+                userMap.setMpOpenId(session.getOpenid());
+                userMap.setUnionId(session.getUnionid());
+                userMap.setUpdateTime(new DateTime());
+                userMap.setNickname(userInfo.getNickName() != null ? userInfo.getNickName() : "微信用户");
+                userMap.setAvatar(userInfo.getAvatarUrl() != null ? userInfo.getAvatarUrl() : null);
+                userMap.setPhone(phoneNoInfo.getPhoneNumber());
+                userService.updateFsUser(userMap);
+            } else {
+                //新增
+                user = new FsUser();
+                user.setNickname(userInfo.getNickName() != null ? userInfo.getNickName() : "微信用户");
+                user.setAvatar(userInfo.getAvatarUrl() != null ? userInfo.getAvatarUrl() : null);
+                user.setStatus(1);
+                user.setMpOpenId(session.getOpenid());
+                user.setUnionId(session.getUnionid());
+                user.setCreateTime(new Date());
+                user.setPhone(phoneNoInfo.getPhoneNumber());
+                userService.insertFsUser(user);
+            }
+            log.info("保存成功的用户信息user: {}, 用户id: {}", user, user.getUserId());
+            String token = jwtUtils.generateToken(user.getUserId());
+            // 返回一个写死的数据到前端
+            return R.ok("登录成功").put("token", token).put("phoneNumber", phoneNoInfo.getPhoneNumber()).put("nickName", "微信用户").put("user", user);
+        } catch (WxErrorException e) {
+            this.logger.error(e.getMessage(), e);
+            return R.error("授权失败," + e.getMessage());
+        }
+    }
+
+//    @Login(isMiniLogin = true)
+//    @ApiOperation("获取销售通过小程序登录后的用户信息")
+//    @GetMapping("/getMaUser")
+//    public R getUserInfo() {
+//        try {
+//            CompanyUser companyUser = companyUserService.selectCompanyUserById(Long.parseLong(getUserId()));
+//            if (companyUser == null) {
+//                return R.error(401, "用户信息不存在");
+//            }
+//            return R.ok().put("user", companyUser);
+//        } catch (Exception e) {
+//            return R.error("操作异常");
+//        }
+//    }
+
+    /**
+     * 特殊要求:销售小程序临时登录,登录后页面中还有一个之前常用的登录,所以为了区分,token名称不能跟之前的一样
+     *
+     * @return 用户id
+     */
+    public String getUserId() {
+        String headValue = ServletUtils.getRequest().getHeader("UserToken");
+        Claims claims = jwtUtils.getClaimByToken(headValue);
+        String userId = claims.getSubject().toString();
+        return userId;
+    }
+
+
+}

+ 34 - 0
fs-user-app/src/main/java/com/fs/app/param/LoginMaWxParam.java

@@ -0,0 +1,34 @@
+package com.fs.app.param;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+
+@Data
+public class LoginMaWxParam implements Serializable {
+
+    @NotBlank(message = "code参数缺失")
+    @ApiModelProperty(value = "小程序登陆code")
+    private String code;
+
+    @ApiModelProperty(value = "小程序完整用户信息的加密数据")
+    private String encryptedData;
+
+    @ApiModelProperty(value = "小程序加密算法的初始向量")
+    private String iv;
+
+//    @ApiModelProperty(value = "公司id,如果不是第一位销售,都需要传")
+//    private Long companyId;
+
+//    @ApiModelProperty(value = "电话号码")
+//    private String phoneNumber;
+
+//    @ApiModelProperty(value = "上级销售id,如果没有则不传")
+//    private Long parentCompanyUseId;
+//
+//    @ApiModelProperty(value = "用户密码")
+//    private String password;
+
+}

+ 1 - 1
fs-user-app/src/main/resources/application.yml

@@ -50,7 +50,7 @@ server:
 # 日志配置
 logging:
   level:
-    com.fs: info
+    com.fs: debug
     org.springframework: warn
 
 # Spring配置