Selaa lähdekoodia

企微聊天 侧边栏看课记录、课程管理接口同步

Long 1 kuukausi sitten
vanhempi
commit
eec31f0fc7
30 muutettua tiedostoa jossa 443 lisäystä ja 91 poistoa
  1. 103 0
      fs-company/src/main/java/com/fs/qw/QwMsgController.java
  2. 0 34
      fs-company/src/main/java/com/fs/qw/vo/QwMessageListVO.java
  3. 0 5
      fs-company/src/main/java/com/fs/users/controller/FsUserController.java
  4. 11 0
      fs-service-system/src/main/java/com/fs/course/dto/WatchLogDTO.java
  5. 58 0
      fs-service-system/src/main/java/com/fs/course/mapper/FsCourseWatchLogMapper.java
  6. 8 0
      fs-service-system/src/main/java/com/fs/course/mapper/FsUserCourseMapper.java
  7. 13 0
      fs-service-system/src/main/java/com/fs/course/mapper/FsUserCourseVideoMapper.java
  8. 32 0
      fs-service-system/src/main/java/com/fs/course/param/FsCourseListBySidebarParam.java
  9. 1 0
      fs-service-system/src/main/java/com/fs/course/service/IFsUserCourseService.java
  10. 3 0
      fs-service-system/src/main/java/com/fs/course/service/IFsUserCourseVideoService.java
  11. 5 0
      fs-service-system/src/main/java/com/fs/course/service/impl/FsUserCourseServiceImpl.java
  12. 6 1
      fs-service-system/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java
  13. 26 0
      fs-service-system/src/main/java/com/fs/course/vo/FsCourseListBySidebarVO.java
  14. 37 0
      fs-service-system/src/main/java/com/fs/course/vo/FsCourseVideoListBySidebarVO.java
  15. 1 0
      fs-service-system/src/main/java/com/fs/fastGpt/service/impl/AiHookServiceImpl.java
  16. 2 0
      fs-service-system/src/main/java/com/fs/qw/mapper/QwExternalContactInfoMapper.java
  17. 4 0
      fs-service-system/src/main/java/com/fs/qw/mapper/QwExternalContactMapper.java
  18. 3 1
      fs-service-system/src/main/java/com/fs/qw/service/IQwExternalContactInfoService.java
  19. 7 2
      fs-service-system/src/main/java/com/fs/qw/service/IQwExternalContactService.java
  20. 5 0
      fs-service-system/src/main/java/com/fs/qw/service/impl/QwExternalContactInfoServiceImpl.java
  21. 10 0
      fs-service-system/src/main/java/com/fs/qw/service/impl/QwExternalContactServiceImpl.java
  22. 1 0
      fs-service-system/src/main/java/com/fs/qw/service/impl/QwMsgServiceImpl.java
  23. 1 0
      fs-service-system/src/main/java/com/fs/qw/vo/QwMessageListVO.java
  24. 15 0
      fs-service-system/src/main/java/com/fs/statis/dto/WatchCourseStatisticsDTO.java
  25. 22 0
      fs-service-system/src/main/java/com/fs/statis/param/WatchCourseStatisticsParam.java
  26. 6 1
      fs-service-system/src/main/java/com/fs/statis/service/IStatisticsService.java
  27. 21 1
      fs-service-system/src/main/java/com/fs/statis/service/impl/StatisticsServiceImpl.java
  28. 0 6
      fs-service-system/src/main/java/com/fs/store/service/IFsUserService.java
  29. 0 39
      fs-service-system/src/main/java/com/fs/store/service/impl/FsUserServiceImpl.java
  30. 42 1
      fs-service-system/src/main/resources/mapper/qw/QwExternalContactInfoMapper.xml

+ 103 - 0
fs-company/src/main/java/com/fs/qw/QwMsgController.java

@@ -6,18 +6,32 @@ import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
+import com.fs.common.exception.CustomException;
 import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.core.security.LoginUser;
 import com.fs.core.web.service.TokenService;
+import com.fs.course.param.FsCourseListBySidebarParam;
+import com.fs.course.service.IFsUserCourseService;
+import com.fs.course.service.IFsUserCourseVideoService;
+import com.fs.course.vo.FsCourseListBySidebarVO;
+import com.fs.course.vo.FsCourseVideoListBySidebarVO;
+import com.fs.qw.domain.QwExternalContact;
+import com.fs.qw.domain.QwExternalContactInfo;
 import com.fs.qw.domain.QwMsg;
 import com.fs.qw.domain.QwUser;
 import com.fs.qw.param.QwMsgSendParam;
 import com.fs.qw.param.QwSessionParam;
+import com.fs.qw.service.IQwExternalContactInfoService;
+import com.fs.qw.service.IQwExternalContactService;
 import com.fs.qw.service.IQwMsgService;
+import com.fs.qw.service.IQwUserService;
 import com.fs.qw.vo.QwContactListVO;
 import com.fs.qw.vo.QwMessageListVO;
+import com.fs.statis.dto.WatchCourseStatisticsDTO;
+import com.fs.statis.param.WatchCourseStatisticsParam;
+import com.fs.statis.service.IStatisticsService;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
 import io.swagger.annotations.Api;
@@ -44,6 +58,18 @@ public class QwMsgController extends BaseController
     private IQwMsgService qwMsgService;
     @Autowired
     private TokenService tokenService;
+    @Autowired
+    private IQwExternalContactInfoService qwExternalContactInfoService;
+    @Autowired
+    private IQwExternalContactService qwExternalContactService;
+    @Autowired
+    private IQwUserService qwUserService;
+    @Autowired
+    private IStatisticsService statisticsService;
+    @Autowired
+    private IFsUserCourseService fsUserCourseService;
+    @Autowired
+    private IFsUserCourseVideoService fsUserCourseVideoService;
 
     /**
      * 查询企微聊天记录列表
@@ -160,4 +186,81 @@ public class QwMsgController extends BaseController
         QwContactListVO data = qwMsgService.selectQwSessionBycId(param.getConversationId(),param.getUserId());
         return R.ok().put("data",data);
     }
+
+    @GetMapping("/getQwExternalContactDetails")
+    public R getQwExternalContactDetails(@RequestParam(value = "qwExternalContactId") Long qwExternalContactId){
+        return R.ok().put("data", qwExternalContactService.getQwExternalContactDetailsById(qwExternalContactId));
+    }
+
+    @GetMapping("/getQwUserInfo")
+    @ApiOperation("获取企微用户信息")
+    public R getQwUserInfo(@RequestParam(value = "qwExternalContactId") Long qwExternalContactId){
+        if(qwExternalContactId == null) {
+            throw new CustomException("企微外部联系人id不能为空!");
+        }
+        QwExternalContactInfo contactInfo = qwExternalContactInfoService.selectQwExternalContactInfoByExternalContactId(qwExternalContactId);
+        if (contactInfo==null){
+
+            contactInfo = new QwExternalContactInfo();
+            contactInfo.setExternalContactId(qwExternalContactId);
+            qwExternalContactInfoService.insertQwExternalContactInfo(contactInfo);
+
+        }
+
+        return R.ok().put("moreInfo",contactInfo);
+    }
+
+    @PostMapping("/updateQwUserInfo")
+    @ApiOperation("更新企微用户信息")
+    public R updateQwUserInfo(@RequestBody QwExternalContactInfo qwExternalContactInfo){
+        if(qwExternalContactInfo.getExternalContactId() == null) {
+            throw new CustomException("企微外部联系人id不能为空!");
+        }
+        qwExternalContactInfoService.updateQwExternalContactInfoByExternalContactId(qwExternalContactInfo);
+        return R.ok();
+    }
+
+    @PostMapping("/course/watch")
+    @ApiOperation("查询看课记录")
+    public R queryCourseWatchStatistics(@RequestBody WatchCourseStatisticsParam param) {
+        if(param.getQwExternalContactId() == null) {
+            throw new CustomException("外部联系人id为空!");
+        }
+
+        WatchCourseStatisticsDTO watchCourseStatisticsDTO = statisticsService.queryWatchCourse(param);
+
+        return R.ok().put("data",watchCourseStatisticsDTO);
+    }
+
+    @PostMapping("/getFsCourseListBySidebar")
+    @ApiOperation("获取视频课程下拉列表 侧边栏")
+    public R getFsCourseListBySidebar(@RequestBody FsCourseListBySidebarParam param) {
+
+        QwExternalContact externalContact = qwExternalContactService.getById(param.getExtId());
+        QwUser qwUser = qwUserService.selectQwUserById(externalContact.getQwUserId());
+
+        if (qwUser == null || qwUser.getCompanyId() == null) {
+            return R.error("员工未绑定 销售公司 或 未获取到员工信息,请重试!");
+        }
+        param.setCompanyId(qwUser.getCompanyId());
+
+        PageHelper.startPage(param.getPageNum(), param.getPageSize());
+        List<FsCourseListBySidebarVO> fsCourseListBySidebar = fsUserCourseService.getFsCourseListBySidebar(param);
+        PageInfo<FsCourseListBySidebarVO> result = new PageInfo<>(fsCourseListBySidebar);
+        return R.ok().put("data", result);
+    }
+
+    @PostMapping("/getFsCourseVideoListBySidebar")
+    @ApiOperation("获取视频课程的课节下拉列表 侧边栏")
+    public R getFsCourseVideoListBySidebar(@RequestBody FsCourseListBySidebarParam param) {
+
+        if (param.getCourseId()==null){
+            return R.error("课程id不能为空");
+        }
+
+        PageHelper.startPage(param.getPageNum(), param.getPageSize());
+        List<FsCourseVideoListBySidebarVO> videoListBySidebar = fsUserCourseVideoService.getFsCourseVideoListBySidebar(param);
+        PageInfo<FsCourseVideoListBySidebarVO> result = new PageInfo<>(videoListBySidebar);
+        return R.ok().put("data", result);
+    }
 }

+ 0 - 34
fs-company/src/main/java/com/fs/qw/vo/QwMessageListVO.java

@@ -1,34 +0,0 @@
-package com.fs.qw.vo;
-
-import com.fs.qw.domain.QWFromUser;
-import com.fs.qw.domain.QwMsg;
-import lombok.Data;
-
-@Data
-public class QwMessageListVO {
-    private String id;
-    private String status;
-    private String type;
-    private Long sendTime;
-    private String content;
-    private String url;
-    private Long fileSize;
-    private String fileName;
-    private Integer fileShowType;
-    private String imageUrl;
-    private Integer duration; //时长
-    private String toContactId;
-    private QWFromUser fromUser;
-
-    //获取fromUser
-    public  QWFromUser getQwFromUser(Long senderId,QwMsg qwMsg){
-        QWFromUser fromUser=new QWFromUser();
-        fromUser.setId(senderId);
-        if(qwMsg!=null){
-            fromUser.setAvatar(qwMsg.getAvatar());
-            fromUser.setDisplayName(qwMsg.getAvatar());
-        }
-        return fromUser;
-    }
-
-}

+ 0 - 5
fs-company/src/main/java/com/fs/users/controller/FsUserController.java

@@ -140,9 +140,4 @@ public class FsUserController extends BaseController
         Boolean r = fsUserService.disabledUser(ids, true);
         return ResponseResult.ok(r);
     }
-
-    @GetMapping("/getUserInfoBySessionId")
-    public R getUserInfoBySessionId(@RequestParam Long sessionId) {
-        return R.ok().put("data", fsUserService.getUserInfoBySessionId(sessionId));
-    }
 }

+ 11 - 0
fs-service-system/src/main/java/com/fs/course/dto/WatchLogDTO.java

@@ -0,0 +1,11 @@
+package com.fs.course.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class WatchLogDTO implements Serializable {
+    private String date;
+    private Integer logType;
+}

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

@@ -2,6 +2,7 @@ package com.fs.course.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.fs.course.domain.FsCourseWatchLog;
+import com.fs.course.dto.WatchLogDTO;
 import com.fs.course.param.*;
 import com.fs.course.vo.*;
 import com.fs.sop.vo.QwRatingVO;
@@ -323,4 +324,61 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
 
     @Select("select * from fs_course_watch_log where user_id = #{userId} and video_id = #{videoId} and send_type = 1")
     FsCourseWatchLog getCourseWatchLogByUser(@Param("userId") Long userId, @Param("videoId") Long videoId);
+
+    @Select("WITH date_series AS (\n" +
+            "  SELECT DATE_SUB(CURRENT_DATE(), INTERVAL 6-n DAY) AS report_date\n" +
+            "  FROM (\n" +
+            "    SELECT 0 AS n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 \n" +
+            "    UNION SELECT 4 UNION SELECT 5 UNION SELECT 6\n" +
+            "  ) days\n" +
+            "  ORDER BY n\n" +
+            "),\n" +
+            "daily_data AS (\n" +
+            "  SELECT \n" +
+            "    DATE(create_time) AS log_date,\n" +
+            "    log_type,\n" +
+            "    ROW_NUMBER() OVER (PARTITION BY DATE(create_time) ORDER BY create_time DESC) AS rn\n" +
+            "  FROM fs_course_watch_log\n" +
+            "  WHERE qw_external_contact_id = #{extId}\n" +
+            "    AND create_time >= DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)\n" +
+            ")\n" +
+            "SELECT \n" +
+            "ds.report_date AS date,"+
+            "  IFNULL(dd.log_type, 0) AS log_type\n" +
+            "FROM date_series ds\n" +
+            "LEFT JOIN (\n" +
+            "  SELECT log_date, log_type FROM daily_data WHERE rn = 1\n" +
+            ") dd ON ds.report_date = dd.log_date\n" +
+            "ORDER BY ds.report_date ASC  ")
+    List<WatchLogDTO> selectFsCourseWatchLog7Day(@Param("extId") Long extId);
+
+    @Select("WITH date_series AS (\n" +
+            "  SELECT DATE_SUB(CURRENT_DATE(), INTERVAL 29-n DAY) AS report_date\n" +
+            "  FROM (\n" +
+            "    SELECT 0 AS n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 \n" +
+            "    UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10 UNION SELECT 11 \n" +
+            "    UNION SELECT 12 UNION SELECT 13 UNION SELECT 14 UNION SELECT 15 UNION SELECT 16 UNION SELECT 17 \n" +
+            "    UNION SELECT 18 UNION SELECT 19 UNION SELECT 20 UNION SELECT 21 UNION SELECT 22 UNION SELECT 23 \n" +
+            "    UNION SELECT 24 UNION SELECT 25 UNION SELECT 26 UNION SELECT 27 UNION SELECT 28 UNION SELECT 29\n" +
+            "  ) days\n" +
+            "  ORDER BY n\n" +
+            "),\n" +
+            "daily_data AS (\n" +
+            "  SELECT \n" +
+            "    DATE(create_time) AS log_date,\n" +
+            "    log_type,\n" +
+            "    ROW_NUMBER() OVER (PARTITION BY DATE(create_time) ORDER BY create_time DESC) AS rn\n" +
+            "  FROM fs_course_watch_log\n" +
+            "  WHERE qw_external_contact_id = #{extId}\n" +
+            "    AND create_time >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)\n" +
+            ")\n" +
+            "SELECT \n" +
+            "  ds.report_date AS date,\n" +
+            "  IFNULL(dd.log_type, 0) AS log_type\n" +
+            "FROM date_series ds\n" +
+            "LEFT JOIN (\n" +
+            "  SELECT log_date, log_type FROM daily_data WHERE rn = 1\n" +
+            ") dd ON ds.report_date = dd.log_date\n" +
+            "ORDER BY ds.report_date ASC")
+    List<WatchLogDTO> selectFsCourseWatchLog30DayByExtId(@Param("extId") Long extId);
 }

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

@@ -1,6 +1,7 @@
 package com.fs.course.mapper;
 
 import com.fs.course.domain.FsUserCourse;
+import com.fs.course.param.FsCourseListBySidebarParam;
 import com.fs.course.param.FsUserCourseAddStudyCourseParam;
 import com.fs.course.param.FsUserCourseListUParam;
 import com.fs.course.param.FsUserCourseParam;
@@ -223,4 +224,11 @@ public interface FsUserCourseMapper
      * @return  list
      */
     List<FsUserCourseParticipationRecordVO> getParticipationRecordByMap(@Param("params") Map<String, Object> params);
+
+    @Select("<script> " +
+            "select course_id,course_name,title,img_url from fs_user_course where is_del=0  and is_private = 1 " +
+            "and find_in_set(#{data.companyId},company_ids)" +
+            "order by course_id asc" +
+            "</script> ")
+    List<FsCourseListBySidebarVO> getFsCourseListBySidebar(@Param("data") FsCourseListBySidebarParam param);
 }

+ 13 - 0
fs-service-system/src/main/java/com/fs/course/mapper/FsUserCourseVideoMapper.java

@@ -2,9 +2,11 @@ package com.fs.course.mapper;
 
 import com.fs.course.domain.FsUserCourseVideo;
 import com.fs.course.param.CourseVideoUpdates;
+import com.fs.course.param.FsCourseListBySidebarParam;
 import com.fs.course.param.FsUserCourseVideoListUParam;
 import com.fs.course.param.FsUserCourseVideoParam;
 import com.fs.course.param.newfs.UserCourseVideoPageParam;
+import com.fs.course.vo.FsCourseVideoListBySidebarVO;
 import com.fs.course.vo.FsUserCourseVideoListUVO;
 import com.fs.course.vo.FsUserCourseVideoVO;
 import com.fs.course.vo.newfs.FsUserCourseVideoPageListVO;
@@ -180,4 +182,15 @@ public interface FsUserCourseVideoMapper
      * @return  list
      */
     List<OptionsVO> selectVideoListByMap(@Param("params") Map<String, Object> params);
+
+    @Select("<script> " +
+            "select v.video_id,v.course_id,v.title,v.video_url,v.thumbnail,v.duration,v.create_time from fs_user_course_video v " +
+            "left join fs_user_course c on c.course_id = v.course_id " +
+            "where c.is_private = 1 and v.is_del = 0 and v.course_id=#{data.courseId} " +
+            "        <if test=\"data.keyword != null and data.keyword !='' \">\n" +
+            "            AND v.title LIKE concat('%',#{data.keyword},'%')\n" +
+            "        </if>" +
+            "order by v.video_id asc " +
+            "</script>")
+    List<FsCourseVideoListBySidebarVO> getFsCourseVideoListBySidebar(@Param("data") FsCourseListBySidebarParam param);
 }

+ 32 - 0
fs-service-system/src/main/java/com/fs/course/param/FsCourseListBySidebarParam.java

@@ -0,0 +1,32 @@
+package com.fs.course.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+@ApiModel
+public class FsCourseListBySidebarParam implements Serializable {
+
+    @ApiModelProperty(value = "页码,默认为1", required = true)
+    private Integer pageNum = 1;
+
+    @ApiModelProperty(value = "页大小,默认为10", required = true)
+    private Integer pageSize = 10;
+
+    @ApiModelProperty(value = "模糊搜索,通过视频名称来匹配")
+    private String keyword;
+
+    @ApiModelProperty(value = "公司id")
+    private Long companyId;
+    /**
+     * 外部联系人主键ID
+     */
+    private Long extId;
+    /**
+     * 课程ID
+     */
+    private Long courseId;
+}

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

@@ -166,4 +166,5 @@ public interface IFsUserCourseService
      */
     String createUserImageQR(String url, String backgroundImagePath, InputStream file, String outputFormat, Long companyUserId) throws Exception;
 
+    List<FsCourseListBySidebarVO> getFsCourseListBySidebar(FsCourseListBySidebarParam param);
 }

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

@@ -8,6 +8,7 @@ import com.fs.course.param.newfs.FsUserCourseAddCompanyUserParam;
 import com.fs.course.param.newfs.FsUserCourseVideoLinkParam;
 import com.fs.course.param.newfs.FsUserCourseVideoUParam;
 import com.fs.course.param.newfs.UserCourseVideoPageParam;
+import com.fs.course.vo.FsCourseVideoListBySidebarVO;
 import com.fs.course.vo.FsUserCourseVideoListUVO;
 import com.fs.course.vo.FsUserCourseVideoQVO;
 import com.fs.course.vo.FsUserCourseVideoVO;
@@ -157,4 +158,6 @@ public interface IFsUserCourseVideoService
      * @return  list
      */
     List<OptionsVO> selectVideoListByMap(Map<String, Object> params);
+
+    List<FsCourseVideoListBySidebarVO> getFsCourseVideoListBySidebar(FsCourseListBySidebarParam param);
 }

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

@@ -741,6 +741,11 @@ public class FsUserCourseServiceImpl implements IFsUserCourseService
         return convertToBase64(combined, outputFormat);
     }
 
+    @Override
+    public List<FsCourseListBySidebarVO> getFsCourseListBySidebar(FsCourseListBySidebarParam param) {
+        return  fsUserCourseMapper.getFsCourseListBySidebar(param);
+    }
+
     private static Calendar getExpireDay(FsCourseLinkCreateParam param, CourseConfig config, Date createTime) {
         Integer expireDuration;
         if (param.getEffectiveDuration() == null || param.getEffectiveDuration() == 0){

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

@@ -22,6 +22,7 @@ import com.fs.course.param.*;
 import com.fs.course.param.newfs.*;
 import com.fs.course.service.IFsUserCourseVideoService;
 import com.fs.course.service.IFsVideoResourceService;
+import com.fs.course.vo.FsCourseVideoListBySidebarVO;
 import com.fs.course.vo.FsUserCourseVideoListUVO;
 import com.fs.course.vo.FsUserCourseVideoQVO;
 import com.fs.course.vo.FsUserCourseVideoVO;
@@ -60,7 +61,6 @@ import org.springframework.transaction.annotation.Transactional;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.time.LocalDateTime;
-import java.time.LocalTime;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
@@ -1193,6 +1193,11 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         return fsUserCourseVideoMapper.selectVideoListByMap(params);
     }
 
+    @Override
+    public List<FsCourseVideoListBySidebarVO> getFsCourseVideoListBySidebar(FsCourseListBySidebarParam param) {
+        return fsUserCourseVideoMapper.getFsCourseVideoListBySidebar(param);
+    }
+
     //会员-更新心跳时间
     public void updateHeartbeatWx(FsUserCourseVideoUParam param) {
         String redisKey = "h5wxuser:watch:heartbeat:" + param.getUserId() + ":" + param.getVideoId() + ":" + param.getCompanyUserId();

+ 26 - 0
fs-service-system/src/main/java/com/fs/course/vo/FsCourseListBySidebarVO.java

@@ -0,0 +1,26 @@
+package com.fs.course.vo;
+
+import lombok.Data;
+
+@Data
+public class FsCourseListBySidebarVO {
+    /**
+    * 课程id
+    */
+    private Long courseId;
+    /**
+    * 课程名称
+    */
+    private String courseName;
+
+    /**
+    * 标题
+    */
+    private String title;
+
+    /**
+    * 课程封面
+    */
+    private String imgUrl;
+
+}

+ 37 - 0
fs-service-system/src/main/java/com/fs/course/vo/FsCourseVideoListBySidebarVO.java

@@ -0,0 +1,37 @@
+package com.fs.course.vo;
+
+import lombok.Data;
+
+@Data
+public class FsCourseVideoListBySidebarVO {
+
+    private Long videoId;
+
+    private Long courseId;
+
+    /**
+    * 视频标题
+    */
+    private String title;
+
+    /**
+    * 视频地址
+    */
+    private String videoUrl;
+
+    /**
+    * 时长
+    */
+    private Integer duration;
+
+    /**
+    * 视频缩略图
+    */
+    private String thumbnail;
+
+    /**
+    * 视频创建时间
+    */
+    private String createTime;
+
+}

+ 1 - 0
fs-service-system/src/main/java/com/fs/fastGpt/service/impl/AiHookServiceImpl.java

@@ -1354,6 +1354,7 @@ public class AiHookServiceImpl implements AiHookService {
         }
         listVO.setType(type);
         listVO.setStatus("succeed");
+        listVO.setExtId(qwMsg.getQwExtId());
         listVO.setFromUser(qwFromUser);
         listVO.setSendTime(qwMsg.getCreateTime().getTime());
         listVO.setId(qwMsg.getMsgId().toString());

+ 2 - 0
fs-service-system/src/main/java/com/fs/qw/mapper/QwExternalContactInfoMapper.java

@@ -69,4 +69,6 @@ public interface QwExternalContactInfoMapper
             "ON DUPLICATE KEY UPDATE " +
             "talk = VALUES(talk);")
     int updateQwExternalContactInfoByExtId(Long id);
+
+    void updateQwExternalContactInfoByExternalContactId(QwExternalContactInfo qwExternalContactInfo);
 }

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

@@ -388,4 +388,8 @@ public interface QwExternalContactMapper extends BaseMapper<QwExternalContact> {
     List<FastgptChatArtificialWords> selectChatGptChatArtificialWords();
 
     List<GroupUserExternalVo> selectByGroupUser(@Param("ids") List<String> ids);
+
+    @Select("SELECT id,external_user_id,name,avatar,remark,description FROM qw_external_contact " +
+            " WHERE id = #{qwExternalContactId}")
+    QwExternalContact getQwExternalContactDetailsById(Long qwExternalContactId);
 }

+ 3 - 1
fs-service-system/src/main/java/com/fs/qw/service/IQwExternalContactInfoService.java

@@ -60,11 +60,13 @@ public interface IQwExternalContactInfoService
      */
     public int deleteQwExternalContactInfoById(Long id);
 
-    Object selectQwExternalContactInfoByExternalContactId(Long id);
+    QwExternalContactInfo selectQwExternalContactInfoByExternalContactId(Long id);
 
     int updateQwExternalContactInfoByIds(Long[] ids);
 
     void updateQwExternalContactInfoBytalk(String talkType, Long externalId);
 
     int updateQwExternalContactInfoByQwUserId(Long id);
+
+    void updateQwExternalContactInfoByExternalContactId(QwExternalContactInfo qwExternalContactInfo);
 }

+ 7 - 2
fs-service-system/src/main/java/com/fs/qw/service/IQwExternalContactService.java

@@ -3,7 +3,6 @@ package com.fs.qw.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.fs.common.core.domain.R;
-import com.fs.common.core.domain.ResponseResult;
 import com.fs.qw.domain.QwExternalContact;
 import com.fs.qw.dto.GetQwRepeatDataDTO;
 import com.fs.qw.param.*;
@@ -23,7 +22,6 @@ import java.io.IOException;
 import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
 
 /**
  * 企业微信客户Service接口
@@ -209,4 +207,11 @@ public interface IQwExternalContactService extends IService<QwExternalContact> {
     List<GetQwRepeatDataVO> getQwRepeatData(GetQwRepeatDataDTO dto);
 
     Integer selectQwIsRepeat(Long id);
+
+    /**
+     * 根据id查询外部联系人信息
+     * @param qwExternalContactId id
+     * @return QwExternalContact
+     */
+    QwExternalContact getQwExternalContactDetailsById(Long qwExternalContactId);
 }

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

@@ -136,4 +136,9 @@ public class QwExternalContactInfoServiceImpl implements IQwExternalContactInfoS
 
         return 1;
     }
+
+    @Override
+    public void updateQwExternalContactInfoByExternalContactId(QwExternalContactInfo qwExternalContactInfo) {
+        qwExternalContactInfoMapper.updateQwExternalContactInfoByExternalContactId(qwExternalContactInfo);
+    }
 }

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

@@ -4561,6 +4561,16 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
         return qwExternalContactMapper.selectQwIsRepeat(id);
     }
 
+    /**
+     * 根据id查询外部联系人信息
+     * @param qwExternalContactId id
+     * @return QwExternalContact
+     */
+    @Override
+    public QwExternalContact getQwExternalContactDetailsById(Long qwExternalContactId) {
+        return qwExternalContactMapper.getQwExternalContactDetailsById(qwExternalContactId);
+    }
+
     //发送好友欢迎语
     void SyncAddSendWelcome(QwExternalContact qwExternalContact, QwUser qwUser, String corpId) {
         QwFriendWelcomeVO qwFriendWelcomeVO = qwFriendWelcomeMapper.selectQwFriendWelcomeByUserIdVO(qwUser.getId(), corpId);

+ 1 - 0
fs-service-system/src/main/java/com/fs/qw/service/impl/QwMsgServiceImpl.java

@@ -500,6 +500,7 @@ public class QwMsgServiceImpl extends ServiceImpl<QwMsgMapper, QwMsg> implements
                 qwFromUser.setDisplayName(user.getQwUserName());
                 qwFromUser.setAvatar("https://cos.his.cdwjyyh.com/fs/20241231/22a765a96da247d1b83ea94fef438a41.png");
             }
+            listVO.setExtId(record.getQwExtId());
             listVO.setFromUser(qwFromUser);
             listVO.setSendTime(record.getCreateTime().getTime());
             listVO.setId(record.getMsgId().toString());

+ 1 - 0
fs-service-system/src/main/java/com/fs/qw/vo/QwMessageListVO.java

@@ -22,6 +22,7 @@ public class QwMessageListVO {
     private QWFromUser fromUser;
     @JSONField(serialize = false)
     private Long companyId;
+    private String extId;
 
     //获取fromUser
     public  QWFromUser getQwFromUser(Long senderId,QwMsg qwMsg){

+ 15 - 0
fs-service-system/src/main/java/com/fs/statis/dto/WatchCourseStatisticsDTO.java

@@ -0,0 +1,15 @@
+package com.fs.statis.dto;
+
+import com.fs.course.dto.WatchLogDTO;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 看课统计
+ */
+@Data
+public class WatchCourseStatisticsDTO implements Serializable {
+    private List<WatchLogDTO> data;
+}

+ 22 - 0
fs-service-system/src/main/java/com/fs/statis/param/WatchCourseStatisticsParam.java

@@ -0,0 +1,22 @@
+ package com.fs.statis.param;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+ /**
+  * 看课统计参数
+  */
+ @Data
+ public class WatchCourseStatisticsParam implements Serializable {
+
+     /**
+      * 0 七天
+      * 1 30天
+      */
+     private Integer type;
+     /**
+      * 企微外部联系人id
+      */
+     private Long qwExternalContactId;
+ }

+ 6 - 1
fs-service-system/src/main/java/com/fs/statis/service/IStatisticsService.java

@@ -1,7 +1,7 @@
 package com.fs.statis.service;
 
-import com.fs.common.core.domain.R;
 import com.fs.statis.dto.*;
+import com.fs.statis.param.WatchCourseStatisticsParam;
 
 import java.util.List;
 
@@ -110,4 +110,9 @@ public interface IStatisticsService {
      * 本月收款数
      */
     void thisMonthRecvCount();
+
+    /**
+     * 查询看课统计
+     */
+    WatchCourseStatisticsDTO queryWatchCourse(WatchCourseStatisticsParam param);
 }

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

@@ -5,10 +5,13 @@ import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.utils.TimeUtils;
 import com.fs.company.cache.ICompanyCacheService;
+import com.fs.course.dto.WatchLogDTO;
 import com.fs.course.mapper.FsCourseTrafficLogMapper;
+import com.fs.course.mapper.FsCourseWatchLogMapper;
 import com.fs.statis.StatisticsRedisConstant;
 import com.fs.statis.dto.*;
 import com.fs.statis.mapper.ConsumptionBalanceMapper;
+import com.fs.statis.param.WatchCourseStatisticsParam;
 import com.fs.statis.service.IStatisticsService;
 import com.fs.statis.service.utils.TrendDataFiller;
 import com.fs.store.service.IFsStoreOrderService;
@@ -27,7 +30,6 @@ import org.springframework.stereotype.Service;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.time.DayOfWeek;
-import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
@@ -68,6 +70,8 @@ public class StatisticsServiceImpl implements IStatisticsService {
 
     @Autowired
     private ISysConfigService configService;
+    @Autowired
+    private FsCourseWatchLogMapper fsCourseWatchLogMapper;
 
     @Override
     public void dataOverviewTask() {
@@ -966,4 +970,20 @@ public class StatisticsServiceImpl implements IStatisticsService {
         R result = R.ok().put("dates", dates).put("orderCount", orderCount).put("payMoney", payMoney);
         redisCache.setCacheObject(THIS_MONTH_RECV_COUNT,result);
     }
+
+    @Override
+    public WatchCourseStatisticsDTO queryWatchCourse(WatchCourseStatisticsParam param) {
+        List<WatchLogDTO> data = null;
+        // 七天
+        if(ObjectUtils.equals(param.getType(),0)) {
+            data = fsCourseWatchLogMapper.selectFsCourseWatchLog7Day(param.getQwExternalContactId());
+        } else if(ObjectUtils.equals(param.getType(),1)){
+            data = fsCourseWatchLogMapper.selectFsCourseWatchLog30DayByExtId(param.getQwExternalContactId());
+        }
+
+        WatchCourseStatisticsDTO watchCourseStatisticsDTO = new WatchCourseStatisticsDTO();
+        watchCourseStatisticsDTO.setData(data);
+
+        return watchCourseStatisticsDTO;
+    }
 }

+ 0 - 6
fs-service-system/src/main/java/com/fs/store/service/IFsUserService.java

@@ -252,10 +252,4 @@ public interface IFsUserService
      */
     void setRepeatFansTag(FsUserCourseBeMemberParam param);
 
-    /**
-     * 根据会话sessionId查询用户信息
-     * @param sessionId sessionId
-     * @return  fsUser
-     */
-    FsUser getUserInfoBySessionId(Long sessionId);
 }

+ 0 - 39
fs-service-system/src/main/java/com/fs/store/service/impl/FsUserServiceImpl.java

@@ -2,15 +2,12 @@ package com.fs.store.service.impl;
 
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.json.JSONUtil;
-import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.common.constant.HttpStatus;
 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.exception.CustomException;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.company.cache.ICompanyTagCacheService;
@@ -33,8 +30,6 @@ import com.fs.course.vo.newfs.FsCourseAnalysisVO;
 import com.fs.course.vo.newfs.FsUserCourseVideoPageListVO;
 import com.fs.his.vo.OptionsVO;
 import com.fs.qw.cache.IQwExternalContactCacheService;
-import com.fs.qw.domain.QwExternalContact;
-import com.fs.qw.domain.QwSession;
 import com.fs.qw.mapper.QwExternalContactMapper;
 import com.fs.qw.mapper.QwSessionMapper;
 import com.fs.qw.param.QwFsUserParam;
@@ -908,40 +903,6 @@ public class FsUserServiceImpl implements IFsUserService
         }
     }
 
-    /**
-     * 根据会话sessionId查询用户信息
-     * @param sessionId sessionId
-     * @return  fsUser
-     */
-    @Override
-    public FsUser getUserInfoBySessionId(Long sessionId) {
-        Wrapper<QwSession> qwSessionWrapper = Wrappers.<QwSession>lambdaQuery()
-        .select(QwSession.class, q -> !q.getColumn().equals("remark"))
-        .eq(QwSession::getSessionId, sessionId);
-        QwSession qwSession = qwSessionMapper.selectOne(qwSessionWrapper);
-        if (Objects.isNull(qwSession)) {
-            log.warn("企微会话不存在 sessionId:{}", sessionId);
-            throw new CustomException("会话不存在");
-        }
-
-        Wrapper<QwExternalContact> qwExternalContactWrapper = Wrappers.<QwExternalContact>lambdaQuery()
-        .select(QwExternalContact.class, q -> !q.getColumn().equals("remark"))
-        .eq(QwExternalContact::getId, qwSession.getQwExtId());
-        QwExternalContact qwExternalContact = qwExternalContactMapper.selectOne(qwExternalContactWrapper);
-        if (Objects.isNull(qwExternalContact)) {
-            log.warn("企微会话对应外部联系人不存在 qwExtId: {}", qwSession.getQwExtId());
-            throw new CustomException("外部联系人不存在");
-        }
-
-        FsUser fsUser = fsUserMapper.selectFsUserById(qwExternalContact.getFsUserId());
-        if (Objects.isNull(fsUser)) {
-            fsUser = new FsUser();
-            fsUser.setAvatar(qwExternalContact.getAvatar());
-            fsUser.setNickname(qwExternalContact.getName());
-        }
-        return fsUser;
-    }
-
     // 判断是否绑定了销售
     private static FsUserCompanyUser getFsUserCompanyUser(FsUserCourseBeMemberParam param, FsUser fsUser) {
         FsUserCompanyUser fsUserCompanyUser = new FsUserCompanyUser();

+ 42 - 1
fs-service-system/src/main/resources/mapper/qw/QwExternalContactInfoMapper.xml

@@ -210,7 +210,48 @@
         </trim>
         where id = #{id}
     </update>
-
+    <update id="updateQwExternalContactInfoByExternalContactId">
+        update qw_external_contact_info
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="externalContactId != null">external_contact_id = #{externalContactId},</if>
+            <if test="name != null">name = #{name},</if>
+            <if test="sex != null">sex = #{sex},</if>
+            <if test="age != null">age = #{age},</if>
+            <if test="address != null">address = #{address},</if>
+            <if test="habits != null">habits = #{habits},</if>
+            <if test="illnessTime != null">illness_time = #{illnessTime},</if>
+            <if test="body != null">body = #{body},</if>
+            <if test="study != null">study = #{study},</if>
+            <if test="courseStatus != null">course_status = #{courseStatus},</if>
+            <if test="family != null">family = #{family},</if>
+            <if test="familyDisease != null">family_disease = #{familyDisease},</if>
+            <if test="talk != null">talk = #{talk},</if>
+            <if test="userType != null">user_type = #{userType},</if>
+            <if test="isSelf != null">is_self = #{isSelf},</if>
+            <if test="intensify != null">intensify = #{intensify},</if>
+            <if test="isCold != null">is_cold = #{isCold},</if>
+            <if test="coldBody != null">cold_body = #{coldBody},</if>
+            <if test="sweat != null">sweat = #{sweat},</if>
+            <if test="other != null">other = #{other},</if>
+            <if test="toilet != null">toilet = #{toilet},</if>
+            <if test="eat != null">eat = #{eat},</if>
+            <if test="menses != null">menses = #{menses},</if>
+            <if test="medicine != null">medicine = #{medicine},</if>
+            <if test="constitution != null">constitution = #{constitution},</if>
+            <if test="recommendMedicine != null">recommend_medicine = #{recommendMedicine},</if>
+            <if test="consultProduct != null">consult_product = #{consultProduct},</if>
+            <if test="isBuy != null">is_buy = #{isBuy},</if>
+            <if test="buyProduct != null">buy_product = #{buyProduct},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="disease != null">disease = #{disease},</if>
+            <if test="isLine != null">is_line = #{isLine},</if>
+            <if test="course != null">course = #{course},</if>
+            <if test="productTalk != null">product_talk = #{productTalk},</if>
+            <if test="diseaseTalk != null">disease_talk = #{diseaseTalk},</if>
+        </trim>
+        where external_contact_id = #{externalContactId}
+    </update>
     <delete id="deleteQwExternalContactInfoById" parameterType="Long">
         delete from qw_external_contact_info where id = #{id}
     </delete>