Jelajahi Sumber

Merge remote-tracking branch 'origin/master'

吴树波 2 minggu lalu
induk
melakukan
eec13cda50
55 mengubah file dengan 1428 tambahan dan 197 penghapusan
  1. 15 0
      fs-company-app/src/main/java/com/fs/app/controller/CompanyTagController.java
  2. 145 1
      fs-company-app/src/main/java/com/fs/app/controller/CompanyUserController.java
  3. 31 11
      fs-company-app/src/main/java/com/fs/app/controller/FsUserController.java
  4. 11 21
      fs-company-app/src/main/java/com/fs/app/controller/FsUserCourseVideoController.java
  5. 29 0
      fs-company-app/src/main/java/com/fs/app/param/CompanyUserChangeApplyParam.java
  6. 32 0
      fs-company-app/src/main/java/com/fs/app/param/CompanyUserParam.java
  7. 27 0
      fs-company-app/src/main/java/com/fs/app/param/CompanyUserUpdateParam.java
  8. 77 0
      fs-company/src/main/java/com/fs/company/controller/CompanyUserChangeApplyController.java
  9. 23 0
      fs-company/src/main/java/com/fs/company/param/CompanyUserChangeApplyAuditParam.java
  10. 15 0
      fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java
  11. 57 0
      fs-service-system/src/main/java/com/fs/company/domain/CompanyUserChangeApply.java
  12. 24 0
      fs-service-system/src/main/java/com/fs/company/domain/CompanyUserChangeApplyUser.java
  13. 8 0
      fs-service-system/src/main/java/com/fs/company/mapper/CompanyDeptMapper.java
  14. 10 0
      fs-service-system/src/main/java/com/fs/company/mapper/CompanyTagUserMapper.java
  15. 26 0
      fs-service-system/src/main/java/com/fs/company/mapper/CompanyUserChangeApplyMapper.java
  16. 24 0
      fs-service-system/src/main/java/com/fs/company/mapper/CompanyUserChangeApplyUserMapper.java
  17. 7 0
      fs-service-system/src/main/java/com/fs/company/service/ICompanyDeptService.java
  18. 9 0
      fs-service-system/src/main/java/com/fs/company/service/ICompanyTagUserService.java
  19. 46 0
      fs-service-system/src/main/java/com/fs/company/service/ICompanyUserChangeApplyService.java
  20. 24 0
      fs-service-system/src/main/java/com/fs/company/service/ICompanyUserChangeApplyUserService.java
  21. 10 0
      fs-service-system/src/main/java/com/fs/company/service/impl/CompanyDeptServiceImpl.java
  22. 11 0
      fs-service-system/src/main/java/com/fs/company/service/impl/CompanyServiceImpl.java
  23. 12 0
      fs-service-system/src/main/java/com/fs/company/service/impl/CompanyTagUserServiceImpl.java
  24. 145 0
      fs-service-system/src/main/java/com/fs/company/service/impl/CompanyUserChangeApplyServiceImpl.java
  25. 34 0
      fs-service-system/src/main/java/com/fs/company/service/impl/CompanyUserChangeApplyUserServiceImpl.java
  26. 15 0
      fs-service-system/src/main/java/com/fs/company/vo/CompanyTagUserVO.java
  27. 15 0
      fs-service-system/src/main/java/com/fs/company/vo/CompanyUserChangeApplyUserVO.java
  28. 61 0
      fs-service-system/src/main/java/com/fs/company/vo/CompanyUserChangeApplyVO.java
  29. 1 0
      fs-service-system/src/main/java/com/fs/course/config/CourseConfig.java
  30. 1 1
      fs-service-system/src/main/java/com/fs/course/mapper/FsCourseRedPacketLogMapper.java
  31. 0 7
      fs-service-system/src/main/java/com/fs/course/mapper/FsUserCourseVideoMapper.java
  32. 5 0
      fs-service-system/src/main/java/com/fs/course/param/newfs/UserCourseVideoPageParam.java
  33. 6 7
      fs-service-system/src/main/java/com/fs/course/service/IFsUserCourseVideoService.java
  34. 17 13
      fs-service-system/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java
  35. 0 61
      fs-service-system/src/main/java/com/fs/course/vo/FsCourseAnalysisVO.java
  36. 0 3
      fs-service-system/src/main/java/com/fs/course/vo/newfs/FsUserCourseListVO.java
  37. 19 0
      fs-service-system/src/main/java/com/fs/course/vo/newfs/FsUserVideoListVO.java
  38. 45 23
      fs-service-system/src/main/java/com/fs/qw/service/impl/QwExternalContactServiceImpl.java
  39. 3 1
      fs-service-system/src/main/java/com/fs/qw/service/impl/QwFriendWelcomeServiceImpl.java
  40. 1 0
      fs-service-system/src/main/java/com/fs/qwApi/param/SendWelcomeMsgParam.java
  41. 8 1
      fs-service-system/src/main/java/com/fs/sop/service/impl/QwSopLogsServiceImpl.java
  42. 5 0
      fs-service-system/src/main/java/com/fs/sop/service/impl/SopUserLogsInfoServiceImpl.java
  43. 7 3
      fs-service-system/src/main/java/com/fs/store/mapper/FsUserMapper.java
  44. 58 2
      fs-service-system/src/main/java/com/fs/store/service/IFsUserService.java
  45. 33 11
      fs-service-system/src/main/java/com/fs/store/service/impl/FsUserServiceImpl.java
  46. 27 0
      fs-service-system/src/main/java/com/fs/store/vo/h5/FsCourseRankingVO.java
  47. 34 0
      fs-service-system/src/main/java/com/fs/store/vo/h5/FsUserGraphicStatisticsVO.java
  48. 1 1
      fs-service-system/src/main/java/com/fs/store/vo/h5/FsUserRankingVO.java
  49. 3 3
      fs-service-system/src/main/java/com/fs/store/vo/h5/FsUserStatisticsVO.java
  50. 10 0
      fs-service-system/src/main/resources/mapper/company/CompanyTagUserMapper.xml
  51. 38 0
      fs-service-system/src/main/resources/mapper/company/CompanyUserChangeApplyMapper.xml
  52. 25 0
      fs-service-system/src/main/resources/mapper/company/CompanyUserChangeApplyUserMapper.xml
  53. 2 11
      fs-service-system/src/main/resources/mapper/course/FsUserCourseVideoMapper.xml
  54. 134 15
      fs-service-system/src/main/resources/mapper/store/FsUserMapper.xml
  55. 2 1
      fs-user-app/src/main/java/com/fs/app/controller/CourseController.java

+ 15 - 0
fs-company-app/src/main/java/com/fs/app/controller/CompanyTagController.java

@@ -6,13 +6,17 @@ import com.fs.common.core.domain.R;
 import com.fs.common.exception.CustomException;
 import com.fs.company.domain.CompanyTag;
 import com.fs.company.service.ICompanyTagService;
+import com.fs.company.service.ICompanyTagUserService;
+import com.fs.company.vo.CompanyTagUserVO;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 @Slf4j
 @Api(tags = "企业标签接口")
@@ -22,6 +26,7 @@ import java.util.List;
 public class CompanyTagController extends AppBaseController {
 
     private final ICompanyTagService companyTagService;
+    private final ICompanyTagUserService companyTagUserService;
 
     /**
      * 查询公司标签列表
@@ -60,4 +65,14 @@ public class CompanyTagController extends AppBaseController {
         companyTagService.deleteCompanyTagByTagIds(tagIds);
         return R.ok();
     }
+
+    @Login
+    @GetMapping("/tagSubUsers")
+    @ApiOperation("标签下会员列表")
+    public R tagSubUsers(@RequestParam Long tagId) {
+        Map<String, Object> params = new HashMap<>();
+        params.put("tagId", tagId);
+        params.put("companyId", getCompanyId());
+        return R.ok().put("data", companyTagUserService.selectUserListByMap(params));
+    }
 }

+ 145 - 1
fs-company-app/src/main/java/com/fs/app/controller/CompanyUserController.java

@@ -1,11 +1,27 @@
 package com.fs.app.controller;
 
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.app.annotation.Login;
+import com.fs.app.param.CompanyUserChangeApplyParam;
+import com.fs.app.param.CompanyUserParam;
+import com.fs.app.param.CompanyUserUpdateParam;
 import com.fs.app.vo.CompanySubUserVO;
+import com.fs.common.annotation.RepeatSubmit;
+import com.fs.common.constant.UserConstants;
 import com.fs.common.core.domain.R;
+import com.fs.common.exception.ServiceException;
 import com.fs.common.utils.bean.BeanUtils;
+import com.fs.company.domain.Company;
+import com.fs.company.domain.CompanyDept;
 import com.fs.company.domain.CompanyUser;
+import com.fs.company.domain.CompanyUserChangeApply;
+import com.fs.company.service.ICompanyDeptService;
+import com.fs.company.service.ICompanyService;
+import com.fs.company.service.ICompanyUserChangeApplyService;
 import com.fs.company.service.ICompanyUserService;
+import com.fs.company.vo.CompanyUserChangeApplyVO;
+import com.fs.core.security.SecurityUtils;
 import com.fs.course.service.IFsCourseRedPacketLogService;
 import com.fs.course.service.IFsCourseWatchLogService;
 import com.github.pagehelper.PageHelper;
@@ -16,6 +32,7 @@ import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.*;
 
+import javax.validation.Valid;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.time.LocalDate;
@@ -30,8 +47,11 @@ import java.util.stream.Collectors;
 public class CompanyUserController extends AppBaseController {
 
     private final ICompanyUserService companyUserService;
+    private final ICompanyService companyService;
+    private final ICompanyDeptService companyDeptService;
     private final IFsCourseWatchLogService courseWatchLogService;
     private final IFsCourseRedPacketLogService courseRedPacketLogService;
+    private final ICompanyUserChangeApplyService companyUserChangeApplyService;
 
     @Login
     @ApiOperation("下级用户列表")
@@ -43,6 +63,7 @@ public class CompanyUserController extends AppBaseController {
         List<CompanyUser> companyUsers = companyUserService.selectCompanySubUserList(Long.parseLong(getUserId()));
         PageInfo<CompanyUser> page = new PageInfo<>(companyUsers);
 
+        // 转换对象
         List<CompanySubUserVO> users = page.getList().stream().map(u -> {
             CompanySubUserVO vo = new CompanySubUserVO();
             BeanUtils.copyProperties(u, vo);
@@ -74,10 +95,133 @@ public class CompanyUserController extends AppBaseController {
             return vo;
         }).collect(Collectors.toList());
 
-        PageInfo<CompanySubUserVO> pageInfo = new PageInfo<>(users);
+        PageInfo<CompanySubUserVO> pageInfo = new PageInfo<>();
         BeanUtils.copyProperties(page, pageInfo);
+        pageInfo.setList(users);
 
         return R.ok().put("data", pageInfo);
     }
 
+    @Login
+    @ApiOperation("修改用户信息")
+    @PostMapping("/updateUserInfo")
+    public R updateUserInfo(@Valid @RequestBody CompanyUserUpdateParam param) {
+        CompanyUser companyUser = companyUserService.selectCompanyUserById(param.getUserId());
+        if (Objects.isNull(companyUser)) {
+            throw new ServiceException("用户不存在");
+        }
+
+        companyUser.setUserId(param.getUserId());
+        companyUser.setNickName(param.getNickName());
+        companyUser.setPhonenumber(param.getPhoneNumber());
+        companyUser.setRemark(param.getRemark());
+        companyUserService.updateCompanyUser(companyUser);
+        return R.ok();
+    }
+
+    @ApiOperation("注册")
+    @PostMapping("/resisterCompanyUser")
+    public R resisterCompanyUser(@Valid @RequestBody CompanyUserParam param) {
+        Company company = companyService.selectCompanyById(param.getCompanyId());
+        if (Objects.isNull(company)) {
+            return R.error("公司不存在");
+        }
+
+        // 判断用户数量是否已达到上线
+        Integer count = companyUserService.selectCompanyUserCountByCompanyId(param.getCompanyId());
+        if(count > company.getLimitUserCount()) {
+            return R.error("用户数量已达到上限");
+        }
+
+        if (UserConstants.NOT_UNIQUE.equals(String.valueOf(companyUserService.checkUserName(param.getPhoneNumber())))) {
+            return R.error("注册用户'" + param.getPhoneNumber() + "'失败,登录账号已存在");
+        }
+
+        // 组装参数
+        CompanyUser companyUser = new CompanyUser();
+        BeanUtils.copyProperties(param, companyUser);
+
+        companyUser.setUserName(param.getPhoneNumber());
+        companyUser.setPhonenumber(param.getPhoneNumber());
+        companyUser.setPassword(SecurityUtils.encryptPassword(companyUser.getPassword()));
+        companyUser.setCreateTime(new Date());
+
+        // 部门
+        CompanyDept dept = companyDeptService.getDefaultCompanyDeptByCompanyId(param.getCompanyId());
+        if (Objects.nonNull(dept)) {
+            companyUser.setDeptId(dept.getDeptId());
+        }
+
+        companyUserService.insertUser(companyUser);
+        return R.ok();
+    }
+
+    @Login
+    @ApiOperation("接收群管列表")
+    @GetMapping("/companyUserListByCompanyId")
+    public R CompanyUserListByCompanyId(){
+        // 查询公司下销售
+        CompanyUser companyUser = new CompanyUser();
+        companyUser.setCompanyId(getCompanyId());
+        List<CompanyUser> companyUsers = companyUserService.selectCompanyUserList(companyUser);
+        return R.ok().put("data",companyUsers);
+    }
+
+    @Login
+    @RepeatSubmit
+    @ApiOperation("更换会员归属申请")
+    @PostMapping("/changeUserParentApply")
+    public R changeVipUser(@Valid @RequestBody CompanyUserChangeApplyParam param) {
+        // 参数校验
+        CompanyUser fromUser = companyUserService.selectCompanyUserById(param.getFrom());
+        if (Objects.isNull(fromUser)) {
+            return R.error("原归属销售不存在");
+        }
+
+        CompanyUser toUser = companyUserService.selectCompanyUserById(param.getTo());
+        if (Objects.isNull(toUser)) {
+            throw new ServiceException("申请更换归属销售不存在");
+        }
+
+        if (param.getType() != 0 && param.getType() != 1) {
+            throw new ServiceException("类型不正确");
+        }
+
+        if (param.getType() == 1 && (Objects.isNull(param.getIds()) || param.getIds().isEmpty())) {
+            throw new ServiceException("请先选择会员");
+        }
+
+        // 存在待审核的申请不能再次申请
+        Wrapper<CompanyUserChangeApply> applyWrapper = Wrappers.<CompanyUserChangeApply>lambdaQuery()
+                .eq(CompanyUserChangeApply::getFrom, fromUser.getUserId())
+                .eq(CompanyUserChangeApply::getStatus, 0);
+        if (companyUserChangeApplyService.count(applyWrapper) > 0) {
+            throw new ServiceException("存在待审核申请");
+        }
+
+        CompanyUser companyUser = companyUserService.selectCompanyUserById(Long.parseLong(getUserId()));
+
+        // 添加申请
+        companyUserChangeApplyService.apply(param.getFrom(), param.getTo(), param.getType(), param.getIds(), companyUser.getCompanyId(), companyUser.getUserName());
+        return R.ok();
+    }
+
+    @Login
+    @ApiOperation("申请列表")
+    @GetMapping("/applyList")
+    public R applyList(@RequestParam(required = false) Integer status,
+                       @RequestParam(required = false, defaultValue = "1") Integer pageNum,
+                       @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
+        log.debug("申请列表 status: {}, pageNum: {}, pageSize: {}", status, pageNum, pageSize);
+
+        Map<String, Object> map = new HashMap<>();
+        map.put("status", status);
+        map.put("companyId", getCompanyId());
+
+        PageHelper.startPage(pageNum, pageSize);
+        List<CompanyUserChangeApplyVO> list = companyUserChangeApplyService.selectApplyListByMap(map);
+        PageInfo<CompanyUserChangeApplyVO> page = new PageInfo<>(list);
+        return R.ok().put("data", page);
+    }
+
 }

+ 31 - 11
fs-company-app/src/main/java/com/fs/app/controller/FsUserController.java

@@ -138,35 +138,55 @@ public class FsUserController extends AppBaseController {
     public ResponseResult<FsUserStatisticsVO> userStatisticsDetails(@ApiParam(value = "课程id") @RequestParam(required = false) String courseId,
                                                                     @ApiParam(value = "视频id") @RequestParam(required = false) String videoId) {
         long userId = Long.parseLong(getUserId());
-        FsUserStatisticsVO fsUserStatisticsVO = fsUserService.userStatisticsDetails(userId, courseId, videoId);
+        long companyId = getCompanyId();
+        FsUserStatisticsVO fsUserStatisticsVO = fsUserService.userStatisticsDetails(userId, courseId, videoId, companyId);
         return ResponseResult.ok(fsUserStatisticsVO);
     }
 
     @GetMapping("/firstPage/userRanking")
     @ApiOperation("首页数据/详情-销售排行榜统计")
-    public ResponseResult<FsUserRankingVO> userRanking(
-            @ApiParam(value = "开始时间") @RequestParam String startTime,
-            @ApiParam(value = "结束时间") @RequestParam String endTime,
+    public ResponseResult<List<FsUserRankingVO>> userRanking(
+            @ApiParam(value = "开始时间") @RequestParam(required = false) String startTime,
+            @ApiParam(value = "结束时间") @RequestParam(required = false) String endTime,
             @ApiParam(value = "课程id") @RequestParam(required = false) String courseId,
             @ApiParam(value = "视频id") @RequestParam(required = false) String videoId,
             @ApiParam(value = "asc-正序,desc-倒序", required = true) @RequestParam String order,
-            @ApiParam(value = "类型,1-按完播率,2-按正确率", required = true) @RequestParam(required = false) Integer type
-            ) {
+            @ApiParam(value = "类型,1-按完播率,2-按正确率", required = true) @RequestParam Integer type
+    ) {
         long userId = Long.parseLong(getUserId());
         return ResponseResult.ok(fsUserService.userRanking(userId, startTime, endTime, courseId, videoId, order, type));
     }
 
     @GetMapping("/firstPage/courseRanking")
     @ApiOperation("首页数据/详情-课程排行榜统计")
-    public ResponseResult<FsUserRankingVO> courseRanking(
-            @ApiParam(value = "开始时间") @RequestParam String startTime,
-            @ApiParam(value = "结束时间") @RequestParam String endTime,
+    public ResponseResult<List<FsCourseRankingVO>> courseRanking(
+            @ApiParam(value = "开始时间") @RequestParam(required = false) String startTime,
+            @ApiParam(value = "结束时间") @RequestParam(required = false) String endTime,
             @ApiParam(value = "课程id") @RequestParam(required = false) String courseId,
             @ApiParam(value = "视频id") @RequestParam(required = false) String videoId,
             @ApiParam(value = "asc-正序,desc-倒序", required = true) @RequestParam String order,
-            @ApiParam(value = "类型,1-按完播率,2-按正确率", required = true) @RequestParam(required = false) Integer type
+            @ApiParam(value = "类型,1-按完播率,2-按正确率", required = true) @RequestParam Integer type
     ) {
         long userId = Long.parseLong(getUserId());
-        return ResponseResult.ok();
+        return ResponseResult.ok(fsUserService.courseRanking(userId, startTime, endTime, courseId, videoId, order, type));
+    }
+
+    @GetMapping("/firstPage/graphic")
+    @ApiOperation("首页数据-转化漏斗图")
+    public ResponseResult<List<FsUserGraphicStatisticsVO>> graphicStatistics(@ApiParam(value = "开始时间", required = true) @RequestParam String startTime,
+                                                                @ApiParam(value = "结束时间", required = true) @RequestParam String endTime) {
+        long userId = Long.parseLong(getUserId());
+        List<FsUserGraphicStatisticsVO> list = fsUserService.graphicStatistics(userId, startTime, endTime, null, null);
+        return ResponseResult.ok(list);
     }
+
+    @GetMapping("/graphic/details")
+    @ApiOperation("详情-转化漏斗图")
+    public ResponseResult<List<FsUserGraphicStatisticsVO>> graphicStatisticsDetails(@ApiParam(value = "课程id") @RequestParam(required = false) String courseId,
+                                                                                    @ApiParam(value = "视频id") @RequestParam(required = false) String videoId) {
+        long userId = Long.parseLong(getUserId());
+        List<FsUserGraphicStatisticsVO> list = fsUserService.graphicStatistics(userId, null, null, courseId, videoId);
+        return ResponseResult.ok(list);
+    }
+
 }

+ 11 - 21
fs-company-app/src/main/java/com/fs/app/controller/FsUserCourseVideoController.java

@@ -6,11 +6,10 @@ import com.fs.course.param.newfs.FsUserCourseListParam;
 import com.fs.course.param.newfs.UserCourseVideoPageParam;
 import com.fs.course.service.IFsUserCourseService;
 import com.fs.course.service.IFsUserCourseVideoService;
-import com.fs.course.vo.FsCourseAnalysisVO;
-import com.fs.course.vo.FsUserCourseListPVO;
 import com.fs.course.vo.newfs.FsUserCourseListVO;
 import com.fs.course.vo.newfs.FsUserCourseVideoDetailsVO;
 import com.fs.course.vo.newfs.FsUserCourseVideoPageListVO;
+import com.fs.course.vo.newfs.FsUserVideoListVO;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
 import io.swagger.annotations.Api;
@@ -40,6 +39,7 @@ public class FsUserCourseVideoController extends AppBaseController {
     @ApiOperation("课程分页列表")
     public ResponseResult<PageInfo<FsUserCourseVideoPageListVO>> list(UserCourseVideoPageParam param) {
         PageHelper.startPage(param.getPageNum(), param.getPageSize());
+        param.setCompanyId(getCompanyId());
         List<FsUserCourseVideoPageListVO> list = fsUserCourseVideoService.pageListCourseVideo(param);
         PageInfo<FsUserCourseVideoPageListVO> pageInfo = new PageInfo<>(list);
         return ResponseResult.ok(pageInfo);
@@ -53,7 +53,7 @@ public class FsUserCourseVideoController extends AppBaseController {
 
     @GetMapping("/courseList")
     @ApiOperation("获取课程下拉列表")
-    public ResponseResult<PageInfo<FsUserCourseListVO>> getAllCompanyUser(FsUserCourseListParam param) {
+    public ResponseResult<PageInfo<FsUserCourseListVO>> getAllCourseList(FsUserCourseListParam param) {
         PageHelper.startPage(param.getPageNum(), param.getPageSize());
         param.setCompanyId(getCompanyId());
         List<FsUserCourseListVO> fsUserCourseList = fsUserCourseService.getFsUserCourseList(param);
@@ -61,23 +61,13 @@ public class FsUserCourseVideoController extends AppBaseController {
         return ResponseResult.ok(pageInfo);
     }
 
-    @ApiOperation("课程分析")
-    @GetMapping("/courseAnalysis")
-    public R courseAnalysis(@RequestParam(required = false) Long courseId,
-                            @RequestParam(required = false) Integer status,
-                            @RequestParam(required = false, value = "true") Boolean isToday,
-                            @RequestParam(required = false, defaultValue = "1") Integer pageNum,
-                            @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
-
-        Map<String,Object> params = new HashMap<>();
-        params.put("courseId", courseId);
-        params.put("companyId", getCompanyId());
-        params.put("isToday", isToday);
-        params.put("status", status);
-
-        // TODO: 查询课程
-        PageHelper.startPage(pageNum, pageSize);
-        List<FsCourseAnalysisVO> list = fsUserCourseVideoService.getCourseAnalysisByMap(params);
-        return R.ok().put("data", new PageInfo<>(list));
+    @GetMapping("/videoList")
+    @ApiOperation("获取视频下拉列表")
+    public ResponseResult<PageInfo<FsUserVideoListVO>> getAllVideoList(UserCourseVideoPageParam param) {
+        PageHelper.startPage(param.getPageNum(), param.getPageSize());
+        param.setCompanyId(getCompanyId());
+        List<FsUserVideoListVO> listCourseVideo = fsUserCourseVideoService.getListCourseVideo(param);
+        PageInfo<FsUserVideoListVO> result = new PageInfo<>(listCourseVideo);
+        return ResponseResult.ok(result);
     }
 }

+ 29 - 0
fs-company-app/src/main/java/com/fs/app/param/CompanyUserChangeApplyParam.java

@@ -0,0 +1,29 @@
+package com.fs.app.param;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+@Data
+public class CompanyUserChangeApplyParam {
+    /**
+     * 原归属销售
+     */
+    @NotNull(message = "原归属销售ID不能为空")
+    private Long from;
+    /**
+     * 申请归属销售
+     */
+    @NotNull(message = "申请更换归属销售ID不能为空")
+    private Long to;
+    /**
+     * 类型  0全部 1部分
+     */
+    @NotNull(message = "类型不能为空")
+    private Integer type;
+    /**
+     * 需更换归属会员id集合
+     */
+    private List<Long> ids;
+}

+ 32 - 0
fs-company-app/src/main/java/com/fs/app/param/CompanyUserParam.java

@@ -0,0 +1,32 @@
+package com.fs.app.param;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+@Data
+public class CompanyUserParam {
+
+    /**
+     * 公司ID
+     */
+    @NotNull(message = "公司ID不能为空")
+    private Long companyId;
+    /**
+     * 手机号码
+     */
+    @NotBlank(message = "手机号码不能为空")
+    private String phoneNumber;
+    /**
+     * 昵称
+     */
+    @NotBlank(message = "昵称不能为空")
+    private String nickName;
+    /**
+     * 密码
+     */
+    @NotBlank(message = "用户密码不能为空")
+    private String password;
+
+}

+ 27 - 0
fs-company-app/src/main/java/com/fs/app/param/CompanyUserUpdateParam.java

@@ -0,0 +1,27 @@
+package com.fs.app.param;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+public class CompanyUserUpdateParam {
+
+    /**
+     * 用户ID
+     */
+    @NotNull(message = "用户ID不能为空")
+    private Long userId;
+    /**
+     * 昵称
+     */
+    private String nickName;
+    /**
+     * 电话号码
+     */
+    private String phoneNumber;
+    /**
+     * 备注
+     */
+    private String remark;
+}

+ 77 - 0
fs-company/src/main/java/com/fs/company/controller/CompanyUserChangeApplyController.java

@@ -0,0 +1,77 @@
+package com.fs.company.controller;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.fs.common.exception.ServiceException;
+import com.fs.common.utils.StringUtils;
+import com.fs.company.param.CompanyUserChangeApplyAuditParam;
+import com.fs.company.service.ICompanyUserChangeApplyService;
+import com.fs.company.vo.CompanyUserChangeApplyVO;
+import com.fs.core.security.SecurityUtils;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+
+import javax.validation.Valid;
+
+/**
+ * 更换会员归属申请Controller
+ */
+@RestController
+@RequestMapping("/company/apply")
+public class CompanyUserChangeApplyController extends BaseController
+{
+    @Autowired
+    private ICompanyUserChangeApplyService companyUserChangeApplyService;
+
+    /**
+     * 查询更换会员归属申请列表
+     */
+    @PreAuthorize("@ss.hasPermi('company:apply:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(@RequestParam(required = false) Integer status)
+    {
+        Map<String, Object> map = new HashMap<>();
+        map.put("status", status);
+        map.put("companyId", SecurityUtils.getLoginUser().getCompany().getCompanyId());
+
+        startPage();
+        List<CompanyUserChangeApplyVO> list = companyUserChangeApplyService.selectApplyListByMap(map);
+        return getDataTable(list);
+    }
+
+    /**
+     * 获取更换会员归属申请详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('company:apply:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return AjaxResult.success(companyUserChangeApplyService.selectApplyDetailById(id));
+    }
+
+    /**
+     * 获取更换会员归属申请详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('company:apply:audit')")
+    @PostMapping(value = "/audit")
+    public AjaxResult audit(@Valid @RequestBody CompanyUserChangeApplyAuditParam param)
+    {
+        if (param.getStatus() != 1 && param.getStatus() != 2) {
+            throw new ServiceException("审核类型不正确");
+        }
+
+        if (param.getStatus() == 2 && StringUtils.isBlank(param.getReason())) {
+            throw new ServiceException("拒绝理由不能为空");
+        }
+
+        companyUserChangeApplyService.audit(param.getId(), param.getStatus(), param.getReason(), SecurityUtils.getUsername());
+        return AjaxResult.success();
+    }
+
+}

+ 23 - 0
fs-company/src/main/java/com/fs/company/param/CompanyUserChangeApplyAuditParam.java

@@ -0,0 +1,23 @@
+package com.fs.company.param;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+public class CompanyUserChangeApplyAuditParam {
+    /**
+     * 申请记录ID
+     */
+    @NotNull(message = "申请记录ID不能为空")
+    private Long id;
+    /**
+     * 状态 0通过 1拒绝
+     */
+    @NotNull(message = "审核状态不能为空")
+    private Integer status;
+    /**
+     * 原因
+     */
+    private String reason;
+}

+ 15 - 0
fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java

@@ -71,6 +71,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
     private static final String miniappRealLink = "/pages_course/video.html?course=";
     private static final String appRealLink = "/pages/courseAnswer/index?link=";
     private static final String appLink = "https://jump.ylrztop.com/jumpapp/pages/index/index?link=";
+    private static final String registerLink = "/registerCourse/pages/index?qwExternalId=";
 
     // Cached configurations and domain names
     private CourseConfig cachedCourseConfig;
@@ -839,6 +840,20 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
                     setting.setLinkUrl(linkByApp.getSortLink());
                     setting.setAppLinkUrl(linkByApp.getAppMsgLink());
 
+                    break;
+                //注册链接
+                case "10":
+                    // 获取缓存的配置
+                    CourseConfig config;
+                    synchronized(configLock) {
+                        config = cachedCourseConfig;
+                    }
+                    if (config != null) {
+                        setting.setLinkUrl(config.getRegisterDomainName()+registerLink+externalId);
+                    }else {
+                        log.error("获取缓存的配置为空:注册链接");
+                    }
+
                     break;
                 default:
                     break;

+ 57 - 0
fs-service-system/src/main/java/com/fs/company/domain/CompanyUserChangeApply.java

@@ -0,0 +1,57 @@
+package com.fs.company.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+@TableName("company_user_change_apply")
+public class CompanyUserChangeApply {
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+    /**
+     * 公司ID
+     */
+    private Long companyId;
+    /**
+     * 原归属销售
+     */
+    @TableField("`from`")
+    private Long from;
+    /**
+     * 申请归属销售
+     */
+    @TableField("`to`")
+    private Long to;
+    /**
+     * 审核状态 0待审核 1通过 2拒绝
+     */
+    private Integer status;
+    /**
+     * 申请人
+     */
+    private String applyBy;
+    /**
+     * 申请时间
+     */
+    private LocalDateTime applyTime;
+    /**
+     * 审核人
+     */
+    private String auditBy;
+    /**
+     * 审核时间
+     */
+    private LocalDateTime auditTime;
+    /**
+     * 被拒原因
+     */
+    private String reason;
+}

+ 24 - 0
fs-service-system/src/main/java/com/fs/company/domain/CompanyUserChangeApplyUser.java

@@ -0,0 +1,24 @@
+package com.fs.company.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+@Data
+@TableName("company_user_change_apply_user")
+public class CompanyUserChangeApplyUser {
+    /**
+     * 主键ID
+     */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    /**
+     * 申请ID
+     */
+    private Long applyId;
+    /**
+     * 用户ID
+     */
+    private Long userId;
+}

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

@@ -82,4 +82,12 @@ public interface CompanyDeptMapper
     List<String> selectCompanyDeptNamesByIds(String ids);
 
     Long selectCompanyDeptByIdCompany(Long deptId);
+
+    /**
+     * 获取公司默认部门
+     * @param companyId 公司ID
+     * @return  公司部门
+     */
+    @Select("select cd.* from company_dept cd where cd.company_id = #{companyId} and cd.dept_name = '默认' and cd.parent_id = 0 limit 1")
+    CompanyDept getTopCompanyDeptByCompanyId(@Param("companyId") Long companyId);
 }

+ 10 - 0
fs-service-system/src/main/java/com/fs/company/mapper/CompanyTagUserMapper.java

@@ -1,7 +1,10 @@
 package com.fs.company.mapper;
 
 import java.util.List;
+import java.util.Map;
+
 import com.fs.company.domain.CompanyTagUser;
+import com.fs.company.vo.CompanyTagUserVO;
 import com.fs.store.param.h5.TagListParam;
 import com.fs.store.vo.h5.CompanyUserTagListVO;
 import org.apache.ibatis.annotations.Param;
@@ -63,4 +66,11 @@ public interface CompanyTagUserMapper
     public int deleteCompanyTagUserByIds(Long[] ids);
 
     List<CompanyUserTagListVO> getTagList(@Param("param") TagListParam param, @Param("keywords") String[] keywords, @Param("userIds") List<Long> userIds);
+
+    /**
+     * 根据条件查询标签下用户
+     * @param params    条件
+     * @return  list
+     */
+    List<CompanyTagUserVO> selectUserListByMap(@Param("params") Map<String, Object> params);
 }

+ 26 - 0
fs-service-system/src/main/java/com/fs/company/mapper/CompanyUserChangeApplyMapper.java

@@ -0,0 +1,26 @@
+package com.fs.company.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.company.domain.CompanyUserChangeApply;
+import com.fs.company.vo.CompanyUserChangeApplyVO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+public interface CompanyUserChangeApplyMapper extends BaseMapper<CompanyUserChangeApply> {
+
+    /**
+     * 查询申请列表
+     * @param map 条件
+     * @return  list
+     */
+    List<CompanyUserChangeApplyVO> selectApplyListByMap(@Param("map") Map<String, Object> map);
+
+    /**
+     * 查询申请详情
+     * @param id    申请记录ID
+     * @return  CompanyUserChangeApplyVO
+     */
+    CompanyUserChangeApplyVO detailById(@Param("id") Long id);
+}

+ 24 - 0
fs-service-system/src/main/java/com/fs/company/mapper/CompanyUserChangeApplyUserMapper.java

@@ -0,0 +1,24 @@
+package com.fs.company.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.company.domain.CompanyUserChangeApplyUser;
+import com.fs.company.vo.CompanyUserChangeApplyUserVO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface CompanyUserChangeApplyUserMapper extends BaseMapper<CompanyUserChangeApplyUser> {
+
+    /**
+     * 查询申请记录关联用户
+     * @param applyId   申请记录ID
+     * @return  list
+     */
+    List<CompanyUserChangeApplyUserVO> getApplyUsers(@Param("applyId") Long applyId);
+
+    /**
+     * 修改申请记录关联用户销售
+     * @param applyId 申请记录ID
+     */
+    void changeUser(@Param("applyId") Long applyId);
+}

+ 7 - 0
fs-service-system/src/main/java/com/fs/company/service/ICompanyDeptService.java

@@ -77,4 +77,11 @@ public interface ICompanyDeptService
     int selectNormalChildrenDeptById(Long deptId);
 
     List<String> selectCompanyDeptNamesByIds(String ids);
+
+    /**
+     * 获取公司默认部门
+     * @param companyId 公司ID
+     * @return 部门
+     */
+    CompanyDept getDefaultCompanyDeptByCompanyId(Long companyId);
 }

+ 9 - 0
fs-service-system/src/main/java/com/fs/company/service/ICompanyTagUserService.java

@@ -1,7 +1,10 @@
 package com.fs.company.service;
 
 import java.util.List;
+import java.util.Map;
+
 import com.fs.company.domain.CompanyTagUser;
+import com.fs.company.vo.CompanyTagUserVO;
 import com.fs.store.param.h5.TagListParam;
 import com.fs.store.vo.h5.CompanyUserTagListVO;
 
@@ -68,4 +71,10 @@ public interface ICompanyTagUserService
      */
     List<CompanyUserTagListVO> getTagList(TagListParam param);
 
+    /**
+     * 根据条件查询标签下用户
+     * @param params    条件
+     * @return  list
+     */
+    List<CompanyTagUserVO> selectUserListByMap(Map<String, Object> params);
 }

+ 46 - 0
fs-service-system/src/main/java/com/fs/company/service/ICompanyUserChangeApplyService.java

@@ -0,0 +1,46 @@
+package com.fs.company.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.company.domain.CompanyUserChangeApply;
+import com.fs.company.vo.CompanyUserChangeApplyVO;
+
+import java.util.List;
+import java.util.Map;
+
+public interface ICompanyUserChangeApplyService extends IService<CompanyUserChangeApply> {
+
+    /**
+     * 申请更换会员归属
+     *
+     * @param from      原归属
+     * @param to        新归属
+     * @param type      类型  0全部 1部分
+     * @param ids       会员
+     * @param companyId 公司ID
+     * @param userName  操作用户
+     */
+    void apply(Long from, Long to, Integer type, List<Long> ids, Long companyId, String userName);
+
+    /**
+     * 查询申请列表
+     * @param map 条件
+     * @return  list
+     */
+    List<CompanyUserChangeApplyVO> selectApplyListByMap(Map<String, Object> map);
+
+    /**
+     * 查询申请详情
+     * @param id    申请记录ID
+     * @return  CompanyUserChangeApplyVO
+     */
+    CompanyUserChangeApplyVO selectApplyDetailById(Long id);
+
+    /**
+     * 申请记录审核
+     * @param id        申请记录ID
+     * @param status    审核状态 1通过 2拒绝
+     * @param reason    拒绝理由
+     * @param username  审核人
+     */
+    void audit(Long id, Integer status, String reason, String username);
+}

+ 24 - 0
fs-service-system/src/main/java/com/fs/company/service/ICompanyUserChangeApplyUserService.java

@@ -0,0 +1,24 @@
+package com.fs.company.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.company.domain.CompanyUserChangeApplyUser;
+import com.fs.company.vo.CompanyUserChangeApplyUserVO;
+import com.fs.company.vo.CompanyUserVO;
+
+import java.util.List;
+
+public interface ICompanyUserChangeApplyUserService extends IService<CompanyUserChangeApplyUser> {
+
+    /**
+     * 查询申请记录关联用户
+     * @param applyId   申请记录ID
+     * @return  list
+     */
+    List<CompanyUserChangeApplyUserVO> getApplyUsers(Long applyId);
+
+    /**
+     * 修改申请记录关联用户销售
+     * @param applyId 申请记录ID
+     */
+    void changeUser(Long applyId);
+}

+ 10 - 0
fs-service-system/src/main/java/com/fs/company/service/impl/CompanyDeptServiceImpl.java

@@ -224,6 +224,16 @@ public class CompanyDeptServiceImpl implements ICompanyDeptService
         return companyDeptMapper.selectCompanyDeptNamesByIds(ids);
     }
 
+    /**
+     * 获取公司默认部门
+     * @param companyId 公司ID
+     * @return 部门
+     */
+    @Override
+    public CompanyDept getDefaultCompanyDeptByCompanyId(Long companyId) {
+        return companyDeptMapper.getTopCompanyDeptByCompanyId(companyId);
+    }
+
     /**
      * 递归列表
      */

+ 11 - 0
fs-service-system/src/main/java/com/fs/company/service/impl/CompanyServiceImpl.java

@@ -115,6 +115,17 @@ public class CompanyServiceImpl implements ICompanyService
             dept.setCreateTime(new Date());
             dept.setDeptName(company.getCompanyName());
             deptMapper.insertCompanyDept(dept);
+
+            // 创建默认部门
+            CompanyDept defaultDept = new CompanyDept();
+            defaultDept.setCompanyId(company.getCompanyId());
+            defaultDept.setParentId(dept.getDeptId());
+            defaultDept.setAncestors("0," + dept.getDeptId());
+            defaultDept.setStatus("0");
+            defaultDept.setCreateTime(new Date());
+            defaultDept.setDeptName("默认");
+            deptMapper.insertCompanyDept(defaultDept);
+
             //创建岗位
             CompanyPost post=new CompanyPost();
             post.setCompanyId(company.getCompanyId());

+ 12 - 0
fs-service-system/src/main/java/com/fs/company/service/impl/CompanyTagUserServiceImpl.java

@@ -2,12 +2,14 @@ package com.fs.company.service.impl;
 
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.company.domain.CompanyUser;
 import com.fs.company.mapper.CompanyUserMapper;
+import com.fs.company.vo.CompanyTagUserVO;
 import com.fs.store.param.h5.TagListParam;
 import com.fs.store.vo.h5.CompanyUserTagListVO;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -121,4 +123,14 @@ public class CompanyTagUserServiceImpl implements ICompanyTagUserService
 
         return companyTagUserMapper.getTagList(param, keywords, userIds);
     }
+
+    /**
+     * 根据条件查询标签下用户
+     * @param params    条件
+     * @return  list
+     */
+    @Override
+    public List<CompanyTagUserVO> selectUserListByMap(Map<String, Object> params) {
+        return companyTagUserMapper.selectUserListByMap(params);
+    }
 }

+ 145 - 0
fs-service-system/src/main/java/com/fs/company/service/impl/CompanyUserChangeApplyServiceImpl.java

@@ -0,0 +1,145 @@
+package com.fs.company.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.common.exception.ServiceException;
+import com.fs.company.domain.CompanyUserChangeApply;
+import com.fs.company.domain.CompanyUserChangeApplyUser;
+import com.fs.company.mapper.CompanyUserChangeApplyMapper;
+import com.fs.company.service.ICompanyUserChangeApplyService;
+import com.fs.company.service.ICompanyUserChangeApplyUserService;
+import com.fs.company.vo.CompanyUserChangeApplyVO;
+import com.fs.store.domain.FsUser;
+import com.fs.store.mapper.FsUserMapper;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDateTime;
+import java.util.*;
+
+@Service
+@AllArgsConstructor
+public class CompanyUserChangeApplyServiceImpl extends ServiceImpl<CompanyUserChangeApplyMapper, CompanyUserChangeApply> implements ICompanyUserChangeApplyService {
+
+    private final ICompanyUserChangeApplyUserService companyUserChangeApplyUserService;
+    private final FsUserMapper userMapper;
+
+    /**
+     * 申请更换会员归属
+     *
+     * @param from      原归属
+     * @param to        新归属
+     * @param type      类型  0全部 1部分
+     * @param ids       会员
+     * @param companyId 公司ID
+     * @param userName  操作用户
+     */
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void apply(Long from, Long to, Integer type, List<Long> ids, Long companyId, String userName) {
+        List<CompanyUserChangeApplyUser> users = new ArrayList<>();
+
+        // 全部
+        if (type == 0) {
+            FsUser param = new FsUser();
+            param.setCompanyUserId(from);
+            List<FsUser> userList = userMapper.selectFsUserList(param);
+            for (FsUser user : userList) {
+                CompanyUserChangeApplyUser uu = new CompanyUserChangeApplyUser();
+                uu.setUserId(user.getUserId());
+                users.add(uu);
+            }
+        }
+        // 部分
+        else {
+            for (Long id : ids) {
+                FsUser user = userMapper.selectFsUserById(id);
+                if (Objects.isNull(user)) {
+                    throw new ServiceException("会员不存在");
+                }
+
+                CompanyUserChangeApplyUser uu = new CompanyUserChangeApplyUser();
+                uu.setUserId(user.getUserId());
+                users.add(uu);
+            }
+        }
+
+        if (users.isEmpty()) {
+            throw new ServiceException("不存在可更换会员");
+        }
+
+        // 添加申请
+        CompanyUserChangeApply apply = new CompanyUserChangeApply();
+        apply.setCompanyId(companyId);
+        apply.setFrom(from);
+        apply.setTo(to);
+        apply.setApplyTime(LocalDateTime.now());
+        apply.setApplyBy(userName);
+        save(apply);
+
+        // 添加申请关联会员
+        users.forEach(user -> user.setApplyId(apply.getId()));
+        companyUserChangeApplyUserService.saveBatch(users);
+    }
+
+    /**
+     * 查询申请列表
+     * @param map 条件
+     * @return  list
+     */
+    @Override
+    public List<CompanyUserChangeApplyVO> selectApplyListByMap(Map<String, Object> map) {
+        List<CompanyUserChangeApplyVO> list = baseMapper.selectApplyListByMap(map);
+        list.forEach(user -> user.setUsers(companyUserChangeApplyUserService.getApplyUsers(user.getId())));
+        return list;
+    }
+
+    /**
+     * 查询申请详情
+     * @param id    申请记录ID
+     * @return  CompanyUserChangeApplyVO
+     */
+    @Override
+    public CompanyUserChangeApplyVO selectApplyDetailById(Long id) {
+        CompanyUserChangeApplyVO companyUserChangeApplyVO = baseMapper.detailById(id);
+        if (Objects.nonNull(companyUserChangeApplyVO)) {
+            companyUserChangeApplyVO.setUsers(companyUserChangeApplyUserService.getApplyUsers(id));
+        }
+        return companyUserChangeApplyVO;
+    }
+
+    /**
+     * 申请记录审核
+     * @param id        申请记录ID
+     * @param status    审核状态
+     * @param reason    拒绝理由
+     * @param username  审核人
+     */
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void audit(Long id, Integer status, String reason, String username) {
+        CompanyUserChangeApply companyUserChangeApply = baseMapper.selectById(id);
+        if (Objects.isNull(companyUserChangeApply)) {
+            throw new ServiceException("申请记录不存在");
+        }
+
+        if (companyUserChangeApply.getStatus() != 0) {
+            throw new ServiceException("请勿重复审核");
+        }
+
+        // 通过
+        if (status == 1) {
+            // 修改会员关联销售
+            companyUserChangeApplyUserService.changeUser(id);
+        }
+        // 拒绝
+        else {
+            companyUserChangeApply.setReason(reason);
+        }
+
+        companyUserChangeApply.setAuditBy(username);
+        companyUserChangeApply.setAuditTime(LocalDateTime.now());
+        companyUserChangeApply.setStatus(status);
+        baseMapper.updateById(companyUserChangeApply);
+    }
+}

+ 34 - 0
fs-service-system/src/main/java/com/fs/company/service/impl/CompanyUserChangeApplyUserServiceImpl.java

@@ -0,0 +1,34 @@
+package com.fs.company.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.company.domain.CompanyUserChangeApplyUser;
+import com.fs.company.mapper.CompanyUserChangeApplyUserMapper;
+import com.fs.company.service.ICompanyUserChangeApplyUserService;
+import com.fs.company.vo.CompanyUserChangeApplyUserVO;
+import org.springframework.stereotype.Service;
+
+import java.util.Collections;
+import java.util.List;
+
+@Service
+public class CompanyUserChangeApplyUserServiceImpl extends ServiceImpl<CompanyUserChangeApplyUserMapper, CompanyUserChangeApplyUser> implements ICompanyUserChangeApplyUserService {
+
+    /**
+     * 查询申请记录关联用户
+     * @param applyId   申请记录ID
+     * @return  list
+     */
+    @Override
+    public List<CompanyUserChangeApplyUserVO> getApplyUsers(Long applyId) {
+        return baseMapper.getApplyUsers(applyId);
+    }
+
+    /**
+     * 修改申请记录关联用户销售
+     * @param applyId 申请记录ID
+     */
+    @Override
+    public void changeUser(Long applyId) {
+        baseMapper.changeUser(applyId);
+    }
+}

+ 15 - 0
fs-service-system/src/main/java/com/fs/company/vo/CompanyTagUserVO.java

@@ -0,0 +1,15 @@
+package com.fs.company.vo;
+
+import lombok.Data;
+
+@Data
+public class CompanyTagUserVO {
+    /**
+     * 用户ID
+     */
+    private Long userId;
+    /**
+     * 用户昵称
+     */
+    private String userName;
+}

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

@@ -0,0 +1,15 @@
+package com.fs.company.vo;
+
+import lombok.Data;
+
+@Data
+public class CompanyUserChangeApplyUserVO {
+    /**
+     * 用户ID
+     */
+    private Long userId;
+    /**
+     * 用户名称
+     */
+    private String userName;
+}

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

@@ -0,0 +1,61 @@
+package com.fs.company.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Data
+public class CompanyUserChangeApplyVO {
+    /**
+     * 主键ID
+     */
+    private Long id;
+    /**
+     * 原销售
+     */
+    private Long from;
+    /**
+     * 原销售名称
+     */
+    private String fromName;
+    /**
+     * 申请更换销售
+     */
+    private Long to;
+    /**
+     * 申请更换销售名称
+     */
+    private String toName;
+    /**
+     * 状态
+     */
+    private Integer status;
+    /**
+     * 申请人
+     */
+    private String applyBy;
+    /**
+     * 申请时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime applyTime;
+    /**
+     * 审核人
+     */
+    private String auditBy;
+    /**
+     * 审核时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime auditTime;
+    /**
+     * 被拒原因
+     */
+    private String reason;
+    /**
+     * 需更换用户
+     */
+    private List<CompanyUserChangeApplyUserVO> users;
+}

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

@@ -14,6 +14,7 @@ public class CourseConfig implements Serializable {
     private Integer answerIntegral;//答题获得积分
     private Integer defaultLine;//默认看课线路
     private String realLinkDomainName;//真链域名
+    private String registerDomainName;//注册域名
     private String courseDomainName;//链接域名
     private Integer rewardType; // 奖励类型 1红包 2积分
     private Integer redPacketMode;//红包模式 1总公司 2销售公司

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

@@ -152,6 +152,6 @@ public interface FsCourseRedPacketLogMapper
      * @param companyUserId 销售ID
      * @return amount
      */
-    @Select("select sum(fcrpl.amount) from fs_course_red_packet_log fcrpl where fcrpl.company_user_id = #{companyUserId}")
+    @Select("select ifnull(sum(fcrpl.amount), 0) from fs_course_red_packet_log fcrpl where fcrpl.company_user_id = #{companyUserId}")
     BigDecimal getSumByCompanyUserIdId(@Param("companyUserId") Long companyUserId);
 }

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

@@ -7,7 +7,6 @@ import com.fs.course.domain.FsUserCourseVideo;
 import com.fs.course.param.FsUserCourseVideoListUParam;
 import com.fs.course.param.FsUserCourseVideoParam;
 import com.fs.course.param.newfs.UserCourseVideoPageParam;
-import com.fs.course.vo.FsCourseAnalysisVO;
 import com.fs.course.vo.FsUserCourseVideoListUVO;
 import com.fs.course.vo.FsUserCourseVideoVO;
 import com.fs.course.vo.newfs.FsUserCourseVideoPageListVO;
@@ -167,10 +166,4 @@ public interface FsUserCourseVideoMapper
 
     List<FsUserCourseVideoPageListVO> selectFsUserCourseVideoPageList(UserCourseVideoPageParam param);
 
-    /**
-     * 获取课程分析数据
-     * @param params 参数
-     * @return list
-     */
-    List<FsCourseAnalysisVO> getCourseAnalysisByMap(@Param("params") Map<String, Object> params);
 }

+ 5 - 0
fs-service-system/src/main/java/com/fs/course/param/newfs/UserCourseVideoPageParam.java

@@ -23,6 +23,11 @@ public class UserCourseVideoPageParam implements Serializable {
     @ApiModelProperty(value = "课程id")
     private Long courseId;
 
+    @ApiModelProperty(value = "公司id")
+    private Long companyId;
+
+
+
 //    @ApiModelProperty(value = "视频状态 1:草稿,2:待审核,3:发布")
 //    private Long status;
 

+ 6 - 7
fs-service-system/src/main/java/com/fs/course/service/IFsUserCourseVideoService.java

@@ -5,12 +5,12 @@ import com.fs.common.core.domain.ResponseResult;
 import com.fs.course.domain.FsUserCourseVideo;
 import com.fs.course.param.*;
 import com.fs.course.param.newfs.UserCourseVideoPageParam;
-import com.fs.course.vo.FsCourseAnalysisVO;
 import com.fs.course.vo.FsUserCourseVideoListUVO;
 import com.fs.course.vo.newfs.FsUserCourseVideoDetailsVO;
 import com.fs.course.vo.newfs.FsUserCourseVideoPageListVO;
 import com.fs.course.vo.FsUserCourseVideoQVO;
 import com.fs.course.vo.FsUserCourseVideoVO;
+import com.fs.course.vo.newfs.FsUserVideoListVO;
 
 import java.util.List;
 import java.util.Map;
@@ -106,13 +106,12 @@ public interface IFsUserCourseVideoService
      */
     ResponseResult<FsUserCourseVideoDetailsVO> getVideoDetails(Long videoId);
 
+    R registerCourse(FsUserCourseRegisterParam param);
+
     /**
-     * 获取课程分析数据
-     * @param params
+     * 获取下拉视频列表(有分页,仅返回两个字段)
+     * @param param 
      * @return list
      */
-    List<FsCourseAnalysisVO> getCourseAnalysisByMap(Map<String, Object> params);
-
-
-    R registerCourse(FsUserCourseRegisterParam param);
+    List<FsUserVideoListVO> getListCourseVideo(UserCourseVideoPageParam param);
 }

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

@@ -16,12 +16,12 @@ import com.fs.course.mapper.*;
 import com.fs.course.param.*;
 import com.fs.course.param.newfs.UserCourseVideoPageParam;
 import com.fs.course.service.IFsUserCourseVideoService;
-import com.fs.course.vo.FsCourseAnalysisVO;
 import com.fs.course.vo.FsUserCourseVideoListUVO;
 import com.fs.course.vo.FsUserCourseVideoQVO;
 import com.fs.course.vo.FsUserCourseVideoVO;
 import com.fs.course.vo.newfs.FsUserCourseVideoDetailsVO;
 import com.fs.course.vo.newfs.FsUserCourseVideoPageListVO;
+import com.fs.course.vo.newfs.FsUserVideoListVO;
 import com.fs.course.vo.newfs.FsUserVideoQuestionVO;
 import com.fs.his.param.WxSendRedPacketParam;
 import com.fs.sop.mapper.SopUserLogsInfoMapper;
@@ -742,16 +742,6 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         return ResponseResult.ok(fsUserCourseVideoDetailsVO);
     }
 
-    /**
-     * 获取课程分析数据
-     * @param params 参数
-     * @return list
-     */
-    @Override
-    public List<FsCourseAnalysisVO> getCourseAnalysisByMap(Map<String, Object> params) {
-        return fsUserCourseVideoMapper.getCourseAnalysisByMap(params);
-    }
-
     @Autowired
     SopUserLogsInfoMapper sopUserLogsInfoMapper;
 
@@ -759,7 +749,11 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
     public R registerCourse(FsUserCourseRegisterParam param) {
 
 
-        FsUser fsUser = fsUserMapper.selectFsUserByUserId(param.getUserId());
+        FsUser fsUser = fsUserMapper.selectFsUserById(param.getUserId());
+        if (fsUser==null){
+            return R.error("未登录成功");
+        }
+        logger.info(""+fsUser);
         if (fsUser.getIsAddQw()==1){
             return R.error("已经注册");
         }
@@ -775,11 +769,21 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         QwExternalContact qw = new QwExternalContact();
         qw.setFsUserId(fsUser.getUserId());
         qw.setId(qwExternalContact.getId());
-        qwExternalContactMapper.updateQwExternalContactByExternalUserId(qw);
+        qwExternalContactMapper.updateById(qw);
         List<String> list= sopUserLogsInfoMapper.selectSopUserLogsInfoByExtId(qwExternalContact.getId());
         if (list!=null&& !list.isEmpty()){
             sopUserLogsInfoMapper.updateSopUserLogsInfoFsUserIdById(list,param.getUserId());
         }
         return R.ok();
     }
+
+    @Override
+    public List<FsUserVideoListVO> getListCourseVideo(UserCourseVideoPageParam param) {
+        List<FsUserCourseVideoPageListVO> list = fsUserCourseVideoMapper.selectFsUserCourseVideoPageList(param);
+        return list.stream().map(v -> {
+            FsUserVideoListVO videoListVO = new FsUserVideoListVO();
+            BeanUtils.copyProperties(v, videoListVO);
+            return videoListVO;
+        }).collect(Collectors.toList());
+    }
 }

+ 0 - 61
fs-service-system/src/main/java/com/fs/course/vo/FsCourseAnalysisVO.java

@@ -1,61 +0,0 @@
-package com.fs.course.vo;
-
-import lombok.Data;
-
-import java.math.BigDecimal;
-
-@Data
-public class FsCourseAnalysisVO {
-    /**
-     * 课程ID
-     */
-    private Long courseId;
-    /**
-     * 课程名称
-     */
-    private String courseName;
-    /**
-     * 标题
-     */
-    private String title;
-    /**
-     * 封面
-     */
-    private String imgUrl;
-    /**
-     * 课程描述
-     */
-    private String description;
-    /**
-     * 观看人数
-     */
-    private Long viewUsers;
-    /**
-     * 完播人数
-     */
-    private Long finishUsers;
-    /**
-     * 完播率
-     */
-    private Long finishRate;
-    /**
-     * 答题红包数
-     */
-    private Long redPacketCount;
-    /**
-     * 答题红包金额
-     */
-    private BigDecimal redPacketAmount;
-    /**
-     * 答题人数
-     */
-    private Long answerUsers;
-    /**
-     * 正确人数
-     */
-    private Long correctUsers;
-    /**
-     * 正确率
-     */
-    private Long correctRate;
-}

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

@@ -5,9 +5,6 @@ import lombok.Data;
 
 /**
  * 课程下拉列表 对象(需要分页)
- *
- * @author fs
- * @date 2024-05-15
  */
 @Data
 public class FsUserCourseListVO {

+ 19 - 0
fs-service-system/src/main/java/com/fs/course/vo/newfs/FsUserVideoListVO.java

@@ -0,0 +1,19 @@
+package com.fs.course.vo.newfs;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 视频下拉列表 对象(需要分页)
+ *
+ */
+@Data
+public class FsUserVideoListVO {
+
+    @ApiModelProperty(value = "视频id")
+    private Long videoId;
+
+    @ApiModelProperty(value = "视频名称")
+    private String title;
+
+}

+ 45 - 23
fs-service-system/src/main/java/com/fs/qw/service/impl/QwExternalContactServiceImpl.java

@@ -12,6 +12,7 @@ import com.fs.common.core.redis.RedisCache;
 import com.fs.common.utils.PubFun;
 import com.fs.common.utils.StringUtils;
 import com.fs.company.service.ICompanyConfigService;
+import com.fs.course.config.CourseConfig;
 import com.fs.course.domain.FsCourseSop;
 import com.fs.course.domain.FsCourseSopLogs;
 import com.fs.course.domain.FsCourseWatchLog;
@@ -90,6 +91,7 @@ import java.util.stream.Stream;
 public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactMapper, QwExternalContact> implements IQwExternalContactService {
 
     private static final String miniappRealLink = "/pages_course/video.html?course=";
+    private static final String registerLink = "/registerCourse/pages/index?qwExternalId=";
 
     @Autowired
     private QwExternalContactMapper qwExternalContactMapper;
@@ -133,6 +135,7 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
     @Autowired
     private FsCourseLinkMapper fsCourseLinkMapper;
 
+
     @Autowired
     QwAutoTagsMapper qwAutoTagsMapper;
     @Autowired
@@ -1207,6 +1210,11 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
         QwContactWay wayId = null;
         SysConfig sysConfig = sysConfigService.selectConfigByConfigKey("qw.config");
         QwConfig qwConfig = JSON.parseObject(sysConfig.getConfigValue(), QwConfig.class);
+
+//
+//        String json = sysConfigService.selectConfigByKey("course.config");
+//        QwConfig qwConfig = JSON.parseObject(json, QwConfig.class);
+
         //先入客户
         QwExternalContact qwExternalContact = qwExternalContactMapper.selectQwExternalByExternalIdAndCompanyIdToIdAndFs(externalUserID, userID, corpId);
         boolean isNewQwExternalContact = qwExternalContact == null ? true : false;
@@ -2633,6 +2641,9 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
             return attachments;
         }
 
+        String json = sysConfigService.selectConfigByKey("course.config");
+        CourseConfig config = JSON.parseObject(json, CourseConfig.class);
+
         attachments.forEach(att -> {
             // 生成短链的条件判断
             if ("link".equals(att.getMsgtype())
@@ -2640,30 +2651,41 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
                     && !StringUtil.strIsNullOrEmpty(att.getLink().getVideoId())) {
 
                 try {
-                    FsCourseLinkCreateParam param = new FsCourseLinkCreateParam();
-                    param.setVideoId(Long.valueOf(att.getLink().getVideoId()));
-                    param.setQwUserId(String.valueOf(qwUser.getId()));
-                    param.setDays(att.getLink().getExpiresDays());
-                    param.setCorpId(corpId);
-                    param.setCourseId(Long.valueOf(att.getLink().getCourseId()));
-                    param.setCompanyUserId(qwUser.getCompanyUserId());
-                    param.setCompanyId(qwUser.getCompanyId());
-                    param.setQwExternalId(qwExternalId);
-                    param.setSendTime(new Date());
-
-                    // 调用服务生成短链
-                    R linkUrl = iFsCourseLinkService.createLinkUrlWc(param);
-
-                    if (linkUrl != null && linkUrl.get("url") != null) {
-                        att.getLink().setUrl(linkUrl.get("url").toString());
+                    //发课程
+                    if (att.getLink().getIsFixed()==0){
+                        FsCourseLinkCreateParam param = new FsCourseLinkCreateParam();
+                        param.setVideoId(Long.valueOf(att.getLink().getVideoId()));
+                        param.setQwUserId(String.valueOf(qwUser.getId()));
+                        param.setDays(att.getLink().getExpiresDays());
+                        param.setCorpId(corpId);
+                        param.setCourseId(Long.valueOf(att.getLink().getCourseId()));
+                        param.setCompanyUserId(qwUser.getCompanyUserId());
+                        param.setCompanyId(qwUser.getCompanyId());
+                        param.setQwExternalId(qwExternalId);
+                        param.setSendTime(new Date());
+
+                        // 调用服务生成短链
+                        R linkUrl = iFsCourseLinkService.createLinkUrlWc(param);
+
+                        if (linkUrl != null && linkUrl.get("url") != null) {
+                            att.getLink().setUrl(linkUrl.get("url").toString());
+                        }
+                        //生成观看记录
+                        addWatchLogIfNeeded(Integer.valueOf(att.getLink().getVideoId()),
+                                Integer.valueOf(att.getLink().getCourseId()),
+                                String.valueOf(qwUser.getId()),
+                                String.valueOf(qwUser.getCompanyUserId()),
+                                String.valueOf(qwUser.getCompanyId()),
+                                String.valueOf(qwExternalId));
+                    }else if (att.getLink().getIsFixed()==1){
+
+                        if (config != null) {
+                            att.getLink().setUrl(config.getRegisterDomainName()+registerLink+qwExternalId);
+                        }else {
+                            logger.error("企业配置信息为空:发送注册链接失败");
+                        }
                     }
-                    //生成观看记录
-                    addWatchLogIfNeeded(Integer.valueOf(att.getLink().getVideoId()),
-                            Integer.valueOf(att.getLink().getCourseId()),
-                            String.valueOf(qwUser.getId()),
-                            String.valueOf(qwUser.getCompanyUserId()),
-                            String.valueOf(qwUser.getCompanyId()),
-                            String.valueOf(qwExternalId));
+
 
                 } catch (Exception e) {
                     logger.error("欢迎语生成短链失败:", e);

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

@@ -54,6 +54,9 @@ public class QwFriendWelcomeServiceImpl implements IQwFriendWelcomeService
     @Autowired
     private QwApiService qwApiService;
 
+
+    private static final String registerLink = "/registerCourse/pages/index?qwExternalId=";
+
     /**
      * 查询好友欢迎语
      *
@@ -148,7 +151,6 @@ public class QwFriendWelcomeServiceImpl implements IQwFriendWelcomeService
                                 return R.error("图片link上传失败:"+uploadimg.getErrMsg());
                             }
 
-
                         } catch (Exception e) {
                             return R.error("图片link上传出错:"+e);
 //                            throw new RuntimeException("insertQwFriendWelcomeVO-attachment/link:"+e);

+ 1 - 0
fs-service-system/src/main/java/com/fs/qwApi/param/SendWelcomeMsgParam.java

@@ -36,6 +36,7 @@ public class SendWelcomeMsgParam {
             private String courseId; // 链接的课程id
             private String videoId; // 链接的课节id
             private Integer expiresDays; // 链接的过期时间
+            private Integer isFixed; // 链接的过期时间
         }
         @Data
         // 用于小程序附件

+ 8 - 1
fs-service-system/src/main/java/com/fs/sop/service/impl/QwSopLogsServiceImpl.java

@@ -1082,7 +1082,14 @@ public class QwSopLogsServiceImpl implements IQwSopLogsService
     @Override
     public QwExternalContactByQwResult getExternalContactByAppKey(String appKey) {
 
-        return  qwExternalContactMapper.getExternalContactByAppKey(appKey);
+//        qwExternalContactMapper.getExternalContactByAppKey(appKey);
+
+
+        QwExternalContactByQwResult contactByQwResult=new QwExternalContactByQwResult();
+        contactByQwResult.setExternalUserId("111222333444555666");
+        contactByQwResult.setName("你好");
+
+        return  contactByQwResult;
     }
 
     //

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

@@ -66,6 +66,7 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
     private static final String miniappRealLink = "/pages_course/video.html?course=";
     private static final String appRealLink = "/pages/courseAnswer/index?link=";
     private static final String appLink = "https://jump.ylrztop.com/jumpapp/pages/index/index?link=";
+    private static final String registerLink = "/registerCourse/pages/index?qwExternalId=";
 //    private static final String miniappRealLink = "/pages/index/index?course=";
 
     @Autowired
@@ -493,6 +494,10 @@ public class SopUserLogsInfoServiceImpl implements ISopUserLogsInfoService {
                         st.setLinkUrl(linkByApp.getSortLink());
                         st.setAppLinkUrl(linkByApp.getAppMsgLink());
 
+                        break;
+                    //注册链接
+                    case "10":
+                        st.setLinkUrl(config.getRegisterDomainName()+registerLink+item.getExternalId());
                         break;
                     default:
                         break;

+ 7 - 3
fs-service-system/src/main/java/com/fs/store/mapper/FsUserMapper.java

@@ -247,10 +247,14 @@ public interface FsUserMapper
 
     Map<String, Object> countUserRedPacket(@Param("userId") Long userId, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("courseId")String courseId, @Param("videoId")String videoId);
 
-    Map<String, Long> countCourseDetails(@Param("userId") Long userId, @Param("courseId")String courseId, @Param("videoId")String videoId);
+    Map<String, Long> countCourseDetails(@Param("userId") Long userId, @Param("courseId")String courseId, @Param("videoId")String videoId,  @Param("companyId")Long companyId);
 
-    FsUserRankingVO countUserRanking(@Param("userId") Long userId, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("courseId")String courseId, @Param("videoId")String videoId, @Param("order")String order);
+    List<FsUserRankingVO> countUserRankingByComplete(@Param("userId") Long userId, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("courseId")String courseId, @Param("videoId")String videoId, @Param("order")String order);
 
-    FsUserRankingVO countCourseRanking(@Param("userId") Long userId, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("courseId")String courseId, @Param("videoId")String videoId, @Param("order")String order);
+    List<FsUserRankingVO> countUserRankingByRight(@Param("userId") Long userId, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("courseId")String courseId, @Param("videoId")String videoId, @Param("order")String order);
+
+    List<FsCourseRankingVO> countCourseRankingByComplete(@Param("userId") Long userId, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("courseId")String courseId, @Param("videoId")String videoId, @Param("order")String order);
+
+    List<FsCourseRankingVO> countCourseRankingByRight(@Param("userId") Long userId, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("courseId")String courseId, @Param("videoId")String videoId, @Param("order")String order);
 
 }

+ 58 - 2
fs-service-system/src/main/java/com/fs/store/service/IFsUserService.java

@@ -154,12 +154,68 @@ public interface IFsUserService
      */
     Map<String, Long> getUserVipCountByCompanyUserId(Long companyUserId);
 
+    /**
+     * 首页-获取用户总数
+     * @param userId 登录用户id
+     * @return vo
+     */
     FsUserSummaryCountVO userSummaryCount(Long userId);
 
+    /**
+     * 首页数据统计-课程、答题、红包统计
+     * @param userId 登录用户id
+     * @param startTime 开始时间
+     * @param endTime 结束时间
+     * @param courseId 课程id
+     * @param videoId 视频id
+     * @return vo
+     */
     FsUserStatisticsVO userStatistics(Long userId, String startTime, String endTime, String courseId, String videoId);
 
-    FsUserStatisticsVO userStatisticsDetails(Long userId, String courseId, String videoId);
+    /**
+     * 数据详情统计-根据课程id 视频id进行详情统计
+     * @param userId 登录用户id
+     * @param courseId 课程id
+     * @param videoId 视频id
+     * @return vo
+     */
+    FsUserStatisticsVO userStatisticsDetails(Long userId, String courseId, String videoId, Long companyId);
 
-    FsUserRankingVO userRanking(Long userId, String startTime, String endTime, String courseId, String videoId, String order, Integer type);
+    /**
+     * 首页数据/详情-获取群管排行榜统计
+     * @param userId 登录用户id
+     * @param startTime 开始时间
+     * @param endTime 结束时间
+     * @param courseId 课程id
+     * @param videoId 视频id
+     * @param order 排序,asc-正序,desc-倒序
+     * @param type 类型,1-按完播率,2-按正确率
+     * @return vo
+     */
+    List<FsUserRankingVO> userRanking(Long userId, String startTime, String endTime, String courseId, String videoId, String order, Integer type);
+
+    /**
+     * 首页数据/详情-获取课程排行榜统计
+     * @param userId 登录用户id
+     * @param startTime 开始时间
+     * @param endTime 结束时间
+     * @param courseId 课程id
+     * @param videoId 视频id
+     * @param order 排序,asc-正序,desc-倒序
+     * @param type 类型,1-按完播率,2-按正确率
+     * @return vo
+     */
+    List<FsCourseRankingVO> courseRanking(Long userId, String startTime, String endTime, String courseId, String videoId, String order, Integer type);
+
+    /**
+     *
+     * @param userId 用户id
+     * @param startTime 开始时间
+     * @param endTime 结束时间
+     * @param courseId 课程id
+     * @param videoId 视频id
+     * @return
+     */
+    List<FsUserGraphicStatisticsVO> graphicStatistics(Long userId, String startTime, String endTime, String courseId, String videoId);
 
 }

+ 33 - 11
fs-service-system/src/main/java/com/fs/store/service/impl/FsUserServiceImpl.java

@@ -2,10 +2,7 @@ package com.fs.store.service.impl;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.stream.Collectors;
 
 
@@ -528,11 +525,11 @@ public class FsUserServiceImpl implements IFsUserService
     }
 
     @Override
-    public FsUserStatisticsVO userStatisticsDetails(Long userId, String courseId, String videoId) {
+    public FsUserStatisticsVO userStatisticsDetails(Long userId, String courseId, String videoId, Long companyId) {
         FsUserStatisticsVO userStatisticsVO = getUserStatistics(userId, null, null, courseId, videoId);
 
         //统计课程数据详情,在查询统计详情的时候需要显示
-        Map<String, Long> courseDetailsMap = fsUserMapper.countCourseDetails(userId, courseId, videoId);
+        Map<String, Long> courseDetailsMap = fsUserMapper.countCourseDetails(userId, courseId, videoId, companyId);
         if(courseDetailsMap != null && courseDetailsMap.get("courseNum") != null && courseDetailsMap.get("videoNum") != null && courseDetailsMap.get("courseUserNum") != null){
             userStatisticsVO.setCourseNum(Integer.parseInt(courseDetailsMap.get("courseNum").toString()))
                     .setVideoNum(Integer.parseInt(courseDetailsMap.get("videoNum").toString()))
@@ -542,16 +539,41 @@ public class FsUserServiceImpl implements IFsUserService
     }
 
     @Override
-    public FsUserRankingVO userRanking(Long userId, String startTime, String endTime, String courseId, String videoId, String order, Integer type) {
-        FsUserRankingVO fsUserRankingVO = null;
+    public List<FsUserRankingVO> userRanking(Long userId, String startTime, String endTime, String courseId, String videoId, String order, Integer type) {
+        List<FsUserRankingVO> listVO = Collections.emptyList();
         if(type == 1){
             //按完播率
-             fsUserRankingVO = fsUserMapper.countUserRanking(userId, startTime, endTime, courseId, videoId, order);
+            listVO = fsUserMapper.countUserRankingByComplete(userId, startTime, endTime, courseId, videoId, order);
         }
         if(type == 2){
             //按正确率
-             fsUserRankingVO = fsUserMapper.countCourseRanking(userId, startTime, endTime, courseId, videoId, order);
+            listVO = fsUserMapper.countUserRankingByRight(userId, startTime, endTime, courseId, videoId, order);
         }
-        return fsUserRankingVO;
+        return listVO;
+    }
+
+    @Override
+    public List<FsCourseRankingVO> courseRanking(Long userId, String startTime, String endTime, String courseId, String videoId, String order, Integer type) {
+        List<FsCourseRankingVO> list = Collections.emptyList();
+        if(type == 1){
+            list = fsUserMapper.countCourseRankingByComplete(userId, startTime, endTime, courseId, videoId, order);
+        }
+        if(type == 2){
+            list = fsUserMapper.countCourseRankingByRight(userId, startTime, endTime, courseId, videoId, order);
+        }
+
+        return list;
+    }
+
+    @Override
+    public List<FsUserGraphicStatisticsVO> graphicStatistics(Long userId, String startTime, String endTime, String courseId, String videoId) {
+        FsUserStatisticsVO userStatistics = getUserStatistics(userId, startTime, endTime, courseId, videoId);
+        List<FsUserGraphicStatisticsVO> list = new ArrayList<>();
+        list.add(new FsUserGraphicStatisticsVO("观看人数",userStatistics.getCourseWatchNum(), userStatistics.getCourseWatchNum()));
+        list.add(new FsUserGraphicStatisticsVO("完播人数", userStatistics.getCourseCompleteNum(), userStatistics.getCourseCompleteNum()));
+        list.add(new FsUserGraphicStatisticsVO("答题人数", userStatistics.getAnswerNum(), userStatistics.getAnswerNum()));
+        list.add(new FsUserGraphicStatisticsVO("正确人数", userStatistics.getAnswerRightNum(), userStatistics.getAnswerRightNum()));
+        list.add(new FsUserGraphicStatisticsVO("答题红包数", userStatistics.getRedPacketNum(), userStatistics.getRedPacketNum()));
+        return list;
     }
 }

+ 27 - 0
fs-service-system/src/main/java/com/fs/store/vo/h5/FsCourseRankingVO.java

@@ -0,0 +1,27 @@
+package com.fs.store.vo.h5;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.math.BigDecimal;
+
+/**
+ * 首页-销售数据排行榜
+ */
+@Data
+@ApiModel
+@Accessors(chain = true)
+public class FsCourseRankingVO {
+
+    @ApiModelProperty(value = "课程名称")
+    private String videoName;
+
+    @ApiModelProperty(value = "完播率")
+    private BigDecimal completeRate;
+
+    @ApiModelProperty(value = "正确率")
+    private BigDecimal answerRightRate;
+
+}

+ 34 - 0
fs-service-system/src/main/java/com/fs/store/vo/h5/FsUserGraphicStatisticsVO.java

@@ -0,0 +1,34 @@
+package com.fs.store.vo.h5;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * 首页-漏斗图统计
+ */
+@Data
+@ApiModel
+@Accessors(chain = true)
+public class FsUserGraphicStatisticsVO {
+
+    @ApiModelProperty(value = "统计名称")
+    private String name;
+
+    @ApiModelProperty(value = "显示文本值")
+    private int contextValue;
+
+    @ApiModelProperty(value = "统计值")
+    private int value;
+
+    public FsUserGraphicStatisticsVO() {
+
+    }
+
+    public FsUserGraphicStatisticsVO(String name, int contextValue, int value) {
+        this.name = name;
+        this.contextValue = contextValue;
+        this.value = value;
+    }
+}

+ 1 - 1
fs-service-system/src/main/java/com/fs/store/vo/h5/FsUserRankingVO.java

@@ -16,7 +16,7 @@ import java.math.BigDecimal;
 public class FsUserRankingVO {
 
     @ApiModelProperty(value = "销售名称")
-    private int userName;
+    private String userName;
 
     @ApiModelProperty(value = "完播率")
     private BigDecimal completeRate;

+ 3 - 3
fs-service-system/src/main/java/com/fs/store/vo/h5/FsUserStatisticsVO.java

@@ -15,13 +15,13 @@ import java.math.BigDecimal;
 @Accessors(chain = true)
 public class FsUserStatisticsVO {
 
-    @ApiModelProperty(value = "观看人数")
+    @ApiModelProperty(value = "课程统计-观看人数")
     private int courseWatchNum;
 
-    @ApiModelProperty(value = "完播人数")
+    @ApiModelProperty(value = "课程统计-完播人数")
     private int courseCompleteNum;
 
-    @ApiModelProperty(value = "完播率")
+    @ApiModelProperty(value = "课程统计-完播率")
     private int courseCompleteRate;
 
 

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

@@ -95,4 +95,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </if>
     </select>
 
+    <!-- 根据条件查询标签下用户 -->
+    <select id="selectUserListByMap" resultType="com.fs.company.vo.CompanyTagUserVO">
+        select
+            fu.user_id,
+            fu.nickname as userName
+        from company_tag_user ctu
+        inner join fs_user fu on fu.user_id = ctu.user_id
+        where ctu.company_id = #{params.companyId} and find_in_set(#{params.tagId}, ctu.tag_ids)
+    </select>
+
 </mapper>

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

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.company.mapper.CompanyUserChangeApplyMapper">
+
+    <resultMap id="applyMap" type="CompanyUserChangeApplyVO">
+    </resultMap>
+
+    <sql id="applySQL">
+        select
+            cuca.*,
+            fu.user_name fromName,
+            tu.user_name toName
+        from company_user_change_apply cuca
+        left join company_user fu on fu.user_id = cuca.`from`
+        left join company_user tu on tu.user_id = cuca.`to`
+    </sql>
+
+    <!-- 查询申请列表 -->
+    <select id="selectApplyListByMap" resultMap="applyMap">
+        <include refid="applySQL"/>
+        <where>
+            <if test="map.status != null">
+                cuca.status = #{map.status}
+            </if>
+            <if test="map.companyId != null">
+                and cuca.company_id = #{map.companyId}
+            </if>
+        </where>
+    </select>
+
+    <!-- 查询申请详情 -->
+    <select id="detailById" resultMap="applyMap">
+        <include refid="applySQL"/>
+        where cuca.id = #{id}
+    </select>
+</mapper>

+ 25 - 0
fs-service-system/src/main/resources/mapper/company/CompanyUserChangeApplyUserMapper.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.company.mapper.CompanyUserChangeApplyUserMapper">
+
+    <!-- 查询申请记录关联用户 -->
+    <select id="getApplyUsers" resultType="com.fs.company.vo.CompanyUserChangeApplyUserVO">
+        select
+            fu.user_id,
+            fu.nickname as userName
+        from company_user_change_apply_user cucau
+        inner join fs_user fu on fu.user_id = cucau.user_id
+        where cucau.apply_id = #{applyId}
+    </select>
+
+    <!-- 修改申请记录关联用户销售 -->
+    <update id="changeUser">
+        update fs_user fu
+        inner join company_user_change_apply_user cucau on cucau.user_id = fu.user_id
+        left join company_user_change_apply cuca on cuca.id = cucau.apply_id
+        set fu.company_user_id = cuca.`to`
+        where cuca.id = #{applyId}
+    </update>
+</mapper>

+ 2 - 11
fs-service-system/src/main/resources/mapper/course/FsUserCourseVideoMapper.xml

@@ -180,6 +180,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         FROM `fs_user_course_video` video
         LEFT JOIN fs_user_course course ON video.course_id = course.course_id
         where 1 = 1
+        and course.is_del = 0
+        AND FIND_IN_SET(#{companyId}, course.company_ids)
         <if test="courseId != null and courseId !='' ">
             AND video.course_id = #{courseId}
         </if>
@@ -189,15 +191,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         order by video.course_sort
     </select>
 
-    <!-- 获取课程分析数据 -->
-    <select id="getCourseAnalysisByMap" resultType="com.fs.course.vo.FsCourseAnalysisVO">
-        select
-            fuc.course_id,
-            fuc.course_name,
-            fucv.title,
-            fuc.img_url,
-            fucv.description
-        from fs_user_course_video fucv
-        left join fs_user_course fuc on fuc.course_id = fucv.course_id
-    </select>
 </mapper>

+ 134 - 15
fs-service-system/src/main/resources/mapper/store/FsUserMapper.xml

@@ -43,6 +43,7 @@
         <result property="userCode" column="user_code"/>
         <result property="isShow" column="is_show"/>
         <result property="qwExtId"    column="qw_ext_id"    />
+        <result property="isAddQw"    column="is_add_qw"    />
     </resultMap>
 
     <sql id="selectFsUserVo">
@@ -80,6 +81,7 @@
                is_del,
                is_weixin_auth,
                company_id,
+               is_add_qw,
                company_user_id,
                register_date,
                register_code,
@@ -261,6 +263,7 @@
             <if test="userCode != null">user_code,</if>
             <if test="isShow != null">is_show,</if>
             <if test="qwExtId != null">qw_ext_id,</if>
+            <if test="isAddQw != null">is_add_qw,</if>
         </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="username != null">#{username},</if>
@@ -301,6 +304,7 @@
             <if test="userCode != null">#{userCode},</if>
             <if test="isShow != null">#{isShow},</if>
             <if test="qwExtId != null">#{qwExtId},</if>
+            <if test="isAddQw != null">#{isAddQw},</if>
         </trim>
     </insert>
 
@@ -345,6 +349,7 @@
             <if test="userCode != null">user_code = #{userCode},</if>
             <if test="isShow != null">is_show = #{isShow},</if>
             <if test="qwExtId != null">qw_ext_id = #{qwExtId},</if>
+            <if test="isAddQw != null">is_add_qw = #{isAddQw},</if>
         </trim>
         where user_id = #{userId}
     </update>
@@ -643,7 +648,7 @@
         SELECT
             (
                 SELECT
-                    count( fcc.user_id )
+                    count(distinct fcc.user_id )
                 FROM
                     fs_user_course_count fcc
                         LEFT JOIN fs_user ON fs_user.user_id = fcc.user_id
@@ -666,7 +671,7 @@
             ) as courseWatchNum,
             (
                 SELECT
-                    count( fcc.user_id )
+                    count(distinct fcc.user_id )
                 FROM
                     fs_user_course_count fcc
                         LEFT JOIN fs_user ON fs_user.user_id = fcc.user_id
@@ -694,7 +699,7 @@
         SELECT
         (
         SELECT
-        count( fs_user.user_id )
+        count(distinct fs_user.user_id )
         FROM
         fs_course_answer_logs
         LEFT JOIN fs_user ON fs_user.user_id = fs_course_answer_logs.user_id
@@ -716,7 +721,7 @@
         ) AS answerNum,
         (
         SELECT
-        count( fs_user.user_id )
+        count(distinct fs_user.user_id )
         FROM
         fs_course_answer_logs
         LEFT JOIN fs_user ON fs_user.user_id = fs_course_answer_logs.user_id
@@ -788,17 +793,20 @@
     </select>
 
     <select id="countCourseDetails" resultType="Map">
-    select (SELECT count(fc.course_id)
+    select (SELECT count(DISTINCT fc.course_id)
             FROM fs_user_course fc
             WHERE fc.is_del = 0
+            AND FIND_IN_SET(#{companyId}, fc.company_ids)
             <if test="courseId != null and courseId != ''">
                 AND fc.course_id =  #{courseId}
             </if>
             ) as courseNum,
 
-           (SELECT count(fcv.video_id)
+           (SELECT count(DISTINCT fcv.video_id)
             FROM fs_user_course_video fcv
                      LEFT JOIN fs_user_course fc ON fc.course_id = fcv.course_id
+            WHERE fc.is_del = 0
+            AND FIND_IN_SET(#{companyId}, fc.company_ids)
             <if test="courseId != null and courseId != ''">
                 AND fcv.course_id =  #{courseId}
             </if>
@@ -806,7 +814,7 @@
                 AND fcv.video_id = #{videoId}
             </if>
             ) as videoNum,
-        ( SELECT count( user_id ) FROM fs_user_course_count fcc
+        ( SELECT count(DISTINCT user_id ) FROM fs_user_course_count fcc
             LEFT JOIN fs_user_course_video fcv ON fcv.course_id = fcc.course_id
         <if test="courseId != null and courseId != ''">
             AND fcc.course_id =  #{courseId}
@@ -817,11 +825,11 @@
          ) as courseUserNum
     </select>
 
-    <select id="countUserRanking" resultType="FsUserRankingVO">
+    <select id="countUserRankingByComplete" resultType="FsUserRankingVO">
         SELECT
         company_user.nick_name as userName,
         ifnull(
-            ROUND((COUNT( CASE WHEN fcc.complete_watch_count > 0 THEN 1 END ) / count( fcc.user_id ))*100,2),0
+            ROUND((COUNT(DISTINCT CASE WHEN fcc.complete_watch_count > 0 THEN 1 END ) / count(1))*100,2),0
         ) as completeRate
         FROM
         fs_user_course_count fcc
@@ -829,7 +837,7 @@
         LEFT JOIN company_user ON fs_user.company_user_id = company_user.user_id
         LEFT JOIN fs_user_course_video fcv ON fcv.course_id = fcc.course_id
         WHERE
-        company_user.parent_id = #{userId}
+        ( company_user.user_id = #{userId} OR company_user.parent_id = #{userId} )
         <if test="startTime != null and startTime !='' ">
             AND fcc.create_time &gt;= #{startTime}
         </if>
@@ -843,15 +851,25 @@
             AND fcv.video_id = #{videoId}
         </if>
         group by fcc.user_id
-        order by completeRate #{order}
+        <choose>
+            <when test="order != null and order == 'asc'">
+                order by completeRate asc
+            </when>
+            <when test="order != null and order == 'desc'">
+                order by completeRate desc
+            </when>
+            <otherwise>
+                order by completeRate desc
+            </otherwise>
+        </choose>
         limit 20
     </select>
 
-    <select id="countCourseRanking" resultType="FsUserRankingVO">
+    <select id="countUserRankingByRight" resultType="FsUserRankingVO">
         SELECT
             company_user.nick_name as userName,
             ifnull(ROUND(
-                           (COUNT( CASE WHEN fs_course_answer_logs.is_right = 1 THEN 1 END ) / count( fs_user.user_id ))
+                           (COUNT(DISTINCT CASE WHEN fs_course_answer_logs.is_right = 1 THEN 1 END ) / count(1))
                                *100,2),0
             ) as answerRightRate
         FROM
@@ -859,7 +877,7 @@
                 LEFT JOIN fs_user ON fs_user.user_id = fs_course_answer_logs.user_id
                 LEFT JOIN company_user ON company_user.user_id = fs_user.company_user_id
         WHERE
-            company_user.parent_id = #{userId}
+        ( company_user.user_id = #{userId} OR company_user.parent_id = #{userId} )
             <if test="startTime != null and startTime !='' ">
                 AND fs_course_answer_logs.create_time &gt;= #{startTime}
             </if>
@@ -873,8 +891,109 @@
                 AND fs_course_answer_logs.video_id = #{videoId}
             </if>
         group by fs_user.user_id
-        order by answerRightRate #{order}
+        <choose>
+            <when test="order != null and order == 'asc'">
+                order by answerRightRate asc
+            </when>
+            <when test="order != null and order == 'desc'">
+                order by answerRightRate desc
+            </when>
+            <otherwise>
+                order by answerRightRate desc
+            </otherwise>
+        </choose>
         limit 20
     </select>
 
+    <select id="countCourseRankingByComplete" resultType="FsCourseRankingVO">
+        SELECT
+        fcv.title AS videoName,
+        ifnull(
+        ROUND((
+        COUNT( DISTINCT CASE WHEN fcc.complete_watch_count > 0 THEN 1 END ) / count(1))* 100,
+        2
+        ),
+        0
+        ) AS completeRate
+        FROM
+        fs_user_course_count fcc
+        LEFT JOIN fs_user ON fs_user.user_id = fcc.user_id
+        LEFT JOIN company_user ON fs_user.company_user_id = company_user.user_id
+        LEFT JOIN fs_user_course_video fcv ON fcv.course_id = fcc.course_id
+        WHERE
+        ( company_user.user_id = #{userId} OR company_user.parent_id = #{userId} )
+        <if test="startTime != null and startTime !='' ">
+            AND fcc.create_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null and endTime != ''">
+            AND fcc.create_time &lt;= #{endTime}
+        </if>
+        <if test="courseId != null and courseId != ''">
+            AND fcc.course_id =  #{courseId}
+        </if>
+        <if test="videoId != null and videoId != ''">
+            AND fcv.video_id = #{videoId}
+        </if>
+        GROUP BY
+        fcv.video_id
+        <choose>
+            <when test="order != null and order == 'asc'">
+                ORDER BY completeRate asc
+            </when>
+            <when test="order != null and order == 'desc'">
+                ORDER BY completeRate desc
+            </when>
+            <otherwise>
+                ORDER BY completeRate desc
+            </otherwise>
+        </choose>
+        LIMIT 20
+    </select>
+
+    <select id="countCourseRankingByRight" resultType="FsCourseRankingVO">
+        SELECT
+        fcv.title AS videoName,
+        ifnull(
+        ROUND(
+        (
+        COUNT( DISTINCT CASE WHEN fs_course_answer_logs.is_right = 1 THEN 1 END ) / count(1)) * 100,
+        2
+        ),
+        0
+        ) AS answerRightRate
+        FROM
+        fs_course_answer_logs
+        LEFT JOIN fs_user ON fs_user.user_id = fs_course_answer_logs.user_id
+        LEFT JOIN company_user ON company_user.user_id = fs_user.company_user_id
+        LEFT JOIN fs_user_course_video fcv ON fcv.video_id = fs_course_answer_logs.video_id
+        WHERE
+        ( company_user.user_id = #{userId} OR company_user.parent_id = #{userId} )
+        <if test="startTime != null and startTime !='' ">
+            AND fs_course_answer_logs.create_time &gt;= #{startTime}
+        </if>
+        <if test="endTime != null and endTime != ''">
+            AND fs_course_answer_logs.create_time &lt;= #{endTime}
+        </if>
+        <if test="courseId != null and courseId != ''">
+            AND fs_course_answer_logs.course_id =  #{courseId}
+        </if>
+        <if test="videoId != null and videoId != ''">
+            AND fs_course_answer_logs.video_id = #{videoId}
+        </if>
+        GROUP BY
+        fs_course_answer_logs.video_id
+        <choose>
+            <when test="order != null and order == 'asc'">
+                ORDER BY answerRightRate asc
+            </when>
+            <when test="order != null and order == 'desc'">
+                ORDER BY answerRightRate desc
+            </when>
+            <otherwise>
+                ORDER BY answerRightRate desc
+            </otherwise>
+        </choose>
+        LIMIT 20
+    </select>
+
 </mapper>

+ 2 - 1
fs-user-app/src/main/java/com/fs/app/controller/CourseController.java

@@ -459,8 +459,9 @@ public class CourseController extends  AppBaseController{
     @PostMapping("/registerCourse")
     public R register(@RequestBody FsUserCourseRegisterParam param) {
         Long userId = Long.parseLong(getUserId());
-        param.setUserId(userId);
 
+        param.setUserId(userId);
+        logger.info("小程序用户Id:"+param.getUserId());
         return courseVideoService.registerCourse(param);
     }
     @Login