Browse Source

Merge remote-tracking branch 'origin/master'

xdd 1 ngày trước cách đây
mục cha
commit
94c57393e6
23 tập tin đã thay đổi với 483 bổ sung25 xóa
  1. 43 2
      fs-qwhook-sop/src/main/java/com/fs/app/controller/ApisQwSopController.java
  2. 6 1
      fs-service/src/main/java/com/fs/course/mapper/FsCourseWatchLogMapper.java
  3. 6 3
      fs-service/src/main/java/com/fs/course/service/IFsCourseWatchLogService.java
  4. 6 5
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseWatchLogServiceImpl.java
  5. 14 0
      fs-service/src/main/java/com/fs/his/mapper/FsUserMapper.java
  6. 6 0
      fs-service/src/main/java/com/fs/qw/mapper/QwExternalContactMapper.java
  7. 26 0
      fs-service/src/main/java/com/fs/qw/param/CourseQuizRedEnvelopeStatsParam.java
  8. 17 0
      fs-service/src/main/java/com/fs/qw/param/ExternalContactParam.java
  9. 37 0
      fs-service/src/main/java/com/fs/qw/param/QwSidebarStatsParam.java
  10. 0 1
      fs-service/src/main/java/com/fs/qw/param/SopMsgParam.java
  11. 6 0
      fs-service/src/main/java/com/fs/qw/service/IQwExternalContactService.java
  12. 5 0
      fs-service/src/main/java/com/fs/qw/service/impl/QwExternalContactServiceImpl.java
  13. 14 0
      fs-service/src/main/java/com/fs/sop/service/IQwSopService.java
  14. 125 3
      fs-service/src/main/java/com/fs/sop/service/impl/QwSopServiceImpl.java
  15. 15 0
      fs-service/src/main/java/com/fs/store/vo/h5/ExternalAnswerStatsVO.java
  16. 16 0
      fs-service/src/main/java/com/fs/store/vo/h5/ExternalRedPacketStatsVO.java
  17. 35 0
      fs-service/src/main/java/com/fs/store/vo/h5/ExternalUserStatsVO.java
  18. 15 0
      fs-service/src/main/java/com/fs/store/vo/h5/ExternalWatchStatsVO.java
  19. 35 0
      fs-service/src/main/resources/mapper/course/FsCourseWatchLogMapper.xml
  20. 4 5
      fs-service/src/main/resources/mapper/his/FsStoreOrderMapper.xml
  21. 44 0
      fs-service/src/main/resources/mapper/his/FsUserMapper.xml
  22. 4 4
      fs-service/src/main/resources/mapper/hisStore/FsStoreOrderScrmMapper.xml
  23. 4 1
      fs-service/src/main/resources/mapper/qw/QwExternalContactMapper.xml

+ 43 - 2
fs-qwhook-sop/src/main/java/com/fs/app/controller/ApisQwSopController.java

@@ -2,12 +2,17 @@ package com.fs.app.controller;
 
 import com.fs.app.params.SopLogsEditParam;
 import com.fs.common.BeanCopyUtils;
+import com.fs.common.core.controller.BaseController;
 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.core.redis.RedisCache;
+import com.fs.common.utils.StringUtils;
+import com.fs.course.vo.FsCourseWatchLogStatisticsListVO;
 import com.fs.fastGpt.param.FastGptChatSessionParam;
 import com.fs.fastGpt.service.IFastGptChatSessionService;
 import com.fs.qw.domain.QwTagGroup;
-import com.fs.qw.param.SopMsgParam;
+import com.fs.qw.param.*;
 import com.fs.qw.param.sidebar.ExternalContactInfoParam;
 import com.fs.qw.param.sidebar.TagGroupListParam;
 import com.fs.qw.param.sidebar.TagGroupUpdateParam;
@@ -21,6 +26,9 @@ import com.fs.sop.domain.QwSopLogs;
 import com.fs.sop.params.GetQwSopLogsByJsApiParam;
 import com.fs.sop.params.SendSopParamDetailsC;
 import com.fs.sop.service.IQwSopLogsService;
+import com.fs.sop.service.IQwSopService;
+import com.fs.store.vo.h5.ExternalUserStatsVO;
+import com.fs.store.vo.h5.FsUserStatisticsVO;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
 import io.swagger.annotations.ApiOperation;
@@ -28,13 +36,14 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
 import java.text.SimpleDateFormat;
+import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 
 
 @RestController
 @RequestMapping("/apis/app/qwSop")
-public class ApisQwSopController {
+public class ApisQwSopController  extends BaseController {
 
     @Autowired
     RedisCache redisCache;
@@ -49,6 +58,8 @@ public class ApisQwSopController {
     @Autowired
     private IQwTagGroupService qwTagGroupService;
 
+    @Autowired
+    private IQwSopService qwSopService;
     /**
      * 更新AI发送状态
      */
@@ -162,4 +173,34 @@ public class ApisQwSopController {
         return R.error();
     }
 
+    //员工看板 课程/答题/红包统计--侧边栏
+    @GetMapping("/boardCourseQuizRedEnvelopeStats")
+    @ApiOperation("员工看板 课程/答题/红包统计")
+    public ResponseResult<FsUserStatisticsVO> boardCourseQuizRedEnvelopeStats(CourseQuizRedEnvelopeStatsParam qwParam) {
+        if (StringUtils.isBlank(qwParam.getStartTime()) || StringUtils.isBlank(qwParam.getEndTime())) {
+            return ResponseResult.ok(new FsUserStatisticsVO());
+        }
+        FsUserStatisticsVO resultVo = qwSopService.boardCourseQuizRedEnvelopeStats(qwParam);
+        return ResponseResult.ok(resultVo);
+    }
+
+    //外部联系人答题/红包/看课统计--侧边栏
+    @GetMapping("/externalStatsList")
+    @ApiOperation("外部联系人答题/红包/看课统计")
+    public ResponseResult<ExternalUserStatsVO> externalStatsList(QwSidebarStatsParam qwParam) {
+        ExternalUserStatsVO vo = qwSopService.externalStatsList(qwParam);
+        return ResponseResult.ok(vo);
+    }
+
+    //外部联系人看课轨迹--侧边栏
+    @GetMapping("/externalWatchRecordStatsList")
+    @ApiOperation("用户看课轨迹")
+    public TableDataInfo externalWatchRecordStatsList(QwSidebarStatsParam qwParam) {
+        if (qwParam.getStartTime() == null || qwParam.getEndTime() == null) {
+            return getDataTable(Collections.emptyList());
+        }
+        List<FsCourseWatchLogStatisticsListVO> list = qwSopService.externalWatchRecordStatsList(qwParam);
+        return getDataTable(list);
+    }
+
 }

+ 6 - 1
fs-service/src/main/java/com/fs/course/mapper/FsCourseWatchLogMapper.java

@@ -6,12 +6,12 @@ import com.fs.course.dto.WatchLogDTO;
 import com.fs.course.param.*;
 import com.fs.course.vo.*;
 import com.fs.qw.domain.QwExternalContact;
+import com.fs.qw.param.QwSidebarStatsParam;
 import com.fs.sop.vo.QwRatingVO;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
 import org.apache.ibatis.annotations.Update;
 
-import java.time.LocalDateTime;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
@@ -530,4 +530,9 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
     Integer getUserCountByCampId(@Param("trainingCampId") Long trainingCampId);
 
     List<FsCourseWatchLogStatisticsListByCompanyVO> selectFsCourseWatchLogStatisticsListByCompanyVO(FsCourseWatchLogStatisticsListParam param);
+
+    /**
+     * 看课统计
+     * */
+    List<FsCourseWatchLogStatisticsListVO> selectQwFsCourseWatchLogStatisticsListVO(QwSidebarStatsParam param);
 }

+ 6 - 3
fs-service/src/main/java/com/fs/course/service/IFsCourseWatchLogService.java

@@ -4,11 +4,9 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.fs.course.domain.FsCourseWatchLog;
 import com.fs.course.param.*;
 import com.fs.course.vo.*;
-import com.fs.qw.param.QwWatchLogStatisticsListParam;
-import com.fs.qw.vo.QwWatchLogStatisticsListVO;
+import com.fs.qw.param.QwSidebarStatsParam;
 
 import java.time.LocalDateTime;
-import java.time.LocalTime;
 import java.util.List;
 import java.util.Map;
 
@@ -135,4 +133,9 @@ public interface IFsCourseWatchLogService extends IService<FsCourseWatchLog> {
     void scheduleBatchUpdateToDatabaseIsOpen();
 
     List<FsCourseWatchLogListVO> selectFsCourseWatchLogListVOexport(FsCourseWatchLogListParam param);
+
+    /**
+     * 看课统计
+     * */
+    List<FsCourseWatchLogStatisticsListVO> selectQwFsCourseWatchLogStatisticsListVO(QwSidebarStatsParam param);
 }

+ 6 - 5
fs-service/src/main/java/com/fs/course/service/impl/FsCourseWatchLogServiceImpl.java

@@ -29,25 +29,21 @@ import com.fs.his.config.FsSysConfig;
 import com.fs.his.domain.FsUser;
 import com.fs.his.service.IFsUserService;
 import com.fs.his.utils.ConfigUtil;
-import com.fs.his.vo.OptionsVO;
 import com.fs.qw.Bean.MsgBean;
 import com.fs.qw.cache.IQwExternalContactCacheService;
 import com.fs.qw.cache.IQwUserCacheService;
 import com.fs.qw.domain.QwExternalContact;
-import com.fs.qw.domain.QwExternalContactInfo;
 import com.fs.qw.domain.QwUser;
 import com.fs.qw.domain.QwWatchLog;
 import com.fs.qw.mapper.QwExternalContactMapper;
 import com.fs.qw.mapper.QwUserMapper;
 import com.fs.qw.mapper.QwWatchLogMapper;
+import com.fs.qw.param.QwSidebarStatsParam;
 import com.fs.qw.param.SendSopParamDetails;
-import com.fs.qw.param.SopUserLogsVO;
 import com.fs.qw.vo.QwSopCourseFinishTempSetting;
 import com.fs.qw.vo.QwSopTempSetting;
 import com.fs.sop.domain.QwSopLogs;
-import com.fs.sop.mapper.QwSopLogsMapper;
 import com.fs.sop.mapper.SopUserLogsMapper;
-import com.fs.sop.service.IQwSopLogsService;
 import com.fs.store.service.cache.IFsUserCacheService;
 import com.fs.store.service.cache.IFsUserCourseCacheService;
 import com.fs.system.service.ISysConfigService;
@@ -1240,4 +1236,9 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
         return list;
     }
 
+    @Override
+    public List<FsCourseWatchLogStatisticsListVO> selectQwFsCourseWatchLogStatisticsListVO(QwSidebarStatsParam param) {
+        return fsCourseWatchLogMapper.selectQwFsCourseWatchLogStatisticsListVO(param);
+    }
+
 }

+ 14 - 0
fs-service/src/main/java/com/fs/his/mapper/FsUserMapper.java

@@ -410,4 +410,18 @@ public interface FsUserMapper
     Map<String, Object> countUserStats(
             UserStatisticsCommonParam param);
 
+    /**
+     * 统计用户领取红包数据(红包个数、红包金额)
+     * */
+    ExternalRedPacketStatsVO countExternalRedPacketStats(UserStatisticsCommonParam param);
+
+    /**
+     * 统计用户答题数据(答题次数、正确次数)
+     * */
+    ExternalAnswerStatsVO countExternalAnswerStats(UserStatisticsCommonParam param);
+
+    /**
+     * 统计用户看课数据(课程观看次数、课程完播次数)
+     * */
+    ExternalWatchStatsVO countExternalWatchStats(UserStatisticsCommonParam param);
 }

+ 6 - 0
fs-service/src/main/java/com/fs/qw/mapper/QwExternalContactMapper.java

@@ -14,6 +14,7 @@ import com.fs.qw.result.QwExternalContactVo;
 import com.fs.qw.vo.*;
 import com.fs.qw.vo.newvo.ExternalContactListVO;
 import com.fs.qw.vo.newvo.ExternalContactNumVO;
+import com.fs.qw.vo.sidebar.ExternalContactQwUserVO;
 import com.fs.qwApi.param.QwExternalContactHParam;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
@@ -522,4 +523,9 @@ public interface QwExternalContactMapper extends BaseMapper<QwExternalContact> {
     void updateQwExternalContactStatusById(QwExternalContact qwExternalContact);
 
     List<QwExternalContactVO> selectQwExternalContactListVONewSys(QwExternalContactParam qwExternalContact);
+
+    /**
+     * 根据qw_user_id+crop_id+external_user_id查询外部联系人信息
+     * */
+    QwExternalContact selectQwUserListVOByQwUserIdAndCorpIdAndExternalUserId(ExternalContactParam externalContactParam);
 }

+ 26 - 0
fs-service/src/main/java/com/fs/qw/param/CourseQuizRedEnvelopeStatsParam.java

@@ -0,0 +1,26 @@
+package com.fs.qw.param;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+
+@Data
+public class CourseQuizRedEnvelopeStatsParam  implements Serializable {
+    @ApiModelProperty(value = "企业id", required = true)
+    @NotBlank(message = "corpId 不能为空")
+    private String corpId;
+
+    @ApiModelProperty(value = "用户id", required = true)
+    @NotBlank(message = "qwUserId 不能为空")
+    private String qwUserId;
+
+    @ApiModelProperty(value = "开始日期", required = true)
+    @NotBlank(message = "startTime 不能为空")
+    private String startTime;
+
+    @ApiModelProperty(value = "截止日期", required = true)
+    @NotBlank(message = "endTime 不能为空")
+    private String endTime;
+}

+ 17 - 0
fs-service/src/main/java/com/fs/qw/param/ExternalContactParam.java

@@ -0,0 +1,17 @@
+package com.fs.qw.param;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class ExternalContactParam  implements Serializable {
+    //企业id
+    private String corpId;
+    //登录用户id
+    private String userId;
+
+    //外部联系人id
+    private String externalUserId;
+
+}

+ 37 - 0
fs-service/src/main/java/com/fs/qw/param/QwSidebarStatsParam.java

@@ -0,0 +1,37 @@
+package com.fs.qw.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+@Data
+@ApiModel
+public class QwSidebarStatsParam implements Serializable {
+    @NotBlank(message = "corpId 不能为空")
+    @ApiModelProperty(value = "企业id", required = true)
+    private String corpId;
+
+    @ApiModelProperty(value = "用户id", required = true)
+    @NotBlank(message = "qwUserId 不能为空")
+    private String qwUserId;
+
+    @ApiModelProperty(value = "外部联系人id", required = true)
+    @NotBlank(message = "externalUserId 不能为空")
+    private String externalUserId;
+
+    @ApiModelProperty(value = "页码,默认为1", required = false)
+    private Integer pageNum = 1;
+
+    @ApiModelProperty(value = "页大小,默认为10", required = false)
+    private Integer pageSize = 10;
+
+    private String startTime;
+
+    private String endTime;
+
+    //外部联系人主键Id
+    private Long qwExternalContactId;
+
+}

+ 0 - 1
fs-service/src/main/java/com/fs/qw/param/SopMsgParam.java

@@ -17,7 +17,6 @@ public class SopMsgParam {
     private String qwUserid;
 
     /** 企微外部联系人id */
-
     @NotBlank(message = "externalUserId 不能为空")
     private String externalUserId;
 

+ 6 - 0
fs-service/src/main/java/com/fs/qw/service/IQwExternalContactService.java

@@ -16,8 +16,10 @@ import com.fs.qw.vo.*;
 import com.fs.qw.vo.newvo.ExternalContactListVO;
 import com.fs.qw.vo.newvo.ExternalContactPageVO;
 import com.fs.qw.vo.sidebar.ExternalContactInfoVO;
+import com.fs.qw.vo.sidebar.ExternalContactQwUserVO;
 import com.fs.qw.vo.sidebar.ExternalContactTagVO;
 import com.fs.qwApi.param.QwExternalContactHParam;
+import org.apache.ibatis.annotations.Param;
 import org.codehaus.jettison.json.JSONException;
 
 import java.io.IOException;
@@ -251,4 +253,8 @@ public interface IQwExternalContactService extends IService<QwExternalContact> {
 
     R getRepeat(RepeatParam param);
     List<QwExternalContactVO> selectQwExternalContactListVONewSys(QwExternalContactParam qwExternalContact);
+    /**
+     * 根据qw_user_id+crop_id+external_user_id查询外部联系人信息
+     * */
+    QwExternalContact selectQwUserListVOByQwUserIdAndCorpIdAndExternalUserId(ExternalContactParam externalContactParam);
 }

+ 5 - 0
fs-service/src/main/java/com/fs/qw/service/impl/QwExternalContactServiceImpl.java

@@ -5899,6 +5899,11 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
         return qwExternalContactMapper.selectQwExternalContactListVONewSys(qwExternalContact);
     }
 
+    @Override
+    public QwExternalContact selectQwUserListVOByQwUserIdAndCorpIdAndExternalUserId(ExternalContactParam externalContactParam) {
+        return qwExternalContactMapper.selectQwUserListVOByQwUserIdAndCorpIdAndExternalUserId(externalContactParam);
+    }
+
 
     public Boolean getSopAiChatByRedis(String qwUserId,String corpId,String externalUserId){
 

+ 14 - 0
fs-service/src/main/java/com/fs/sop/service/IQwSopService.java

@@ -1,13 +1,18 @@
 package com.fs.sop.service;
 
 import com.fs.common.core.domain.R;
+import com.fs.course.vo.FsCourseWatchLogStatisticsListVO;
 import com.fs.qw.domain.QwSopUpdateStatus;
+import com.fs.qw.param.CourseQuizRedEnvelopeStatsParam;
+import com.fs.qw.param.QwSidebarStatsParam;
 import com.fs.sop.domain.QwSop;
 import com.fs.sop.params.GetSOPTaskDataParam;
 import com.fs.sop.params.QwSopAutoTime;
 import com.fs.sop.params.QwSopEditQwUserParam;
 import com.fs.sop.vo.QwSopTask;
 import com.fs.sop.vo.SopVoiceListVo;
+import com.fs.store.vo.h5.ExternalUserStatsVO;
+import com.fs.store.vo.h5.FsUserStatisticsVO;
 
 import java.io.IOException;
 import java.util.List;
@@ -100,4 +105,13 @@ public interface IQwSopService
     List<QwSop> selectAllQwSopInfo(QwSop qwSop);
 
     int deleteQwSopLogsBySopIds(String[] ids);
+
+    //员工看板 课程/答题/红包统计--侧边栏
+    FsUserStatisticsVO boardCourseQuizRedEnvelopeStats(CourseQuizRedEnvelopeStatsParam qwParam);
+
+    //红包/看课统计--侧边栏
+    ExternalUserStatsVO externalStatsList(QwSidebarStatsParam qwParam);
+
+    //看课足迹--侧边栏
+    List<FsCourseWatchLogStatisticsListVO> externalWatchRecordStatsList (QwSidebarStatsParam qwParam);
 }

+ 125 - 3
fs-service/src/main/java/com/fs/sop/service/impl/QwSopServiceImpl.java

@@ -13,13 +13,18 @@ import com.fs.company.mapper.CompanyUserMapper;
 import com.fs.company.vo.CompanyQwUserByIdsVo;
 import com.fs.course.mapper.FsCourseWatchLogMapper;
 import com.fs.course.service.IFsCourseLinkService;
+import com.fs.course.service.IFsCourseWatchLogService;
+import com.fs.course.vo.FsCourseWatchLogStatisticsListVO;
+import com.fs.his.mapper.FsUserMapper;
+import com.fs.his.service.IFsUserService;
+import com.fs.qw.domain.QwExternalContact;
 import com.fs.qw.domain.QwSopUpdateStatus;
 import com.fs.qw.domain.QwUser;
 import com.fs.qw.mapper.QwUserMapper;
-import com.fs.qw.param.QwAutoSopTimeParam;
+import com.fs.qw.param.*;
 import com.fs.qw.result.QwFilterSopCustomersResult;
+import com.fs.qw.service.IQwExternalContactService;
 import com.fs.qw.service.impl.AsyncChatSopService;
-import com.fs.qw.service.impl.AsyncSopService;
 import com.fs.qw.service.impl.AsyncSopTestService;
 import com.fs.qw.service.impl.AsyncWxSopService;
 import com.fs.qw.vo.QwSopRuleTimeVO;
@@ -32,9 +37,12 @@ import com.fs.sop.service.*;
 import com.fs.sop.vo.QwSopTask;
 import com.fs.sop.vo.SopVoiceListVo;
 import com.fs.sop.vo.VoiceVo;
+import com.fs.store.param.h5.UserStatisticsCommonParam;
+import com.fs.store.vo.h5.*;
 import com.fs.voice.utils.StringUtil;
 import com.fs.wxUser.mapper.CompanyWxUserMapper;
 import com.fs.wxUser.param.CompanyWxUserSopParam;
+import com.github.pagehelper.PageHelper;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.rocketmq.spring.core.RocketMQTemplate;
 import org.slf4j.Logger;
@@ -122,6 +130,17 @@ public class QwSopServiceImpl implements IQwSopService
     @Autowired
     private RocketMQTemplate rocketMQTemplate;
 
+    @Autowired
+    private IQwExternalContactService qwExternalContactService;
+
+    @Autowired
+    private IFsUserService fsUserService;
+
+    @Autowired
+    private IFsCourseWatchLogService fsCourseWatchLogService;
+
+    @Autowired
+    private FsUserMapper fsUserMapper;
     /**
      * 查询企微sop
      *
@@ -1100,7 +1119,6 @@ public class QwSopServiceImpl implements IQwSopService
         }
         return qwSopLogsMapper.delete(new QueryWrapper<QwSopLogs>().in("sop_id", Arrays.asList(ids)));
     }
-
     /**
      *新增员工执行SOP
      */
@@ -1253,4 +1271,108 @@ public class QwSopServiceImpl implements IQwSopService
     }
 
 
+    @Override
+    public FsUserStatisticsVO boardCourseQuizRedEnvelopeStats(CourseQuizRedEnvelopeStatsParam qwParam) {
+        String startTime = qwParam.getStartTime();
+        String endTime = qwParam.getEndTime();
+        //1:获取当前登录企微用户信息
+        QwUser qwUser = qwExternalContactService.getQwUserByRedis(qwParam.getCorpId().trim(),qwParam.getQwUserId().trim());
+        if (qwUser==null||qwUser.getCompanyUserId()==null){
+            return new FsUserStatisticsVO();
+        }
+        Long userId = qwUser.getCompanyUserId();
+        UserStatisticsCommonParam param = new UserStatisticsCommonParam();
+        param.setUserId(userId).setStartTime(startTime).setEndTime(endTime);
+        //2:获取当前用户统计数据
+        FsUserStatisticsVO vo = fsUserService.userStatistics(param);
+        DateTimeFormatter dfm = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        LocalDate today = LocalDate.now();
+        LocalDateTime startDateTime = LocalDateTime.parse(startTime, dfm);
+        LocalDateTime endDateTime = LocalDateTime.parse(endTime, dfm);
+        if (startDateTime.toLocalDate().equals(today) && endDateTime.toLocalDate().equals(today)) {
+            String yesterday = LocalDate.now().minusDays(1).toString();
+            UserStatisticsCommonParam paramYes = new UserStatisticsCommonParam();
+            paramYes.setUserId(userId).setStartTime(yesterday + " 00:00:00").setEndTime(yesterday + " 23:59:59");
+            FsUserStatisticsVO fsUserStatisticsVO = fsUserService.userStatistics(paramYes);
+            vo.setYesterdayVO(fsUserStatisticsVO);
+        } else {
+            vo.setYesterdayVO(new FsUserStatisticsVO());
+        }
+        return vo;
+    }
+
+
+    @Override
+    public ExternalUserStatsVO externalStatsList(QwSidebarStatsParam qwParam) {
+        ExternalUserStatsVO resultVo=new ExternalUserStatsVO();
+        //外部联系人入参对象
+        QwExternalContact externalContact = getExternalContact(
+                qwParam.getQwUserId(),
+                qwParam.getCorpId(),
+                qwParam.getExternalUserId()
+        );
+        if (externalContact == null) return new ExternalUserStatsVO();
+        Long fsUserId = externalContact.getFsUserId();
+        if (fsUserId == null || fsUserId <= 0) {
+            log.info("外部联系人没有绑定fs用户:{}",externalContact.getExternalUserId());
+            return resultVo;
+        }
+        Long companyUserId = externalContact.getCompanyUserId();
+        if (companyUserId == null || companyUserId <= 0){
+            log.info("外部联系人没有绑定销售人员:{}",externalContact.getExternalUserId());
+            return resultVo;
+        }
+        UserStatisticsCommonParam queryParam = new UserStatisticsCommonParam();
+        queryParam.setUserId(fsUserId).setCompanyUserId(String.valueOf(companyUserId)).setStartTime(qwParam.getStartTime()).setEndTime(qwParam.getEndTime());
+        //获取用户领取红包数据(红包个数、红包金额)
+        ExternalRedPacketStatsVO redPacketStatsVo = fsUserMapper.countExternalRedPacketStats(queryParam);
+        resultVo.setRedPacketNum(redPacketStatsVo.getRedPacketNum());
+        resultVo.setRedPacketAmount(redPacketStatsVo.getRedPacketAmount());
+        //获取用户答题数据(答题次数、正确次数)
+        ExternalAnswerStatsVO externalAnswerStatsVO = fsUserMapper.countExternalAnswerStats(queryParam);
+        resultVo.setAnswerNum(externalAnswerStatsVO.getAnswerNum());
+        resultVo.setAnswerRightNum(externalAnswerStatsVO.getAnswerRightNum());
+        //获取用户看课数据(观看次数、完播次数)
+        ExternalWatchStatsVO externalWatchStatsVO = fsUserMapper.countExternalWatchStats(queryParam);
+        resultVo.setCourseWatchNum(externalWatchStatsVO.getCourseWatchNum());
+        resultVo.setCourseCompleteNum(externalWatchStatsVO.getCourseCompleteNum());
+        return resultVo;
+    }
+
+    @Override
+    public List<FsCourseWatchLogStatisticsListVO> externalWatchRecordStatsList(QwSidebarStatsParam qwParam) {
+        QwExternalContact externalContact = getExternalContact(
+                qwParam.getQwUserId(),
+                qwParam.getCorpId(),
+                qwParam.getExternalUserId()
+        );
+        if (externalContact == null) return Collections.emptyList();
+        //根据外部联系人主键id获取用户的课程观看记录
+        qwParam.setQwExternalContactId(externalContact.getId());
+        PageHelper.startPage(qwParam.getPageNum(), qwParam.getPageSize());
+        List<FsCourseWatchLogStatisticsListVO> list = fsCourseWatchLogService.selectQwFsCourseWatchLogStatisticsListVO(qwParam);
+        if (CollectionUtils.isEmpty(list)){
+            return Collections.emptyList();
+        }
+        return list;
+    }
+
+    /**
+     *  获取外部联系人信息
+     * */
+    private QwExternalContact getExternalContact(String qwUserId, String corpId, String externalUserId) {
+        ExternalContactParam param = new ExternalContactParam();
+        param.setUserId(qwUserId);
+        param.setCorpId(corpId);
+        param.setExternalUserId(externalUserId);
+
+        QwExternalContact contact = qwExternalContactService.selectQwUserListVOByQwUserIdAndCorpIdAndExternalUserId(param);
+
+        if (contact == null) {
+            log.info("未查询到关联的外部联系人信息: userId={}, corpId={}, externalUserId={}",
+                    qwUserId, corpId, externalUserId);
+        }
+        return contact;
+    }
+
 }

+ 15 - 0
fs-service/src/main/java/com/fs/store/vo/h5/ExternalAnswerStatsVO.java

@@ -0,0 +1,15 @@
+package com.fs.store.vo.h5;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel
+public class ExternalAnswerStatsVO {
+    @ApiModelProperty(value = "答题次数")
+    private int answerNum;
+
+    @ApiModelProperty(value = "正确次数")
+    private int answerRightNum;
+}

+ 16 - 0
fs-service/src/main/java/com/fs/store/vo/h5/ExternalRedPacketStatsVO.java

@@ -0,0 +1,16 @@
+package com.fs.store.vo.h5;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+@Data
+@ApiModel
+public class ExternalRedPacketStatsVO {
+    @ApiModelProperty(value = "答题红包数")
+    private int redPacketNum;
+
+    @ApiModelProperty(value = "答题红包金额")
+    private BigDecimal redPacketAmount = BigDecimal.ZERO;
+}

+ 35 - 0
fs-service/src/main/java/com/fs/store/vo/h5/ExternalUserStatsVO.java

@@ -0,0 +1,35 @@
+package com.fs.store.vo.h5;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+/*
+*   侧边栏外部联系人统计数据 (课程/答题/红包等数据)
+* */
+@Data
+@ApiModel
+public class ExternalUserStatsVO {
+
+    @ApiModelProperty(value = "课程统计-观看次数")
+    private int courseWatchNum;
+
+    @ApiModelProperty(value = "课程统计-完播次数")
+    private int courseCompleteNum;
+
+
+    @ApiModelProperty(value = "答题次数")
+    private int answerNum;
+
+    @ApiModelProperty(value = "正确次数")
+    private int answerRightNum;
+
+    @ApiModelProperty(value = "答题红包数")
+    private int redPacketNum;
+
+    @ApiModelProperty(value = "答题红包金额")
+    private BigDecimal redPacketAmount = BigDecimal.ZERO;
+
+
+}

+ 15 - 0
fs-service/src/main/java/com/fs/store/vo/h5/ExternalWatchStatsVO.java

@@ -0,0 +1,15 @@
+package com.fs.store.vo.h5;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel
+public class ExternalWatchStatsVO {
+    @ApiModelProperty(value = "看课统计-观看次数")
+    private int courseWatchNum;
+
+    @ApiModelProperty(value = "看课统计-完播次数")
+    private int courseCompleteNum;
+}

+ 35 - 0
fs-service/src/main/resources/mapper/course/FsCourseWatchLogMapper.xml

@@ -915,4 +915,39 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         comp.company_id,
             DATE (o.create_time)
     </select>
+    <select id="selectQwFsCourseWatchLogStatisticsListVO"
+            resultType="com.fs.course.vo.FsCourseWatchLogStatisticsListVO" parameterType="com.fs.qw.param.QwSidebarStatsParam">
+        SELECT
+        o.project,
+        o.course_id AS courseId,
+        uc.course_name AS courseName,
+        o.video_id AS videoId,
+        v.title AS videoName,
+        CASE WHEN o.log_type = 1 THEN 1 END AS type1,
+        CASE WHEN o.log_type = 2 THEN 1 END AS type2,
+        CASE WHEN o.log_type = 3 THEN 1 END AS type3,
+        CASE WHEN o.log_type = 4 THEN 1 END AS type4,
+        o.qw_user_id,
+        o.user_id AS userId,
+        o.company_user_id AS companyUserId,
+        o.company_id AS companyId,
+        o.create_time AS createTime
+        FROM
+        fs_course_watch_log o
+        LEFT JOIN fs_user_course_video v ON v.video_id = o.video_id
+        LEFT JOIN fs_user_course uc ON uc.course_id = v.course_id
+        WHERE o.qw_external_contact_id=#{qwExternalContactId}
+        <if test="sendType != null">
+            AND send_type = #{sendType}
+        </if>
+        <if test="startTime != null">
+            AND DATE(o.create_time) &gt;= DATE(#{startTime})
+        </if>
+
+        <if test="endTime != null">
+            AND DATE(o.create_time) &lt;= DATE(#{endTime})
+        </if>
+        o.create_time DESC
+    </select>
+
 </mapper>

+ 4 - 5
fs-service/src/main/resources/mapper/his/FsStoreOrderMapper.xml

@@ -2120,17 +2120,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
         FROM fs_store_order
         WHERE is_del = 0 AND status > 1
-        <if test="startTime != null">
+        <if test="startTime != null and startTime !=''">
             AND create_time &gt;= #{startTime}
         </if>
-        <if test="endTime != null">
+        <if test="endTime != null and endTime != ''">
             AND create_time &lt;= #{endTime}
         </if>
-
-        <if test="companyId != null">
+        <if test="companyId != null and companyId !=''">
             AND company_id = #{companyId}
         </if>
-        <if test="companyUserId != null">
+        <if test="companyUserId != null and companyUserId !=''">
             AND company_user_id = #{companyUserId}
         </if>
     </select>

+ 44 - 0
fs-service/src/main/resources/mapper/his/FsUserMapper.xml

@@ -2136,4 +2136,48 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </if>
     </select>
 
+    <select id="countExternalRedPacketStats" resultType="com.fs.store.vo.h5.ExternalRedPacketStatsVO">
+        SELECT
+            COUNT(red.log_id) AS redPacketNum,
+            COALESCE(SUM(red.amount), 0) AS redPacketAmount
+        FROM fs_course_red_packet_log log
+        WHERE log.status = 1
+          AND log.user_id = #{userId} AND log.company_user_id = #{companyUserId}
+        <if test="startTime != null  and startTime != ''">
+            AND log.create_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null  and endTime != ''">
+            AND log.create_time &lt;= #{endTime}
+        </if>
+    </select>
+
+    <select id="countExternalAnswerStats" resultType="com.fs.store.vo.h5.ExternalAnswerStatsVO">
+        SELECT
+        COUNT(*) AS answerNum,
+        SUM(CASE WHEN is_right = 1 THEN 1 ELSE 0 END) AS answerRightNum
+        FROM fs_course_answer_logs log
+        WHERE log.user_id = #{userId} AND log.company_user_id = #{companyUserId}
+        <if test="startTime != null  and startTime != ''">
+            AND log.create_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null  and endTime != ''">
+            AND log.create_time &lt;= #{endTime}
+
+        </if>
+    </select>
+
+    <select id="countExternalWatchStats" resultType="com.fs.store.vo.h5.ExternalWatchStatsVO">
+        SELECT
+        COUNT(CASE WHEN log_type != 3 THEN 1 END) AS courseWatchNum,
+        COUNT(CASE WHEN log_type = 2 THEN 1 END) AS courseCompleteNum
+        FROM fs_course_watch_log log
+        WHERE log.user_id = #{userId} AND log.company_user_id = #{companyUserId}
+        <if test="startTime != null  and startTime != ''">
+            AND log.create_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null  and endTime != ''">
+            AND log.create_time &lt;= #{endTime}
+        </if>
+    </select>
+
 </mapper>

+ 4 - 4
fs-service/src/main/resources/mapper/hisStore/FsStoreOrderScrmMapper.xml

@@ -1877,16 +1877,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         SUM(CASE WHEN pay_type IN ('2', '3') THEN COALESCE(pay_money, 0) ELSE 0 END) AS codAmount
         FROM fs_store_order_scrm
         WHERE is_del = 0 AND status > 0
-        <if test="startTime != null">
+        <if test="startTime != null and startTime !=''">
             AND create_time &gt;= #{startTime}
         </if>
-        <if test="endTime != null">
+        <if test="endTime != null and endTime != ''">
             AND create_time &lt;= #{endTime}
         </if>
-        <if test="companyId != null">
+        <if test="companyId != null and companyId !=''">
             AND company_id = #{companyId}
         </if>
-        <if test="companyUserId != null">
+        <if test="companyUserId != null and companyUserId !=''">
             AND company_user_id = #{companyUserId}
         </if>
     </select>

+ 4 - 1
fs-service/src/main/resources/mapper/qw/QwExternalContactMapper.xml

@@ -782,5 +782,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             order by ec.create_time desc, ec.id desc
     </select>
 
-
+    <select id="selectQwUserListVOByQwUserIdAndCorpIdAndExternalUserId" resultMap="QwExternalContactResult">
+        <include refid="selectQwExternalContactVo"/>
+        where user_id = #{userId} and corp_id = #{corpId} and external_user_id = #{externalUserId}
+    </select>
 </mapper>