Browse Source

Merge remote-tracking branch 'origin/master'

yjwang 16 hours ago
parent
commit
a76c9ee704
56 changed files with 1218 additions and 656 deletions
  1. 25 0
      fs-admin/src/main/java/com/fs/company/controller/CompanyUserController.java
  2. 1 1
      fs-admin/src/main/java/com/fs/his/controller/FsUserController.java
  3. 14 0
      fs-admin/src/main/java/com/fs/his/task/FsCourseTask.java
  4. 11 0
      fs-company-app/src/main/java/com/fs/app/controller/CommonController.java
  5. 11 5
      fs-company-app/src/main/java/com/fs/app/controller/FsUserController.java
  6. 12 16
      fs-company-app/src/main/java/com/fs/app/controller/FsUserCourseVideoController.java
  7. 1 1
      fs-company/src/main/java/com/fs/company/controller/store/FsUserController.java
  8. 1 0
      fs-company/src/main/java/com/fs/framework/config/DataSourceConfig.java
  9. 42 3
      fs-company/src/main/java/com/fs/user/FsUserAdminController.java
  10. 1 0
      fs-framework/src/main/java/com/fs/framework/config/DataSourceConfig.java
  11. 1 0
      fs-qw-api/src/main/java/com/fs/framework/config/DataSourceConfig.java
  12. 1 1
      fs-qw-task/src/main/java/com/fs/app/task/CourseWatchLogScheduler.java
  13. 1 1
      fs-qw-task/src/main/java/com/fs/app/task/UserCourseWatchCountTask.java
  14. 34 18
      fs-qw-task/src/main/java/com/fs/app/task/qwTask.java
  15. 21 9
      fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java
  16. 6 23
      fs-qwhook-sop/src/main/java/com/fs/app/controller/ApisFsUserCourseVideoController.java
  17. 6 23
      fs-qwhook-sop/src/main/java/com/fs/app/controller/FsUserCourseVideoController.java
  18. 1 0
      fs-qwhook-sop/src/main/java/com/fs/framework/config/DataSourceConfig.java
  19. 6 23
      fs-qwhook/src/main/java/com/fs/app/controller/ApisFsUserCourseVideoController.java
  20. 6 23
      fs-qwhook/src/main/java/com/fs/app/controller/FsUserCourseVideoController.java
  21. 1 0
      fs-qwhook/src/main/java/com/fs/framework/config/DataSourceConfig.java
  22. 1 1
      fs-service/src/main/java/com/fs/company/mapper/CompanyTagMapper.java
  23. 7 1
      fs-service/src/main/java/com/fs/company/service/impl/CompanyTagUserServiceImpl.java
  24. 3 0
      fs-service/src/main/java/com/fs/course/domain/FsCourseAnswerLogs.java
  25. 2 0
      fs-service/src/main/java/com/fs/course/domain/FsCourseRedPacketLog.java
  26. 1 0
      fs-service/src/main/java/com/fs/course/param/FsCourseLinkRoomParam.java
  27. 1 0
      fs-service/src/main/java/com/fs/course/param/FsCourseQuestionAnswerUParam.java
  28. 2 0
      fs-service/src/main/java/com/fs/course/param/FsUserCourseVideoAddKfUParam.java
  29. 4 0
      fs-service/src/main/java/com/fs/course/service/IFsCourseLinkService.java
  30. 111 12
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseLinkServiceImpl.java
  31. 1 0
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseQuestionBankServiceImpl.java
  32. 94 27
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java
  33. 12 10
      fs-service/src/main/java/com/fs/his/mapper/FsUserMapper.java
  34. 85 37
      fs-service/src/main/java/com/fs/his/service/impl/FsUserServiceImpl.java
  35. 10 0
      fs-service/src/main/java/com/fs/his/vo/FsUserVO.java
  36. 3 0
      fs-service/src/main/java/com/fs/qw/mapper/CustomerTransferApprovalMapper.java
  37. 5 0
      fs-service/src/main/java/com/fs/qw/service/ICustomerTransferApprovalService.java
  38. 13 0
      fs-service/src/main/java/com/fs/qw/service/impl/CustomerTransferApprovalServiceImpl.java
  39. 4 0
      fs-service/src/main/java/com/fs/sop/domain/QwSop.java
  40. 4 1
      fs-service/src/main/java/com/fs/sop/mapper/QwSopLogsMapper.java
  41. 1 1
      fs-service/src/main/java/com/fs/sop/service/IQwSopLogsService.java
  42. 170 132
      fs-service/src/main/java/com/fs/sop/service/impl/QwSopLogsServiceImpl.java
  43. 5 0
      fs-service/src/main/java/com/fs/sop/vo/SopUserLogsVo.java
  44. 4 0
      fs-service/src/main/java/com/fs/store/param/h5/FsUserPageListParam.java
  45. 1 1
      fs-service/src/main/resources/application-config-druid-jzzx.yml
  46. 2 2
      fs-service/src/main/resources/application-druid-jzzx.yml
  47. 6 3
      fs-service/src/main/resources/mapper/course/FsCourseAnswerLogsMapper.xml
  48. 9 2
      fs-service/src/main/resources/mapper/course/FsCourseRedPacketLogMapper.xml
  49. 9 7
      fs-service/src/main/resources/mapper/course/FsUserCourseMapper.xml
  50. 397 263
      fs-service/src/main/resources/mapper/his/FsUserMapper.xml
  51. 4 0
      fs-service/src/main/resources/mapper/qw/CustomerTransferApprovalMapper.xml
  52. 23 3
      fs-service/src/main/resources/mapper/sop/QwSopLogsMapper.xml
  53. 3 0
      fs-service/src/main/resources/mapper/sop/QwSopMapper.xml
  54. 2 1
      fs-service/src/main/resources/mapper/sop/SopUserLogsMapper.xml
  55. 15 5
      fs-service/src/main/resources/mapper/store/FsUserCourseCountMapper.xml
  56. 1 0
      fs-user-app/src/main/java/com/fs/framework/config/DataSourceConfig.java

+ 25 - 0
fs-admin/src/main/java/com/fs/company/controller/CompanyUserController.java

@@ -136,4 +136,29 @@ public class CompanyUserController extends BaseController
         List<CompanyUser> list = companyUserService.selectCompanyUserList(map);
         return  R.ok().put("data",list);
     }
+
+    /**
+     * 更换会员归属销售
+     * @return
+     */
+    @PreAuthorize("@ss.hasPermi('company:companyUser:change')")
+    @Log(title = "更换会员归属", businessType = BusinessType.OTHER)
+    @PostMapping("/changeCompanyUser")
+    public AjaxResult changeCompanyUser(@RequestBody List<Long> userIds, @RequestParam Long companyUserId, @RequestParam Long companyId)
+    {
+        return toAjax(companyUserService.changeCompanyUser(userIds, companyUserId, companyId));
+    }
+    /**
+     * 根据登录的用户公司获取所有的销售
+     * @return
+     */
+    @GetMapping("/getCompanyUserList")
+    public R getCompanyUserList(@RequestParam Long companyId)
+    {
+        CompanyUser cu = new CompanyUser();
+        cu.setCompanyId(companyId);
+        List<CompanyUser> list = companyUserService.selectCompanyUserList(cu);
+        return  R.ok().put("data",list);
+    }
+
 }

+ 1 - 1
fs-admin/src/main/java/com/fs/his/controller/FsUserController.java

@@ -197,7 +197,7 @@ public class FsUserController extends BaseController
     @ApiOperation("小黑屋")
     public R darkRoomList(FsUserPageListParam param) {
 //        startPage();
-        PageHelper.startPage(param.getPageNum(), param.getPageSize());
+//        PageHelper.startPage(param.getPageNum(), param.getPageSize());
         PageInfo<FsUserPageListVO> fsUserPageListVOPageInfo = fsUserService.selectFsUserPageList(param);
         if(ObjectUtils.isNotNull(fsUserPageListVOPageInfo)){
             for (FsUserPageListVO fsUserPageListVO : fsUserPageListVOPageInfo.getList()) {

+ 14 - 0
fs-admin/src/main/java/com/fs/his/task/FsCourseTask.java

@@ -1,7 +1,9 @@
 package com.fs.his.task;
 
 import com.fs.course.service.IFsCourseWatchLogService;
+import com.fs.qw.service.ICustomerTransferApprovalService;
 import com.fs.qw.service.IHyWorkTaskService;
+import com.fs.statis.service.FsStatisSalerWatchService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -16,6 +18,11 @@ public class FsCourseTask {
     private IFsCourseWatchLogService fsCourseWatchLogService;
     @Autowired
     private IHyWorkTaskService hyWorkTaskService;
+
+    @Autowired
+    private FsStatisSalerWatchService fsStatisSalerWatchService;
+    @Autowired
+    private ICustomerTransferApprovalService customerTransferApprovalService;
     /**
      * 添加会员观看日志
      * @throws Exception
@@ -44,4 +51,11 @@ public class FsCourseTask {
         hyWorkTaskService.hyWorkTask();
     }
 
+    /**
+     * 客户转移审批自动通过
+     */
+    public void fsUserTransferAutoPass(){
+        customerTransferApprovalService.autoApprovePass();
+    }
+
 }

+ 11 - 0
fs-company-app/src/main/java/com/fs/app/controller/CommonController.java

@@ -25,6 +25,7 @@ import com.fs.his.service.IFsAppVersionService;
 import com.fs.his.service.IFsCityService;
 import com.fs.jpush.service.JpushService;
 
+import com.fs.store.service.IFsUserCourseCountService;
 import com.fs.system.oss.CloudStorageService;
 import com.fs.system.oss.OSSFactory;
 import com.fs.system.service.ISysConfigService;
@@ -228,5 +229,15 @@ public class CommonController extends AppBaseController {
 	}
 
 
+	@Autowired
+	private IFsUserCourseCountService userCourseCountService;
+
+	@PostMapping("test")
+	public R test() throws Exception
+	{
+		userCourseCountService.insertFsUserCourseCountTask();
+		return R.ok();
+	}
+
 
 }

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

@@ -39,8 +39,9 @@ import org.springframework.web.bind.annotation.*;
 
 import javax.validation.Valid;
 import java.io.InputStream;
-import java.text.SimpleDateFormat;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 import java.util.*;
 
 @Slf4j
@@ -75,7 +76,7 @@ public class FsUserController extends AppBaseController {
     @ApiOperation("用户会员分页列表")
     public ResponseResult<PageInfo<FsUserPageListVO>> pageList(@RequestBody FsUserPageListParam param) {
         param.setUserId(Long.parseLong(getUserId()));
-        PageHelper.startPage(param.getPageNum(), param.getPageSize());
+//        PageHelper.startPage(param.getPageNum(), param.getPageSize());
         PageInfo<FsUserPageListVO> fsUserPageListVOPageInfo = fsUserService.selectFsUserPageList(param);
         return ResponseResult.ok(fsUserPageListVOPageInfo);
     }
@@ -152,18 +153,23 @@ public class FsUserController extends AppBaseController {
     public ResponseResult<FsUserStatisticsVO> userStatistics(@ApiParam(value = "开始时间", required = true) @RequestParam String startTime,
                                                              @ApiParam(value = "结束时间", required = true) @RequestParam String endTime) {
         long userId = Long.parseLong(getUserId());
-        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-        String nowDate = dateFormat.format(new Date());
         /*---------- 如果传入的日期是今天 ----------*/
         UserStatisticsCommonParam param = new UserStatisticsCommonParam();
         param.setUserId(userId).setStartTime(startTime).setEndTime(endTime);
         FsUserStatisticsVO vo = fsUserService.userStatistics(param);
-        if (nowDate.compareTo(startTime) > 0 && nowDate.compareTo(endTime) < 0) {
+
+        DateTimeFormatter dfm = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        LocalDate today = LocalDate.now();
+        LocalDateTime startDateTime = LocalDateTime.parse(startTime, dfm);
+        LocalDateTime endDateTime = LocalDateTime.parse(endTime, dfm);
+        if (startDateTime.toLocalDate().equals(today) && endDateTime.toLocalDate().equals(today)) {
             String yesterday = LocalDate.now().minusDays(1).toString();
             UserStatisticsCommonParam paramYes = new UserStatisticsCommonParam();
             paramYes.setUserId(userId).setStartTime(yesterday + " 00:00:00").setEndTime(yesterday + " 23:59:59");
             FsUserStatisticsVO fsUserStatisticsVO = fsUserService.userStatistics(paramYes);
             vo.setYesterdayVO(fsUserStatisticsVO);
+        } else {
+            vo.setYesterdayVO(new FsUserStatisticsVO());
         }
         return ResponseResult.ok(vo);
     }

+ 12 - 16
fs-company-app/src/main/java/com/fs/app/controller/FsUserCourseVideoController.java

@@ -4,11 +4,9 @@ import com.fs.app.annotation.Login;
 import com.fs.app.config.ImageStorageConfig;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.ResponseResult;
-import com.fs.common.enums.BizResponseEnum;
 import com.fs.common.utils.StringUtils;
 import com.fs.company.domain.CompanyUser;
 import com.fs.company.service.ICompanyUserService;
-import com.fs.company.service.impl.CompanyServiceImpl;
 import com.fs.course.domain.FsUserCoursePeriod;
 import com.fs.course.param.FsCourseLinkCreateParam;
 import com.fs.course.param.FsWatchCourseTimeParam;
@@ -63,7 +61,7 @@ public class FsUserCourseVideoController extends AppBaseController {
     @Autowired
     private IFsUserCoursePeriodService fsUserCoursePeriodService;
     @Autowired
-    private ICompanyUserService companyService;
+    private ICompanyUserService companyUserService;
 
     @Login
     @GetMapping("/pageList")
@@ -114,24 +112,22 @@ public class FsUserCourseVideoController extends AppBaseController {
                                                       @RequestParam(required = false) String keyword,
                                                       @RequestParam(required = false, defaultValue = "1") Integer pageNum,
                                                       @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
-        log.debug("参与记录 keyword: {}, pageNum: {}, pageSize: {}", keyword, pageNum, pageSize);
-        String userId = getUserId();
+        log.debug("参与记录 videoId:{}, type:{}, keyword: {}, pageNum: {}, pageSize: {}", videoId, type, keyword, pageNum, pageSize);
         Map<String, Object> params = new HashMap<>();
-        //判断是否管理员 管理员查所有
-        CompanyUser companyUser = companyService.selectCompanyUserById(Long.valueOf(userId));
-        if (companyUser != null) {
-            if (companyUser.isAdmin()) {
-                params.put("companyId", companyUser.getCompanyId());
-            } else {
-                params.put("companyUserId", userId);
-            }
-        } else {
-            return ResponseResult.fail(BizResponseEnum.PARAM_ERROR);
-        }
         params.put("videoId", videoId);
         params.put("type", type);
         params.put("keyword", keyword);
 
+        // type 0 答题领奖记录----答题正确并且领取红包的
+        // type 1 完播----这堂课看完的人
+        // type 2 未完播---看课中断
+        // 管理员看整个公司 否则看自己的
+        CompanyUser companyUser = companyUserService.selectCompanyUserByUserId(Long.parseLong(getUserId()));
+        if (companyUser.isAdmin()) {
+            params.put("companyId", companyUser.getCompanyId());
+        } else {
+            params.put("companyUserId", companyUser.getUserId());
+        }
 
         PageHelper.startPage(pageNum, pageSize);
         List<FsUserCourseParticipationRecordVO> record = fsUserCourseService.getParticipationRecordByMap(params);

+ 1 - 1
fs-company/src/main/java/com/fs/company/controller/store/FsUserController.java

@@ -235,7 +235,7 @@ public class FsUserController extends BaseController
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         param.setUserId(loginUser.getUser().getUserId());
 //        startPage();
-        PageHelper.startPage(param.getPageNum(), param.getPageSize());
+//        PageHelper.startPage(param.getPageNum(), param.getPageSize());
         PageInfo<FsUserPageListVO> fsUserPageListVOPageInfo = fsUserService.selectFsUserPageList(param);
         Map<String, Object> map = new HashMap<String, Object>();
         map.put("rows", fsUserPageListVOPageInfo.getList());

+ 1 - 0
fs-company/src/main/java/com/fs/framework/config/DataSourceConfig.java

@@ -40,6 +40,7 @@ public class DataSourceConfig {
     @Primary
     public DynamicDataSource dataSource(@Qualifier("masterDataSource") DataSource masterDataSource, @Qualifier("sopDataSource") DataSource sopDataSource) {
         Map<Object, Object> targetDataSources = new HashMap<>();
+        targetDataSources.put(DataSourceType.MASTER, masterDataSource);
         targetDataSources.put(DataSourceType.SOP.name(), sopDataSource);
         return new DynamicDataSource(masterDataSource, targetDataSources);
     }

+ 42 - 3
fs-company/src/main/java/com/fs/user/FsUserAdminController.java

@@ -1,5 +1,6 @@
 package com.fs.user;
 
+import com.alibaba.fastjson.JSON;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.page.TableDataInfo;
@@ -7,11 +8,16 @@ import com.fs.common.utils.ServletUtils;
 import com.fs.company.cache.ICompanyUserCacheService;
 import com.fs.framework.security.LoginUser;
 import com.fs.framework.service.TokenService;
+
 import com.fs.his.service.IFsUserService;
+import com.fs.qw.domain.CustomerTransferApproval;
+import com.fs.qw.dto.FsUserTransferParamDTO;
+import com.fs.qw.service.ICustomerTransferApprovalService;
 import com.fs.store.param.h5.FsUserPageListParam;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -19,8 +25,11 @@ import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.util.Date;
+
 @Api(tags = "会员管理接口")
 @RestController
+@Slf4j
 @RequestMapping("/user/fsUser")
 @AllArgsConstructor
 public class FsUserAdminController extends BaseController {
@@ -34,6 +43,9 @@ public class FsUserAdminController extends BaseController {
     @Autowired
     private TokenService tokenService;
 
+    @Autowired
+    private ICustomerTransferApprovalService transferApprovalService;
+
     @PreAuthorize("@ss.hasPermi('user:fsUser:list')")
     @PostMapping("/list")
     @ApiOperation("会员列表(与移动端使用的相同查询)")
@@ -41,9 +53,12 @@ public class FsUserAdminController extends BaseController {
         //startPage();
 
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        param.setCompanyId(loginUser.getCompany().getCompanyId());
-        param.setCompanyUserId(String.valueOf(loginUser.getUser().getUserId()));
-
+        if (param.isMyFsUser()){
+            param.setCompanyId(loginUser.getCompany().getCompanyId());
+            param.setCompanyUserId(String.valueOf(loginUser.getUser().getUserId()));
+        }else {
+            param.setCompanyId(loginUser.getCompany().getCompanyId());
+        }
         if(param.getCompanyUserId() == null) {
             throw new IllegalArgumentException("当前销售不存在!");
         }
@@ -60,5 +75,29 @@ public class FsUserAdminController extends BaseController {
         return R.error();
     }
 
+    /**
+     * 转移
+     * @param param
+     */
+    @PostMapping("/transfer")
+    public R transfer(@RequestBody FsUserTransferParamDTO param){
+        log.info("客户转移: {}",param);
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        param.setSourceCompanyUserId(loginUser.getUser().getUserId());
+        CustomerTransferApproval customerTransferApproval = new CustomerTransferApproval();
+        customerTransferApproval.setCorpId(String.valueOf(loginUser.getCompany().getCompanyId()));
+        customerTransferApproval.setCustomerIds(JSON.toJSONString(param.getUserIds()));
+        customerTransferApproval.setOriginalUserId(param.getSourceCompanyUserId());
+        customerTransferApproval.setTargetUserId(param.getTargetCompanyUserId());
+        customerTransferApproval.setInitiatorUserId(param.getSourceCompanyUserId());
+        customerTransferApproval.setContent(param.getContent());
+        customerTransferApproval.setCreatedAt(new Date());
+        customerTransferApproval.setUpdatedAt(new Date());
+        customerTransferApproval.setApprovalStatus(0);
+        customerTransferApproval.setTransferType(2);
+        transferApprovalService.insertCustomerTransferApproval(customerTransferApproval);
+        return R.ok("转移申请已经提交,等待转移成功!");
+    }
+
 
 }

+ 1 - 0
fs-framework/src/main/java/com/fs/framework/config/DataSourceConfig.java

@@ -43,6 +43,7 @@ public class DataSourceConfig {
     @Primary
     public DynamicDataSource dataSource(@Qualifier("clickhouseDataSource") DataSource clickhouseDataSource,@Qualifier("masterDataSource") DataSource masterDataSource, @Qualifier("sopDataSource") DataSource sopDataSource) {
         Map<Object, Object> targetDataSources = new HashMap<>();
+        targetDataSources.put(DataSourceType.MASTER, masterDataSource);
         targetDataSources.put(DataSourceType.SOP.name(), sopDataSource);
         targetDataSources.put(DataSourceType.CLICKHOUSE.name(), clickhouseDataSource);
         return new DynamicDataSource(masterDataSource, targetDataSources);

+ 1 - 0
fs-qw-api/src/main/java/com/fs/framework/config/DataSourceConfig.java

@@ -40,6 +40,7 @@ public class DataSourceConfig {
     @Primary
     public DynamicDataSource dataSource(@Qualifier("masterDataSource") DataSource masterDataSource, @Qualifier("sopDataSource") DataSource sopDataSource) {
         Map<Object, Object> targetDataSources = new HashMap<>();
+        targetDataSources.put(DataSourceType.MASTER, masterDataSource);
         targetDataSources.put(DataSourceType.SOP.name(), sopDataSource);
         return new DynamicDataSource(masterDataSource, targetDataSources);
     }

+ 1 - 1
fs-qw-task/src/main/java/com/fs/app/task/CourseWatchLogScheduler.java

@@ -126,7 +126,7 @@ public class CourseWatchLogScheduler {
 
     }
 
-    @Scheduled(fixedRate = 60000) // 每分钟执行一次
+    @Scheduled(fixedRate = 30000) // 每分钟执行一次
     public void checkFsUserWatchStatus() {
         // 尝试设置标志为 true,表示任务开始执行
         if (!isRunning4.compareAndSet(false, true)) {

+ 1 - 1
fs-qw-task/src/main/java/com/fs/app/task/UserCourseWatchCountTask.java

@@ -16,7 +16,7 @@ public class UserCourseWatchCountTask {
     /**
      * 每15分钟执行一次
      */
-    @Scheduled(cron = "0 */15 * * * ?")  // 每15分钟执行一次
+    @Scheduled(cron = "0 */10 * * * ?")  // 每10分钟执行一次
     public void userCourseCountTask() {
         try {
             log.info("==============会员看课统计任务执行===============开始");

+ 34 - 18
fs-qw-task/src/main/java/com/fs/app/task/qwTask.java

@@ -28,7 +28,7 @@ import java.util.List;
 /**
  * 企业微信SOP定时任务管理类
  * 负责处理各种定时任务,包括SOP规则检查、消息发送、数据清理等
- * 
+ *
  * @author 系统
  * @version 1.0
  */
@@ -50,10 +50,10 @@ public class qwTask {
 
     @Autowired
     private ISopUserLogsService sopUserLogsService;
-    
+
     @Autowired
     private SopLogsTaskService sopLogsTaskService;
-    
+
     @Autowired
     private SopWxLogsService sopWxLogsService;
 
@@ -71,7 +71,7 @@ public class qwTask {
 
     @Autowired
     private QwSopLogsMapper qwSopLogsMapper;
-    
+
     @Autowired
     private IQwSopTagService qwSopTagService;
 
@@ -99,7 +99,7 @@ public class qwTask {
      * 定时任务:根据营期生成sopLogs待发记录
      * 执行时间:每小时的第5分钟执行
      * 功能:根据营期时间生成需要发送的SOP日志记录
-     * 
+     *
      * @throws Exception 执行异常
      */
     @Scheduled(cron = "0 5 * * * ?") // 每小时的第5分钟触发
@@ -118,7 +118,7 @@ public class qwTask {
      * 定时任务:微信SOP处理
      * 执行时间:每小时的第5分钟执行
      * 功能:处理微信相关的SOP日志
-     * 
+     *
      * @throws Exception 执行异常
      */
     @Scheduled(cron = "0 5 * * * ?") // 每小时的第5分钟触发
@@ -136,7 +136,7 @@ public class qwTask {
      * 定时任务:处理聊天SOP用户日志
      * 执行时间:已注释,原为每分钟的第5秒执行
      * 功能:将clickHouse的sopUserLogsChat(营期表)按每分钟巡回处理
-     * 
+     *
      * @throws Exception 执行异常
      */
 //    @Scheduled(cron = "5 0/1 * * * ?")
@@ -149,20 +149,36 @@ public class qwTask {
     }
 
     /**
-     * 定时任务:发送企业微信SOP群发消息(新版-按营期发送)
-     * 执行时间:每天凌晨 0:20:00
-     * 功能:通过调用企业微信接口发送SOP群发消息
+     * 定时 发送 通过调用 企业微信接口 发送的 SOP 群发消息(按单链发)
      */
-    @Scheduled(cron = "0 20 0 * * ?")
-    public void SendQwApiSopLogTimerNew() {
-        log.info("zyp \n【企微官方接口群发开始】");
-        
-        // 获取当前日期
+    @Scheduled(cron = "0 20 1 * * ?")
+    public void SendQwApiSopLogTimer(){
+        log.info("zyp \n【企微官方接口群发开始-单链】");
+//        qwSopLogsService.checkQwSopLogs();
         LocalDate localDate = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0).toLocalDate();
         String date = localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
 
-        // 根据用户日志创建企业群发
-        qwSopLogsService.createCorpMassSendingByUserLogs(date);
+        qwSopLogsService.createCorpMassSending(date);
+    }
+
+    /**
+     * 定时 发送 通过调用 企业微信接口 发送的 SOP 群发消息(新版-安装营期发)
+     */
+    @Scheduled(cron = "0 10 0,1 * * ?")
+    public void SendQwApiSopLogTimerNew(){
+
+        log.info("zyp \n【企微官方接口群发开始】");
+//        qwSopLogsService.checkQwSopLogs();
+//        LocalDate localDate = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0).toLocalDate();
+//        String date = localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+
+        int currentHour = LocalDateTime.now().getHour();
+        String taskStartTime = LocalDate.now().atTime(currentHour, 0, 0)
+                .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+        String taskEndTime = LocalDate.now().atTime(currentHour, 59, 59)
+                .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+
+        qwSopLogsService.createCorpMassSendingByUserLogs(taskStartTime,taskEndTime);
     }
 
     /**
@@ -246,7 +262,7 @@ public class qwTask {
 
     /**
      * 批量处理插入逻辑,支持每500条数据一次的批量插入
-     * 
+     *
      * @param logsByJsApiNotExtId 需要处理的日志列表
      */
     private void processAndInsertQwSopLogs(List<QwSopLogsDoSendListTVO> logsByJsApiNotExtId) {

+ 21 - 9
fs-qw-task/src/main/java/com/fs/app/taskService/impl/SopLogsTaskServiceImpl.java

@@ -774,22 +774,33 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
         sopLogs.setQwUserid(logVo.getQwUserId());
         sopLogs.setCorpId(logVo.getCorpId());
         sopLogs.setLogType(ruleTimeVO.getType());
+        sopLogs.setTakeRecords(0);
 
         if (isOfficial == 1) {
 
-            if (fsUserId== null || Long.valueOf(0L).equals(fsUserId)){
-                sopLogs.setSendType(2);
-                sopLogs.setRemark("未绑定小程序用户,单链补发");
-                //时间设置成固定7点
-                LocalDateTime dateTime = LocalDateTime.parse(formattedSendTime, DATE_TIME_FORMATTER);
-                sopLogs.setSendTime(OUTPUT_FORMATTER.format(dateTime));
+            if (logVo.getIsSampSend()== 1) {
+                if (fsUserId == null || Long.valueOf(0L).equals(fsUserId)) {
+                    sopLogs.setSendType(2);
+                    sopLogs.setRemark("未绑定小程序用户,单链补发");
+                    //时间设置成固定8点
+                    LocalDateTime dateTime = LocalDateTime.parse(formattedSendTime, DATE_TIME_FORMATTER);
+                    sopLogs.setSendTime(OUTPUT_FORMATTER.format(dateTime));
+                } else {
+                    sopLogs.setSendType(1);
+                }
+
             }else {
-                sopLogs.setSendType(1);
+                if (fsUserId == null || Long.valueOf(0L).equals(fsUserId)) {
+                    sopLogs.setTakeRecords(1);
+                    sopLogs.setSendType(1);
+                }else {
+                    sopLogs.setSendType(1);
+                }
             }
 
-        }else if (isOfficial==0){
+        } else if (isOfficial == 0) {
             sopLogs.setSendType(ruleTimeVO.getSendType() == 1 ? 2 : ruleTimeVO.getSendType());
-        }else{
+        } else {
             sopLogs.setSendType(ruleTimeVO.getSendType());
         }
 
@@ -1828,6 +1839,7 @@ public class SopLogsTaskServiceImpl implements SopLogsTaskService {
         sopLogs.setExternalUserId(externalContact.getExternalUserId());
         sopLogs.setExternalUserName(externalContact.getName());
         sopLogs.setFsUserId(finishLog.getUserId() != null ? finishLog.getUserId() : null );
+        sopLogs.setUserLogsId("-");
         // 解析模板设置
         List<QwSopCourseFinishTempSetting.Setting> settings = parseSettings(finishTemp.getSetting());
         if (settings == null) {

+ 6 - 23
fs-qwhook-sop/src/main/java/com/fs/app/controller/ApisFsUserCourseVideoController.java

@@ -144,7 +144,11 @@ public class ApisFsUserCourseVideoController extends BaseController {
             return R.error("客户id不能为空");
         }
 
-        return fsUserCourseVideoService.createCartLink(param);
+        if (param.getType()==null || param.getType()==1){
+            return fsUserCourseVideoService.createCartLink(param);
+        }else {
+            return fsUserCourseVideoService.createMiniLink(param);
+        }
     }
 
     @GetMapping("/createRoomLink")
@@ -154,28 +158,7 @@ public class ApisFsUserCourseVideoController extends BaseController {
         if (qwUser==null||qwUser.getCompanyId()==null){
             return R.error("无权限");
         }
-        FsCourseLinkCreateParam createParam = new FsCourseLinkCreateParam();
-        createParam.setCourseId(param.getCourseId());
-        createParam.setVideoId(param.getVideoId());
-        createParam.setCorpId(param.getCorpId());
-        createParam.setCompanyUserId(qwUser.getCompanyUserId());
-        createParam.setCompanyId(qwUser.getCompanyId());
-        createParam.setQwUserId(qwUser.getId());
-        String linkUrl;
-        R createLink = courseLinkService.createRoomLinkUrl(createParam);
-        if (createLink.get("code").equals(500)){
-            return R.error("链接生成失败!");
-        }
-        linkUrl = (String) createLink.get("url");
-
-        FsUserCourse course = fsUserCourseService.selectFsUserCourseByCourseId(param.getCourseId());
-
-        JSONObject news = new JSONObject(true); // true 表示保持字段顺序
-        news.put("link", linkUrl);
-        news.put("title", course.getCourseName());
-        news.put("desc", param.getTitle());
-        news.put("imgUrl", course.getImgUrl());
-        return R.ok().put("news",news);
+        return courseLinkService.createRoomLink(param, qwUser);
     }
 
 }

+ 6 - 23
fs-qwhook-sop/src/main/java/com/fs/app/controller/FsUserCourseVideoController.java

@@ -101,28 +101,7 @@ public class FsUserCourseVideoController {
         if (qwUser==null||qwUser.getCompanyId()==null){
             return R.error("无权限");
         }
-        FsCourseLinkCreateParam createParam = new FsCourseLinkCreateParam();
-        createParam.setCourseId(param.getCourseId());
-        createParam.setVideoId(param.getVideoId());
-        createParam.setCorpId(param.getCorpId());
-        createParam.setCompanyUserId(qwUser.getCompanyUserId());
-        createParam.setCompanyId(qwUser.getCompanyId());
-        createParam.setQwUserId(qwUser.getId());
-        String linkUrl;
-        R createLink = courseLinkService.createRoomLinkUrl(createParam);
-        if (createLink.get("code").equals(500)){
-            return R.error("链接生成失败!");
-        }
-        linkUrl = (String) createLink.get("url");
-
-        FsUserCourse course = fsUserCourseService.selectFsUserCourseByCourseId(param.getCourseId());
-
-        JSONObject news = new JSONObject(true); // true 表示保持字段顺序
-        news.put("link", linkUrl);
-        news.put("title", course.getCourseName());
-        news.put("desc", param.getTitle());
-        news.put("imgUrl", course.getImgUrl());
-        return R.ok().put("news",news);
+        return courseLinkService.createRoomLink(param, qwUser);
     }
 
     /**
@@ -177,6 +156,10 @@ public class FsUserCourseVideoController {
             return R.error("客户id不能为空");
         }
 
-        return fsUserCourseVideoService.createCartLink(param);
+        if (param.getType()==null || param.getType()==1){
+            return fsUserCourseVideoService.createCartLink(param);
+        }else {
+            return fsUserCourseVideoService.createMiniLink(param);
+        }
     }
 }

+ 1 - 0
fs-qwhook-sop/src/main/java/com/fs/framework/config/DataSourceConfig.java

@@ -40,6 +40,7 @@ public class DataSourceConfig {
     @Primary
     public DynamicDataSource dataSource(@Qualifier("masterDataSource") DataSource masterDataSource, @Qualifier("sopDataSource") DataSource sopDataSource) {
         Map<Object, Object> targetDataSources = new HashMap<>();
+        targetDataSources.put(DataSourceType.MASTER, masterDataSource);
         targetDataSources.put(DataSourceType.SOP.name(), sopDataSource);
         return new DynamicDataSource(masterDataSource, targetDataSources);
     }

+ 6 - 23
fs-qwhook/src/main/java/com/fs/app/controller/ApisFsUserCourseVideoController.java

@@ -143,7 +143,11 @@ public class ApisFsUserCourseVideoController extends BaseController {
             return R.error("客户id不能为空");
         }
 
-        return fsUserCourseVideoService.createCartLink(param);
+        if (param.getType()==null || param.getType()==1){
+            return fsUserCourseVideoService.createCartLink(param);
+        }else {
+            return fsUserCourseVideoService.createMiniLink(param);
+        }
 
     }
 
@@ -154,28 +158,7 @@ public class ApisFsUserCourseVideoController extends BaseController {
         if (qwUser==null||qwUser.getCompanyId()==null){
             return R.error("无权限");
         }
-        FsCourseLinkCreateParam createParam = new FsCourseLinkCreateParam();
-        createParam.setCourseId(param.getCourseId());
-        createParam.setVideoId(param.getVideoId());
-        createParam.setCorpId(param.getCorpId());
-        createParam.setCompanyUserId(qwUser.getCompanyUserId());
-        createParam.setCompanyId(qwUser.getCompanyId());
-        createParam.setQwUserId(qwUser.getId());
-        String linkUrl;
-        R createLink = courseLinkService.createRoomLinkUrl(createParam);
-        if (createLink.get("code").equals(500)){
-            return R.error("链接生成失败!");
-        }
-        linkUrl = (String) createLink.get("url");
-
-        FsUserCourse course = fsUserCourseService.selectFsUserCourseByCourseId(param.getCourseId());
-
-        JSONObject news = new JSONObject(true); // true 表示保持字段顺序
-        news.put("link", linkUrl);
-        news.put("title", course.getCourseName());
-        news.put("desc", param.getTitle());
-        news.put("imgUrl", course.getImgUrl());
-        return R.ok().put("news",news);
+        return courseLinkService.createRoomLink(param, qwUser);
     }
 
 }

+ 6 - 23
fs-qwhook/src/main/java/com/fs/app/controller/FsUserCourseVideoController.java

@@ -150,7 +150,11 @@ public class FsUserCourseVideoController {
             return R.error("客户id不能为空");
         }
 
-        return fsUserCourseVideoService.createCartLink(param);
+        if (param.getType()==null || param.getType()==1){
+            return fsUserCourseVideoService.createCartLink(param);
+        }else {
+            return fsUserCourseVideoService.createMiniLink(param);
+        }
 
     }
 
@@ -161,28 +165,7 @@ public class FsUserCourseVideoController {
         if (qwUser==null||qwUser.getCompanyId()==null){
             return R.error("无权限");
         }
-        FsCourseLinkCreateParam createParam = new FsCourseLinkCreateParam();
-        createParam.setCourseId(param.getCourseId());
-        createParam.setVideoId(param.getVideoId());
-        createParam.setCorpId(param.getCorpId());
-        createParam.setCompanyUserId(qwUser.getCompanyUserId());
-        createParam.setCompanyId(qwUser.getCompanyId());
-        createParam.setQwUserId(qwUser.getId());
-        String linkUrl;
-        R createLink = courseLinkService.createRoomLinkUrl(createParam);
-        if (createLink.get("code").equals(500)){
-            return R.error("链接生成失败!");
-        }
-        linkUrl = (String) createLink.get("url");
-
-        FsUserCourse course = fsUserCourseService.selectFsUserCourseByCourseId(param.getCourseId());
-
-        JSONObject news = new JSONObject(true); // true 表示保持字段顺序
-        news.put("link", linkUrl);
-        news.put("title", course.getCourseName());
-        news.put("desc", param.getTitle());
-        news.put("imgUrl", course.getImgUrl());
-        return R.ok().put("news",news);
+        return courseLinkService.createRoomLink(param, qwUser);
     }
 
 }

+ 1 - 0
fs-qwhook/src/main/java/com/fs/framework/config/DataSourceConfig.java

@@ -40,6 +40,7 @@ public class DataSourceConfig {
     @Primary
     public DynamicDataSource dataSource(@Qualifier("masterDataSource") DataSource masterDataSource, @Qualifier("sopDataSource") DataSource sopDataSource) {
         Map<Object, Object> targetDataSources = new HashMap<>();
+        targetDataSources.put(DataSourceType.MASTER, masterDataSource);
         targetDataSources.put(DataSourceType.SOP.name(), sopDataSource);
         return new DynamicDataSource(masterDataSource, targetDataSources);
     }

+ 1 - 1
fs-service/src/main/java/com/fs/company/mapper/CompanyTagMapper.java

@@ -78,6 +78,6 @@ public interface CompanyTagMapper
     List<CompanyTag> selectCompanyTagListByUserId(@Param("userId") Long userId);
 
     String findUserTagByUserId(@Param("userId") Long userId,@Param("companyUserId") Long companyUserId);
-    @MapKey("tag_id")
+    @MapKey("tagId")
     Map<Long,CompanyTag> queryAllTagMap();
 }

+ 7 - 1
fs-service/src/main/java/com/fs/company/service/impl/CompanyTagUserServiceImpl.java

@@ -117,8 +117,14 @@ public class CompanyTagUserServiceImpl implements ICompanyTagUserService
                 keywords = param.getKeyword().split(",");
             }
         }
+        // 判断是否是管理员
+        Long companyId = null;
+        CompanyUser companyUser = companyUserMapper.selectCompanyUserById(param != null ? param.getUserId() : null);
+        if (companyUser != null && companyUser.isAdmin()){
+            companyId = companyUser.getCompanyId();
+        }
         //获取所有销售
-        List<CompanyUser> companyUsers = companyUserMapper.selectAllCompanyUserAndSelf(param != null ? param.getUserId() : null,null);
+        List<CompanyUser> companyUsers = companyUserMapper.selectAllCompanyUserAndSelf(param != null ? param.getUserId() : null, companyId);
         List<Long> userIds = Collections.emptyList();
         if(companyUsers != null && !companyUsers.isEmpty()){
             userIds = companyUsers.stream().map(CompanyUser::getUserId).collect(Collectors.toList());

+ 3 - 0
fs-service/src/main/java/com/fs/course/domain/FsCourseAnswerLogs.java

@@ -66,4 +66,7 @@ public class FsCourseAnswerLogs extends BaseEntity {
     private String questionJson;
 
     private Long watchLogId;//绑定观看的记录id
+
+    /** 营期id */
+    private Long periodId;
 }

+ 2 - 0
fs-service/src/main/java/com/fs/course/domain/FsCourseRedPacketLog.java

@@ -57,4 +57,6 @@ public class FsCourseRedPacketLog extends BaseEntity
     /** 营期id */
     private Long periodId;
 
+    private String result;
+
 }

+ 1 - 0
fs-service/src/main/java/com/fs/course/param/FsCourseLinkRoomParam.java

@@ -14,5 +14,6 @@ public class FsCourseLinkRoomParam {
     private Long courseId;
 
     private String title;//视频标题
+    private String chatId;
 
 }

+ 1 - 0
fs-service/src/main/java/com/fs/course/param/FsCourseQuestionAnswerUParam.java

@@ -30,5 +30,6 @@ public class FsCourseQuestionAnswerUParam implements Serializable
     private Long duration;
     private Long qwExternalId;
     private List<FsCourseQuestionBank> questions;
+    private Long periodId;
 
 }

+ 2 - 0
fs-service/src/main/java/com/fs/course/param/FsUserCourseVideoAddKfUParam.java

@@ -61,5 +61,7 @@ public class FsUserCourseVideoAddKfUParam implements Serializable {
     private String link;
 
     private Integer isRoom;
+    private String chatId;
+    private String nickName;
 
 }

+ 4 - 0
fs-service/src/main/java/com/fs/course/service/IFsCourseLinkService.java

@@ -3,6 +3,8 @@ package com.fs.course.service;
 import com.fs.common.core.domain.R;
 import com.fs.course.domain.FsCourseLink;
 import com.fs.course.param.FsCourseLinkCreateParam;
+import com.fs.course.param.FsCourseLinkRoomParam;
+import com.fs.qw.domain.QwUser;
 
 import java.util.List;
 
@@ -79,4 +81,6 @@ public interface IFsCourseLinkService
     R createRoomLinkUrl(FsCourseLinkCreateParam param);
 
     R getRealLinkH5(String link);
+
+    R createRoomLink(FsCourseLinkRoomParam param, QwUser qwUser);
 }

+ 111 - 12
fs-service/src/main/java/com/fs/course/service/impl/FsCourseLinkServiceImpl.java

@@ -1,47 +1,51 @@
 package com.fs.course.service.impl;
 
-import cn.hutool.core.util.IdUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.alibaba.fastjson.JSONObject;
 import com.fs.common.core.domain.R;
 import com.fs.common.utils.DateUtils;
+import com.fs.common.utils.PubFun;
 import com.fs.common.utils.StringUtils;
-import com.fs.company.domain.CompanyUser;
+import com.fs.common.utils.date.DateUtil;
 import com.fs.company.mapper.CompanyUserMapper;
 import com.fs.config.cloud.CloudHostProper;
 import com.fs.course.config.CourseConfig;
-import com.fs.course.domain.FsCourseDomainName;
-import com.fs.course.domain.FsCourseLink;
-import com.fs.course.domain.FsCourseRealLink;
-import com.fs.course.domain.FsUserCourseVideo;
+import com.fs.course.domain.*;
 import com.fs.course.mapper.FsCourseDomainNameMapper;
 import com.fs.course.mapper.FsCourseLinkMapper;
+import com.fs.course.mapper.FsCourseWatchLogMapper;
 import com.fs.course.mapper.FsUserCourseVideoMapper;
 import com.fs.course.param.FsCourseLinkCreateParam;
-import com.fs.course.service.IFsCourseDomainNameService;
+import com.fs.course.param.FsCourseLinkRoomParam;
 import com.fs.course.service.IFsCourseLinkService;
+import com.fs.course.service.IFsUserCourseService;
+import com.fs.qw.domain.QwGroupChat;
+import com.fs.qw.domain.QwGroupChatUser;
 import com.fs.qw.domain.QwUser;
+import com.fs.qw.mapper.QwExternalContactMapper;
 import com.fs.qw.mapper.QwUserMapper;
+import com.fs.qw.service.IQwGroupChatService;
+import com.fs.qw.service.IQwGroupChatUserService;
+import com.fs.qw.vo.GroupUserExternalVo;
 import com.fs.system.service.ISysConfigService;
 import com.fs.voice.utils.StringUtil;
 import lombok.Synchronized;
 import lombok.extern.slf4j.Slf4j;
-import org.checkerframework.checker.units.qual.A;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.io.UnsupportedEncodingException;
-import java.net.URI;
 import java.net.URLDecoder;
-import java.security.SecureRandom;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.*;
 
 import static com.fs.course.utils.LinkUtil.generateRandomStringWithLock;
+import static com.fs.sop.service.impl.SopUserLogsInfoServiceImpl.convertStringToDate;
 
 /**
  * 短链Service业务层处理
@@ -60,6 +64,21 @@ public class FsCourseLinkServiceImpl implements IFsCourseLinkService
 
     @Autowired
     private FsCourseDomainNameMapper fsCourseDomainNameMapper;
+
+    @Autowired
+    private FsCourseWatchLogMapper fsCourseWatchLogMapper;
+
+    @Autowired
+    private QwExternalContactMapper qwExternalContactMapper;
+
+    @Autowired
+    private IFsUserCourseService fsUserCourseService;
+
+    @Autowired
+    private IQwGroupChatService qwGroupChatService;
+
+    @Autowired
+    private IQwGroupChatUserService qwGroupChatUserService;
     @Autowired
     private QwUserMapper qwUserMapper;
     @Autowired
@@ -202,7 +221,7 @@ public class FsCourseLinkServiceImpl implements IFsCourseLinkService
     }
 
     @Override
-    public R createRoomLinkUrl(FsCourseLinkCreateParam param) {
+    public R  createRoomLinkUrl(FsCourseLinkCreateParam param) {
 //        QwUser qwUser;
 //        if(param.getQwUserId() != null){
 //            qwUser = qwUserMapper.selectById(param.getQwUserIdLong());
@@ -559,4 +578,84 @@ public class FsCourseLinkServiceImpl implements IFsCourseLinkService
             return R.error("发生未知错误,请稍后再试").put("realLink", link);
         }
     }
+
+    @Override
+    public R createRoomLink(FsCourseLinkRoomParam param, QwUser qwUser) {
+        FsCourseLinkCreateParam createParam = new FsCourseLinkCreateParam();
+        createParam.setCourseId(param.getCourseId());
+        createParam.setVideoId(param.getVideoId());
+        createParam.setCorpId(param.getCorpId());
+        createParam.setCompanyUserId(qwUser.getCompanyUserId());
+        createParam.setCompanyId(qwUser.getCompanyId());
+        createParam.setQwUserId(qwUser.getId());
+        createParam.setChatId(param.getChatId());
+        String linkUrl;
+        R createLink = createRoomLinkUrl(createParam);
+        if (createLink.get("code").equals(500)){
+            return R.error("链接生成失败!");
+        }
+
+        QwGroupChat groupChat = qwGroupChatService.selectQwGroupChatByChatId(param.getChatId());
+        List<QwGroupChatUser> qwGroupChatUserList = qwGroupChatUserService.selectQwGroupChatUserByChatIds(new String[]{param.getChatId()});
+        List<String> groupChatUserIds = PubFun.listToNewList(qwGroupChatUserList, QwGroupChatUser::getUserId);
+        if(!groupChatUserIds.isEmpty()){
+            List<GroupUserExternalVo> userList = qwExternalContactMapper.selectByGroupUser(groupChatUserIds);
+            Map<String, List<GroupUserExternalVo>> userMap = PubFun.listToMapByGroupList(userList, GroupUserExternalVo::getExternalUserId);
+            qwGroupChatUserList.forEach(e -> {
+                e.setUserList(userMap.getOrDefault(e.getUserId(), Collections.emptyList()));
+            });
+        }
+        try {
+            qwGroupChatUserList.stream().filter(e -> e.getUserList() != null && !e.getUserList().isEmpty()).forEach(e -> {
+                Map<String, GroupUserExternalVo> userMap = PubFun.listToMapByGroupObject(e.getUserList(), GroupUserExternalVo::getUserId);
+                GroupUserExternalVo vo = userMap.get(groupChat.getOwner());
+                if (vo != null && vo.getId() != null) {
+                    addWatchLogIfNeeded(param.getVideoId(), param.getCourseId(), vo.getFsUserId(), qwUser.getId(), qwUser.getCompanyUserId(), qwUser.getCompanyId(), vo.getId(), new Date(), new Date());
+                }
+            });
+        } catch (Exception e) {
+            log.error("群聊创建看课记录失败!", e);
+        }
+
+        linkUrl = (String) createLink.get("url");
+
+        FsUserCourse course = fsUserCourseService.selectFsUserCourseByCourseId(param.getCourseId());
+
+        JSONObject news = new JSONObject(true); // true 表示保持字段顺序
+        news.put("link", linkUrl);
+        news.put("title", course.getCourseName());
+        news.put("desc", param.getTitle());
+        news.put("imgUrl", course.getImgUrl());
+        return R.ok().put("news",news);
+    }
+
+
+    private void addWatchLogIfNeeded(Long videoId, Long courseId,
+                                     Long fsUserId, Long qwUserId, Long companyUserId,
+                                     Long companyId, Long externalId, Date startTime,Date createTime) {
+
+        try {
+            FsCourseWatchLog watchLog = new FsCourseWatchLog();
+            watchLog.setVideoId(videoId);
+            watchLog.setQwExternalContactId(externalId);
+            watchLog.setSendType(2);
+            watchLog.setQwUserId(qwUserId);
+            watchLog.setDuration(0L);
+            watchLog.setCourseId(courseId);
+            watchLog.setCompanyUserId(companyUserId);
+            watchLog.setCompanyId(companyId);
+            watchLog.setCreateTime(createTime);
+            watchLog.setUpdateTime(createTime);
+            watchLog.setLogType(3);
+            watchLog.setUserId(fsUserId);
+            watchLog.setCampPeriodTime(startTime);
+            //存看课记录
+            fsCourseWatchLogMapper.insertOrUpdateFsCourseWatchLog(watchLog);
+        }catch (Exception e){
+            log.error("一键群发失败-插入观看记录失败:"+e.getMessage());
+        }
+
+    }
+
+
 }

+ 1 - 0
fs-service/src/main/java/com/fs/course/service/impl/FsCourseQuestionBankServiceImpl.java

@@ -230,6 +230,7 @@ public class FsCourseQuestionBankServiceImpl implements IFsCourseQuestionBankSer
         logs.setQwUserId(param.getQwUserId() != null ? param.getQwUserId() : null );
         logs.setQuestionJson(JSONObject.toJSONString(param.getQuestions()));
         logs.setCreateTime(new Date());
+        logs.setPeriodId(param.getPeriodId());
 
         if (thisRightCount == param.getQuestions().size()) {
             logs.setIsRight(1);

+ 94 - 27
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -51,6 +51,7 @@ import com.fs.qw.mapper.QwUserMapper;
 import com.fs.qw.service.IQwCompanyService;
 import com.fs.qw.service.IQwExternalContactService;
 import com.fs.qwApi.Result.QwAddContactWayResult;
+import com.fs.qwApi.Result.QwGroupChatDetailsResult;
 import com.fs.qwApi.param.QwAddContactWayParam;
 import com.fs.qwApi.service.QwApiService;
 import com.fs.repeat.vo.RepeatUploadVo;
@@ -59,6 +60,7 @@ import com.fs.sop.mapper.SopUserLogsInfoMapper;
 import com.fs.sop.service.ISopUserLogsInfoService;
 import com.fs.system.service.ISysConfigService;
 import com.fs.voice.utils.StringUtil;
+import com.fs.wx.cp.config.WxCpProperties;
 import com.github.binarywang.wxpay.bean.transfer.TransferBillsResult;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
@@ -391,7 +393,6 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
     }
 
     @Override
-    @Transactional
     public R isAddKf(FsUserCourseVideoAddKfUParam param) {
         logger.info("zyp \n【判断添加客服】:{}",param);
         //查询用户
@@ -433,35 +434,101 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
     }
 
     private R handleRoom(FsUserCourseVideoAddKfUParam param,FsUser user) {
-        //查询客户列表
-        List<QwExternalContact> contacts = qwExternalContactMapper.selectQwExternalContactListVOByfsUserId(user.getUserId());
-        if (contacts.isEmpty()){
-            return R.error("未注册");
-        }
-        //找出对应销售匹配的客户
-        QwExternalContact matchedContact = contacts.stream()
-                .filter(contact -> contact.getQwUserId().equals(Long.parseLong(param.getQwUserId())))
-                .findFirst()
-                .orElse(null);
-
-        if (matchedContact==null){
-            return R.error("无权限观看,未添加本群主");
-        }
-
-        param.setQwExternalId(matchedContact.getId());
-//        //查询是否有添加客服
-//        QwExternalContact externalContact = qwExternalContactMapper.selectQwExternalContactById(param.getQwExternalId());
-//        if (externalContact==null){
-//            return R.error("客户不存在!");
+//        //查询客户列表
+//        List<QwExternalContact> contacts = qwExternalContactMapper.selectQwExternalContactListVOByfsUserId(user.getUserId());
+//        if (contacts.isEmpty()){
+//            return R.error("未注册");
+//        }
+//        //找出对应销售匹配的客户
+//        QwExternalContact matchedContact = contacts.stream()
+//                .filter(contact -> contact.getQwUserId().equals(Long.parseLong(param.getQwUserId())))
+//                .findFirst()
+//                .orElse(null);
+//
+//        if (matchedContact==null){
+//            return R.error("无权限观看,未添加本群主");
 //        }
-//        if (!externalContact.getQwUserId().equals(param.getUserId())){
-//            return R.error("无权限观看,添加群主非本群主");
+//
+//        param.setQwExternalId(matchedContact.getId());
+////        //查询是否有添加客服
+////        QwExternalContact externalContact = qwExternalContactMapper.selectQwExternalContactById(param.getQwExternalId());
+////        if (externalContact==null){
+////            return R.error("客户不存在!");
+////        }
+////        if (!externalContact.getQwUserId().equals(param.getUserId())){
+////            return R.error("无权限观看,添加群主非本群主");
+////        }
+//        FsCourseWatchLog log = courseWatchLogMapper.getWatchCourseVideoByExt(param.getQwExternalId(), param.getVideoId(),param.getQwUserId());
+//        if (log==null){
+//            createWatchLog(param);
 //        }
-        FsCourseWatchLog log = courseWatchLogMapper.getWatchCourseVideoByExt(param.getQwExternalId(), param.getVideoId(),param.getQwUserId());
-        if (log==null){
-            createWatchLog(param);
+//        return R.ok().put("qwExternalId",matchedContact.getId());
+        FsCourseLink courseLink = courseLinkMapper.selectFsCourseLinkByLink(param.getLink());
+        String msg = "<div style=\"color: red;margin-bottom: 15px;font-weight: bold;\">本课程为群会员独享<br>请长按二维码</div>\n" +
+                "\t\t\t\t\t<div style=\"color: #999;font-size: 14px;font-weight: bold;\">添加伴学助手免费领取会员权限</div>";
+        QwGroupChatDetailsResult result = qwApiService.groupChatDetails(courseLink.getChatId(), param.getCorpId());
+        if(result.getErrCode() != 0){
+            return R.error("企微接口请求失败,请联系管理员:" +result.getErrMsg());
+        }
+        List<QwGroupChatDetailsResult.Member> collect = result.getGroupChat().getMemberList().stream().filter(e -> e.getType() == 2).collect(Collectors.toList());
+        if(collect.isEmpty()){
+            return addCustomerService(param.getQwUserId(),msg);
+        }
+        Optional<QwGroupChatDetailsResult.Member> optional = collect.stream().filter(e -> e.getName().equals(user.getNickName()) || e.getName().equals(param.getNickName())).findFirst();
+        if(!optional.isPresent()){
+            return addCustomerService(param.getQwUserId(),msg);
+        }
+        QwGroupChatDetailsResult.Member member = optional.get();
+        QwExternalContact qwExternalContact = qwExternalContactMapper.selectOne(new QueryWrapper<QwExternalContact>().eq("user_id", result.getGroupChat().getOwner()).eq("external_user_id", member.getUserId()));
+        if(qwExternalContact==null){
+            return addCustomerService(param.getQwUserId(),msg);
+        }
+        Long qwExternalId = qwExternalContact.getId();
+        log.info("外部联系人数据:{}", qwExternalContact);
+//        addCompanyCompanyFsUser(param);
+        FsCourseWatchLog log = courseWatchLogMapper.getWatchCourseVideoByExt(qwExternalId, param.getVideoId(),param.getQwUserId());
+        if (log==null ){
+            return addCustomerService(param.getQwUserId(),msg);
+        }
+        //判断外部联系人有没有绑定userId
+        if (qwExternalContact.getFsUserId()!=null){
+            //有客户有小程序id  但 登录的小程序id和根据外部联系人id查出来的小程序id不一致
+            if (!qwExternalContact.getFsUserId().equals(param.getUserId())) {
+                return addCustomerService(param.getQwUserId(),msg);
+            }
+            List<QwExternalContact> qwExternalContacts = qwExternalContactMapper.selectQwExternalContactByMiniUserId(param.getUserId());
+            //匹配客户公司id
+            if (qwExternalContacts.stream().noneMatch(contact -> contact.getCorpId().equals(param.getCorpId()))){
+                return addCustomerService(param.getQwUserId(),msg);
+            }
+
+            //看课记录中userId为0绑定userId
+            if (log.getUserId()==null||log.getUserId().equals(0L) || !log.getUserId().equals(param.getUserId())){
+                log.setUserId(param.getUserId());
+            }
+
+            log.setUpdateTime(new Date());
+            courseWatchLogMapper.updateFsCourseWatchLog(log);
+
+            iSopUserLogsInfoService.updateSopUserInfoByExternalId(qwExternalId,param.getUserId());
+        }else {
+            //没绑定fsUser直接绑定fsUser
+            QwExternalContact contact = new QwExternalContact();
+            contact.setId(qwExternalId);
+            contact.setFsUserId(param.getUserId());
+            qwExternalContactMapper.updateQwExternalContact(contact);
+            FsUser fsUser = new FsUser();
+            fsUser.setUserId(user.getUserId());
+            fsUser.setIsAddQw(1);
+            fsUserMapper.updateFsUser(fsUser);
+            //绑定上之后 更新观看记录
+            //看课记录中userId为0绑定userId
+            log.setUserId(param.getUserId());
+            log.setUpdateTime(new Date());
+            courseWatchLogMapper.updateFsCourseWatchLog(log);
         }
-        return R.ok().put("qwExternalId",matchedContact.getId());
+
+        return R.ok().put("qwExternalId", qwExternalContact.getId());
     }
 
     private void createWatchLog(FsUserCourseVideoAddKfUParam param) {

+ 12 - 10
fs-service/src/main/java/com/fs/his/mapper/FsUserMapper.java

@@ -76,7 +76,9 @@ public interface FsUserMapper
      */
     public int deleteFsUserByUserIds(Long[] userIds);
     @Select({"<script> " +
-                "select f1.*,f2.nick_name tui_name,f2.phone tui_phone FROM fs_user f1 LEFT JOIN fs_user f2 ON f1.tui_user_id =f2.user_id "+
+                "select f1.*,f2.nick_name tui_name,f2.phone tui_phone,cu.nick_name AS companyUserNickName,co.company_name FROM fs_user f1 LEFT JOIN fs_user f2 ON f1.tui_user_id =f2.user_id "+
+            " LEFT JOIN company_user cu ON cu.user_id = f1.company_user_id"+
+            " LEFT JOIN company co on co.company_id = f1.company_id"+
             " where f1.is_del=0 "+
             "  <if test=\"nickName != null  and nickName != ''\"> and f1.nick_name like concat( #{nickName}, '%')</if>\n" +
             "            <if test=\"avatar != null  and avatar != ''\"> and f1.avatar = #{avatar}</if>\n" +
@@ -297,7 +299,7 @@ public interface FsUserMapper
     @Select("select * from fs_user where union_id=#{unionId}")
     FsUser selectFsUserByUnionId(String unionId);
 
-    List<UserListCountVO> getUserNumber(@Param("userId") Long userId);
+    List<UserListCountVO> getUserNumber(@Param("userId") Long userId, @Param("companyId") Long companyId);
 
     int getRepeatUserNumber(@Param("userId") Long userId);
 
@@ -307,9 +309,9 @@ public interface FsUserMapper
 
     UserDetailsVO getCountRedPacket(@Param("userId") Long userId, @Param("fsUserId") Long fsUserId, @Param("dateTag") String dateTag);
 
-    FsUserSummaryCountVO countUserSummary(@Param("userId") Long userId);
+    FsUserSummaryCountVO countUserSummary(@Param("userId") Long userId, @Param("companyId") Long companyId);
 
-    List<FsUserSummaryCountTagVO> countTag(@Param("userId") Long userId);
+    List<FsUserSummaryCountTagVO> countTag(@Param("userId") Long userId, @Param("companyId") Long companyId);
 
     Map<String, Long> countUserCourse(UserStatisticsCommonParam param);
 
@@ -317,21 +319,21 @@ public interface FsUserMapper
 
     Map<String, Long> countCourseDetails(UserStatisticsCommonParam param);
 
-    List<FsUserRankingVO> countUserRankingByComplete(@Param("userId") Long userId, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("periodId") String periodId, @Param("videoId") String videoId, @Param("order") String order);
+    List<FsUserRankingVO> countUserRankingByComplete(@Param("userId") Long userId, @Param("companyId") Long companyId, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("periodId")String periodId, @Param("videoId")String videoId, @Param("order")String order);
 
-    List<FsUserRankingVO> countUserRankingByRight(@Param("userId") Long userId, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("periodId") String periodId, @Param("videoId") String videoId, @Param("order") String order);
+    List<FsUserRankingVO> countUserRankingByRight(@Param("userId") Long userId, @Param("companyId") Long companyId, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("periodId")String periodId, @Param("videoId")String videoId, @Param("order")String order);
 
-    List<FsCourseRankingVO> countCourseRankingByComplete(@Param("userId") Long userId, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("periodId") String periodId, @Param("videoId") String videoId, @Param("order") String order);
+    List<FsCourseRankingVO> countCourseRankingByComplete(@Param("userId") Long userId, @Param("companyId") Long companyId, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("periodId")String periodId, @Param("videoId")String videoId, @Param("order")String order);
 
-    List<FsCourseRankingVO> countCourseRankingByRight(@Param("userId") Long userId, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("periodId") String periodId, @Param("videoId") String videoId, @Param("order") String order);
+    List<FsCourseRankingVO> countCourseRankingByRight(@Param("userId") Long userId, @Param("companyId") Long companyId, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("periodId")String periodId, @Param("videoId")String videoId, @Param("order")String order);
 
     Map<String, Object> countUserRedPacket(UserStatisticsCommonParam param);
 
     List<FsCourseAnalysisCountVO> courseAnalysisCourseCount(CourseAnalysisParam param);
 
-    CompanyUserSummaryCountVO companyUserCount(@Param("companyUserId") String companyUserId);
+    CompanyUserSummaryCountVO companyUserCount(@Param("companyUserId")String companyUserId, @Param("companyId") Long companyId);
 
-    CompanyUserSummaryCountVO newUserRedPacketCount(@Param("companyUserId") String companyUserId);
+    CompanyUserSummaryCountVO newUserRedPacketCount(@Param("companyUserId")String companyUserId, @Param("companyId") Long companyId);
 
 
     @Select("select * from fs_user where course_ma_open_id=#{openId}")

+ 85 - 37
fs-service/src/main/java/com/fs/his/service/impl/FsUserServiceImpl.java

@@ -509,7 +509,7 @@ public class FsUserServiceImpl implements IFsUserService
 
     @Override
     public PageInfo<FsUserPageListVO> selectFsUserPageList(FsUserPageListParam param) {
-          CompanyUser companyUser = companyUserMapper.selectCompanyUserById(param.getUserId());
+
 
 //        List<CompanyRole> companyRoles = companyRoleMapper.selectRolePermissionByUserId(param.getUserId());
 //        List<CompanyUser> companyUsers;
@@ -527,40 +527,42 @@ public class FsUserServiceImpl implements IFsUserService
 //            companyUsers = new ArrayList<>();
 //        }
 
-        if(ObjectUtils.isNotNull(companyUser)){
-            if (companyUser.isAdmin()){
-                param.setUserId(0L);
-                param.setCompanyId(companyUser.getCompanyId());
-            }
+        if (param.getUserId() != null) {
+            CompanyUser companyUser = companyUserMapper.selectCompanyUserById(param.getUserId());
+                if (companyUser.isAdmin()){
+                    param.setUserId(0L);
+                    param.setCompanyId(companyUser.getCompanyId());
+                }
+        }
 
-            List<FsUserPageListVO> fsUserPageListVOS = fsUserMapper.selectFsUserPageList(param);
-            // 获取当前销售所有重粉会员
-            List<FsUserCompanyUser> fsUserCompanyUsers = fsUserCompanyUserMapper.selectRepeatUser(companyUser.getUserId());
+        PageHelper.startPage(param.getPageNum(), param.getPageSize());
 
-            if(!fsUserCompanyUsers.isEmpty()){
-                List<Long> userIds = fsUserCompanyUsers.stream().map(FsUserCompanyUser::getUserId).collect(Collectors.toList());
-                // 获取会员所属的重粉销售
-                List<FsUserCompanyUser> repeatCompanyUserNames = fsUserCompanyUserMapper.selectRepeatCompanyUserName(userIds);
-                Map<Long, String> map = repeatCompanyUserNames.stream().collect(Collectors.toMap(FsUserCompanyUser::getUserId, FsUserCompanyUser::getRepeatCompanyUserName));
+        List<FsUserPageListVO> fsUserPageListVOS = fsUserMapper.selectFsUserPageList(param);
+        // 获取当前销售所有重粉会员
+        List<FsUserCompanyUser> fsUserCompanyUsers = fsUserCompanyUserMapper.selectRepeatUser(param.getUserId());
 
-                for (FsUserPageListVO fsUserPageListVO : fsUserPageListVOS) {
-                    fsUserPageListVO.setRepeatCompanyUserName(map.get(fsUserPageListVO.getUserId()));
-                    if ("微信用户".equals(fsUserPageListVO.getNickname()) && StringUtils.isNotEmpty(fsUserPageListVO.getPhone())) {
-                        fsUserPageListVO.setNickname(fsUserPageListVO.getPhone());
-                    }
-                    if(StringUtils.isNotEmpty(fsUserPageListVO.getTag()) && fsUserPageListVO.getIsRepeatFans() == 0){
-                        StringBuilder newTag = removeRepeatFansTag(fsUserPageListVO);
-                        fsUserPageListVO.setTag(newTag.toString());
-                    }
+        if(!fsUserCompanyUsers.isEmpty()){
+            List<Long> userIds = fsUserCompanyUsers.stream().map(FsUserCompanyUser::getUserId).collect(Collectors.toList());
+            // 获取会员所属的重粉销售
+            List<FsUserCompanyUser> repeatCompanyUserNames = fsUserCompanyUserMapper.selectRepeatCompanyUserName(userIds);
+            Map<Long, String> map = repeatCompanyUserNames.stream().collect(Collectors.toMap(FsUserCompanyUser::getUserId, FsUserCompanyUser::getRepeatCompanyUserName));
+
+            for (FsUserPageListVO fsUserPageListVO : fsUserPageListVOS) {
+                fsUserPageListVO.setRepeatCompanyUserName(map.get(fsUserPageListVO.getUserId()));
+                if ("微信用户".equals(fsUserPageListVO.getNickname()) && StringUtils.isNotEmpty(fsUserPageListVO.getPhone())) {
+                    fsUserPageListVO.setNickname(fsUserPageListVO.getPhone());
+                }
+                if(StringUtils.isNotEmpty(fsUserPageListVO.getTag()) && fsUserPageListVO.getIsRepeatFans() == 0){
+                    StringBuilder newTag = removeRepeatFansTag(fsUserPageListVO);
+                    fsUserPageListVO.setTag(newTag.toString());
                 }
-                return new PageInfo<>(fsUserPageListVOS);
-            } else {
-                return new PageInfo<>(fsUserPageListVOS);
             }
-        }else {
-            return null;
+            return new PageInfo<>(fsUserPageListVOS);
+        } else {
+            return new PageInfo<>(fsUserPageListVOS);
         }
 
+
     }
 
     private static StringBuilder removeRepeatFansTag(FsUserPageListVO fsUserPageListVO) {
@@ -700,7 +702,14 @@ public class FsUserServiceImpl implements IFsUserService
 
     @Override
     public UserListPageVO getUserNumber(Long userId) {
-        List<UserListCountVO> list = fsUserMapper.getUserNumber(userId);
+        // 判断是否是管理员
+        Long companyId = null;
+        CompanyUser companyUser = companyUserMapper.selectCompanyUserById(userId);
+        if (companyUser != null && companyUser.isAdmin()){
+            userId = 0L;
+            companyId = companyUser.getCompanyId();
+        }
+        List<UserListCountVO> list = fsUserMapper.getUserNumber(userId, companyId);
         Map<String, Integer> map = list.stream()
                 .collect(Collectors.toMap(UserListCountVO::getStatus, UserListCountVO::getNum, (v1, v2) -> v1));
         UserListPageVO pageVO = new UserListPageVO();
@@ -744,8 +753,15 @@ public class FsUserServiceImpl implements IFsUserService
 
     @Override
     public FsUserSummaryCountVO userSummaryCount(Long userId) {
-        FsUserSummaryCountVO fsUserSummaryCountVO = fsUserMapper.countUserSummary(userId);
-        List<FsUserSummaryCountTagVO> countTagList = fsUserMapper.countTag(userId);
+        // 判断是否是管理员
+        Long companyId = null;
+        CompanyUser companyUser = companyUserMapper.selectCompanyUserById(userId);
+        if (companyUser != null && companyUser.isAdmin()){
+            userId = 0L;
+            companyId = companyUser.getCompanyId();
+        }
+        FsUserSummaryCountVO fsUserSummaryCountVO = fsUserMapper.countUserSummary(userId, companyId);
+        List<FsUserSummaryCountTagVO> countTagList = fsUserMapper.countTag(userId, companyId);
         fsUserSummaryCountVO.setTagList(countTagList);
         return fsUserSummaryCountVO;
     }
@@ -759,6 +775,11 @@ public class FsUserServiceImpl implements IFsUserService
     public FsUserStatisticsVO userStatisticsDetails(UserStatisticsCommonParam param) {
         FsUserStatisticsVO userStatisticsVO = getUserStatistics(param);
 
+        // 判断是否是管理员
+        CompanyUser companyUser = companyUserMapper.selectCompanyUserById(param.getUserId());
+        if (companyUser != null && companyUser.isAdmin()){
+            param.setUserId(0L);
+        }
         //统计课程数据详情,在查询统计详情的时候需要显示
         Map<String, Long> courseDetailsMap = fsUserMapper.countCourseDetails(param);
         if(courseDetailsMap != null && courseDetailsMap.get("courseNum") != null && courseDetailsMap.get("videoNum") != null && courseDetailsMap.get("courseUserNum") != null){
@@ -772,25 +793,39 @@ public class FsUserServiceImpl implements IFsUserService
     @Override
     public List<FsUserRankingVO> userRanking(Long userId, String startTime, String endTime, String periodId, String videoId, String order, Integer type) {
         List<FsUserRankingVO> listVO = Collections.emptyList();
+        // 判断是否是管理员
+        Long companyId = null;
+        CompanyUser companyUser = companyUserMapper.selectCompanyUserById(userId);
+        if (companyUser != null && companyUser.isAdmin()){
+            userId = 0L;
+            companyId = companyUser.getCompanyId();
+        }
         if(type == 1){
             //按完播率
-            listVO = fsUserMapper.countUserRankingByComplete(userId, startTime, endTime, periodId, videoId, order);
+            listVO = fsUserMapper.countUserRankingByComplete(userId, companyId, startTime, endTime, periodId, videoId, order);
         }
         if(type == 2){
             //按正确率
-            listVO = fsUserMapper.countUserRankingByRight(userId, startTime, endTime, periodId, videoId, order);
+            listVO = fsUserMapper.countUserRankingByRight(userId, companyId, startTime, endTime, periodId, videoId, order);
         }
         return listVO;
     }
 
     @Override
     public List<FsCourseRankingVO> courseRanking(Long userId, String startTime, String endTime, String periodId, String videoId, String order, Integer type) {
+        // 判断是否是管理员
+        Long companyId = null;
+        CompanyUser companyUser = companyUserMapper.selectCompanyUserById(userId);
+        if (companyUser != null && companyUser.isAdmin()){
+            userId = 0L;
+            companyId = companyUser.getCompanyId();
+        }
         List<FsCourseRankingVO> list = Collections.emptyList();
         if(type == 1){
-            list = fsUserMapper.countCourseRankingByComplete(userId, startTime, endTime, periodId, videoId, order);
+            list = fsUserMapper.countCourseRankingByComplete(userId, companyId, startTime, endTime, periodId, videoId, order);
         }
         if(type == 2){
-            list = fsUserMapper.countCourseRankingByRight(userId, startTime, endTime, periodId, videoId, order);
+            list = fsUserMapper.countCourseRankingByRight(userId, companyId, startTime, endTime, periodId, videoId, order);
         }
 
         return list;
@@ -862,8 +897,15 @@ public class FsUserServiceImpl implements IFsUserService
 
     @Override
     public CompanyUserSummaryCountVO companyUserSummaryCount(Long userId, String companyUserId) {
-        CompanyUserSummaryCountVO companyUserCount = fsUserMapper.companyUserCount(companyUserId);
-        CompanyUserSummaryCountVO newUserRedPacketCount = fsUserMapper.newUserRedPacketCount(companyUserId);
+        // 判断是否是管理员
+        Long companyId = null;
+        CompanyUser companyUser = companyUserMapper.selectCompanyUserById(userId);
+        if (companyUser != null && companyUser.isAdmin()){
+            companyUserId = String.valueOf(0);
+            companyId = companyUser.getCompanyId();
+        }
+        CompanyUserSummaryCountVO companyUserCount = fsUserMapper.companyUserCount(companyUserId, companyId);
+        CompanyUserSummaryCountVO newUserRedPacketCount = fsUserMapper.newUserRedPacketCount(companyUserId, companyId);
         CompanyUserSummaryCountVO vo = new CompanyUserSummaryCountVO();
         BeanUtils.copyProperties(companyUserCount, vo);
         vo.setUserRedPacketNum(newUserRedPacketCount.getUserRedPacketNum());
@@ -948,6 +990,12 @@ public class FsUserServiceImpl implements IFsUserService
     private FsUserStatisticsVO getUserStatistics(UserStatisticsCommonParam param) {
         FsUserStatisticsVO fsUserStatisticsVO = new FsUserStatisticsVO();
 
+        // 判断是否是管理员
+        CompanyUser companyUser = companyUserMapper.selectCompanyUserById(param.getUserId());
+        if (companyUser != null && companyUser.isAdmin()){
+            param.setUserId(0L);
+            param.setCompanyId(companyUser.getCompanyId());
+        }
         // 获取课程统计
         Map<String, Long> couserMap = fsUserMapper.countUserCourse(param);
         if (couserMap != null) {

+ 10 - 0
fs-service/src/main/java/com/fs/his/vo/FsUserVO.java

@@ -2,6 +2,7 @@ package com.fs.his.vo;
 
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fs.common.annotation.Excel;
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import javax.crypto.Cipher;
@@ -99,6 +100,15 @@ public class FsUserVO implements Serializable {
 
     private String source;//app来源
 
+
+    @ApiModelProperty(value = "销售名称")
+    @Excel(name = "所属销售", sort = 10)
+    private String companyUserNickName;
+
+    @ApiModelProperty(value = "所属公司")
+    @Excel(name = "所属公司", sort = 9)
+    private String companyName;
+
     public void setPhone(String phone)
     {
        this.phone = phone;

+ 3 - 0
fs-service/src/main/java/com/fs/qw/mapper/CustomerTransferApprovalMapper.java

@@ -59,4 +59,7 @@ public interface CustomerTransferApprovalMapper
      * @return 结果
      */
     public int deleteCustomerTransferApprovalByIds(Long[] ids);
+
+
+    List<CustomerTransferApproval> queryPendingData();
 }

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

@@ -59,4 +59,9 @@ public interface ICustomerTransferApprovalService
      * @return 结果
      */
     public int deleteCustomerTransferApprovalById(Long id);
+
+    /**
+     * 自动审批通过
+     */
+    public void autoApprovePass();
 }

+ 13 - 0
fs-service/src/main/java/com/fs/qw/service/impl/CustomerTransferApprovalServiceImpl.java

@@ -18,6 +18,7 @@ import com.fs.qw.vo.TransferCustomDTO;
 import com.fs.store.service.cache.IFsUserCacheService;
 import com.hc.openapi.tool.util.StringUtils;
 import org.apache.http.util.Asserts;
+import org.springframework.aop.framework.AopContext;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.EnableAspectJAutoProxy;
 import org.springframework.stereotype.Service;
@@ -263,4 +264,16 @@ public class CustomerTransferApprovalServiceImpl implements ICustomerTransferApp
     {
         return customerTransferApprovalMapper.deleteCustomerTransferApprovalById(id);
     }
+
+    @Override
+    public void autoApprovePass() {
+        List<CustomerTransferApproval> customerTransferApprovals = customerTransferApprovalMapper.queryPendingData();
+        for (CustomerTransferApproval approval : customerTransferApprovals) {
+            approval.setApprovalStatus(1);
+            approval.setApprovalRemark("自动审批");
+            approval.setApproverUserId(1L);
+            ICustomerTransferApprovalService service = (ICustomerTransferApprovalService) AopContext.currentProxy();
+            service.updateCustomerTransferApproval(approval);
+        }
+    }
 }

+ 4 - 0
fs-service/src/main/java/com/fs/sop/domain/QwSop.java

@@ -116,4 +116,8 @@ public class QwSop implements Serializable
     @Excel(name = "开启评论或者弹幕,1-开启评论;2-开启弹幕;3-都关闭")
     private Integer openCommentStatus;
 
+    /**
+     * 是否按照营期 发送官方群发 1是 2否(否的时候按单链发)
+     */
+    private Integer isSampSend;
 }

+ 4 - 1
fs-service/src/main/java/com/fs/sop/mapper/QwSopLogsMapper.java

@@ -197,7 +197,10 @@ public interface QwSopLogsMapper extends BaseMapper<QwSopLogs> {
 
 
     @DataSource(DataSourceType.SOP)
-    public List<QwSopLogs> selectSopLogsByCreateCorpMassSending(@Param("date") String date);
+    public List<QwSopLogs> createCorpMassSending(@Param("date") String date);
+
+    @DataSource(DataSourceType.SOP)
+    public List<QwSopLogs> selectSopLogsByCreateCorpMassSending(@Param("taskStartTime") String taskStartTime,@Param("taskEndTime") String taskEndTime);
 
     /**
     * 为了避免一直轮询无效(发送不了,给不了反馈的)数据,只查与定时的时间过后,之前3天内的的数据反馈

+ 1 - 1
fs-service/src/main/java/com/fs/sop/service/IQwSopLogsService.java

@@ -95,7 +95,7 @@ public interface IQwSopLogsService
     /**
      *  创建企业群发(按照营期发)
      */
-    public void createCorpMassSendingByUserLogs(String date);
+    public void createCorpMassSendingByUserLogs(String taskStartTime,String taskEndTime);
 
     /**
      *  检索执行符合条件的定时任务的结果回调(企业微信)

+ 170 - 132
fs-service/src/main/java/com/fs/sop/service/impl/QwSopLogsServiceImpl.java

@@ -54,6 +54,7 @@ import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.concurrent.*;
 import java.util.function.Function;
+import java.util.stream.Collector;
 import java.util.stream.Collectors;
 
 /**
@@ -744,12 +745,44 @@ public class QwSopLogsServiceImpl implements IQwSopLogsService
             List<QwSopLogsDoSendListTVO> logsByJsApi = qwSopLogsMapper.getQwSopLogsByJsApiAll(param);
 
 
+//            // 优先返回 sendType == 8 的第一条记录
+//            List<QwSopLogsDoSendListTVO> result = logsByJsApi.stream()
+//                    .filter(log -> log.getSendType() == 8)
+//                    .findFirst()
+//                    .map(Collections::singletonList) // 单元素不可变 List
+//                    .orElse(logsByJsApi); // 如果没有匹配项,返回原列表
             // 优先返回 sendType == 8 的第一条记录
             List<QwSopLogsDoSendListTVO> result = logsByJsApi.stream()
-                    .filter(log -> log.getSendType() == 8)
-                    .findFirst()
-                    .map(Collections::singletonList) // 单元素不可变 List
-                    .orElse(logsByJsApi); // 如果没有匹配项,返回原列表
+                    .collect(Collector.of(
+                            () -> new Object() {
+                                QwSopLogsDoSendListTVO type8 = null;
+                                List<QwSopLogsDoSendListTVO> type9List = new ArrayList<>();
+                                List<QwSopLogsDoSendListTVO> otherList = new ArrayList<>();
+                            },
+                            (acc, log) -> {
+                                if (acc.type8 == null && log.getSendType() == 8) {
+                                    acc.type8 = log;
+                                } else if (acc.type8 == null) {
+                                    if (log.getSendType() == 9) {
+                                        acc.type9List.add(log);
+                                    } else {
+                                        acc.otherList.add(log);
+                                    }
+                                }
+                            },
+                            (acc1, acc2) -> { throw new UnsupportedOperationException(); },
+                            acc -> {
+                                if (acc.type8 != null) {
+                                    return Collections.singletonList(acc.type8);
+                                } else if (!acc.type9List.isEmpty()) {
+                                    List<QwSopLogsDoSendListTVO> combined = new ArrayList<>(acc.type9List.size() + acc.otherList.size());
+                                    combined.addAll(acc.type9List);
+                                    combined.addAll(acc.otherList);
+                                    return combined;
+                                }
+                                return logsByJsApi;
+                            }
+                    ));
 
             // 查询员工信息的id
             QwUser qwUser = qwExternalContactService.getQwUserByRedis(param.getCorpId().trim(),param.getQwUserId().trim());
@@ -1326,173 +1359,178 @@ public class QwSopLogsServiceImpl implements IQwSopLogsService
      * 该方法负责处理企业微信的群发消息创建和发送
      */
     @Override
-    public void createCorpMassSending(String date) {
+    public void createCorpMassSending(String date)  {
+
         long startTime = System.currentTimeMillis();
         logger.info("开始执行企业微信群发消息创建任务");
 
-        String json = configService.selectConfigByKey("course.config");
-        CourseConfig config = JSON.parseObject(json, CourseConfig.class);
-
-        if (config == null) {
-            logger.error("课程默认配置为空,不执行");
-            return;
-        }
-        // 获取需要发送的SOP日志记录
-        List<QwSopLogs> qwSopLogs = qwSopLogsMapper.selectSopLogsByCreateCorpMassSending(date);
-//        List<QwSopLogs> qwSopLogs = qwSopLogsMapper.checkQwSopLogs();
+        List<QwSopLogs> qwSopLogs = qwSopLogsMapper.createCorpMassSending(date);
         if (qwSopLogs.isEmpty()) {
             logger.error("zyp \n【企微官方群发记录为空】");
             return;
         }
 
-        // 按照企业员工ID、发送时间、SOP ID和企业ID进行分组
         Map<String, List<QwSopLogs>> groupedLogs = new HashMap<>();
         for (QwSopLogs log : qwSopLogs) {
             String key = log.getQwUserid() + "|" + log.getSendTime() + "|" + log.getSopId() + "|" + log.getCorpId();
             groupedLogs.computeIfAbsent(key, k -> new ArrayList<>()).add(log);
         }
 
-        // 创建线程池,使用固定大小的线程池以避免过多线程导致的资源竞争
         int threadCount = Math.min(10, Runtime.getRuntime().availableProcessors() + 1);
         ExecutorService executorService = Executors.newFixedThreadPool(threadCount);
-
-        // 创建用于发送消息的嵌套线程池
         ExecutorService messageExecutorService = Executors.newFixedThreadPool(20);
-
-        // 用于存储需要批量更新的日志记录,使用线程安全的集合
         List<QwSopLogs> updateList = Collections.synchronizedList(new ArrayList<>());
 
-        // 使用CountDownLatch等待所有任务完成
         CountDownLatch latch = new CountDownLatch(groupedLogs.size());
 
-        // 处理每个分组
-        for (Map.Entry<String, List<QwSopLogs>> entry : groupedLogs.entrySet()) {
-            String key = entry.getKey();
-            List<QwSopLogs> logs = entry.getValue();
-            String[] keys = key.split("\\|");
-            String qwUserid = keys[0];
-            String corpId = keys[3];
-
-//            QwUser qwUser = qwUserMapper.selectQwUserByCorpIdAndUserId(corpId, qwUserid);
-            // 查询员工信息的id
-            QwUser qwUser = qwExternalContactService.getQwUserByRedis(corpId.trim(),qwUserid.trim());
-            if (qwUser != null && qwUser.getIsDel() == 0) {
-                // 提交到线程池处理每个分组
-                executorService.submit(() -> {
-                    try {
-                        // 按外部用户ID分组
-                        Map<String, List<QwSopLogs>> userLogsMap = new HashMap<>();
-                        for (QwSopLogs log : logs) {
-                            String externalUserId = log.getExternalUserId();
-                            userLogsMap.computeIfAbsent(externalUserId, k -> new ArrayList<>()).add(log);
-                        }
-
-                        // 使用嵌套的CountDownLatch等待所有消息发送完成
-                        CountDownLatch messageLatch = new CountDownLatch(userLogsMap.size());
-
-                        // 处理每个外部用户
-                        for (Map.Entry<String, List<QwSopLogs>> userEntry : userLogsMap.entrySet()) {
-                            String externalUserId = userEntry.getKey();
-                            List<QwSopLogs> userLogs = userEntry.getValue();
+        try {
+            for (Map.Entry<String, List<QwSopLogs>> entry : groupedLogs.entrySet()) {
+                String key = entry.getKey();
+                List<QwSopLogs> logs = entry.getValue();
+                String[] keys = key.split("\\|");
+                String qwUserid = keys[0];
+                String corpId = keys[3];
+
+                QwUser qwUser = qwExternalContactService.getQwUserByRedis(corpId.trim(), qwUserid.trim());
+                if (qwUser != null && qwUser.getIsDel() == 0) {
+                    executorService.submit(() -> {
+                        try {
+                            Map<String, List<QwSopLogs>> userLogsMap = new HashMap<>();
+                            for (QwSopLogs log : logs) {
+                                userLogsMap.computeIfAbsent(log.getExternalUserId(), k -> new ArrayList<>()).add(log);
+                            }
 
-                            // 提交到消息发送线程池
-                            messageExecutorService.submit(() -> {
-                                try {
-                                    QwMsgTemplateSop templateSop = new QwMsgTemplateSop();
-                                    templateSop.setChatType("single");
-                                    templateSop.setAllowSelect(false);
-                                    templateSop.setSender(qwUserid);
-                                    templateSop.setExternalUseridList(Collections.singletonList(externalUserId));
-
-                                    List<QwMsgTemplateSop.Attachment> attachments = new ArrayList<>();
-                                    boolean hasError = false;
-
-                                    for (QwSopLogs log : userLogs) {
-                                        try {
-                                            QwSopTempSetting.Content content = JSON.parseObject(log.getContentJson(), QwSopTempSetting.Content.class);
-                                            if (content == null || content.getSetting() == null) continue;
-                                            Long courseId = content.getCourseId();
-                                            for (QwSopTempSetting.Content.Setting set : content.getSetting()) {
-                                                processContent(set, corpId, templateSop, attachments, courseId);
+                            CountDownLatch messageLatch = new CountDownLatch(userLogsMap.size());
+                            for (Map.Entry<String, List<QwSopLogs>> userEntry : userLogsMap.entrySet()) {
+                                String externalUserId = userEntry.getKey();
+                                List<QwSopLogs> userLogs = userEntry.getValue();
+
+                                messageExecutorService.submit(() -> {
+                                    try {
+                                        QwMsgTemplateSop templateSop = new QwMsgTemplateSop();
+                                        templateSop.setChatType("single");
+                                        templateSop.setAllowSelect(false);
+                                        templateSop.setSender(qwUserid);
+                                        templateSop.setExternalUseridList(Collections.singletonList(externalUserId));
+
+                                        List<QwMsgTemplateSop.Attachment> attachments = new ArrayList<>();
+                                        boolean hasError = false;
+                                        for (QwSopLogs log : userLogs) {
+                                            try {
+                                                QwSopTempSetting.Content content = JSON.parseObject(log.getContentJson(), QwSopTempSetting.Content.class);
+                                                if (content == null || content.getSetting() == null) continue;
+                                                Long courseId = content.getCourseId();
+                                                for (QwSopTempSetting.Content.Setting set : content.getSetting()) {
+                                                    processContent(set, corpId, templateSop, attachments, courseId);
+                                                }
+                                            } catch (Exception e) {
+                                                logger.error("消息内容解析失败,logId:{},{},{}", log.getId(), e,key);
+                                                hasError = true;
                                             }
-                                        } catch (Exception e) {
-                                            logger.error("消息内容解析失败,logId:{}", log.getId(), e);
-                                            hasError = true;
                                         }
-                                    }
+                                        if (!hasError && (!attachments.isEmpty() || templateSop.getTextContent() != null)) {
+                                            templateSop.setAttachments(attachments);
+                                            try {
+                                                QwAddMsgTemplateResult result = qwApiService.addMsgTemplateBySop(templateSop, corpId);
+                                                if (result.getErrCode() == 0 || result.getErrCode() == 41063){
+                                                    for (QwSopLogs log : userLogs) {
+                                                        log.setSendStatus(1L);
+                                                        log.setMsgId(result.getMsgId());
+                                                        updateList.add(log);
+                                                    }
+                                                }else {
+
+                                                    for (QwSopLogs log : userLogs) {
+                                                        log.setSendType(2);
+                                                        log.setSendStatus(3L);
+                                                        log.setRemark("官方有误,sop补发");
+                                                        log.setReceivingStatus(0L);
+                                                        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+                                                        LocalDateTime currentTime = LocalDateTime.now();
+                                                        String newTimeString = currentTime.format(formatter);
+                                                        log.setSendTime(newTimeString);
+                                                        log.setSort(30000001);
+                                                        updateList.add(log);
+                                                    }
 
-                                    if (!hasError && (!attachments.isEmpty() || templateSop.getTextContent() != null)) {
-                                        templateSop.setAttachments(attachments);
-                                        try {
-                                            QwAddMsgTemplateResult result = qwApiService.addMsgTemplateBySop(templateSop, corpId);
-                                            for (QwSopLogs log : userLogs) {
-                                                log.setSendStatus(result.getErrCode() == 0 || result.getErrCode() == 41063 ? 1L : 0L);
-                                                log.setMsgId(result.getMsgId());
-                                                updateList.add(log);
-                                            }
-                                            if (result.getErrCode() != 0 && result.getErrCode() != 41063){
-                                                logger.error("企业微信接口-消息发送失败,corpId:{},errCode:{},errMsg:{}", corpId, result.getErrCode(), result.getErrMsg());
-                                            }
-                                        } catch (Exception e) {
-                                            logger.error("消息发送失败,user:{}", externalUserId, e);
-                                            for (QwSopLogs log : userLogs) {
-                                                log.setSendStatus(0L);
-                                                updateList.add(log);
+                                                    logger.error("企业微信接口-消息发送失败-进入sop补偿,corpId:{},errCode:{},errMsg:{},key:{}", corpId, result.getErrCode(), result.getErrMsg(),key);
+                                                }
+                                            } catch (Exception e) {
+                                                logger.error("消息发送失败,user:{},{},{}", externalUserId, e,key);
+                                                for (QwSopLogs log : userLogs) {
+                                                    log.setSendStatus(0L);
+                                                    log.setRemark("信息异常");
+                                                    updateList.add(log);
+                                                }
                                             }
                                         }
+
+                                    } finally {
+                                        logger.info("执行结束-messageLatch-countDown:"+updateList.size());
+                                        messageLatch.countDown();
                                     }
-                                } finally {
-                                    messageLatch.countDown();
-                                }
-                            });
-                        }
+                                });
 
-                        // 等待所有消息发送完成
-                        try {
+                            }
+
+                            logger.info("messageExecutorService-updateList总量:"+updateList.size());
+
+                            // 等待所有消息发送完成
                             messageLatch.await();
+
                         } catch (InterruptedException e) {
-                            logger.error("等待消息发送完成时被中断", e);
+                            logger.info("messageExecutorService-Thread.currentThread().interrupt():"+updateList.size());
                             Thread.currentThread().interrupt();
+                        } finally {
+                            logger.info("finally-latch.countDown:"+updateList.size());
+                            latch.countDown();
                         }
-                    } finally {
-                        latch.countDown();
-                    }
-                });
-            }else {
-                logger.error("官方群发 员工信息有误:"+corpId+":"+qwUserid);
+                    });
+                } else {
+                    logger.error("员工信息无效-不存在或被删除,corpId:{}, userId:{}", corpId, qwUserid);
+
+                    latch.countDown(); // 确保每个分组都减少计数
+                }
             }
 
-        }
+            latch.await(); // 等待所有分组提交的任务完成
+            logger.info("关闭线程池并等待任务完成:"+updateList.size());
+            // 关闭线程池并等待任务完成
+            executorService.shutdown();
+            messageExecutorService.shutdown();
+            if (!executorService.awaitTermination(300, TimeUnit.SECONDS)) {
+                logger.error("ExecutorService未完全关闭");
+            }
+            if (!messageExecutorService.awaitTermination(300, TimeUnit.SECONDS)) {
+                logger.error("MessageExecutorService未完全关闭");
+            }
 
-        // 等待所有分组处理完成
-        try {
-            latch.await();
-        } catch (InterruptedException e) {
-            logger.error("等待分组处理完成时被中断", e);
-            Thread.currentThread().interrupt();
-        }
+            // 5. 同步块生成快照(终极防护),创建快照避免并发修改
+            List<QwSopLogs> batchList;
+            synchronized (updateList) { // 加锁确保无并发修改
+                batchList = new ArrayList<>(updateList);
+            }
 
-        // 批量更新发送状态,每500条一批
-        if (!updateList.isEmpty()) {
-            int batchSize = 500;
-            for (int i = 0; i < updateList.size(); i += batchSize) {
-                int endIndex = Math.min(i + batchSize, updateList.size());
-                List<QwSopLogs> batch = updateList.subList(i, endIndex);
-                try {
-                    qwSopLogsMapper.batchUpdateStatus(batch);
-                    logger.info("批量修改 sopLogs 成功,修改数量: " + batch.size());
-                } catch (Exception e) {
-                    logger.error("批量修改 sopLogs 失败", e);
+
+            logger.info("批量修改总数: {}", batchList.size());
+
+            if (!batchList.isEmpty()){
+                int batchSize = 1000;
+                for (int i = 0; i < batchList.size(); i += batchSize) {
+                    int end = Math.min(i + batchSize, batchList.size());
+                    List<QwSopLogs> subList = batchList.subList(i, end);
+                    qwSopLogsMapper.batchUpdateStatus(subList);
                 }
             }
-        }
 
-        // 关闭线程池
-        executorService.shutdown();
-        messageExecutorService.shutdown();
 
-        long endTime = System.currentTimeMillis();
-        logger.info("企业微信群发消息创建任务执行完成,总耗时: {} 毫秒", (endTime - startTime));
+        } catch (InterruptedException e) {
+            logger.error("线程中断异常", e);
+            Thread.currentThread().interrupt();
+        } finally {
+            long endTime = System.currentTimeMillis();
+            logger.info("任务完成,耗时: {} 毫秒", endTime - startTime);
+        }
     }
 
     // 处理不同类型的内容
@@ -1593,12 +1631,12 @@ public class QwSopLogsServiceImpl implements IQwSopLogsService
 //    }
 
     @Override
-    public void createCorpMassSendingByUserLogs(String date) {
+    public void createCorpMassSendingByUserLogs(String taskStartTime,String taskEndTime) {
 
         long startTime = System.currentTimeMillis();
         logger.info("开始执行企业微信群发消息创建任务");
 
-        List<QwSopLogs> qwSopLogsList = qwSopLogsMapper.selectSopLogsByCreateCorpMassSending(date);
+        List<QwSopLogs> qwSopLogsList = qwSopLogsMapper.selectSopLogsByCreateCorpMassSending(taskStartTime,taskEndTime);
         if (qwSopLogsList.isEmpty()) {
             logger.error("zyp \n【企微官方群发记录为空】");
             return;

+ 5 - 0
fs-service/src/main/java/com/fs/sop/vo/SopUserLogsVo.java

@@ -40,4 +40,9 @@ public class SopUserLogsVo  {
     private Integer isRegister;
     private String chatId;
 
+    /**
+     * 是否按照营期 发送官方群发 1 按照【营期+插件补发】的形式发  2 按照【营期+官方单链】的形式发
+     */
+    private Integer isSampSend;
+
 }

+ 4 - 0
fs-service/src/main/java/com/fs/store/param/h5/FsUserPageListParam.java

@@ -70,6 +70,10 @@ public class FsUserPageListParam implements Serializable {
      * 销售端登录用户id(该字段用于区分之前的登录用户)
      */
     private Long pcLoginUserId;
+    /**
+     * 是否为我的
+     */
+    private boolean isMyFsUser = true;
 
 
 

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

@@ -84,7 +84,7 @@ tmp_secret_config:
 cloud_host:
   company_name: 九州在线
 headerImg:
-  imgUrl: https://jz-cos-1356808054.cos.ap-chengdu.myqcloud.com/fs/20250515/0877754b59814ea8a428fa3697b20e68.png
+  imgUrl: https://jiuzhouzaixian.obs.cn-southwest-2.myhuaweicloud.com/fs/20250623/1750665141214.png
 ipad:
   ipadUrl: http://ipad.cdwjyyh.com
 wx_miniapp_temp:

+ 2 - 2
fs-service/src/main/resources/application-druid-jzzx.yml

@@ -5,13 +5,13 @@ spring:
     # redis 配置
     redis:
         # 地址
-        host: 127.0.0.1
+        host: 192.168.0.125
         # 端口,默认为6379
         port: 6379
         # 数据库索引
         database: 0
         # 密码
-        password:
+        password: Ylrztek250218!3@.
         # 连接超时时间
         timeout: 20s
         lettuce:

+ 6 - 3
fs-service/src/main/resources/mapper/course/FsCourseAnswerLogsMapper.xml

@@ -17,7 +17,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="answer"    column="answer"    />
         <result property="questionId"    column="question_id"    />
         <result property="questionJson"    column="question_json"    />
-        <result property="watchLogId"    column="watch_log_id"    />
+        <result property="periodId"    column="period_id"    />
     </resultMap>
 
     <sql id="selectFsCourseAnswerLogsVo">
@@ -54,7 +54,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="courseId != null">course_id,</if>
             <if test="questionJson != null">question_json,</if>
             <if test="watchLogId != null">watch_log_id,</if>
-         </trim>
+            <if test="periodId != null">period_id,</if>
+        </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="userId != null">#{userId},</if>
             <if test="videoId != null">#{videoId},</if>
@@ -66,7 +67,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="courseId != null">#{courseId},</if>
             <if test="questionJson != null">#{questionJson},</if>
             <if test="watchLogId != null">#{watchLogId},</if>
-         </trim>
+            <if test="periodId != null">#{periodId},</if>
+        </trim>
     </insert>
 
     <update id="updateFsCourseAnswerLogs" parameterType="FsCourseAnswerLogs">
@@ -81,6 +83,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="qwUserId != null">qw_user_id = #{qwUserId},</if>
             <if test="courseId != null">course_id = #{courseId},</if>
             <if test="watchLogId != null">watch_log_id = #{watchLogId},</if>
+            <if test="periodId != null">period_id = #{periodId},</if>
         </trim>
         where log_id = #{logId}
     </update>

+ 9 - 2
fs-service/src/main/resources/mapper/course/FsCourseRedPacketLogMapper.xml

@@ -19,10 +19,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="updateTime"    column="update_time"    />
         <result property="watchLogId"    column="watch_log_id"    />
         <result property="remark"    column="remark"    />
+        <result property="result"    column="result"    />
+        <result property="periodId"    column="period_id"    />
     </resultMap>
 
     <sql id="selectFsCourseRedPacketLogVo">
-        select log_id,watch_log_id, remark,out_batch_no,status,update_time,course_id, user_id, video_id, company_user_id, company_id, amount, create_time, qw_user_id from fs_course_red_packet_log
+        select log_id,watch_log_id, remark,out_batch_no,status,update_time,course_id, user_id, video_id, company_user_id, company_id, amount, create_time, qw_user_id,period_id from fs_course_red_packet_log
     </sql>
 
     <select id="selectFsCourseRedPacketLogList" parameterType="FsCourseRedPacketLog" resultMap="FsCourseRedPacketLogResult">
@@ -101,6 +103,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="updateTime != null">update_time,</if>
             <if test="watchLogId != null">watch_log_id,</if>
             <if test="remark != null">remark,</if>
+            <if test="result != null">result,</if>
+            <if test="periodId != null">period_id,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="courseId != null">#{courseId},</if>
@@ -116,7 +120,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="updateTime != null">#{updateTime},</if>
             <if test="watchLogId != null">#{watchLogId},</if>
             <if test="remark != null">#{remark},</if>
-         </trim>
+            <if test="periodId != null">#{periodId},</if>
+            <if test="result != null">#{result},</if>
+        </trim>
     </insert>
 
     <update id="updateFsCourseRedPacketLog" parameterType="FsCourseRedPacketLog">
@@ -134,6 +140,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="status != null">status = #{status},</if>
             <if test="updateTime != null">update_time = #{updateTime},</if>
             <if test="watchLogId != null">watch_log_id = #{watchLogId},</if>
+            <if test="periodId != null">period_id = #{periodId},</if>
             <if test="remark != null">remark = #{remark},</if>
         </trim>
         where log_id = #{logId}

+ 9 - 7
fs-service/src/main/resources/mapper/course/FsUserCourseMapper.xml

@@ -123,20 +123,22 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <choose>
             <when test="params.type == 0">
                 and (
-                select count(log_id) as count
-                from fs_course_answer_logs
-                where user_id = fu.user_id and fcwl.video_id = fucv.video_id and is_right = 1
+                select count(log.log_id) as count
+                from fs_course_answer_logs log
+                where log.user_id = fu.user_id and log.video_id = fucv.video_id and log.is_right = 1
+                ) > 0
+                and (
+                select count(log.log_id) as count
+                from fs_course_red_packet_log log
+                where log.user_id = fu.user_id and log.video_id = fucv.video_id and log.status = 1
                 ) > 0
             </when>
             <when test="params.type == 1">
                 and fcwl.log_type = 2
             </when>
             <when test="params.type == 2">
-                and fcwl.log_type in (1,4)
+                and fcwl.log_type = 4
             </when>
-            <otherwise>
-                and fcwl.log_type = 3
-            </otherwise>
         </choose>
         group by fu.user_id, fucv.video_id, fu.nick_name, fu.username, fu.avatar, fu.phone, fu.create_time
     </select>

+ 397 - 263
fs-service/src/main/resources/mapper/his/FsUserMapper.xml

@@ -124,8 +124,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         LEFT JOIN fs_user ON fs_user.user_id = flog.user_id
         LEFT JOIN company_user ON company_user.user_id = fs_user.company_user_id
         <where>
-            <if test="companyUserId != null and companyUserId !='' ">
-                AND company_user.user_id = #{companyUserId}
+            <if test="companyUserId != null and companyUserId != 0 ">
+                AND fs_user.company_user_id = #{companyUserId}
+            </if>
+            <if test="companyUserId != null and companyUserId == 0 ">
+                and fs_user.company_id = #{companyId}
             </if>
             <if test="periodId != null and periodId != ''">
                 AND flog.period_id =  #{periodId}
@@ -163,8 +166,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         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>
-            <if test="companyUserId != null and companyUserId !='' ">
-                AND company_user.user_id = #{companyUserId}
+            <if test="companyUserId != null and companyUserId != 0 ">
+                AND fs_user.company_user_id = #{companyUserId}
+            </if>
+            <if test="companyUserId != null and companyUserId == 0 ">
+                and fs_user.company_id = #{companyId}
             </if>
             <if test="periodId != null and periodId != ''">
                 AND fs_course_answer_logs.period_id =  #{periodId}
@@ -579,9 +585,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         fs_user
         LEFT JOIN fs_user_company_user ON fs_user_company_user.user_id = fs_user.user_id
         LEFT JOIN company_user ON company_user.user_id = fs_user_company_user.company_user_id
-        WHERE
-        (company_user.user_id = #{userId} OR company_user.parent_id = #{userId} )
-        and fs_user.is_del = 0
+        WHERE fs_user.is_del = 0
+        <if test="userId != null and userId != 0 ">
+            and (fs_user.company_user_id = #{userId} OR company_user.parent_id = #{userId} )
+        </if>
+        <if test="companyId != null ">
+            and fs_user.company_id = #{companyId}
+        </if>
         GROUP BY
         fs_user.`status`
     </select>
@@ -601,8 +611,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
     <select id="getCountWatchCourse" resultType="com.fs.store.vo.h5.UserDetailsVO">
         SELECT
-        ifnull( complete_watch_count, 0 ) AS completeWatchCount ,
-        ifnull( watch_times, 0 ) AS watchTimes,
+        <if test="dateTag == null or dateTag =='' ">
+            ifnull( sum(complete_watch_count), 0 ) AS completeWatchCount ,
+            ifnull( sum(watch_times), 0 ) AS watchTimes,
+        </if>
+        <if test="dateTag != null and dateTag !='' ">
+            ifnull( complete_watch_count, 0 ) AS completeWatchCount ,
+            ifnull( watch_times, 0 ) AS watchTimes,
+        </if>
         fs_user.user_id
         FROM
         fs_user_course_count
@@ -625,11 +641,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                     </when>
                 </choose>
             </if>
+            and fs_user.user_id = #{fsUserId}
         </where>
         GROUP BY
         fs_user.user_id
-        HAVING
-        fs_user.user_id = #{fsUserId}
     </select>
 
     <select id="getCountAnswer" resultType="com.fs.store.vo.h5.UserDetailsVO">
@@ -641,28 +656,28 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         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
-        WHERE
-        (company_user.user_id = #{userId} or company_user.parent_id = #{userId} )
-        <if test="dateTag != null and dateTag !='' ">
-            <choose>
-                <when test = "dateTag == '今天'">
-                    and to_days(fs_course_answer_logs.create_time) = to_days(now())
-                </when>
-                <when test = "dateTag == '昨天'">
-                    and fs_course_answer_logs.create_time &gt;= CURDATE() - INTERVAL 1 DAY AND fs_course_answer_logs.create_time &lt; CURDATE()
-                </when>
-                <when test = "dateTag == '前天'">
-                    and fs_course_answer_logs.create_time &gt;= CURDATE() - INTERVAL 2 DAY AND fs_course_answer_logs.create_time &lt; CURDATE() - INTERVAL 1 DAY
-                </when>
-                <when test = "dateTag == '近七天'">
-                    and fs_course_answer_logs.create_time &gt;= CURDATE() - INTERVAL 7 DAY
-                </when>
-            </choose>
-        </if>
+        <where>
+
+            <if test="dateTag != null and dateTag !='' ">
+                <choose>
+                    <when test = "dateTag == '今天'">
+                        and to_days(fs_course_answer_logs.create_time) = to_days(now())
+                    </when>
+                    <when test = "dateTag == '昨天'">
+                        and fs_course_answer_logs.create_time &gt;= CURDATE() - INTERVAL 1 DAY AND fs_course_answer_logs.create_time &lt; CURDATE()
+                    </when>
+                    <when test = "dateTag == '前天'">
+                        and fs_course_answer_logs.create_time &gt;= CURDATE() - INTERVAL 2 DAY AND fs_course_answer_logs.create_time &lt; CURDATE() - INTERVAL 1 DAY
+                    </when>
+                    <when test = "dateTag == '近七天'">
+                        and fs_course_answer_logs.create_time &gt;= CURDATE() - INTERVAL 7 DAY
+                    </when>
+                </choose>
+            </if>
+            and fs_user.user_id = #{fsUserId}
+        </where>
         GROUP BY
         fs_user.user_id
-        HAVING
-        fs_user.user_id = #{fsUserId}
         ) AS answerTime,
         (
         SELECT
@@ -671,29 +686,28 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         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
-        WHERE
-        (company_user.user_id = #{userId} or company_user.parent_id = #{userId} )
-        AND fs_course_answer_logs.is_right = 1
-        <if test="dateTag != null and dateTag !='' ">
-            <choose>
-                <when test = "dateTag == '今天'">
-                    and to_days(fs_course_answer_logs.create_time) = to_days(now())
-                </when>
-                <when test = "dateTag == '昨天'">
-                    and fs_course_answer_logs.create_time &gt;= CURDATE() - INTERVAL 1 DAY AND fs_course_answer_logs.create_time &lt; CURDATE()
-                </when>
-                <when test = "dateTag == '前天'">
-                    and fs_course_answer_logs.create_time &gt;= CURDATE() - INTERVAL 2 DAY AND fs_course_answer_logs.create_time &lt; CURDATE() - INTERVAL 1 DAY
-                </when>
-                <when test = "dateTag == '近七天'">
-                    and fs_course_answer_logs.create_time &gt;= CURDATE() - INTERVAL 7 DAY
-                </when>
-            </choose>
-        </if>
+        <where>
+            fs_course_answer_logs.is_right = 1
+            <if test="dateTag != null and dateTag !='' ">
+                <choose>
+                    <when test = "dateTag == '今天'">
+                        and to_days(fs_course_answer_logs.create_time) = to_days(now())
+                    </when>
+                    <when test = "dateTag == '昨天'">
+                        and fs_course_answer_logs.create_time &gt;= CURDATE() - INTERVAL 1 DAY AND fs_course_answer_logs.create_time &lt; CURDATE()
+                    </when>
+                    <when test = "dateTag == '前天'">
+                        and fs_course_answer_logs.create_time &gt;= CURDATE() - INTERVAL 2 DAY AND fs_course_answer_logs.create_time &lt; CURDATE() - INTERVAL 1 DAY
+                    </when>
+                    <when test = "dateTag == '近七天'">
+                        and fs_course_answer_logs.create_time &gt;= CURDATE() - INTERVAL 7 DAY
+                    </when>
+                </choose>
+            </if>
+            and fs_user.user_id = #{fsUserId}
+        </where>
         GROUP BY
         fs_user.user_id
-        HAVING
-        fs_user.user_id = #{fsUserId}
         ) AS answerRightTime;
     </select>
 
@@ -706,44 +720,52 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         fs_course_red_packet_log
         LEFT JOIN fs_user ON fs_user.user_id = fs_course_red_packet_log.user_id
         LEFT JOIN company_user ON company_user.user_id = fs_user.company_user_id
-        WHERE
-        (company_user.user_id = #{userId} or company_user.parent_id = #{userId} )
-        and fs_course_red_packet_log.status = 1
-        <if test="dateTag != null and dateTag !='' ">
-            <choose>
-                <when test = "dateTag == '今天'">
-                    and to_days(fs_course_red_packet_log.create_time) = to_days(now())
-                </when>
-                <when test = "dateTag == '昨天'">
-                    and fs_course_red_packet_log.create_time &gt;= CURDATE() - INTERVAL 1 DAY AND fs_course_red_packet_log.create_time &lt; CURDATE()
-                </when>
-                <when test = "dateTag == '前天'">
-                    and fs_course_red_packet_log.create_time &gt;= CURDATE() - INTERVAL 2 DAY AND fs_course_red_packet_log.create_time &lt; CURDATE() - INTERVAL 1 DAY
-                </when>
-                <when test = "dateTag == '近七天'">
-                    and fs_course_red_packet_log.create_time &gt;= CURDATE() - INTERVAL 7 DAY
-                </when>
-            </choose>
-        </if>
+        <where>
+            fs_course_red_packet_log.status = 1
+            <if test="dateTag != null and dateTag !='' ">
+                <choose>
+                    <when test = "dateTag == '今天'">
+                        and to_days(fs_course_red_packet_log.create_time) = to_days(now())
+                    </when>
+                    <when test = "dateTag == '昨天'">
+                        and fs_course_red_packet_log.create_time &gt;= CURDATE() - INTERVAL 1 DAY AND fs_course_red_packet_log.create_time &lt; CURDATE()
+                    </when>
+                    <when test = "dateTag == '前天'">
+                        and fs_course_red_packet_log.create_time &gt;= CURDATE() - INTERVAL 2 DAY AND fs_course_red_packet_log.create_time &lt; CURDATE() - INTERVAL 1 DAY
+                    </when>
+                    <when test = "dateTag == '近七天'">
+                        and fs_course_red_packet_log.create_time &gt;= CURDATE() - INTERVAL 7 DAY
+                    </when>
+                </choose>
+            </if>
+            and  fs_user.user_id = #{fsUserId}
+        </where>
         GROUP BY
         fs_user.user_id
-        HAVING
-        fs_user.user_id = #{fsUserId}
     </select>
 
     <select id="countUserSummary" resultType="com.fs.store.vo.h5.FsUserSummaryCountVO">
         SELECT (SELECT count(fs_user.user_id)
         FROM fs_user
         LEFT JOIN company_user ON fs_user.company_user_id = company_user.user_id
-        WHERE (
-        company_user.user_id = #{userId}
-        OR company_user.parent_id = #{userId}
-        ) and fs_user.is_del = 0) as userTotal,
+        WHERE fs_user.is_del = 0
+        <if test="userId != null and userId != 0 ">
+            and (fs_user.company_user_id = #{userId} OR company_user.parent_id = #{userId} )
+        </if>
+        <if test="companyId != null ">
+            and fs_user.company_id = #{companyId}
+        </if>
+        ) as userTotal,
         (SELECT count(fs_user.user_id)
         FROM fs_user
         LEFT JOIN company_user ON fs_user.company_user_id = company_user.user_id
-        WHERE (company_user.user_id = #{userId} OR company_user.parent_id = #{userId})
-        and fs_user.is_del = 0
+        WHERE fs_user.is_del = 0
+        <if test="userId != null and userId != 0 ">
+            and (fs_user.company_user_id = #{userId} OR company_user.parent_id = #{userId} )
+        </if>
+        <if test="companyId != null ">
+            and fs_user.company_id = #{companyId}
+        </if>
         AND to_days(fs_user.create_time) = to_days(now())) as todayNewUser
     </select>
 
@@ -756,7 +778,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         LEFT JOIN fs_user ON fs_user.user_id = company_tag_user.user_id
         LEFT JOIN company_tag ON FIND_IN_SET( company_tag.tag_id, company_tag_user.tag_ids ) > 0
         LEFT JOIN company_user ON fs_user.company_user_id = company_user.user_id
-        where (company_user.user_id = #{userId} or company_user.parent_id = #{userId} ) and company_tag.tag_id is not null
+        <where>
+            <if test="userId != null and userId != 0 ">
+                and (fs_user.company_user_id = #{userId} OR company_user.parent_id = #{userId} )
+            </if>
+            <if test="companyId != null ">
+                and fs_user.company_id = #{companyId}
+            </if>
+            and company_tag.tag_id is not null
+        </where>
         GROUP BY
         company_tag.tag_id
     </select>
@@ -771,25 +801,30 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         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_period_days fcpd ON FIND_IN_SET(fcpd.period_id, fcc.course_ids) > 0
-        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="periodId != null and periodId != ''">
-            AND fcpd.period_id = #{periodId}
-        </if>
-        <if test="videoId != null and videoId != ''">
-            AND fcpd.video_id = #{videoId}
-        </if>
-        -- 单独通过销售id查询
-        <if test="companyUserId != null and companyUserId != ''">
-            AND company_user.user_id = #{companyUserId}
-        </if>
-
+        <where>
+            <if test="userId != null and userId != 0 ">
+                and (fs_user.company_user_id = #{userId} OR company_user.parent_id = #{userId} )
+            </if>
+            <if test="userId != null and userId == 0 ">
+                and fs_user.company_id = #{companyId}
+            </if>
+            <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="periodId != null and periodId != ''">
+                AND fcpd.period_id = #{periodId}
+            </if>
+            <if test="videoId != null and videoId != ''">
+                AND fcpd.video_id = #{videoId}
+            </if>
+            -- 单独通过销售id查询
+            <if test="companyUserId != null and companyUserId != ''">
+                AND company_user.user_id = #{companyUserId}
+            </if>
+        </where>
         ) as courseWatchNum,
         (
         SELECT
@@ -799,25 +834,31 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         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_period_days fcpd ON FIND_IN_SET(fcpd.period_id, fcc.course_ids) > 0
-        WHERE
-        ( company_user.user_id = #{userId}  OR company_user.parent_id = #{userId}  )
-        AND fcc.complete_watch_count > 0
-        <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="periodId != null and periodId != ''">
-            AND fcpd.period_id = #{periodId}
-        </if>
-        <if test="videoId != null and videoId != ''">
-            AND fcpd.video_id = #{videoId}
-        </if>
-        -- 单独通过销售id查询
-        <if test="companyUserId != null and companyUserId != ''">
-            AND company_user.user_id = #{companyUserId}
-        </if>
+        <where>
+            <if test="userId != null and userId != 0 ">
+                and (fs_user.company_user_id = #{userId} OR company_user.parent_id = #{userId} )
+            </if>
+            <if test="userId != null and userId == 0 ">
+                and fs_user.company_id = #{companyId}
+            </if>
+            AND fcc.complete_watch_count > 0
+            <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="periodId != null and periodId != ''">
+                AND fcpd.period_id = #{periodId}
+            </if>
+            <if test="videoId != null and videoId != ''">
+                AND fcpd.video_id = #{videoId}
+            </if>
+            -- 单独通过销售id查询
+            <if test="companyUserId != null and companyUserId != ''">
+                AND company_user.user_id = #{companyUserId}
+            </if>
+        </where>
         ) as courseCompleteNum
     </select>
 
@@ -830,24 +871,30 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         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
-        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="periodId != null and periodId != ''">
-            AND fs_course_answer_logs.period_id = #{periodId}
-        </if>
-        <if test="videoId != null and videoId != ''">
-            AND fs_course_answer_logs.video_id = #{videoId}
-        </if>
-        -- 单独通过销售id查询
-        <if test="companyUserId != null and companyUserId != ''">
-            AND company_user.user_id = #{companyUserId}
-        </if>
+        <where>
+            <if test="userId != null and userId != 0 ">
+                and (fs_user.company_user_id = #{userId} OR company_user.parent_id = #{userId} )
+            </if>
+            <if test="userId != null and userId == 0 ">
+                and fs_user.company_id = #{companyId}
+            </if>
+            <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="periodId != null and periodId != ''">
+                AND fs_course_answer_logs.period_id = #{periodId}
+            </if>
+            <if test="videoId != null and videoId != ''">
+                AND fs_course_answer_logs.video_id = #{videoId}
+            </if>
+            -- 单独通过销售id查询
+            <if test="companyUserId != null and companyUserId != ''">
+                AND company_user.user_id = #{companyUserId}
+            </if>
+        </where>
         ) AS answerNum,
         (
         SELECT
@@ -856,25 +903,31 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         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
-        WHERE
-        ( company_user.user_id = #{userId} OR company_user.parent_id = #{userId} )
-        AND fs_course_answer_logs.is_right = 1
-        <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="periodId != null and periodId != ''">
-            AND fs_course_answer_logs.period_id = #{periodId}
-        </if>
-        <if test="videoId != null and videoId != ''">
-            AND fs_course_answer_logs.video_id = #{videoId}
-        </if>
-        -- 单独通过销售id查询
-        <if test="companyUserId != null and companyUserId != ''">
-            AND company_user.user_id = #{companyUserId}
-        </if>
+        <where>
+            <if test="userId != null and userId != 0 ">
+                and (fs_user.company_user_id = #{userId} OR company_user.parent_id = #{userId} )
+            </if>
+            <if test="userId != null and userId == 0 ">
+                and fs_user.company_id = #{companyId}
+            </if>
+            AND fs_course_answer_logs.is_right = 1
+            <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="periodId != null and periodId != ''">
+                AND fs_course_answer_logs.period_id = #{periodId}
+            </if>
+            <if test="videoId != null and videoId != ''">
+                AND fs_course_answer_logs.video_id = #{videoId}
+            </if>
+            -- 单独通过销售id查询
+            <if test="companyUserId != null and companyUserId != ''">
+                AND company_user.user_id = #{companyUserId}
+            </if>
+        </where>
         ) AS answerRightNum
     </select>
 
@@ -888,6 +941,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         LEFT JOIN fs_user ON fs_user.user_id = fcc.user_id
         WHERE 1=1
         AND FIND_IN_SET(#{companyId}, fpd.company_id)
+        <if test="userId != null and userId != 0 ">
+            AND fs_user.company_user_id = #{userId}
+        </if>
+        <if test="userId != null and userId == 0 ">
+            and fs_user.company_id = #{companyId}
+        </if>
         <if test="periodId != null and periodId != ''">
             AND fcpd.period_id =  #{periodId}
         </if>
@@ -904,6 +963,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         LEFT JOIN fs_user ON fs_user.user_id = fcc.user_id
         WHERE 1=1
         AND FIND_IN_SET(#{companyId}, fpd.company_id)
+        <if test="userId != null and userId != 0 ">
+            AND fs_user.company_user_id = #{userId}
+        </if>
+        <if test="userId != null and userId == 0 ">
+            and fs_user.company_id = #{companyId}
+        </if>
         <if test="periodId != null and periodId != ''">
             AND fcpd.period_id =  #{periodId}
         </if>
@@ -929,6 +994,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <if test="companyUserId != null and companyUserId != ''">
             AND fs_user.company_user_id = #{companyUserId}
         </if>
+        <where>
+            <if test="userId != null and userId != 0 ">
+                AND fs_user.company_user_id = #{userId}
+            </if>
+            <if test="userId != null and userId == 0 ">
+                and fs_user.company_id = #{companyId}
+            </if>
+        </where>
         ) as courseUserNum
     </select>
 
@@ -943,20 +1016,26 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         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_period_days fcpd ON FIND_IN_SET( fcpd.period_id, fcc.course_ids ) > 0
-        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="periodId != null and periodId != ''">
-            AND fcpd.period_id =  #{periodId}
-        </if>
-        <if test="videoId != null and videoId != ''">
-            AND fcpd.video_id = #{videoId}
-        </if>
+        <where>
+            <if test="userId != null and userId != 0 ">
+                AND  ( fs_user.company_user_id = #{userId} OR company_user.parent_id = #{userId} )
+            </if>
+            <if test="userId != null and userId == 0 ">
+                and fs_user.company_id = #{companyId}
+            </if>
+            <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="periodId != null and periodId != ''">
+                AND fcpd.period_id =  #{periodId}
+            </if>
+            <if test="videoId != null and videoId != ''">
+                AND fcpd.video_id = #{videoId}
+            </if>
+        </where>
         group by fcc.user_id
         <choose>
             <when test="order != null and order == 'asc'">
@@ -983,20 +1062,26 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         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
-        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="periodId != null and periodId != ''">
-            AND fs_course_answer_logs.period_id =  #{periodId}
-        </if>
-        <if test="videoId != null and videoId != ''">
-            AND fs_course_answer_logs.video_id = #{videoId}
-        </if>
+        <where>
+            <if test="userId != null and userId != 0 ">
+                AND  ( fs_user.company_user_id = #{userId} OR company_user.parent_id = #{userId} )
+            </if>
+            <if test="userId != null and userId == 0 ">
+                and fs_user.company_id = #{companyId}
+            </if>
+            <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="periodId != null and periodId != ''">
+                AND fs_course_answer_logs.period_id =  #{periodId}
+            </if>
+            <if test="videoId != null and videoId != ''">
+                AND fs_course_answer_logs.video_id = #{videoId}
+            </if>
+        </where>
         group by fs_user.user_id
         <choose>
             <when test="order != null and order == 'asc'">
@@ -1028,20 +1113,26 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         LEFT JOIN company_user ON fs_user.company_user_id = company_user.user_id
         LEFT JOIN fs_user_course_period_days fcpd ON FIND_IN_SET( fcpd.period_id, fcc.course_ids ) > 0
         LEFT JOIN fs_user_course_video fcv ON fcv.video_id = fcpd.video_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="periodId != null and periodId != ''">
-            AND fcpd.period_id =  #{periodId}
-        </if>
-        <if test="videoId != null and videoId != ''">
-            AND fcpd.video_id = #{videoId}
-        </if>
+        <where>
+            <if test="userId != null and userId != 0 ">
+                AND ( fs_user.company_user_id = #{userId} OR company_user.parent_id = #{userId} )
+            </if>
+            <if test="userId != null and userId == 0 ">
+                and fs_user.company_id = #{companyId}
+            </if>
+            <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="periodId != null and periodId != ''">
+                AND fcpd.period_id =  #{periodId}
+            </if>
+            <if test="videoId != null and videoId != ''">
+                AND fcpd.video_id = #{videoId}
+            </if>
+        </where>
         GROUP BY
         fcpd.video_id
         <choose>
@@ -1074,20 +1165,26 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         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="periodId != null and periodId != ''">
-            AND fs_course_answer_logs.period_id = #{periodId}
-        </if>
-        <if test="videoId != null and videoId != ''">
-            AND fs_course_answer_logs.video_id = #{videoId}
-        </if>
+        <where>
+            <if test="userId != null and userId != 0 ">
+                AND ( fs_user.company_user_id = #{userId} OR company_user.parent_id = #{userId} )
+            </if>
+            <if test="userId != null and userId == 0 ">
+                and fs_user.company_id = #{companyId}
+            </if>
+            <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="periodId != null and periodId != ''">
+                AND fs_course_answer_logs.period_id = #{periodId}
+            </if>
+            <if test="videoId != null and videoId != ''">
+                AND fs_course_answer_logs.video_id = #{videoId}
+            </if>
+        </where>
         GROUP BY
         fs_course_answer_logs.video_id
         <choose>
@@ -1113,24 +1210,30 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         fs_course_red_packet_log flog
         LEFT JOIN fs_user ON fs_user.user_id = flog.user_id
         LEFT JOIN company_user ON company_user.user_id = fs_user.company_user_id
-        WHERE
-        ( company_user.user_id = #{userId}  OR company_user.parent_id = #{userId}  )
-        <if test="startTime != null and startTime !='' ">
-            AND flog.create_time &gt;= #{startTime}
-        </if>
-        <if test="endTime != null and endTime != ''">
-            AND flog.create_time &lt;= #{endTime}
-        </if>
-        <if test="periodId != null and periodId != ''">
-            AND flog.period_id =  #{periodId}
-        </if>
-        <if test="videoId != null and videoId != ''">
-            AND flog.video_id = #{videoId}
-        </if>
-        -- 单独通过销售id查询
-        <if test="companyUserId != null and companyUserId != ''">
-            AND company_user.user_id = #{companyUserId}
-        </if>
+        <where>
+            <if test="userId != null and userId != 0 ">
+                and (fs_user.company_user_id = #{userId} OR company_user.parent_id = #{userId} )
+            </if>
+            <if test="userId != null and userId == 0 ">
+                and fs_user.company_id = #{companyId}
+            </if>
+            <if test="startTime != null and startTime !='' ">
+                AND flog.create_time &gt;= #{startTime}
+            </if>
+            <if test="endTime != null and endTime != ''">
+                AND flog.create_time &lt;= #{endTime}
+            </if>
+            <if test="periodId != null and periodId != ''">
+                AND flog.period_id =  #{periodId}
+            </if>
+            <if test="videoId != null and videoId != ''">
+                AND flog.video_id = #{videoId}
+            </if>
+            -- 单独通过销售id查询
+            <if test="companyUserId != null and companyUserId != ''">
+                AND company_user.user_id = #{companyUserId}
+            </if>
+        </where>
         ) AS redPacketNum,
         (
         SELECT
@@ -1139,24 +1242,30 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         fs_course_red_packet_log flog
         LEFT JOIN fs_user ON fs_user.user_id = flog.user_id
         LEFT JOIN company_user ON company_user.user_id = fs_user.company_user_id
-        WHERE
-        ( company_user.user_id = #{userId}  OR company_user.parent_id = #{userId}  )
-        <if test="startTime != null and startTime !='' ">
-            AND flog.create_time &gt;= #{startTime}
-        </if>
-        <if test="endTime != null and endTime != ''">
-            AND flog.create_time &lt;= #{endTime}
-        </if>
-        <if test="periodId != null and periodId != ''">
-            AND flog.period_id =  #{periodId}
-        </if>
-        <if test="videoId != null and videoId != ''">
-            AND flog.video_id = #{videoId}
-        </if>
-        -- 单独通过销售id查询
-        <if test="companyUserId != null and companyUserId != ''">
-            AND company_user.user_id = #{companyUserId}
-        </if>
+        <where>
+            <if test="userId != null and userId != 0 ">
+                and (fs_user.company_user_id = #{userId} OR company_user.parent_id = #{userId} )
+            </if>
+            <if test="userId != null and userId == 0 ">
+                and fs_user.company_id = #{companyId}
+            </if>
+            <if test="startTime != null and startTime !='' ">
+                AND flog.create_time &gt;= #{startTime}
+            </if>
+            <if test="endTime != null and endTime != ''">
+                AND flog.create_time &lt;= #{endTime}
+            </if>
+            <if test="periodId != null and periodId != ''">
+                AND flog.period_id =  #{periodId}
+            </if>
+            <if test="videoId != null and videoId != ''">
+                AND flog.video_id = #{videoId}
+            </if>
+            -- 单独通过销售id查询
+            <if test="companyUserId != null and companyUserId != ''">
+                AND company_user.user_id = #{companyUserId}
+            </if>
+        </where>
         ) AS redPacketAmount
     </select>
 
@@ -1178,14 +1287,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         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_period_days fcpd ON FIND_IN_SET( fcpd.period_id, fcc.course_ids ) > 0
-        WHERE
-        company_user.user_id = #{companyUserId}
-        <if test="periodId != null and periodId != ''">
-            AND fcpd.period_id =  #{periodId}
-        </if>
-        <if test="videoId != null and videoId != ''">
-            AND fcpd.video_id = #{videoId}
-        </if>
+        <where>
+            <if test="companyUserId != null and companyUserId != 0 ">
+                AND fs_user.company_user_id = #{companyUserId}
+            </if>
+            <if test="companyUserId != null and companyUserId == 0 ">
+                and fs_user.company_id = #{companyId}
+            </if>
+            <if test="periodId != null and periodId != ''">
+                AND fcpd.period_id =  #{periodId}
+            </if>
+            <if test="videoId != null and videoId != ''">
+                AND fcpd.video_id = #{videoId}
+            </if>
+        </where>
         GROUP BY
         fcpd.video_id
     </select>
@@ -1194,7 +1309,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         SELECT
         (
         SELECT count( fs_user.user_id ) FROM fs_user LEFT JOIN company_user ON fs_user.company_user_id = company_user.user_id
-        WHERE company_user.user_id = #{companyUserId}
+        <where>
+            <if test="companyUserId != null and companyUserId != '' and companyUserId != '0' ">
+                AND fs_user.company_user_id = #{companyUserId}
+            </if>
+            <if test="companyUserId != null and companyUserId != '' and companyUserId == '0' ">
+                and fs_user.company_id = #{companyId}
+            </if>
+        </where>
         ) AS userTotal,
         (
         SELECT
@@ -1202,11 +1324,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         FROM
         fs_user
         LEFT JOIN company_user ON fs_user.company_user_id = company_user.user_id
-        WHERE
-        company_user.user_id = #{companyUserId}
-        and fs_user.is_del = 0
-        AND to_days( fs_user.create_time ) = to_days(
-        now())
+        <where>
+            <if test="companyUserId != null and companyUserId != '' and companyUserId != '0' ">
+                AND fs_user.company_user_id = #{companyUserId}
+            </if>
+            <if test="companyUserId != null and companyUserId != '' and companyUserId == '0' ">
+                and fs_user.company_id = #{companyId}
+            </if>
+            and fs_user.is_del = 0
+            AND to_days( fs_user.create_time ) = to_days(
+            now())
+        </where>
         ) AS todayNewUser
     </select>
 
@@ -1217,7 +1345,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         FROM
         fs_course_red_packet_log flog
         LEFT JOIN fs_user ON fs_user.user_id = flog.user_id
-        WHERE
-        fs_user.company_user_id = #{companyUserId}
+        <where>
+            <if test="companyUserId != null and companyUserId != '' and companyUserId != '0' ">
+                AND fs_user.company_user_id = #{companyUserId}
+            </if>
+            <if test="companyUserId != null and companyUserId != '' and companyUserId == '0' ">
+                and fs_user.company_id = #{companyId}
+            </if>
+        </where>
     </select>
 </mapper>

+ 4 - 0
fs-service/src/main/resources/mapper/qw/CustomerTransferApprovalMapper.xml

@@ -51,6 +51,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         where id = #{id}
     </select>
 
+    <select id="queryPendingData" resultType="com.fs.qw.domain.CustomerTransferApproval">
+        select * from customer_transfer_approval where approval_status=0
+    </select>
+
     <insert id="insertCustomerTransferApproval" parameterType="CustomerTransferApproval" useGeneratedKeys="true" keyProperty="id">
         insert into customer_transfer_approval
         <trim prefix="(" suffix=")" suffixOverrides=",">

+ 23 - 3
fs-service/src/main/resources/mapper/sop/QwSopLogsMapper.xml

@@ -328,9 +328,26 @@
     </select>
 
 
+    <select id="createCorpMassSending" parameterType="String" resultType="QwSopLogs" >
+        <![CDATA[
+        select * from qw_sop_logs
+        where log_type=2
+          and send_status=3
+          and send_type=1
+          and send_time >= #{date}
+          AND take_records = 1
+        ]]>
+    </select>
+
     <select id="selectSopLogsByCreateCorpMassSending" parameterType="String" resultType="QwSopLogs" >
         <![CDATA[
-            select * from qw_sop_logs where log_type=2 and send_status=3 and send_type=1 and send_time >= #{date}
+        select * from qw_sop_logs
+        where log_type=2
+          and send_status=3
+          and send_type=1
+          AND send_time >= #{taskStartTime}
+          AND send_time <= #{taskEndTime}
+          AND take_records = 0
         ]]>
     </select>
 
@@ -544,7 +561,7 @@
         qw_userid, external_user_id,external_id, external_user_name, log_type,
         content_json, send_status, send_time, real_send_time, send_type,
         company_id, receiving_status, msg_id, sop_id, remark,
-        corp_id, customer_id, fs_user_id, expiration_time
+        corp_id, customer_id, fs_user_id, expiration_time,sort,user_logs_id,take_records
         )
         VALUES
         <foreach collection="qwSopLogs" item="log" separator=",">
@@ -567,7 +584,10 @@
             #{log.corpId},
             #{log.customerId},
             #{log.fsUserId},
-            #{log.expirationTime}
+            #{log.expirationTime},
+            #{log.sort},
+            #{log.userLogsId},
+            #{log.takeRecords}
             )
         </foreach>
     </insert>

+ 3 - 0
fs-service/src/main/resources/mapper/sop/QwSopMapper.xml

@@ -33,6 +33,7 @@
         <result property="courseDay"    column="course_day"    />
         <result property="chatId"    column="chat_id"    />
         <result property="openCommentStatus"    column="open_comment_status"    />
+        <result property="isSampSend"    column="is_samp_send"    />
     </resultMap>
 
     <sql id="selectQwSopVo">
@@ -429,6 +430,8 @@
             <if test="data.isRating != null">is_rating = #{data.isRating},</if>
             <if test="data.courseDay != null">course_day = #{data.courseDay},</if>
             <if test="data.openCommentStatus != null">open_comment_status = #{data.openCommentStatus},</if>
+            <if test="data.chatId != null">chat_id = #{data.chatId},</if>
+            <if test="data.isSampSend != null">is_samp_send = #{data.isSampSend},</if>
         </trim>
         where id = #{data.id}
     </update>

+ 2 - 1
fs-service/src/main/resources/mapper/sop/SopUserLogsMapper.xml

@@ -199,7 +199,8 @@
                b.is_fixed,
                b.is_register,
                b.chat_id,
-               b.filter_mode
+               b.filter_mode,
+               b.is_samp_send
         from sop_user_logs a
                  inner join qw_sop b on a.sop_id = b.id
         where a.start_time &lt;= Now()

+ 15 - 5
fs-service/src/main/resources/mapper/store/FsUserCourseCountMapper.xml

@@ -1,7 +1,7 @@
 <?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">
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.fs.store.mapper.FsUserCourseCountMapper">
 
     <resultMap type="FsUserCourseCount" id="FsUserCourseCountResult">
@@ -80,7 +80,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="completeWatchCount != null">complete_watch_count,</if>
             <if test="watchTimes != null">watch_times,</if>
             <if test="createDate != null">create_date,</if>
-         </trim>
+        </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="id != null">#{id},</if>
             <if test="userId != null">#{userId},</if>
@@ -101,7 +101,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="completeWatchCount != null">#{completeWatchCount},</if>
             <if test="watchTimes != null">#{watchTimes},</if>
             <if test="createDate != null">#{createDate},</if>
-         </trim>
+        </trim>
     </insert>
 
     <update id="updateFsUserCourseCount" parameterType="FsUserCourseCount">
@@ -160,7 +160,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             fs_course_watch_log fwl
         where fwl.send_type = 1 and fwl.create_time &gt;= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
         GROUP BY
-            fwl.user_id
+            fwl.user_id, date(fwl.create_time)
     </select>
 
     <select id="getUserStatusAndLastWatchDate" resultType="FsUserCourseCount">
@@ -231,6 +231,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </trim>
         on duplicate key update
         <trim suffixOverrides=",">
+            <if test="watchCourseCount != null">watch_course_count = #{watchCourseCount},</if>
+            <if test="missCourseCount != null">miss_course_count = #{missCourseCount},</if>
+            <if test="missCourseStatus != null">miss_course_status = #{missCourseStatus},</if>
+            <if test="courseIds != null">course_ids = #{courseIds},</if>
+            <if test="partCourseCount != null">part_course_count = #{partCourseCount},</if>
+            <if test="lastWatchDate != null">last_watch_date = #{lastWatchDate},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="completeWatchDate != null">complete_watch_date = #{completeWatchDate},</if>
+            <if test="completeWatchCount != null">complete_watch_count = #{completeWatchCount},</if>
+            <if test="watchTimes != null">watch_times = #{watchTimes},</if>
             <if test="updateTime != null">update_time = #{updateTime},</if>
         </trim>
     </insert>

+ 1 - 0
fs-user-app/src/main/java/com/fs/framework/config/DataSourceConfig.java

@@ -40,6 +40,7 @@ public class DataSourceConfig {
     @Primary
     public DynamicDataSource dataSource(@Qualifier("masterDataSource") DataSource masterDataSource, @Qualifier("sopDataSource") DataSource sopDataSource) {
         Map<Object, Object> targetDataSources = new HashMap<>();
+        targetDataSources.put(DataSourceType.MASTER, masterDataSource);
         targetDataSources.put(DataSourceType.SOP.name(), sopDataSource);
         return new DynamicDataSource(masterDataSource, targetDataSources);
     }