Browse Source

feat: 会员看课统计(未完成)

caoliqin 4 days ago
parent
commit
9e36c51fca
16 changed files with 1457 additions and 0 deletions
  1. 103 0
      fs-admin/src/main/java/com/fs/course/controller/FsUserWatchCourseStatisticsController.java
  2. 113 0
      fs-admin/src/main/java/com/fs/course/controller/FsUserWatchStatisticsController.java
  3. 118 0
      fs-service-system/src/main/java/com/fs/course/domain/FsUserWatchCourseStatistics.java
  4. 60 0
      fs-service-system/src/main/java/com/fs/course/domain/FsUserWatchStatistics.java
  5. 8 0
      fs-service-system/src/main/java/com/fs/course/mapper/FsUserCoursePeriodDaysMapper.java
  6. 61 0
      fs-service-system/src/main/java/com/fs/course/mapper/FsUserWatchCourseStatisticsMapper.java
  7. 73 0
      fs-service-system/src/main/java/com/fs/course/mapper/FsUserWatchStatisticsMapper.java
  8. 66 0
      fs-service-system/src/main/java/com/fs/course/service/IFsUserWatchCourseStatisticsService.java
  9. 66 0
      fs-service-system/src/main/java/com/fs/course/service/IFsUserWatchStatisticsService.java
  10. 174 0
      fs-service-system/src/main/java/com/fs/course/service/impl/FsUserWatchCourseStatisticsServiceImpl.java
  11. 183 0
      fs-service-system/src/main/java/com/fs/course/service/impl/FsUserWatchStatisticsServiceImpl.java
  12. 15 0
      fs-service-system/src/main/java/com/fs/store/mapper/FsUserMapper.java
  13. 19 0
      fs-service-system/src/main/resources/mapper/course/FsUserCoursePeriodDaysMapper.xml
  14. 161 0
      fs-service-system/src/main/resources/mapper/course/FsUserWatchCourseStatisticsMapper.xml
  15. 146 0
      fs-service-system/src/main/resources/mapper/course/FsUserWatchStatisticsMapper.xml
  16. 91 0
      fs-service-system/src/main/resources/mapper/store/FsUserMapper.xml

+ 103 - 0
fs-admin/src/main/java/com/fs/course/controller/FsUserWatchCourseStatisticsController.java

@@ -0,0 +1,103 @@
+package com.fs.course.controller;
+
+import java.util.List;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+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.FsUserWatchCourseStatistics;
+import com.fs.course.service.IFsUserWatchCourseStatisticsService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 会员看课统计-按课程统计Controller
+ * 
+ * @author fs
+ * @date 2025-06-16
+ */
+@RestController
+@RequestMapping("/course/userWatchCourseStatistics")
+public class FsUserWatchCourseStatisticsController extends BaseController
+{
+    @Autowired
+    private IFsUserWatchCourseStatisticsService fsUserWatchCourseStatisticsService;
+
+    /**
+     * 查询会员看课统计-按课程统计列表
+     */
+    @PreAuthorize("@ss.hasPermi('course:userWatchCourseStatistics:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(FsUserWatchCourseStatistics fsUserWatchCourseStatistics)
+    {
+        startPage();
+        List<FsUserWatchCourseStatistics> list = fsUserWatchCourseStatisticsService.selectFsUserWatchCourseStatisticsList(fsUserWatchCourseStatistics);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出会员看课统计-按课程统计列表
+     */
+    @PreAuthorize("@ss.hasPermi('course:userWatchCourseStatistics:export')")
+    @Log(title = "会员看课统计-按课程统计", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(FsUserWatchCourseStatistics fsUserWatchCourseStatistics)
+    {
+        List<FsUserWatchCourseStatistics> list = fsUserWatchCourseStatisticsService.selectFsUserWatchCourseStatisticsList(fsUserWatchCourseStatistics);
+        ExcelUtil<FsUserWatchCourseStatistics> util = new ExcelUtil<FsUserWatchCourseStatistics>(FsUserWatchCourseStatistics.class);
+        return util.exportExcel(list, "会员看课统计-按课程统计数据");
+    }
+
+    /**
+     * 获取会员看课统计-按课程统计详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('course:userWatchCourseStatistics:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(fsUserWatchCourseStatisticsService.selectFsUserWatchCourseStatisticsById(id));
+    }
+
+    /**
+     * 新增会员看课统计-按课程统计
+     */
+    @PreAuthorize("@ss.hasPermi('course:userWatchCourseStatistics:add')")
+    @Log(title = "会员看课统计-按课程统计", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody FsUserWatchCourseStatistics fsUserWatchCourseStatistics)
+    {
+        return toAjax(fsUserWatchCourseStatisticsService.insertFsUserWatchCourseStatistics(fsUserWatchCourseStatistics));
+    }
+
+    /**
+     * 修改会员看课统计-按课程统计
+     */
+    @PreAuthorize("@ss.hasPermi('course:userWatchCourseStatistics:edit')")
+    @Log(title = "会员看课统计-按课程统计", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody FsUserWatchCourseStatistics fsUserWatchCourseStatistics)
+    {
+        return toAjax(fsUserWatchCourseStatisticsService.updateFsUserWatchCourseStatistics(fsUserWatchCourseStatistics));
+    }
+
+    /**
+     * 删除会员看课统计-按课程统计
+     */
+    @PreAuthorize("@ss.hasPermi('course:userWatchCourseStatistics:remove')")
+    @Log(title = "会员看课统计-按课程统计", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(fsUserWatchCourseStatisticsService.deleteFsUserWatchCourseStatisticsByIds(ids));
+    }
+}

+ 113 - 0
fs-admin/src/main/java/com/fs/course/controller/FsUserWatchStatisticsController.java

@@ -0,0 +1,113 @@
+package com.fs.course.controller;
+
+import java.util.List;
+
+import io.swagger.annotations.ApiOperation;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+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.FsUserWatchStatistics;
+import com.fs.course.service.IFsUserWatchStatisticsService;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.common.core.page.TableDataInfo;
+
+/**
+ * 会员看课统计-按营期统计Controller
+ *
+ * @author fs
+ * @date 2025-06-16
+ */
+@RestController
+@RequestMapping("/course/userWatchStatistics")
+public class FsUserWatchStatisticsController extends BaseController
+{
+    @Autowired
+    private IFsUserWatchStatisticsService fsUserWatchStatisticsService;
+
+    /**
+     * 查询会员看课统计-按营期统计列表
+     */
+    @PreAuthorize("@ss.hasPermi('course:userWatchStatistics:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(FsUserWatchStatistics fsUserWatchStatistics)
+    {
+        startPage();
+        List<FsUserWatchStatistics> list = fsUserWatchStatisticsService.selectFsUserWatchStatisticsList(fsUserWatchStatistics);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出会员看课统计-按营期统计列表
+     */
+    @PreAuthorize("@ss.hasPermi('course:userWatchStatistics:export')")
+    @Log(title = "会员看课统计-按营期统计", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(FsUserWatchStatistics fsUserWatchStatistics)
+    {
+        List<FsUserWatchStatistics> list = fsUserWatchStatisticsService.selectFsUserWatchStatisticsList(fsUserWatchStatistics);
+        ExcelUtil<FsUserWatchStatistics> util = new ExcelUtil<FsUserWatchStatistics>(FsUserWatchStatistics.class);
+        return util.exportExcel(list, "会员看课统计-按营期统计数据");
+    }
+
+    /**
+     * 获取会员看课统计-按营期统计详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('course:userWatchStatistics:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(fsUserWatchStatisticsService.selectFsUserWatchStatisticsById(id));
+    }
+
+    /**
+     * 新增会员看课统计-按营期统计
+     */
+    @PreAuthorize("@ss.hasPermi('course:userWatchStatistics:add')")
+    @Log(title = "会员看课统计-按营期统计", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody FsUserWatchStatistics fsUserWatchStatistics)
+    {
+        return toAjax(fsUserWatchStatisticsService.insertFsUserWatchStatistics(fsUserWatchStatistics));
+    }
+
+    /**
+     * 修改会员看课统计-按营期统计
+     */
+    @PreAuthorize("@ss.hasPermi('course:userWatchStatistics:edit')")
+    @Log(title = "会员看课统计-按营期统计", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody FsUserWatchStatistics fsUserWatchStatistics)
+    {
+        return toAjax(fsUserWatchStatisticsService.updateFsUserWatchStatistics(fsUserWatchStatistics));
+    }
+
+    /**
+     * 删除会员看课统计-按营期统计
+     */
+    @PreAuthorize("@ss.hasPermi('course:userWatchStatistics:remove')")
+    @Log(title = "会员看课统计-按营期统计", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(fsUserWatchStatisticsService.deleteFsUserWatchStatisticsByIds(ids));
+    }
+
+
+    @PostMapping("/test")
+    @ApiOperation("测试营期看课统计定时任务")
+    public void userCourseCountTask() {
+        fsUserWatchStatisticsService.insertStatistics();
+    }
+
+}

+ 118 - 0
fs-service-system/src/main/java/com/fs/course/domain/FsUserWatchCourseStatistics.java

@@ -0,0 +1,118 @@
+package com.fs.course.domain;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fs.common.annotation.Excel;
+import lombok.Data;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 会员看课统计-按课程统计对象 fs_user_watch_course_statistics
+ *
+ * @author fs
+ * @date 2025-06-17
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class FsUserWatchCourseStatistics extends BaseEntity{
+
+    /** 主键id */
+    private Long id;
+
+    /** 营期id */
+    @Excel(name = "营期id")
+    private Long periodId;
+
+    /** 营期名称 */
+    @Excel(name = "营期名称")
+    private String periodName;
+
+    /** 课程id */
+    @Excel(name = "课程id")
+    private Long courseId;
+
+    /** 课程名称 */
+    @Excel(name = "课程名称")
+    private String courseName;
+
+    /** 视频id */
+    @Excel(name = "视频id")
+    private Long videoId;
+
+    /** 视频标题 */
+    @Excel(name = "视频标题")
+    private String videoTitle;
+
+    /** 销售公司id */
+    @Excel(name = "销售公司id")
+    private Long companyId;
+
+    /** 销售公司名称 */
+    @Excel(name = "销售公司名称")
+    private String companyName;
+
+    /** 销售id */
+    @Excel(name = "销售id")
+    private Long companyUserId;
+
+    /** 课程开始日期 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "课程开始日期", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date courseStartDateTime;
+
+    /** 销售名称 */
+    @Excel(name = "销售名称")
+    private String companyUserName;
+
+    /** 营期开始日期 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "营期开始日期", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date periodStartingTime;
+
+    /** 新增会员数量 */
+    @Excel(name = "新增会员数量")
+    private Integer newUserNum;
+
+    /** 会员数量 */
+    @Excel(name = "会员数量")
+    private Integer userNum;
+
+    /** 观看人数 */
+    @Excel(name = "观看人数")
+    private Integer watchNum;
+
+    /** 完播人数 */
+    @Excel(name = "完播人数")
+    private Integer completeWatchNum;
+
+    /** 完播率 */
+    @Excel(name = "完播率")
+    private BigDecimal completeWatchRate;
+
+    /** 答题人数 */
+    @Excel(name = "答题人数")
+    private Integer answerNum;
+
+    /** 答题正确人数 */
+    @Excel(name = "答题正确人数")
+    private Integer answerRightNum;
+
+    /** 答题正确率 */
+    @Excel(name = "答题正确率")
+    private BigDecimal answerRightRate;
+
+    /** 红包领取数量 */
+    @Excel(name = "红包领取数量")
+    private Integer redPacketNum;
+
+    /** 红包领取总额 */
+    @Excel(name = "红包领取总额")
+    private BigDecimal redPacketAmount;
+
+
+
+
+}

+ 60 - 0
fs-service-system/src/main/java/com/fs/course/domain/FsUserWatchStatistics.java

@@ -0,0 +1,60 @@
+package com.fs.course.domain;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fs.common.annotation.Excel;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 会员看课统计-按营期统计对象 fs_user_watch_statistics
+ *
+ * @author fs
+ * @date 2025-06-16
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class FsUserWatchStatistics extends BaseEntity{
+
+    /** 主键id */
+    private Long id;
+
+    /** 营期id */
+    @Excel(name = "营期id")
+    private Long periodId;
+
+    /** 营期名称 */
+    @Excel(name = "营期名称")
+    private String periodName;
+
+    /** 营期开始日期 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "营期开始日期", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date periodStartingTime;
+
+    /** 新增会员数量 */
+    @Excel(name = "新增会员数量")
+    private Integer newUserNum;
+
+    /** 会员数量 */
+    @Excel(name = "会员数量")
+    private Integer userNum;
+
+    /** 观看人数 */
+    @Excel(name = "观看人数")
+    private Integer watchNum;
+
+    /** 完播人数 */
+    @Excel(name = "完播人数")
+    private Integer completeWatchNum;
+
+    /** 完播率 */
+    @Excel(name = "完播率")
+    private BigDecimal completeWatchRate;
+
+
+}

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

@@ -2,6 +2,7 @@ package com.fs.course.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.fs.course.domain.FsUserCoursePeriodDays;
+import com.fs.course.domain.FsUserWatchCourseStatistics;
 import com.fs.his.vo.OptionsVO;
 import org.apache.ibatis.annotations.Param;
 
@@ -95,4 +96,11 @@ public interface FsUserCoursePeriodDaysMapper extends BaseMapper<FsUserCoursePer
      * @param now  时间
      */
     void endPeriodCourse(@Param("now") LocalDateTime now);
+
+    /**
+     * 查询视频相关信息
+     * @return
+     */
+    List<FsUserWatchCourseStatistics> selectDaysCountList();
+
 }

+ 61 - 0
fs-service-system/src/main/java/com/fs/course/mapper/FsUserWatchCourseStatisticsMapper.java

@@ -0,0 +1,61 @@
+package com.fs.course.mapper;
+
+import java.util.List;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.course.domain.FsUserWatchCourseStatistics;
+
+/**
+ * 会员看课统计-按课程统计Mapper接口
+ * 
+ * @author fs
+ * @date 2025-06-17
+ */
+public interface FsUserWatchCourseStatisticsMapper extends BaseMapper<FsUserWatchCourseStatistics>{
+    /**
+     * 查询会员看课统计-按课程统计
+     * 
+     * @param id 会员看课统计-按课程统计主键
+     * @return 会员看课统计-按课程统计
+     */
+    FsUserWatchCourseStatistics selectFsUserWatchCourseStatisticsById(Long id);
+
+    /**
+     * 查询会员看课统计-按课程统计列表
+     * 
+     * @param fsUserWatchCourseStatistics 会员看课统计-按课程统计
+     * @return 会员看课统计-按课程统计集合
+     */
+    List<FsUserWatchCourseStatistics> selectFsUserWatchCourseStatisticsList(FsUserWatchCourseStatistics fsUserWatchCourseStatistics);
+
+    /**
+     * 新增会员看课统计-按课程统计
+     * 
+     * @param fsUserWatchCourseStatistics 会员看课统计-按课程统计
+     * @return 结果
+     */
+    int insertFsUserWatchCourseStatistics(FsUserWatchCourseStatistics fsUserWatchCourseStatistics);
+
+    /**
+     * 修改会员看课统计-按课程统计
+     * 
+     * @param fsUserWatchCourseStatistics 会员看课统计-按课程统计
+     * @return 结果
+     */
+    int updateFsUserWatchCourseStatistics(FsUserWatchCourseStatistics fsUserWatchCourseStatistics);
+
+    /**
+     * 删除会员看课统计-按课程统计
+     * 
+     * @param id 会员看课统计-按课程统计主键
+     * @return 结果
+     */
+    int deleteFsUserWatchCourseStatisticsById(Long id);
+
+    /**
+     * 批量删除会员看课统计-按课程统计
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    int deleteFsUserWatchCourseStatisticsByIds(Long[] ids);
+}

+ 73 - 0
fs-service-system/src/main/java/com/fs/course/mapper/FsUserWatchStatisticsMapper.java

@@ -0,0 +1,73 @@
+package com.fs.course.mapper;
+
+import java.util.List;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.course.domain.FsUserWatchStatistics;
+
+/**
+ * 会员看课统计-按营期统计Mapper接口
+ *
+ * @author fs
+ * @date 2025-06-16
+ */
+public interface FsUserWatchStatisticsMapper extends BaseMapper<FsUserWatchStatistics>{
+    /**
+     * 查询会员看课统计-按营期统计
+     *
+     * @param id 会员看课统计-按营期统计主键
+     * @return 会员看课统计-按营期统计
+     */
+    FsUserWatchStatistics selectFsUserWatchStatisticsById(Long id);
+
+    /**
+     * 查询会员看课统计-按营期统计列表
+     *
+     * @param fsUserWatchStatistics 会员看课统计-按营期统计
+     * @return 会员看课统计-按营期统计集合
+     */
+    List<FsUserWatchStatistics> selectFsUserWatchStatisticsList(FsUserWatchStatistics fsUserWatchStatistics);
+
+    /**
+     * 新增会员看课统计-按营期统计
+     *
+     * @param fsUserWatchStatistics 会员看课统计-按营期统计
+     * @return 结果
+     */
+    int insertFsUserWatchStatistics(FsUserWatchStatistics fsUserWatchStatistics);
+
+    /**
+     * 修改会员看课统计-按营期统计
+     *
+     * @param fsUserWatchStatistics 会员看课统计-按营期统计
+     * @return 结果
+     */
+    int updateFsUserWatchStatistics(FsUserWatchStatistics fsUserWatchStatistics);
+
+    /**
+     * 删除会员看课统计-按营期统计
+     *
+     * @param id 会员看课统计-按营期统计主键
+     * @return 结果
+     */
+    int deleteFsUserWatchStatisticsById(Long id);
+
+    /**
+     * 批量删除会员看课统计-按营期统计
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    int deleteFsUserWatchStatisticsByIds(Long[] ids);
+
+    /**
+     * 获取看课统计-按营期统计
+     * @return
+     */
+    List<FsUserWatchStatistics> getCourseWatchStatistics();
+
+    /**
+     * 插入看课统计数据
+     */
+    void insertFsUserWatchStatisticsTask(FsUserWatchStatistics fsUserWatchStatistics);
+
+}

+ 66 - 0
fs-service-system/src/main/java/com/fs/course/service/IFsUserWatchCourseStatisticsService.java

@@ -0,0 +1,66 @@
+package com.fs.course.service;
+
+import java.util.List;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.course.domain.FsUserWatchCourseStatistics;
+
+/**
+ * 会员看课统计-按课程统计Service接口
+ *
+ * @author fs
+ * @date 2025-06-17
+ */
+public interface IFsUserWatchCourseStatisticsService extends IService<FsUserWatchCourseStatistics>{
+    /**
+     * 查询会员看课统计-按课程统计
+     *
+     * @param id 会员看课统计-按课程统计主键
+     * @return 会员看课统计-按课程统计
+     */
+    FsUserWatchCourseStatistics selectFsUserWatchCourseStatisticsById(Long id);
+
+    /**
+     * 查询会员看课统计-按课程统计列表
+     *
+     * @param fsUserWatchCourseStatistics 会员看课统计-按课程统计
+     * @return 会员看课统计-按课程统计集合
+     */
+    List<FsUserWatchCourseStatistics> selectFsUserWatchCourseStatisticsList(FsUserWatchCourseStatistics fsUserWatchCourseStatistics);
+
+    /**
+     * 新增会员看课统计-按课程统计
+     *
+     * @param fsUserWatchCourseStatistics 会员看课统计-按课程统计
+     * @return 结果
+     */
+    int insertFsUserWatchCourseStatistics(FsUserWatchCourseStatistics fsUserWatchCourseStatistics);
+
+    /**
+     * 修改会员看课统计-按课程统计
+     *
+     * @param fsUserWatchCourseStatistics 会员看课统计-按课程统计
+     * @return 结果
+     */
+    int updateFsUserWatchCourseStatistics(FsUserWatchCourseStatistics fsUserWatchCourseStatistics);
+
+    /**
+     * 批量删除会员看课统计-按课程统计
+     *
+     * @param ids 需要删除的会员看课统计-按课程统计主键集合
+     * @return 结果
+     */
+    int deleteFsUserWatchCourseStatisticsByIds(Long[] ids);
+
+    /**
+     * 删除会员看课统计-按课程统计信息
+     *
+     * @param id 会员看课统计-按课程统计主键
+     * @return 结果
+     */
+    int deleteFsUserWatchCourseStatisticsById(Long id);
+
+    /**
+     * 新增按营期课程统计会员看课表数据
+     */
+    void insertWatchCourseStatistics();
+}

+ 66 - 0
fs-service-system/src/main/java/com/fs/course/service/IFsUserWatchStatisticsService.java

@@ -0,0 +1,66 @@
+package com.fs.course.service;
+
+import java.util.List;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.course.domain.FsUserWatchStatistics;
+
+/**
+ * 会员看课统计-按营期统计Service接口
+ *
+ * @author fs
+ * @date 2025-06-16
+ */
+public interface IFsUserWatchStatisticsService extends IService<FsUserWatchStatistics>{
+    /**
+     * 查询会员看课统计-按营期统计
+     *
+     * @param id 会员看课统计-按营期统计主键
+     * @return 会员看课统计-按营期统计
+     */
+    FsUserWatchStatistics selectFsUserWatchStatisticsById(Long id);
+
+    /**
+     * 查询会员看课统计-按营期统计列表
+     *
+     * @param fsUserWatchStatistics 会员看课统计-按营期统计
+     * @return 会员看课统计-按营期统计集合
+     */
+    List<FsUserWatchStatistics> selectFsUserWatchStatisticsList(FsUserWatchStatistics fsUserWatchStatistics);
+
+    /**
+     * 新增会员看课统计-按营期统计
+     *
+     * @param fsUserWatchStatistics 会员看课统计-按营期统计
+     * @return 结果
+     */
+    int insertFsUserWatchStatistics(FsUserWatchStatistics fsUserWatchStatistics);
+
+    /**
+     * 修改会员看课统计-按营期统计
+     *
+     * @param fsUserWatchStatistics 会员看课统计-按营期统计
+     * @return 结果
+     */
+    int updateFsUserWatchStatistics(FsUserWatchStatistics fsUserWatchStatistics);
+
+    /**
+     * 批量删除会员看课统计-按营期统计
+     *
+     * @param ids 需要删除的会员看课统计-按营期统计主键集合
+     * @return 结果
+     */
+    int deleteFsUserWatchStatisticsByIds(Long[] ids);
+
+    /**
+     * 删除会员看课统计-按营期统计信息
+     *
+     * @param id 会员看课统计-按营期统计主键
+     * @return 结果
+     */
+    int deleteFsUserWatchStatisticsById(Long id);
+
+    /**
+     * 新增按营期统计会员看课表数据
+     */
+    void insertStatistics();
+}

+ 174 - 0
fs-service-system/src/main/java/com/fs/course/service/impl/FsUserWatchCourseStatisticsServiceImpl.java

@@ -0,0 +1,174 @@
+package com.fs.course.service.impl;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.course.domain.FsUserCoursePeriodDays;
+import com.fs.course.mapper.FsUserCoursePeriodDaysMapper;
+import com.fs.course.vo.FsPeriodCountVO;
+import com.fs.course.vo.newfs.FsCourseAnalysisCountVO;
+import com.fs.store.mapper.FsUserMapper;
+import com.fs.store.param.h5.CourseAnalysisParam;
+import lombok.AllArgsConstructor;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.fs.course.mapper.FsUserWatchCourseStatisticsMapper;
+import com.fs.course.domain.FsUserWatchCourseStatistics;
+import com.fs.course.service.IFsUserWatchCourseStatisticsService;
+
+import static org.apache.coyote.http11.Constants.a;
+
+/**
+ * 会员看课统计-按课程统计Service业务层处理
+ *
+ * @author fs
+ * @date 2025-06-17
+ */
+@Service
+@AllArgsConstructor
+public class FsUserWatchCourseStatisticsServiceImpl extends ServiceImpl<FsUserWatchCourseStatisticsMapper, FsUserWatchCourseStatistics> implements IFsUserWatchCourseStatisticsService {
+
+    private FsUserCoursePeriodDaysMapper fsUserCoursePeriodDaysMapper;
+
+    private FsUserMapper fsUserMapper;
+
+    /**
+     * 查询会员看课统计-按课程统计
+     *
+     * @param id 会员看课统计-按课程统计主键
+     * @return 会员看课统计-按课程统计
+     */
+    @Override
+    public FsUserWatchCourseStatistics selectFsUserWatchCourseStatisticsById(Long id)
+    {
+        return baseMapper.selectFsUserWatchCourseStatisticsById(id);
+    }
+
+    /**
+     * 查询会员看课统计-按课程统计列表
+     *
+     * @param fsUserWatchCourseStatistics 会员看课统计-按课程统计
+     * @return 会员看课统计-按课程统计
+     */
+    @Override
+    public List<FsUserWatchCourseStatistics> selectFsUserWatchCourseStatisticsList(FsUserWatchCourseStatistics fsUserWatchCourseStatistics)
+    {
+        return baseMapper.selectFsUserWatchCourseStatisticsList(fsUserWatchCourseStatistics);
+    }
+
+    /**
+     * 新增会员看课统计-按课程统计
+     *
+     * @param fsUserWatchCourseStatistics 会员看课统计-按课程统计
+     * @return 结果
+     */
+    @Override
+    public int insertFsUserWatchCourseStatistics(FsUserWatchCourseStatistics fsUserWatchCourseStatistics)
+    {
+        return baseMapper.insertFsUserWatchCourseStatistics(fsUserWatchCourseStatistics);
+    }
+
+    /**
+     * 修改会员看课统计-按课程统计
+     *
+     * @param fsUserWatchCourseStatistics 会员看课统计-按课程统计
+     * @return 结果
+     */
+    @Override
+    public int updateFsUserWatchCourseStatistics(FsUserWatchCourseStatistics fsUserWatchCourseStatistics)
+    {
+        return baseMapper.updateFsUserWatchCourseStatistics(fsUserWatchCourseStatistics);
+    }
+
+    /**
+     * 批量删除会员看课统计-按课程统计
+     *
+     * @param ids 需要删除的会员看课统计-按课程统计主键
+     * @return 结果
+     */
+    @Override
+    public int deleteFsUserWatchCourseStatisticsByIds(Long[] ids)
+    {
+        return baseMapper.deleteFsUserWatchCourseStatisticsByIds(ids);
+    }
+
+    /**
+     * 删除会员看课统计-按课程统计信息
+     *
+     * @param id 会员看课统计-按课程统计主键
+     * @return 结果
+     */
+    @Override
+    public int deleteFsUserWatchCourseStatisticsById(Long id)
+    {
+        return baseMapper.deleteFsUserWatchCourseStatisticsById(id);
+    }
+
+    @Override
+    public void insertWatchCourseStatistics() {
+        // 1、获取统计数据
+        // 查询课程相关数据
+        List<FsUserWatchCourseStatistics> fsUserWatchCourseStatistics = fsUserCoursePeriodDaysMapper.selectDaysCountList();
+
+        //2、查询统计数据
+        List<FsUserWatchCourseStatistics> watchLog = fsUserMapper.selectWatchLogCount();
+        List<FsUserWatchCourseStatistics> redPacketLog = fsUserMapper.selectRedPacketLogCount();
+        List<FsUserWatchCourseStatistics> answerLog = fsUserMapper.selectAnswerLogCount();
+//        List<FsCourseAnalysisCountVO> courseCountList = fsUserMapper.courseAnalysisWatchLog(courseAnalysisParam);
+//        List<FsCourseAnalysisCountVO> redPacketCountList = fsUserMapper.courseAnalysisRedPacketCount(courseAnalysisParam);
+//        List<FsCourseAnalysisCountVO> answerCountList = fsUserMapper.courseAnalysisAnswerCount(courseAnalysisParam);
+
+        //3、转化为自定义键的map
+//        Map<Long, FsCourseAnalysisCountVO> courseMap = courseCountList.stream()
+//                .collect(Collectors.toMap(
+//                        FsCourseAnalysisCountVO::getVideoId,
+//                        Function.identity()
+//                ));
+//        Map<Long, FsCourseAnalysisCountVO> redPacketMap = redPacketCountList.stream()
+//                .collect(Collectors.toMap(
+//                        FsCourseAnalysisCountVO::getVideoId,
+//                        Function.identity()
+//                ));
+//        Map<Long, FsCourseAnalysisCountVO> answerMap = answerCountList.stream()
+//                .collect(Collectors.toMap(
+//                        FsCourseAnalysisCountVO::getVideoId,
+//                        Function.identity()
+//                ));
+        Map<String, FsUserWatchCourseStatistics> watchLogMap = watchLog.stream().collect(Collectors.toMap(k -> String.format("%s-%s-%s", k.getPeriodId(), k.getVideoId(), k.getCompanyUserId()), v -> v));
+        Map<String, FsUserWatchCourseStatistics> redPacketLogMap = redPacketLog.stream().collect(Collectors.toMap(k -> String.format("%s-%s-%s", k.getPeriodId(), k.getVideoId(), k.getCompanyUserId()), v -> v));
+        Map<String, FsUserWatchCourseStatistics> answerLogMap = answerLog.stream().collect(Collectors.toMap(k -> String.format("%s-%s-%s", k.getPeriodId(), k.getVideoId(), k.getCompanyUserId()), v -> v));
+
+
+
+
+
+//        //4、处理数据
+//        return videoList.stream().map(v -> {
+//            FsPeriodCountVO allVO = new FsPeriodCountVO();
+//            BeanUtils.copyProperties(v, allVO);
+//            allVO.setTitle(v.getVideoName());
+//
+//            FsCourseAnalysisCountVO countVO = getCourseAnalysisCountVO(v, courseMap, redPacketMap, answerMap);
+//            allVO.setCountDetailsVO(countVO);
+//            return allVO;
+//        }).collect(Collectors.toList());
+        for (FsUserWatchCourseStatistics data : fsUserWatchCourseStatistics) {
+            FsUserWatchCourseStatistics vo = new FsUserWatchCourseStatistics();
+            String key = String.format("%s-%s-%s", data.getPeriodId(), data.getVideoId(), data.getCompanyUserId());
+            FsUserWatchCourseStatistics watchLogData = watchLogMap.get(key);
+            FsUserWatchCourseStatistics redPacketLogData = redPacketLogMap.get(key);
+            FsUserWatchCourseStatistics answerLogData = answerLogMap.get(key);
+//            BeanUtils.copyProperties();
+        }
+
+    }
+
+    private String buildKey(Long periodId, Long videoId, Long companyUserId) {
+        return periodId + "|" + videoId + "|" + companyUserId;  // 使用特殊字符分隔,确保唯一性
+    }
+}

+ 183 - 0
fs-service-system/src/main/java/com/fs/course/service/impl/FsUserWatchStatisticsServiceImpl.java

@@ -0,0 +1,183 @@
+package com.fs.course.service.impl;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.course.domain.FsUserCoursePeriod;
+import com.fs.course.mapper.FsUserCoursePeriodMapper;
+import com.fs.course.vo.FsPeriodCountVO;
+import com.fs.course.vo.newfs.FsCourseAnalysisCountVO;
+import com.fs.store.domain.FsUserCourseCount;
+import com.fs.store.mapper.FsUserCourseCountMapper;
+import com.fs.store.mapper.FsUserMapper;
+import com.google.common.collect.Lists;
+import lombok.AllArgsConstructor;
+import org.apache.ibatis.session.ExecutorType;
+import org.apache.ibatis.session.SqlSession;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.fs.course.mapper.FsUserWatchStatisticsMapper;
+import com.fs.course.domain.FsUserWatchStatistics;
+import com.fs.course.service.IFsUserWatchStatisticsService;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * 会员看课统计-按营期统计Service业务层处理
+ *
+ * @author fs
+ * @date 2025-06-16
+ */
+@Service
+@AllArgsConstructor
+public class FsUserWatchStatisticsServiceImpl extends ServiceImpl<FsUserWatchStatisticsMapper, FsUserWatchStatistics> implements IFsUserWatchStatisticsService {
+
+    private final FsUserCoursePeriodMapper fsUserCoursePeriodMapper;
+
+    private final FsUserMapper fsUserMapper;
+
+    @Autowired
+    private SqlSessionFactory sqlSessionFactory;
+
+    /**
+     * 查询会员看课统计-按营期统计
+     *
+     * @param id 会员看课统计-按营期统计主键
+     * @return 会员看课统计-按营期统计
+     */
+    @Override
+    public FsUserWatchStatistics selectFsUserWatchStatisticsById(Long id)
+    {
+        return baseMapper.selectFsUserWatchStatisticsById(id);
+    }
+
+    /**
+     * 查询会员看课统计-按营期统计列表
+     *
+     * @param fsUserWatchStatistics 会员看课统计-按营期统计
+     * @return 会员看课统计-按营期统计
+     */
+    @Override
+    public List<FsUserWatchStatistics> selectFsUserWatchStatisticsList(FsUserWatchStatistics fsUserWatchStatistics)
+    {
+        return baseMapper.selectFsUserWatchStatisticsList(fsUserWatchStatistics);
+    }
+
+    /**
+     * 新增会员看课统计-按营期统计
+     *
+     * @param fsUserWatchStatistics 会员看课统计-按营期统计
+     * @return 结果
+     */
+    @Override
+    public int insertFsUserWatchStatistics(FsUserWatchStatistics fsUserWatchStatistics)
+    {
+        return baseMapper.insertFsUserWatchStatistics(fsUserWatchStatistics);
+    }
+
+    /**
+     * 修改会员看课统计-按营期统计
+     *
+     * @param fsUserWatchStatistics 会员看课统计-按营期统计
+     * @return 结果
+     */
+    @Override
+    public int updateFsUserWatchStatistics(FsUserWatchStatistics fsUserWatchStatistics)
+    {
+        return baseMapper.updateFsUserWatchStatistics(fsUserWatchStatistics);
+    }
+
+    /**
+     * 批量删除会员看课统计-按营期统计
+     *
+     * @param ids 需要删除的会员看课统计-按营期统计主键
+     * @return 结果
+     */
+    @Override
+    public int deleteFsUserWatchStatisticsByIds(Long[] ids)
+    {
+        return baseMapper.deleteFsUserWatchStatisticsByIds(ids);
+    }
+
+    /**
+     * 删除会员看课统计-按营期统计信息
+     *
+     * @param id 会员看课统计-按营期统计主键
+     * @return 结果
+     */
+    @Override
+    public int deleteFsUserWatchStatisticsById(Long id)
+    {
+        return baseMapper.deleteFsUserWatchStatisticsById(id);
+    }
+
+    @Override
+    @Transactional
+    public void insertStatistics() {
+        // 1、获取统计结果
+        // 获取所有营期
+//        FsUserCoursePeriod periodParam = new FsUserCoursePeriod();
+//        List<FsUserCoursePeriod> fsUserCoursePeriods = fsUserCoursePeriodMapper.selectFsUserCoursePeriodList(periodParam);
+
+        //获取会员数量和新增会员数量
+        List<FsUserWatchStatistics> userTotal = fsUserMapper.selectFsUserTotal(0);
+        FsUserWatchStatistics userTotalStatistics = new FsUserWatchStatistics();
+        if(!userTotal.isEmpty()){
+            userTotalStatistics = userTotal.get(0);
+        }
+
+        // 获取看课统计
+        List<FsUserWatchStatistics> courseWatchStatistics = baseMapper.getCourseWatchStatistics();
+
+        // 转化map
+        Map<Long, FsUserWatchStatistics> watchStatisticsMap = courseWatchStatistics.stream()
+                .collect(Collectors.toMap(
+                        FsUserWatchStatistics::getPeriodId,
+                        Function.identity()
+                ));
+        // 组装数据
+//        List<FsUserWatchStatistics> list = fsUserCoursePeriods.stream().map(v -> {
+//            FsUserWatchStatistics fsUserWatchStatistics = new FsUserWatchStatistics();
+//            BeanUtils.copyProperties(v, fsUserWatchStatistics);
+//            FsUserWatchStatistics count = watchStatisticsMap.getOrDefault(v.getPeriodId(), fsUserWatchStatistics);
+//            fsUserWatchStatistics.setWatchNum(count.getWatchNum());
+//            fsUserWatchStatistics.setCompleteWatchNum(count.getCompleteWatchNum());
+//            fsUserWatchStatistics.setCompleteWatchRate(count.getCompleteWatchRate());
+//            return fsUserWatchStatistics;
+//        }).collect(Collectors.toList());
+        for (FsUserWatchStatistics courseWatchStatistic : courseWatchStatistics) {
+            FsUserWatchStatistics count = watchStatisticsMap.getOrDefault(courseWatchStatistic.getPeriodId(), courseWatchStatistic);
+            courseWatchStatistic.setUserNum(userTotalStatistics.getUserNum());
+            courseWatchStatistic.setNewUserNum(userTotalStatistics.getNewUserNum());
+            courseWatchStatistic.setWatchNum(count.getWatchNum());
+            courseWatchStatistic.setCompleteWatchNum(count.getCompleteWatchNum());
+            courseWatchStatistic.setCompleteWatchRate(count.getCompleteWatchRate());
+            courseWatchStatistic.setCreateTime(new Date());
+            courseWatchStatistic.setUpdateTime(new Date());
+        }
+
+        //2、分批次插入数据
+        this.batchInsert(courseWatchStatistics);
+
+    }
+
+    private void batchInsert(List<FsUserWatchStatistics> list) {
+        // 分批次处理,一次提交500条
+        List<List<FsUserWatchStatistics>> batches = Lists.partition(list, 500);
+        batches.forEach(batch -> {
+            SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
+            try {
+                FsUserWatchStatisticsMapper mapper = sqlSession.getMapper(FsUserWatchStatisticsMapper.class);
+                batch.forEach(mapper::insertFsUserWatchStatisticsTask);
+                sqlSession.commit();
+            } finally {
+                sqlSession.close();
+            }
+        });
+    }
+}

+ 15 - 0
fs-service-system/src/main/java/com/fs/store/mapper/FsUserMapper.java

@@ -1,5 +1,7 @@
 package com.fs.store.mapper;
 
+import com.fs.course.domain.FsUserWatchCourseStatistics;
+import com.fs.course.domain.FsUserWatchStatistics;
 import com.fs.course.vo.newfs.FsCourseAnalysisCountVO;
 import com.fs.his.vo.OptionsVO;
 import com.fs.qw.param.QwFsUserParam;
@@ -298,4 +300,17 @@ public interface FsUserMapper
      * @return
      */
     Integer selectFsUserByUserIds(@Param("userIds") String[] userIds, @Param("companyUserId") Long companyUserId);
+
+    /**
+     * 获取会员总数和新增总数-可以按营期/课程
+     * @return
+     */
+    List<FsUserWatchStatistics> selectFsUserTotal(@Param("isCourse") Integer isCourse);
+
+    List<FsUserWatchCourseStatistics> selectWatchLogCount();
+
+    List<FsUserWatchCourseStatistics> selectRedPacketLogCount();
+
+    List<FsUserWatchCourseStatistics> selectAnswerLogCount();
+
 }

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

@@ -174,4 +174,23 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         where ucpd.status = 1 and ucpd.end_date_time < #{now}
         ]]>
     </update>
+
+    <select id="selectDaysCountList" resultType="FsUserWatchCourseStatistics">
+        SELECT
+            a.*,
+            a.start_date_time as courseStartDateTime
+             ,b.course_name
+             ,c.title as videoTitle
+             ,period.period_name,period.period_starting_time
+             ,company.company_id,company.company_name,company_user.nick_name
+        FROM
+            fs_user_course_period_days a
+                INNER JOIN fs_user_course b ON a.course_id = b.course_id
+                INNER JOIN fs_user_course_video c ON a.video_id = c.video_id
+                left join fs_user_course_period period on period.period_id = a.period_id
+                left join company on FIND_IN_SET(company.company_id, period.company_id) > 0
+                left join company_user on company_user.company_id = company.company_id
+        ORDER BY
+            a.day_date
+    </select>
 </mapper>

+ 161 - 0
fs-service-system/src/main/resources/mapper/course/FsUserWatchCourseStatisticsMapper.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.course.mapper.FsUserWatchCourseStatisticsMapper">
+    
+    <resultMap type="FsUserWatchCourseStatistics" id="FsUserWatchCourseStatisticsResult">
+        <result property="id"    column="id"    />
+        <result property="periodId"    column="period_id"    />
+        <result property="periodName"    column="period_name"    />
+        <result property="courseId"    column="course_id"    />
+        <result property="courseName"    column="course_name"    />
+        <result property="videoId"    column="video_id"    />
+        <result property="videoTitle"    column="video_title"    />
+        <result property="companyId"    column="company_id"    />
+        <result property="companyName"    column="company_name"    />
+        <result property="companyUserId"    column="company_user_id"    />
+        <result property="courseStartDateTime"    column="course_start_date_time"    />
+        <result property="companyUserName"    column="company_user_name"    />
+        <result property="periodStartingTime"    column="period_starting_time"    />
+        <result property="newUserNum"    column="new_user_num"    />
+        <result property="userNum"    column="user_num"    />
+        <result property="watchNum"    column="watch_num"    />
+        <result property="completeWatchNum"    column="complete_watch_num"    />
+        <result property="completeWatchRate"    column="complete_watch_rate"    />
+        <result property="answerNum"    column="answer_num"    />
+        <result property="answerRightNum"    column="answer_right_num"    />
+        <result property="answerRightRate"    column="answer_right_rate"    />
+        <result property="redPacketNum"    column="red_packet_num"    />
+        <result property="redPacketAmount"    column="red_packet_amount"    />
+    </resultMap>
+
+    <sql id="selectFsUserWatchCourseStatisticsVo">
+        select id, period_id, period_name, course_id, course_name, video_id, video_title, company_id, company_name, company_user_id, course_start_date_time, company_user_name, period_starting_time, new_user_num, user_num, watch_num, complete_watch_num, complete_watch_rate, answer_num, answer_right_num, answer_right_rate, red_packet_num, red_packet_amount from fs_user_watch_course_statistics
+    </sql>
+
+    <select id="selectFsUserWatchCourseStatisticsList" parameterType="FsUserWatchCourseStatistics" resultMap="FsUserWatchCourseStatisticsResult">
+        <include refid="selectFsUserWatchCourseStatisticsVo"/>
+        <where>  
+            <if test="periodId != null "> and period_id = #{periodId}</if>
+            <if test="periodName != null  and periodName != ''"> and period_name like concat('%', #{periodName}, '%')</if>
+            <if test="courseId != null "> and course_id = #{courseId}</if>
+            <if test="courseName != null  and courseName != ''"> and course_name like concat('%', #{courseName}, '%')</if>
+            <if test="videoId != null "> and video_id = #{videoId}</if>
+            <if test="videoTitle != null  and videoTitle != ''"> and video_title = #{videoTitle}</if>
+            <if test="companyId != null "> and company_id = #{companyId}</if>
+            <if test="companyName != null  and companyName != ''"> and company_name like concat('%', #{companyName}, '%')</if>
+            <if test="companyUserId != null "> and company_user_id = #{companyUserId}</if>
+            <if test="courseStartDateTime != null "> and course_start_date_time = #{courseStartDateTime}</if>
+            <if test="companyUserName != null  and companyUserName != ''"> and company_user_name like concat('%', #{companyUserName}, '%')</if>
+            <if test="periodStartingTime != null "> and period_starting_time = #{periodStartingTime}</if>
+            <if test="newUserNum != null "> and new_user_num = #{newUserNum}</if>
+            <if test="userNum != null "> and user_num = #{userNum}</if>
+            <if test="watchNum != null "> and watch_num = #{watchNum}</if>
+            <if test="completeWatchNum != null "> and complete_watch_num = #{completeWatchNum}</if>
+            <if test="completeWatchRate != null "> and complete_watch_rate = #{completeWatchRate}</if>
+            <if test="answerNum != null "> and answer_num = #{answerNum}</if>
+            <if test="answerRightNum != null "> and answer_right_num = #{answerRightNum}</if>
+            <if test="answerRightRate != null "> and answer_right_rate = #{answerRightRate}</if>
+            <if test="redPacketNum != null "> and red_packet_num = #{redPacketNum}</if>
+            <if test="redPacketAmount != null "> and red_packet_amount = #{redPacketAmount}</if>
+        </where>
+    </select>
+    
+    <select id="selectFsUserWatchCourseStatisticsById" parameterType="Long" resultMap="FsUserWatchCourseStatisticsResult">
+        <include refid="selectFsUserWatchCourseStatisticsVo"/>
+        where id = #{id}
+    </select>
+        
+    <insert id="insertFsUserWatchCourseStatistics" parameterType="FsUserWatchCourseStatistics" useGeneratedKeys="true" keyProperty="id">
+        insert into fs_user_watch_course_statistics
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="periodId != null">period_id,</if>
+            <if test="periodName != null">period_name,</if>
+            <if test="courseId != null">course_id,</if>
+            <if test="courseName != null">course_name,</if>
+            <if test="videoId != null">video_id,</if>
+            <if test="videoTitle != null">video_title,</if>
+            <if test="companyId != null">company_id,</if>
+            <if test="companyName != null">company_name,</if>
+            <if test="companyUserId != null">company_user_id,</if>
+            <if test="courseStartDateTime != null">course_start_date_time,</if>
+            <if test="companyUserName != null">company_user_name,</if>
+            <if test="periodStartingTime != null">period_starting_time,</if>
+            <if test="newUserNum != null">new_user_num,</if>
+            <if test="userNum != null">user_num,</if>
+            <if test="watchNum != null">watch_num,</if>
+            <if test="completeWatchNum != null">complete_watch_num,</if>
+            <if test="completeWatchRate != null">complete_watch_rate,</if>
+            <if test="answerNum != null">answer_num,</if>
+            <if test="answerRightNum != null">answer_right_num,</if>
+            <if test="answerRightRate != null">answer_right_rate,</if>
+            <if test="redPacketNum != null">red_packet_num,</if>
+            <if test="redPacketAmount != null">red_packet_amount,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="periodId != null">#{periodId},</if>
+            <if test="periodName != null">#{periodName},</if>
+            <if test="courseId != null">#{courseId},</if>
+            <if test="courseName != null">#{courseName},</if>
+            <if test="videoId != null">#{videoId},</if>
+            <if test="videoTitle != null">#{videoTitle},</if>
+            <if test="companyId != null">#{companyId},</if>
+            <if test="companyName != null">#{companyName},</if>
+            <if test="companyUserId != null">#{companyUserId},</if>
+            <if test="courseStartDateTime != null">#{courseStartDateTime},</if>
+            <if test="companyUserName != null">#{companyUserName},</if>
+            <if test="periodStartingTime != null">#{periodStartingTime},</if>
+            <if test="newUserNum != null">#{newUserNum},</if>
+            <if test="userNum != null">#{userNum},</if>
+            <if test="watchNum != null">#{watchNum},</if>
+            <if test="completeWatchNum != null">#{completeWatchNum},</if>
+            <if test="completeWatchRate != null">#{completeWatchRate},</if>
+            <if test="answerNum != null">#{answerNum},</if>
+            <if test="answerRightNum != null">#{answerRightNum},</if>
+            <if test="answerRightRate != null">#{answerRightRate},</if>
+            <if test="redPacketNum != null">#{redPacketNum},</if>
+            <if test="redPacketAmount != null">#{redPacketAmount},</if>
+         </trim>
+    </insert>
+
+    <update id="updateFsUserWatchCourseStatistics" parameterType="FsUserWatchCourseStatistics">
+        update fs_user_watch_course_statistics
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="periodId != null">period_id = #{periodId},</if>
+            <if test="periodName != null">period_name = #{periodName},</if>
+            <if test="courseId != null">course_id = #{courseId},</if>
+            <if test="courseName != null">course_name = #{courseName},</if>
+            <if test="videoId != null">video_id = #{videoId},</if>
+            <if test="videoTitle != null">video_title = #{videoTitle},</if>
+            <if test="companyId != null">company_id = #{companyId},</if>
+            <if test="companyName != null">company_name = #{companyName},</if>
+            <if test="companyUserId != null">company_user_id = #{companyUserId},</if>
+            <if test="courseStartDateTime != null">course_start_date_time = #{courseStartDateTime},</if>
+            <if test="companyUserName != null">company_user_name = #{companyUserName},</if>
+            <if test="periodStartingTime != null">period_starting_time = #{periodStartingTime},</if>
+            <if test="newUserNum != null">new_user_num = #{newUserNum},</if>
+            <if test="userNum != null">user_num = #{userNum},</if>
+            <if test="watchNum != null">watch_num = #{watchNum},</if>
+            <if test="completeWatchNum != null">complete_watch_num = #{completeWatchNum},</if>
+            <if test="completeWatchRate != null">complete_watch_rate = #{completeWatchRate},</if>
+            <if test="answerNum != null">answer_num = #{answerNum},</if>
+            <if test="answerRightNum != null">answer_right_num = #{answerRightNum},</if>
+            <if test="answerRightRate != null">answer_right_rate = #{answerRightRate},</if>
+            <if test="redPacketNum != null">red_packet_num = #{redPacketNum},</if>
+            <if test="redPacketAmount != null">red_packet_amount = #{redPacketAmount},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteFsUserWatchCourseStatisticsById" parameterType="Long">
+        delete from fs_user_watch_course_statistics where id = #{id}
+    </delete>
+
+    <delete id="deleteFsUserWatchCourseStatisticsByIds" parameterType="String">
+        delete from fs_user_watch_course_statistics where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 146 - 0
fs-service-system/src/main/resources/mapper/course/FsUserWatchStatisticsMapper.xml

@@ -0,0 +1,146 @@
+<?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.course.mapper.FsUserWatchStatisticsMapper">
+
+    <resultMap type="FsUserWatchStatistics" id="FsUserWatchStatisticsResult">
+        <result property="id"    column="id"    />
+        <result property="periodId"    column="period_id"    />
+        <result property="periodName"    column="period_name"    />
+        <result property="periodStartingTime"    column="period_starting_time"    />
+        <result property="newUserNum"    column="new_user_num"    />
+        <result property="userNum"    column="user_num"    />
+        <result property="watchNum"    column="watch_num"    />
+        <result property="completeWatchNum"    column="complete_watch_num"    />
+        <result property="completeWatchRate"    column="complete_watch_rate"    />
+    </resultMap>
+
+    <sql id="selectFsUserWatchStatisticsVo">
+        select id, period_id, period_name, period_starting_time, new_user_num, user_num, watch_num, complete_watch_num, complete_watch_rate from fs_user_watch_statistics
+    </sql>
+
+    <select id="selectFsUserWatchStatisticsList" parameterType="FsUserWatchStatistics" resultMap="FsUserWatchStatisticsResult">
+        <include refid="selectFsUserWatchStatisticsVo"/>
+        <where>
+            <if test="periodId != null "> and period_id = #{periodId}</if>
+            <if test="periodName != null  and periodName != ''"> and period_name like concat('%', #{periodName}, '%')</if>
+            <if test="periodStartingTime != null "> and period_starting_time = #{periodStartingTime}</if>
+            <if test="newUserNum != null "> and new_user_num = #{newUserNum}</if>
+            <if test="userNum != null "> and user_num = #{userNum}</if>
+            <if test="watchNum != null "> and watch_num = #{watchNum}</if>
+            <if test="completeWatchNum != null "> and complete_watch_num = #{completeWatchNum}</if>
+            <if test="completeWatchRate != null "> and complete_watch_rate = #{completeWatchRate}</if>
+        </where>
+    </select>
+
+    <select id="selectFsUserWatchStatisticsById" parameterType="Long" resultMap="FsUserWatchStatisticsResult">
+        <include refid="selectFsUserWatchStatisticsVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertFsUserWatchStatistics" parameterType="FsUserWatchStatistics" useGeneratedKeys="true" keyProperty="id">
+        insert into fs_user_watch_statistics
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="periodId != null">period_id,</if>
+            <if test="periodName != null">period_name,</if>
+            <if test="periodStartingTime != null">period_starting_time,</if>
+            <if test="newUserNum != null">new_user_num,</if>
+            <if test="userNum != null">user_num,</if>
+            <if test="watchNum != null">watch_num,</if>
+            <if test="completeWatchNum != null">complete_watch_num,</if>
+            <if test="completeWatchRate != null">complete_watch_rate,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="periodId != null">#{periodId},</if>
+            <if test="periodName != null">#{periodName},</if>
+            <if test="periodStartingTime != null">#{periodStartingTime},</if>
+            <if test="newUserNum != null">#{newUserNum},</if>
+            <if test="userNum != null">#{userNum},</if>
+            <if test="watchNum != null">#{watchNum},</if>
+            <if test="completeWatchNum != null">#{completeWatchNum},</if>
+            <if test="completeWatchRate != null">#{completeWatchRate},</if>
+         </trim>
+    </insert>
+
+    <update id="updateFsUserWatchStatistics" parameterType="FsUserWatchStatistics">
+        update fs_user_watch_statistics
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="periodId != null">period_id = #{periodId},</if>
+            <if test="periodName != null">period_name = #{periodName},</if>
+            <if test="periodStartingTime != null">period_starting_time = #{periodStartingTime},</if>
+            <if test="newUserNum != null">new_user_num = #{newUserNum},</if>
+            <if test="userNum != null">user_num = #{userNum},</if>
+            <if test="watchNum != null">watch_num = #{watchNum},</if>
+            <if test="completeWatchNum != null">complete_watch_num = #{completeWatchNum},</if>
+            <if test="completeWatchRate != null">complete_watch_rate = #{completeWatchRate},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteFsUserWatchStatisticsById" parameterType="Long">
+        delete from fs_user_watch_statistics where id = #{id}
+    </delete>
+
+    <delete id="deleteFsUserWatchStatisticsByIds" parameterType="String">
+        delete from fs_user_watch_statistics where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+
+    <select id="getCourseWatchStatistics" resultType="FsUserWatchStatistics">
+        SELECT
+            count( DISTINCT CASE WHEN fwl.log_type != 3 THEN fwl.user_id END ) AS watchNum,
+            count( DISTINCT CASE WHEN fwl.log_type = 2 THEN fwl.user_id END ) AS completeWatchNum,
+            ifnull(
+                ROUND(
+                    (
+                        COUNT( DISTINCT CASE WHEN fwl.log_type = 2 THEN fwl.user_id END ) / count( DISTINCT CASE WHEN fwl.log_type != 3 THEN fwl.user_id END )) * 100,
+                    2
+                    ),
+                    0
+            ) AS completeWatchRate,
+            fwl.period_id
+            ,fs_user_course_period.period_name,
+            fs_user_course_period.period_starting_time
+        FROM
+            fs_course_watch_log fwl
+                LEFT JOIN fs_user_course_period ON fwl.period_id = fs_user_course_period.period_id
+        WHERE
+            fwl.send_type = 1
+        GROUP BY
+            fwl.period_id
+    </select>
+
+    <insert id="insertFsUserWatchStatisticsTask" parameterType="FsUserWatchStatistics" useGeneratedKeys="true" keyProperty="id">
+        insert into fs_user_watch_statistics
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="periodId != null">period_id,</if>
+            <if test="periodName != null">period_name,</if>
+            <if test="periodStartingTime != null">period_starting_time,</if>
+            <if test="newUserNum != null">new_user_num,</if>
+            <if test="userNum != null">user_num,</if>
+            <if test="watchNum != null">watch_num,</if>
+            <if test="completeWatchNum != null">complete_watch_num,</if>
+            <if test="completeWatchRate != null">complete_watch_rate,</if>
+            <if test="createTime != null">create_time,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="periodId != null">#{periodId},</if>
+            <if test="periodName != null">#{periodName},</if>
+            <if test="periodStartingTime != null">#{periodStartingTime},</if>
+            <if test="newUserNum != null">#{newUserNum},</if>
+            <if test="userNum != null">#{userNum},</if>
+            <if test="watchNum != null">#{watchNum},</if>
+            <if test="completeWatchNum != null">#{completeWatchNum},</if>
+            <if test="completeWatchRate != null">#{completeWatchRate},</if>
+            <if test="createTime != null">#{createTime},</if>
+        </trim>
+        on duplicate key update
+        <trim suffixOverrides=",">
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+        </trim>
+    </insert>
+
+</mapper>

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

@@ -1447,4 +1447,95 @@
         </if>
     </select>
 
+    <select id="selectFsUserTotal" resultType="FsUserWatchStatistics">
+        SELECT
+            count( fs_user.user_id ) as userNum,
+            count( DISTINCT CASE WHEN to_days( fs_user.create_time ) = to_days( now()) THEN fs_user.user_id END ) as newUserNum
+        <if test="isCourse != null and isCourse == 1 ">
+            ,company.company_id,
+            company.company_name,
+            GROUP_CONCAT( DISTINCT company_user.user_id ) AS company_user_id,
+            GROUP_CONCAT( DISTINCT company_user.nick_name ) AS companyUserName
+        </if>
+        FROM
+            fs_user
+            LEFT JOIN company_user ON company_user.user_id = fs_user.company_user_id
+            LEFT JOIN company ON company.company_id = fs_user.company_id
+        WHERE
+            fs_user.is_del = 0
+          AND fs_user.`status` = 1
+        <if test="isCourse != null and isCourse == 1 ">
+        GROUP BY
+            fs_user.company_id
+        </if>
+    </select>
+
+
+    <select id="selectWatchLogCount" resultType="FsUserWatchCourseStatistics">
+        SELECT
+            count( DISTINCT CASE WHEN fwl.log_type != 3 THEN fwl.user_id END ) AS watchNum,
+
+            count( DISTINCT CASE WHEN fwl.log_type = 2 THEN fwl.user_id END ) AS completeWatchNum,
+
+            ifnull(
+                    ROUND(
+                            (
+                                COUNT( DISTINCT CASE WHEN fwl.log_type = 2 THEN fwl.user_id END ) / count( DISTINCT CASE WHEN fwl.log_type != 3 THEN fwl.user_id END )) * 100,
+                            2
+                    ),
+                    0
+            ) AS completeWatchRate,
+            fwl.period_id, fwl.video_id, fwl.company_user_id, fwl.company_id
+        FROM
+            fs_course_watch_log fwl
+        WHERE
+            fwl.send_type = 1
+        GROUP BY
+            fwl.period_id, fwl.video_id, fwl.company_user_id
+    </select>
+
+    <select id="selectRedPacketLogCount" resultType="FsUserWatchCourseStatistics">
+        SELECT
+            count( flog.log_id ) AS redPacketNum,
+            ifnull ( sum( flog.amount ), 0 ) AS redPacketAmount,
+            flog.period_id,
+            flog.video_id,
+            flog.company_user_id,
+            flog.company_id
+        FROM
+            fs_course_red_packet_log flog
+                LEFT JOIN fs_user ON fs_user.user_id = flog.user_id
+                LEFT JOIN company_user ON company_user.user_id = fs_user.company_user_id
+        GROUP BY
+            flog.period_id,
+            flog.video_id,
+            flog.company_user_id
+    </select>
+
+    <select id="selectAnswerLogCount" resultType="FsUserWatchCourseStatistics">
+        SELECT
+            count( DISTINCT fs_user.user_id ) AS answerNum,
+            COUNT( DISTINCT CASE WHEN fs_course_answer_logs.is_right = 1 THEN fs_user.user_id END ) AS answerRightNum,
+            ifnull(
+                    ROUND(
+                            (
+                                COUNT( DISTINCT CASE WHEN fs_course_answer_logs.is_right = 1 THEN fs_user.user_id END ) / count( DISTINCT fs_user.user_id )) * 100,
+                            2
+                    ),
+                    0
+            ) AS answerRightRate,
+            fs_course_answer_logs.period_id,
+            fs_course_answer_logs.video_id,
+            fs_course_answer_logs.company_user_id,
+            fs_course_answer_logs.company_id
+        FROM
+            fs_course_answer_logs
+                LEFT JOIN fs_user ON fs_user.user_id = fs_course_answer_logs.user_id
+                LEFT JOIN company_user ON company_user.user_id = fs_user.company_user_id
+        GROUP BY
+            fs_course_answer_logs.period_id,
+            fs_course_answer_logs.video_id,
+            fs_course_answer_logs.company_user_id
+    </select>
+
 </mapper>