Browse Source

Merge remote-tracking branch 'origin/master'

zyp 1 week ago
parent
commit
9dfaa5eef9
32 changed files with 412 additions and 70 deletions
  1. 4 4
      fs-admin/src/main/java/com/fs/task/FsCourseTask.java
  2. 6 0
      fs-admin/src/test/java/com/fs/task/StoreTaskTest.java
  3. 12 0
      fs-company-app/src/main/java/com/fs/app/controller/CompanyUserController.java
  4. 18 0
      fs-company-app/src/main/java/com/fs/app/controller/FsUserCourseVideoController.java
  5. 41 0
      fs-company-app/src/main/java/com/fs/app/controller/WxMpController.java
  6. 15 0
      fs-company-app/src/main/java/com/fs/app/exception/FSExceptionHandler.java
  7. 4 0
      fs-company-app/src/main/java/com/fs/app/vo/CompanySubUserVO.java
  8. 1 1
      fs-company/src/main/java/com/fs/course/controller/FsCourseTrafficLogController.java
  9. 4 4
      fs-company/src/main/java/com/fs/course/controller/FsCourseWatchLogController.java
  10. 16 0
      fs-company/src/main/java/com/fs/qw/vo/QwWatchLogAllStatisticsListVO.java
  11. 17 0
      fs-company/src/main/java/com/fs/qw/vo/QwWatchLogStatisticsListVO.java
  12. 2 2
      fs-company/src/main/resources/application.yml
  13. 6 5
      fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java
  14. 4 0
      fs-service-system/src/main/java/com/fs/company/vo/CompanyUserChangeApplyUserVO.java
  15. 8 0
      fs-service-system/src/main/java/com/fs/company/vo/CompanyUserChangeApplyVO.java
  16. 1 1
      fs-service-system/src/main/java/com/fs/course/mapper/FsCourseWatchLogMapper.java
  17. 39 0
      fs-service-system/src/main/java/com/fs/course/param/newfs/FsCourseSortLinkParam.java
  18. 8 4
      fs-service-system/src/main/java/com/fs/course/service/IFsUserCourseService.java
  19. 4 4
      fs-service-system/src/main/java/com/fs/course/service/impl/FsCourseWatchLogServiceImpl.java
  20. 79 9
      fs-service-system/src/main/java/com/fs/course/service/impl/FsUserCourseServiceImpl.java
  21. 6 2
      fs-service-system/src/main/java/com/fs/qw/mapper/QwWatchLogMapper.java
  22. 3 3
      fs-service-system/src/main/java/com/fs/qw/service/impl/QwWatchLogServiceImpl.java
  23. 1 0
      fs-service-system/src/main/java/com/fs/qw/vo/WxSopRuleTimeVO.java
  24. 6 5
      fs-service-system/src/main/java/com/fs/sop/service/impl/SopUserLogsInfoServiceImpl.java
  25. 2 2
      fs-service-system/src/main/java/com/fs/store/service/cache/impl/FsUserCourseCacheServiceImpl.java
  26. 1 1
      fs-service-system/src/main/resources/application-config.yml
  27. 1 1
      fs-service-system/src/main/resources/mapper/company/CompanyTagUserMapper.xml
  28. 2 0
      fs-service-system/src/main/resources/mapper/company/CompanyUserChangeApplyMapper.xml
  29. 2 1
      fs-service-system/src/main/resources/mapper/company/CompanyUserChangeApplyUserMapper.xml
  30. 3 3
      fs-service-system/src/main/resources/mapper/course/FsCourseWatchLogMapper.xml
  31. 32 16
      fs-service-system/src/main/resources/mapper/qw/QwWatchLogMapper.xml
  32. 64 2
      fs-service-system/src/main/resources/mapper/sop/QwSopMapper.xml

+ 4 - 4
fs-admin/src/main/java/com/fs/task/FsCourseTask.java

@@ -28,7 +28,7 @@ public class FsCourseTask {
 
 
     /**
-     * 看课面板定时任务-1
+     * 企微任务定时更新
      * @throws Exception
      */
     public void qwWorkTask1() throws Exception
@@ -37,7 +37,7 @@ public class FsCourseTask {
         qwWorkTaskService.addQwWorkByCourseLastTime();
     }
     /**
-     * 看课面板定时任务-2
+     * 企微待看课和先导课
      * @throws Exception
      */
     public void qwWorkTask2() throws Exception
@@ -46,7 +46,7 @@ public class FsCourseTask {
         qwWorkTaskService.addQwWorkByFirstCourse();
     }
     /**
-     * 看课面板定时任务-3
+     * 用户大小转
      * @throws Exception
      */
     public void qwWorkTask3() throws Exception
@@ -54,7 +54,7 @@ public class FsCourseTask {
         qwWorkTaskService.addQwWorkByConversionDay();
     }
     /**
-     * 看课面板定时任务-4
+     * 删除过期数据
      * @throws Exception
      */
     public void qwWorkTask4() throws Exception

+ 6 - 0
fs-admin/src/test/java/com/fs/task/StoreTaskTest.java

@@ -13,8 +13,14 @@ import org.springframework.boot.test.context.SpringBootTest;
 public class StoreTaskTest {
     @Autowired
     private IFsCourseWatchLogService fsCourseWatchLogService;
+    @Autowired
+    private FsCourseTask fsCourseTask;
     @Test
     public void addQwWatchLog() {
         fsCourseWatchLogService.addCourseWatchLogDayNew();
     }
+    @Test
+    public void test() throws Exception {
+        fsCourseTask.qwWorkTask1();
+    }
 }

+ 12 - 0
fs-company-app/src/main/java/com/fs/app/controller/CompanyUserController.java

@@ -93,6 +93,18 @@ public class CompanyUserController extends AppBaseController {
             BigDecimal amount = courseRedPacketLogService.getSumByCompanyUserIdId(u.getUserId());
             vo.setTodayRedPacketAmount(amount);
 
+            // 是否存在会员转移申请
+            Wrapper<CompanyUserChangeApply> applyWrapper = Wrappers.<CompanyUserChangeApply>lambdaQuery()
+                    .eq(CompanyUserChangeApply::getFrom, u.getUserId())
+                    .orderByDesc(CompanyUserChangeApply::getApplyTime)
+                    .last("limit 1");
+            CompanyUserChangeApply apply = companyUserChangeApplyService.getOne(applyWrapper);
+            int applyStatus = 3; // 不存在
+            if (Objects.nonNull(apply)) {
+                applyStatus = apply.getStatus();
+            }
+            vo.setApplyStatus(applyStatus);
+
             return vo;
         }).collect(Collectors.toList());
 

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

@@ -3,6 +3,8 @@ package com.fs.app.controller;
 import com.fs.app.annotation.Login;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.ResponseResult;
+import com.fs.course.param.FsCourseLinkCreateParam;
+import com.fs.course.param.newfs.FsCourseSortLinkParam;
 import com.fs.course.param.newfs.FsUserCourseListParam;
 import com.fs.course.param.newfs.UserCourseVideoPageParam;
 import com.fs.course.service.IFsUserCourseService;
@@ -17,6 +19,7 @@ import com.github.pagehelper.PageInfo;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
@@ -91,4 +94,19 @@ public class FsUserCourseVideoController extends AppBaseController {
         List<FsUserCourseParticipationRecordVO> record = fsUserCourseService.getParticipationRecordByMap(params);
         return ResponseResult.ok(new PageInfo<>(record));
     }
+
+    @Login
+    @GetMapping("/courseSortLink")
+    @ApiOperation("生成课程分享短链")
+    public R createCourseSortLink(FsCourseSortLinkParam param) {
+        FsCourseLinkCreateParam fsCourseLinkCreateParam = new FsCourseLinkCreateParam();
+        // todo 入参需要确认调整
+        BeanUtils.copyProperties(param, fsCourseLinkCreateParam);
+
+        R courseSortLink = fsUserCourseService.createCourseSortLink(fsCourseLinkCreateParam);
+        String url = courseSortLink.get("url").toString();
+        Map<String, Object> map = new HashMap<>();
+        map.put("url", url);
+        return R.ok(map);
+    }
 }

+ 41 - 0
fs-company-app/src/main/java/com/fs/app/controller/WxMpController.java

@@ -0,0 +1,41 @@
+package com.fs.app.controller;
+
+import com.fs.common.core.domain.R;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.Synchronized;
+import me.chanjar.weixin.common.bean.WxJsapiSignature;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.mp.api.WxMpService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+
+
+@RestController
+@Api("微信配置")
+@RequestMapping("/app/wx/mp")
+public class WxMpController {
+
+    @Autowired
+    private WxMpService wxMpService;
+
+
+    @GetMapping("/getWeiXinConfig")
+    @ApiOperation("微信url验证")
+    @Synchronized
+    public R getWxConfig(@RequestParam String url) throws WxErrorException {
+        try {
+            String sLink = URLDecoder.decode(url, "UTF-8");
+            final WxJsapiSignature jsapiSignature = wxMpService.createJsapiSignature(sLink);
+            return R.ok().put("data", jsapiSignature);
+        } catch (UnsupportedEncodingException e) {
+            // URL解码异常
+            return R.error(e.getMessage());
+        }
+    }
+
+
+}

+ 15 - 0
fs-company-app/src/main/java/com/fs/app/exception/FSExceptionHandler.java

@@ -2,8 +2,11 @@ package com.fs.app.exception;
 
 
 
+import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
 import com.fs.common.exception.CustomException;
+import com.fs.common.exception.ServiceException;
+import com.fs.common.utils.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.dao.DuplicateKeyException;
@@ -17,6 +20,7 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
 import org.springframework.web.bind.annotation.RestControllerAdvice;
 import org.springframework.web.servlet.NoHandlerFoundException;
 
+import javax.servlet.http.HttpServletRequest;
 import java.util.List;
 
 
@@ -86,4 +90,15 @@ public class FSExceptionHandler {
 
 		return R.error(e.getMessage());
 	}
+
+	/**
+	 * 业务异常
+	 */
+	@ExceptionHandler(ServiceException.class)
+	public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request)
+	{
+		logger.error(e.getMessage(), e);
+		Integer code = e.getCode();
+		return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());
+	}
 }

+ 4 - 0
fs-company-app/src/main/java/com/fs/app/vo/CompanySubUserVO.java

@@ -25,4 +25,8 @@ public class CompanySubUserVO extends CompanyUser {
      * 今日红包金额
      */
     private BigDecimal todayRedPacketAmount;
+    /**
+     * 审核状态
+     */
+    private Integer applyStatus;
 }

+ 1 - 1
fs-company/src/main/java/com/fs/course/controller/FsCourseTrafficLogController.java

@@ -1,6 +1,6 @@
 package com.fs.course.controller;
 
-import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import  com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;

+ 4 - 4
fs-company/src/main/java/com/fs/course/controller/FsCourseWatchLogController.java

@@ -93,7 +93,7 @@ public class FsCourseWatchLogController extends BaseController
         if (param.getSTime()==null||param.getETime()==null){
             return getDataTable(new ArrayList<>());
         }
-        List<QwWatchLogStatisticsListVO> list = qwWatchLogService.selectQwWatchLogStatisticsListVO(param);
+        List<QwWatchLogStatisticsListVO> list = qwWatchLogService.selectQwWatchLogStatisticsListVONew(param);
         return getDataTable(list);
     }
     @GetMapping("/myQwWatchLogStatisticsList")
@@ -106,7 +106,7 @@ public class FsCourseWatchLogController extends BaseController
         if (param.getSTime()==null||param.getETime()==null){
             return getDataTable(new ArrayList<>());
         }
-        List<QwWatchLogStatisticsListVO> list = qwWatchLogService.selectQwWatchLogStatisticsListVO(param);
+        List<QwWatchLogStatisticsListVO> list = qwWatchLogService.selectQwWatchLogStatisticsListVONew(param);
         return getDataTable(list);
     }
 
@@ -120,7 +120,7 @@ public class FsCourseWatchLogController extends BaseController
         if (param.getSTime()==null||param.getETime()==null){
             return getDataTable(new ArrayList<>());
         }
-        List<QwWatchLogAllStatisticsListVO> list = qwWatchLogService.selectQwWatchLogAllStatisticsListVO(param);
+        List<QwWatchLogAllStatisticsListVO> list = qwWatchLogService.selectQwWatchLogAllStatisticsListVONew(param);
         return getDataTable(list);
     }
     @GetMapping("/myQwWatchLogAllStatisticsList")
@@ -133,7 +133,7 @@ public class FsCourseWatchLogController extends BaseController
         if (param.getSTime()==null||param.getETime()==null){
             return getDataTable(new ArrayList<>());
         }
-        List<QwWatchLogAllStatisticsListVO> list = qwWatchLogService.selectQwWatchLogAllStatisticsListVO(param);
+        List<QwWatchLogAllStatisticsListVO> list = qwWatchLogService.selectQwWatchLogAllStatisticsListVONew(param);
         return getDataTable(list);
     }
     @GetMapping("/watchLogStatistics")

+ 16 - 0
fs-company/src/main/java/com/fs/qw/vo/QwWatchLogAllStatisticsListVO.java

@@ -78,5 +78,21 @@ public class QwWatchLogAllStatisticsListVO {
     Long d29Over;
     Long d30Online;
     Long d30Over;
+    /**
+     * 项目
+     */
+    private Long project;
+    private String projectName;
 
+    /**
+     * 课程
+     */
+    private Long courseId;
+    private String courseName;
+
+    /**
+     * 小节
+     */
+    private Long videoId;
+    private String videoName;
 }

+ 17 - 0
fs-company/src/main/java/com/fs/qw/vo/QwWatchLogStatisticsListVO.java

@@ -25,4 +25,21 @@ public class QwWatchLogStatisticsListVO {
     private Long d;
     private Long los;//流失数
     private Long del;//删除数
+    /**
+     * 项目
+     */
+    private Long project;
+    private String projectName;
+
+    /**
+     * 课程
+     */
+    private Long courseId;
+    private String courseName;
+
+    /**
+     * 小节
+     */
+    private Long videoId;
+    private String videoName;
 }

+ 2 - 2
fs-company/src/main/resources/application.yml

@@ -43,8 +43,8 @@ spring:
     # 国际化资源文件路径
     basename: i18n/messages
   profiles:
-    active: dev
-#    active: druid
+#    active: dev
+    active: druid
     include: config
   # 文件上传
   servlet:

+ 6 - 5
fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java

@@ -803,7 +803,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                     String sortLink = createLinkByMiniApp(setting, logVo, sendTime, courseId, videoId,
                             qwUserId, companyUserId, companyId, externalId,fsUserId);
 
-                    setting.setMiniprogramPage(sortLink);
+                    setting.setMiniprogramPage(sortLink.replaceAll("^[\\s\\u2005]+", ""));
 
                     try {
                         setting.setMiniprogramPicUrl(StringUtil.strIsNullOrEmpty(setting.getMiniprogramPicUrl())?"https://cos.his.cdwjyyh.com/fs/20250331/ec2b4e73be8048afbd526124a655ad56.png":setting.getMiniprogramPicUrl());
@@ -819,8 +819,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                     QwCreateLinkByAppDTO linkByApp = createLinkByApp(setting, logVo, sendTime, courseId, videoId,
                             qwUserId, companyUserId, companyId, externalId,sopLogs.getCorpId(),qwUserName,fsUserId);
 
-                    setting.setLinkUrl(linkByApp.getSortLink());
-                    setting.setAppLinkUrl(linkByApp.getAppMsgLink());
+                    setting.setLinkUrl(linkByApp.getSortLink().replaceAll("^[\\s\\u2005]+", ""));
+                    setting.setAppLinkUrl(linkByApp.getAppMsgLink().replaceAll("^[\\s\\u2005]+", ""));
 
                     break;
                 //注册链接
@@ -831,7 +831,8 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                         config = cachedCourseConfig;
                     }
                     if (config != null) {
-                        setting.setLinkUrl(config.getRegisterDomainName()+registerLink+externalId);
+                        String URL= config.getRegisterDomainName()+registerLink+externalId;
+                        setting.setLinkUrl(URL.replaceAll("^[\\s\\u2005]+", ""));
                     }else {
                         log.error("获取缓存的配置为空:注册链接");
                     }
@@ -1109,7 +1110,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
         //取销售绑定的二级域名
         String sortLink = logVo.getDomain() + SHORT_LINK_PREFIX + link.getLink();
         enqueueCourseLink(link);
-        return sortLink;
+        return sortLink.replaceAll("^[\\s\\u2005]+", "");
     }
 
 

+ 4 - 0
fs-service-system/src/main/java/com/fs/company/vo/CompanyUserChangeApplyUserVO.java

@@ -12,4 +12,8 @@ public class CompanyUserChangeApplyUserVO {
      * 用户名称
      */
     private String userName;
+    /**
+     * 用户头像
+     */
+    private String avatar;
 }

+ 8 - 0
fs-service-system/src/main/java/com/fs/company/vo/CompanyUserChangeApplyVO.java

@@ -16,6 +16,10 @@ public class CompanyUserChangeApplyVO {
      * 原销售
      */
     private Long from;
+    /**
+     * 原销售头像
+     */
+    private String fromAvatar;
     /**
      * 原销售名称
      */
@@ -24,6 +28,10 @@ public class CompanyUserChangeApplyVO {
      * 申请更换销售
      */
     private Long to;
+    /**
+     * 申请更换销售头像
+     */
+    private String toAvatar;
     /**
      * 申请更换销售名称
      */

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

@@ -297,7 +297,7 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
     @Select("SELECT min(create_time) FROM fs_course_watch_log WHERE user_id=#{userId} limit 1")
     Date queryFirstWatchDateLogByVideoId(@Param("userId") Long userId);
 
-    @Select("SELECT l.qw_external_contact_id,l.log_type,l.qw_user_id,l.create_time lineTime,l.company_user_id as company_user_id,l.user_id as user_id,l.company_id as company_id FROM fs_course_watch_log l" +
+    @Select("SELECT l.qw_external_contact_id,l.project,l.video_id,l.course_id,l.log_type,l.qw_user_id,l.create_time lineTime,l.company_user_id as company_user_id,l.user_id as user_id,l.company_id as company_id FROM fs_course_watch_log l" +
             " WHERE DATE(l.create_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY) and l.video_id =#{videoId}")
     List<FsQwCourseWatchLogVO> selectFsCourseBeforeMonthWatchLogByVideoId(Long videoId);
 

+ 39 - 0
fs-service-system/src/main/java/com/fs/course/param/newfs/FsCourseSortLinkParam.java

@@ -0,0 +1,39 @@
+package com.fs.course.param.newfs;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel(description = "生成课程短链入参")
+public class FsCourseSortLinkParam {
+
+    @ApiModelProperty(value = "视频id")
+    private Long videoId;
+
+    private String qwUserId;
+
+    private String corpId;
+
+    @ApiModelProperty(value = "公司id")
+    private Long companyId;
+
+    @ApiModelProperty(value = "销售id")
+    private Long companyUserId;
+
+    @ApiModelProperty(value = "课程id")
+    private Long courseId;
+
+    @ApiModelProperty(value = "标题")
+    private String title;
+
+    @ApiModelProperty(value = "封面")
+    private String imageUrl;
+
+    @ApiModelProperty(value = "描述")
+    private String desc;
+
+//    @ApiModelProperty(value = "跳转的链接地址,格式举例:/course/pages/xxx?course=")
+//    private String realLink;
+
+}

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

@@ -5,10 +5,7 @@ import java.util.Map;
 
 import com.fs.common.core.domain.R;
 import com.fs.course.domain.FsUserCourse;
-import com.fs.course.param.FsUserCourseAddStudyCourseParam;
-import com.fs.course.param.FsUserCourseGetIntegralParam;
-import com.fs.course.param.FsUserCourseListUParam;
-import com.fs.course.param.FsUserCourseParam;
+import com.fs.course.param.*;
 import com.fs.course.param.newfs.FsUserCourseListParam;
 import com.fs.course.vo.*;
 import com.fs.course.vo.newfs.FsUserCourseListVO;
@@ -118,4 +115,11 @@ public interface IFsUserCourseService
      * @return  list
      */
     List<FsUserCourseParticipationRecordVO> getParticipationRecordByMap(Map<String, Object> params);
+
+    /**
+     * 创建生成课程短链
+     * @param param 入参
+     * @return
+     */
+    R createCourseSortLink(FsCourseLinkCreateParam param);
 }

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

@@ -392,9 +392,9 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
             }
             // 课程名
             if(ObjectUtils.isNotNull(item.getCourseId())) {
-                FsUserCourse course = fsUserCourseCacheService.selectFsUserCourseByCourseId(item.getCourseId());
-                if(ObjectUtils.isNotNull(course)){
-                    item.setCourseName(course.getCourseName());
+                String courseName = fsUserCourseCacheService.selectCourseNameByCourseId(item.getCourseId());
+                if(ObjectUtils.isNotNull(courseName)){
+                    item.setCourseName(courseName);
                 }
             }
             // 小节名
@@ -583,7 +583,7 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
                         // 获取进线时间
                         FsUser fsUser = fsUserService.selectFsUserById(fsCourseWatchLog.getUserId());
                         if (fsUser!=null){
-                            fsCourseWatchLog.setFirstTime(fsUser.getCreateTime());
+                            fsCourseWatchLog.setLineTime(fsUser.getCreateTime());
                         }
                         // 查询首次观看时间
                         Date date = fsCourseWatchLogMapper.queryFirstWatchDateLogByVideoId(fsCourseWatchLog.getUserId());

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

@@ -1,6 +1,7 @@
 package com.fs.course.service.impl;
 
 import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.fs.common.core.domain.R;
 import com.fs.common.utils.DateUtils;
@@ -10,24 +11,21 @@ import com.fs.company.domain.CompanyTag;
 import com.fs.company.domain.CompanyTagUser;
 import com.fs.company.mapper.CompanyTagMapper;
 import com.fs.company.mapper.CompanyTagUserMapper;
-import com.fs.course.domain.FsUserCourse;
-import com.fs.course.domain.FsUserCourseStudy;
-import com.fs.course.domain.FsUserCourseStudyLog;
-import com.fs.course.domain.FsUserCourseVideo;
+import com.fs.company.mapper.CompanyUserMapper;
+import com.fs.course.config.CourseConfig;
+import com.fs.course.domain.*;
 import com.fs.course.mapper.*;
-import com.fs.course.param.FsUserCourseAddStudyCourseParam;
-import com.fs.course.param.FsUserCourseGetIntegralParam;
-import com.fs.course.param.FsUserCourseListUParam;
-import com.fs.course.param.FsUserCourseParam;
+import com.fs.course.param.*;
 import com.fs.course.param.newfs.FsUserCourseListParam;
 import com.fs.course.service.IFsUserCourseService;
 import com.fs.course.vo.*;
 import com.fs.course.vo.newfs.FsUserCourseListVO;
 import com.fs.his.vo.OptionsVO;
+import com.fs.system.service.ISysConfigService;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-
 import java.util.*;
 
 /**
@@ -53,6 +51,15 @@ public class FsUserCourseServiceImpl implements IFsUserCourseService
     private FsUserCourseStudyLogMapper fsUserCourseStudyLogMapper;
     @Autowired
     private CompanyTagMapper companyTagMapper;
+    @Autowired
+    private ISysConfigService configService;
+    @Autowired
+    private FsCourseLinkMapper fsCourseLinkMapper;
+    @Autowired
+    private CompanyUserMapper companyUserMapper;
+
+    // todo 链接url需要调整
+    private static final String realLink = "/courseh5/pages/course/learning?course=";
 
     /**
      * 查询课程
@@ -390,4 +397,67 @@ public class FsUserCourseServiceImpl implements IFsUserCourseService
         });
         return list;
     }
+
+    @Override
+    public R createCourseSortLink(FsCourseLinkCreateParam param) {
+        String json = configService.selectConfigByKey("course.config");
+        CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
+
+        //新增链接表信息
+        FsCourseLink link = new FsCourseLink();
+        BeanUtils.copyProperties(param, link);
+        link.setLinkType(0);
+        link.setIsRoom(0);
+
+        FsCourseRealLink courseMap = new FsCourseRealLink();
+        BeanUtils.copyProperties(link, courseMap);
+        String courseJson = JSON.toJSONString(courseMap);
+
+        link.setRealLink(realLink + courseJson);
+        link.setLink(generateRandomString());
+        link.setCreateTime(new Date());
+
+        //获取过期时间
+        Calendar calendar = getExpireDay(param, config, link.getCreateTime());
+        link.setUpdateTime(calendar.getTime());
+        int i = fsCourseLinkMapper.insertFsCourseLink(link);
+        if (i > 0){
+            String domainName = getDomainName(param.getCompanyUserId(), config);
+            String sortLink = domainName + "/s/" + link.getLink();
+            return R.ok().put("url", sortLink);
+        }
+        return R.error("生成链接失败!");
+    }
+
+    private static Calendar getExpireDay(FsCourseLinkCreateParam param, CourseConfig config, Date createTime) {
+        Integer expireDays;
+        if (param.getDays() == null || param.getDays() == 0){
+            expireDays = config.getVideoLinkExpireDate();
+        }else {
+            expireDays = param.getDays();
+        }
+        // 设置过期时间
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(createTime);
+        calendar.add(Calendar.DAY_OF_MONTH, expireDays);
+        return calendar;
+    }
+
+
+    //
+
+    /**
+     * 生成随机的八位数字字母大小写的字符串(改为生成随机不重复的雪花id)
+     */
+    public static String generateRandomString() {
+        return FsCourseLinkServiceImpl.generateRandomString();
+    }
+
+    private String getDomainName(Long companyUserId, CourseConfig config){
+        String domainName = companyUserMapper.selectDomainByUserId(companyUserId);
+        if (StringUtils.isEmpty(domainName)){
+            domainName = config.getRealLinkDomainName();
+        }
+        return domainName;
+    }
 }

+ 6 - 2
fs-service-system/src/main/java/com/fs/qw/mapper/QwWatchLogMapper.java

@@ -105,7 +105,9 @@ public interface QwWatchLogMapper extends BaseMapper<QwWatchLog>{
             " from qw_watch_log where qw_user_id=#{id} and DATE(line_time) = DATE(#{createTime})")
     QwWatchLogStatisticsListVO selectQwWatchLogByQwUserId(@Param("id")Long id,@Param("createTime") Date createTime);
 
-    List<QwWatchLogStatisticsListVO> selectQwWatchLogByCompanyUserId(@Param("companyUserId") Long companyUserId,
+    List<QwWatchLogStatisticsListVO> selectQwWatchLogByCompanyUserId(
+            @Param("companyId") Long companyId,
+            @Param("companyUserId") Long companyUserId,
                                                                      @Param("sTime") Date sTime,
                                                                      @Param("dTime") Date dTime,
                                                                      @Param("project") Long project,
@@ -187,7 +189,9 @@ public interface QwWatchLogMapper extends BaseMapper<QwWatchLog>{
     QwWatchLogAllStatisticsListVO selectQwWatchLogAllStatisticsListVO(@Param("id")Long id,@Param("createTime") Date createTime);
 
 
-    List<QwWatchLogAllStatisticsListVO> selectQwWatchLogAllStatisticsListVONew(@Param("companyUserId")Long companyUserId, @Param("sDate") Date sDate, @Param("eDate") Date eDate,
+    List<QwWatchLogAllStatisticsListVO> selectQwWatchLogAllStatisticsListVONew(@Param("companyUserId")Long companyUserId,
+                                                                               @Param("companyId")Long companyId,
+                                                                               @Param("sDate") Date sDate, @Param("eDate") Date eDate,
                                                                                @Param("project") Long project,
                                                                                @Param("courseId") Long courseId,
                                                                                @Param("videoId") Long videoId);

+ 3 - 3
fs-service-system/src/main/java/com/fs/qw/service/impl/QwWatchLogServiceImpl.java

@@ -151,8 +151,8 @@ public class QwWatchLogServiceImpl extends ServiceImpl<QwWatchLogMapper, QwWatch
         List<QwWatchLogStatisticsListVO> list = new ArrayList<>();
         for (CompanyUser companyUser : companyUsers) {
             // 统计销售下面的所有记录
-            List<QwWatchLogStatisticsListVO> vos = qwWatchLogMapper.selectQwWatchLogByCompanyUserId(companyUser.getCompanyId(),
-                    param.getSTime(),param.getETime(),param.getProject(),param.getCourseId(),param.getVideoId());
+            List<QwWatchLogStatisticsListVO> vos = qwWatchLogMapper.selectQwWatchLogByCompanyUserId(companyUser.getCompanyId(),companyUser.getUserId()
+                    , param.getSTime(),param.getETime(),param.getProject(),param.getCourseId(),param.getVideoId());
             for (QwWatchLogStatisticsListVO item : vos) {
                 item.setCompanyUserName(String.format("%s_%d",companyUser.getUserName(),companyUser.getUserId()));
                 item.setCreateTime(companyUser.getCreateTime());
@@ -217,7 +217,7 @@ public class QwWatchLogServiceImpl extends ServiceImpl<QwWatchLogMapper, QwWatch
 
         for (CompanyUser companyUser : companyUsers) {
             List<QwWatchLogAllStatisticsListVO> vos = qwWatchLogMapper
-                    .selectQwWatchLogAllStatisticsListVONew(companyUser.getCompanyId(), param.getSTime(), param.getETime(),
+                    .selectQwWatchLogAllStatisticsListVONew(companyUser.getUserId(),companyUser.getCompanyId(), param.getSTime(), param.getETime(),
                             param.getProject(),param.getCourseId(),param.getVideoId()
                             );
             for (QwWatchLogAllStatisticsListVO item : vos) {

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

@@ -6,6 +6,7 @@ import com.fs.common.core.domain.BaseEntity;
 import lombok.Data;
 
 import java.time.LocalDate;
+import java.util.Date;
 
 //查出要执行的SOP
 @Data

+ 6 - 5
fs-service-system/src/main/java/com/fs/sop/service/impl/SopUserLogsInfoServiceImpl.java

@@ -485,7 +485,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                         String linkByMiniApp = createLinkByMiniApp(st, param.getCorpId(), createTime, param.getCourseId(), param.getVideoId(),
                                 qwUserId, companyUserId, companyId, item.getExternalId(), config,contact.getFsUserId());
 
-                        st.setMiniprogramPage(linkByMiniApp);
+                        st.setMiniprogramPage(linkByMiniApp.replaceAll("^[\\s\\u2005]+", ""));
                         break;
                     //app
                     case "9":
@@ -493,13 +493,14 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
 
                         QwCreateLinkByAppVO linkByApp = createLinkByApp(st, param.getCorpId(), createTime, param.getCourseId(), param.getVideoId(),
                                 qwUserId, companyUserId, companyId, item.getExternalId(), config,qwUser.getQwUserName(),contact.getFsUserId());
-                        st.setLinkUrl(linkByApp.getSortLink());
-                        st.setAppLinkUrl(linkByApp.getAppMsgLink());
+                        st.setLinkUrl(linkByApp.getSortLink().replaceAll("^[\\s\\u2005]+", ""));
+                        st.setAppLinkUrl(linkByApp.getAppMsgLink().replaceAll("^[\\s\\u2005]+", ""));
 
                         break;
                     //注册链接
                     case "10":
-                        st.setLinkUrl(config.getRegisterDomainName()+registerLink+item.getExternalId());
+                        String url=config.getRegisterDomainName()+registerLink+item.getExternalId();
+                        st.setLinkUrl(url.replaceAll("^[\\s\\u2005]+", ""));
                         break;
                     default:
                         break;
@@ -650,7 +651,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
         //存短链-
         fsCourseLinkMapper.insertFsCourseLink(link);
 
-        return sortLink;
+        return sortLink.replaceAll("^[\\s\\u2005]+", "");
     }
 
     private String createLinkByMiniApp(QwSopCourseFinishTempSetting.Setting setting, String corpId, Date sendTime,

+ 2 - 2
fs-service-system/src/main/java/com/fs/store/service/cache/impl/FsUserCourseCacheServiceImpl.java

@@ -19,11 +19,11 @@ public class FsUserCourseCacheServiceImpl implements IFsUserCourseCacheService {
     private final IFsUserCourseService fsUserCourseService;
     private static final Cache<Long, FsUserCourse> FS_USER_COURSE_CACHE = Caffeine.newBuilder()
             .maximumSize(1000)
-            .expireAfterWrite(1, TimeUnit.MINUTES)
+            .expireAfterWrite(3, TimeUnit.MINUTES)
             .build();
     private static final Cache<Long, String> COURSE_ID_AND_NAME = Caffeine.newBuilder()
             .maximumSize(1000)
-            .expireAfterWrite(1, TimeUnit.MINUTES)
+            .expireAfterWrite(3, TimeUnit.MINUTES)
             .build();
     @Override
     public FsUserCourse selectFsUserCourseByCourseId(Long courseId) {

+ 1 - 1
fs-service-system/src/main/resources/application-config.yml

@@ -18,7 +18,7 @@ fsConfig:
   erpWdAppsecret: 6ec212f06
   erpWdSid: apidevnew2
   erpWdShopCode: beiliyou2-test
-  erpWdBaseUrl: https://sandbox.wangdian.cn/openapi2/
+  erpWdBaseUrl: https://api.wangdian.cn/openapi2/
   erpWarehouseCode: beiliyou2-test
   #第三方支付配置
   payOpen: 1

+ 1 - 1
fs-service-system/src/main/resources/mapper/company/CompanyTagUserMapper.xml

@@ -80,7 +80,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </delete>
 
     <select id="getTagList" resultType="CompanyUserTagListVO">
-        SELECT
+        SELECT distinct
         company_tag.tag as tagName,
         company_tag.tag_id
         FROM

+ 2 - 0
fs-service-system/src/main/resources/mapper/company/CompanyUserChangeApplyMapper.xml

@@ -10,7 +10,9 @@
     <sql id="applySQL">
         select
             cuca.*,
+            fu.avatar    fromAvatar,
             fu.user_name fromName,
+            tu.avatar    toAvatar,
             tu.user_name toName
         from company_user_change_apply cuca
         left join company_user fu on fu.user_id = cuca.`from`

+ 2 - 1
fs-service-system/src/main/resources/mapper/company/CompanyUserChangeApplyUserMapper.xml

@@ -8,7 +8,8 @@
     <select id="getApplyUsers" resultType="com.fs.company.vo.CompanyUserChangeApplyUserVO">
         select
             fu.user_id,
-            fu.nickname as userName
+            fu.nickname as userName,
+            fu.avatar
         from company_user_change_apply_user cucau
         inner join fs_user fu on fu.user_id = cucau.user_id
         where cucau.apply_id = #{applyId}

+ 3 - 3
fs-service-system/src/main/resources/mapper/course/FsCourseWatchLogMapper.xml

@@ -463,10 +463,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                 o.company_id=#{companyId}
             </if>
             <if test= 'sTime != null '>
-                and DATE(o.create_time) &gt;= DATE(#{sTime})
+                and o.create_time &gt;= #{sTime}
             </if>
             <if test='eTime != null '>
-                and DATE(o.create_time) &lt;= DATE(#{eTime})
+                and o.create_time &lt;= #{eTime}
             </if>
             <if test ='courseId !=null'>
                 and o.course_id = #{courseId}
@@ -485,7 +485,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             </if>
         </where>
 
-        GROUP BY o.video_id,o.user_id,DATE(o.create_time)
+        GROUP BY o.video_id,o.user_id,DATE(o.create_time),o.project,o.course_id
         ORDER BY o.video_id ,DATE(o.create_time)
     </select>
     <select id="selectFsCourseWatchLogListVONew" resultType="com.fs.course.vo.FsCourseWatchLogListVO">

+ 32 - 16
fs-service-system/src/main/resources/mapper/qw/QwWatchLogMapper.xml

@@ -41,18 +41,25 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             COUNT(CASE WHEN day = 1 and status in (1,2) THEN 1 END) AS d1Online,
             COUNT(CASE WHEN day = 1 and status=2 THEN 1 END) AS d1Over,
             COUNT(1) AS line,project,course_id,video_id
-             from qw_watch_log where
-           company_user_id=#{companyUserId}
-            <if test="project != null">
-                and project=#{project}
-            </if>
-            <if test="courseId != null">
-                and course_id=#{courseId}
-            </if>
-            <if test="videoId != null">
-                and video_id=#{videoId}
-            </if>
-           and DATE(line_time) between #{sTime} and #{dTime}
+             from qw_watch_log
+             <where>
+                 <if test="companyUserId">
+                     and company_user_id = #{companyUserId}
+                 </if>
+                 <if test="companyId">
+                     and company_id = #{companyId}
+                 </if>
+                 <if test="project != null">
+                     and project=#{project}
+                 </if>
+                 <if test="courseId != null">
+                     and course_id=#{courseId}
+                 </if>
+                 <if test="videoId != null">
+                     and video_id=#{videoId}
+                 </if>
+                 and DATE(line_time) between #{sTime} and #{dTime}
+             </where>
             group by project,course_id,video_id
     </select>
     <select id="selectQwWatchLogAllStatisticsListVONew"
@@ -123,12 +130,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             COUNT(1) AS line,project,course_id,video_id
              from qw_watch_log
             <where>
-                company_user_id=#{companyUserId}
+                 <if test="companyUserId">
+                     and company_user_id=#{companyUserId}
+                 </if>
+                <if test="companyId">
+                    and company_id = #{companyId}
+                </if>
                 <if test="project != null">
                     and project = #{project}
                 </if>
                 <if test="courseId != null">
-                    and course_id = #{project}
+                    and course_id = #{courseId}
                 </if>
                 <if test="videoId != null">
                     and video_id =#{videoId}
@@ -170,7 +182,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         line_time,
         fs_user_id,
         company_id,
-        company_user_id
+        company_user_id,
+        course_id,
+        video_id
         )
         VALUES
     <foreach collection="watchLogs" item="log" separator=",">
@@ -184,7 +198,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             #{log.lineTime},
              #{log.fsUserId},
              #{log.companyId},
-             #{log.companyUserId}
+             #{log.companyUserId},
+             #{log.courseId},
+             #{log.videoId}
             )
     </foreach>
     </insert>

+ 64 - 2
fs-service-system/src/main/resources/mapper/sop/QwSopMapper.xml

@@ -28,6 +28,8 @@
         <result property="minSend"    column="min_send"    />
         <result property="maxSend"    column="max_send"    />
         <result property="stopTime"    column="stop_time"    />
+        <result property="isRating"    column="is_rating"    />
+        <result property="courseDay"    column="course_day"    />
     </resultMap>
 
     <sql id="selectQwSopVo">
@@ -92,6 +94,34 @@
         )
     </select>
 
+    <select id="selectQwSopAutoByTagsByForeachRemoveNotAuto"  resultType="com.fs.qw.vo.QwSopRuleTimeVO">
+        SELECT
+        qs.*,
+        qst.name AS temp_name,
+        qst.setting AS temp_setting,
+        qst.status AS temp_status,
+        qst.gap AS temp_gap,
+        qst.sort AS temp_sort,
+        qst.create_time AS temp_create_time,
+        qst.create_by AS temp_create_by,
+        qst.corp_id AS temp_company_id
+        FROM
+        qw_sop qs
+        LEFT JOIN
+        qw_sop_temp qst ON qs.temp_id = qst.id
+        WHERE
+        FIND_IN_SET(#{map.qwUserId}, COALESCE(qs.qw_user_ids, '')) > 0
+        AND qs.corp_id = #{map.corpId}
+        AND qst.status = '1'
+        AND qs.status IN (2, 3, 4)
+        AND qs.send_type = #{map.sendType}
+        AND (
+        <foreach collection='map.tagsIdsSelectList' item='item' index='index' separator=' and '>
+          NOT find_in_set( #{item}, TRIM(REGEXP_REPLACE(qs.tags, '[\"\\\\[\\\\]]', '')) )
+        </foreach>
+        )
+    </select>
+
     <select id="selectQwAiSopAutoByTagsByForeach"  resultType="com.fs.qw.vo.QwSopRuleTimeVO">
         SELECT
         qs.*,
@@ -186,7 +216,7 @@
             <if test="name != null  and name != ''"> and name like concat('%', #{name}, '%')</if>
             <if test="status != null "> and status = #{status}</if>
             <if test="type != null "> and type = #{type}</if>
-            <if test="id != null "> and id = #{id}</if>
+            <if test="id != null and id!='' "> and id = #{id}</if>
             <if test="companyId != null "> and company_id = #{companyId}</if>
             <if test="qwUserIds != null  and qwUserIds != ''"> and FIND_IN_SET(#{qwUserIds}, qw_user_ids) > 0</if>
             <if test="createBy != null  and createBy != ''"> and create_by = #{createBy}</if>
@@ -211,7 +241,12 @@
             and status != 6
          order by create_time desc
     </select>
-
+    <select id="selectQwSopByIsRating" parameterType="QwSop" resultMap="QwSopResult">
+        <include refid="selectQwSopVo"/>
+        where is_rating = 1
+        and send_type in(2,3)
+        order by create_time desc
+    </select>
     <select id="selectQwSopById" parameterType="String" resultMap="QwSopResult">
         <include refid="selectQwSopVo"/>
         where id = #{id}
@@ -241,6 +276,8 @@
             <if test="data.maxConversionDay != null">max_conversion_day,</if>
             <if test="data.minSend != null">min_send,</if>
             <if test="data.maxSend != null">max_send,</if>
+            <if test="data.isRating != null">is_rating,</if>
+            <if test="data.courseDay != null">course_day,</if>
         </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="data.name != null">#{data.name},</if>
@@ -264,6 +301,8 @@
             <if test="data.maxConversionDay != null">#{data.maxConversionDay},</if>
             <if test="data.minSend != null">#{data.minSend},</if>
             <if test="data.maxSend != null">#{data.maxSend},</if>
+            <if test="data.isRating != null">#{data.isRating},</if>
+            <if test="data.courseDay != null">#{data.courseDay},</if>
         </trim>
     </insert>
 
@@ -308,6 +347,23 @@
             #{id}
         </foreach>
     </select>
+    <select id="executeSopWxByIds"  resultType="com.fs.qw.vo.WxSopRuleTimeVO">
+        SELECT qs.*,
+        qst.name AS temp_name,
+        qst.setting AS temp_setting,
+        qst.status AS temp_status,
+        qst.gap AS temp_gap,
+        qst.sort AS temp_sort,
+        qst.create_time AS temp_create_time,
+        qst.create_by AS temp_create_by,
+        qst.corp_id AS temp_company_id
+        FROM qw_sop qs
+        LEFT JOIN qw_sop_temp qst ON qs.temp_id = qst.id
+        WHERE qs.id IN
+        <foreach item="id" collection="ids"  open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </select>
 
     <select id="selectAiChatQwSopList" resultType="com.fs.sop.domain.QwSop">
         <include refid="selectQwSopVo"/>
@@ -335,6 +391,10 @@
     <select id="selectByTemplateId" resultType="com.fs.sop.domain.QwSop">
         select * from qw_sop where temp_id = #{tempId}
     </select>
+    <select id="selectWxSop" resultType="com.fs.sop.domain.QwSop">
+        select a.* from qw_sop a
+        where a.send_type != 4 and a.status in (2,3) and a.type = 1
+    </select>
     <update id="updateQwSop" parameterType="QwSop" useGeneratedKeys="false" keyProperty="id" >
         UPDATE  qw_sop
         <trim prefix="SET" suffixOverrides=",">
@@ -360,6 +420,8 @@
             <if test="data.minSend != null">min_send = #{data.minSend},</if>
             <if test="data.maxSend != null">max_send = #{data.maxSend},</if>
             <if test="data.voice != null">voice = #{data.voice},</if>
+            <if test="data.isRating != null">is_rating = #{data.isRating},</if>
+            <if test="data.courseDay != null">course_day = #{data.courseDay},</if>
         </trim>
         where id = #{data.id}
     </update>