Jelajahi Sumber

Merge remote-tracking branch 'origin/master'

ct 5 hari lalu
induk
melakukan
3a97376a6c

+ 75 - 0
fs-admin/src/main/java/com/fs/qw/qwTask/qwTask.java

@@ -1,17 +1,24 @@
 package com.fs.qw.qwTask;
 
 import com.fs.course.service.IFsUserCourseService;
+import com.fs.qw.domain.QwIpadServerLog;
+import com.fs.qw.domain.QwUser;
+import com.fs.qw.mapper.QwUserMapper;
 import com.fs.qw.service.*;
 import com.fs.sop.service.impl.QwSopLogsServiceImpl;
 import com.fs.sop.service.impl.QwSopServiceImpl;
 import com.fs.sop.service.ISopUserLogsService;
 import com.fs.statis.IFsStatisQwWatchService;
 import com.fs.statis.service.FsStatisSalerWatchService;
+import com.fs.wxwork.dto.WxWorkGetQrCodeDTO;
+import com.fs.wxwork.service.WxWorkService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
+import java.util.Date;
+import java.util.List;
 
 @Component("qwTask")
 public class qwTask {
@@ -47,6 +54,23 @@ public class qwTask {
     private IQwMaterialService iQwMaterialService;
 
 
+    @Autowired
+    private QwUserMapper qwUserMapper;
+
+    @Autowired
+    private IQwIpadServerService ipadServerService;
+
+    @Autowired
+    private IQwIpadServerLogService qwIpadServerLogService;
+
+    @Autowired
+    private IQwIpadServerUserService qwIpadServerUserService;
+
+    @Autowired
+    private IQwExternalContactService externalContactService;
+
+    @Autowired
+    private WxWorkService wxWorkService;
 
 
     //正在使用
@@ -211,4 +235,55 @@ public class qwTask {
 
 
     }
+
+    /**
+     * 定时清除 占着茅坑不拉屎的ipad 账号
+     */
+    public void selectQwUserByUnbindIpad(){
+        List<QwUser> list = qwUserMapper.selectQwUserByTest();
+        for (QwUser qwUser : list) {
+            try {
+                Integer serverStatus = qwUser.getServerStatus();
+                Long serverId = qwUser.getServerId();
+                if (serverStatus==0){
+                    System.out.println("不需要解绑");
+                }
+                if (serverId==null){
+                    System.out.println("serverId不存在");
+                }
+                QwUser u = new QwUser();
+                u.setId(qwUser.getId());
+                u.setServerId(null);
+                u.setServerStatus(0);
+                qwUserMapper.updateQwUser(u);
+                ipadServerService.addServer(serverId);
+                QwIpadServerLog qwIpadServerLog = new QwIpadServerLog();
+                qwIpadServerLog.setType(2);
+                qwIpadServerLog.setTilie("解绑");
+                qwIpadServerLog.setServerId(serverId);
+                qwIpadServerLog.setQwUserId(qwUser.getId());
+                qwIpadServerLog.setCompanyUserId(qwUser.getCompanyUserId());
+                qwIpadServerLog.setCompanyId(qwUser.getCompanyId());
+                qwIpadServerLog.setCreateTime(new Date());
+                qwIpadServerLogService.insertQwIpadServerLog(qwIpadServerLog);
+                qwIpadServerUserService.deleteQwIpadServerUserByQwUserId(qwUser.getId());
+                WxWorkGetQrCodeDTO wxWorkGetQrCodeDTO = new WxWorkGetQrCodeDTO();
+                wxWorkGetQrCodeDTO.setUuid(qwUser.getUid());
+                wxWorkService.LoginOut(wxWorkGetQrCodeDTO,qwUser.getServerId());
+                updateIpadStatus(qwUser.getId(),0);
+            } catch (Exception e) {
+                System.out.println("解绑ipad报错"+e);
+
+            }
+        }
+    }
+
+
+    void updateIpadStatus(Long id ,Integer status){
+        QwUser u = new QwUser();
+        u.setId(id);
+        u.setIpadStatus(status);
+        qwUserMapper.updateQwUser(u);
+    }
+
 }

+ 2 - 1
fs-quartz/src/main/java/com/fs/quartz/config/ScheduleConfig.java

@@ -8,7 +8,7 @@ import java.util.Properties;
 
 /**
  * 定时任务配置
- * 
+ *
 
  */
 @Configuration
@@ -51,6 +51,7 @@ public class ScheduleConfig
         factory.setOverwriteExistingJobs(true);
         // 设置自动启动,默认为true
         factory.setAutoStartup(true);
+//        factory.setAutoStartup(false);
 
         return factory;
     }

+ 76 - 3
fs-qw-task/src/main/java/com/fs/app/controller/CommonController.java

@@ -21,10 +21,11 @@ import com.fs.his.service.IFsInquiryOrderService;
 import com.fs.his.utils.qrcode.QRCodeUtils;
 import com.fs.qw.domain.QwCompany;
 import com.fs.qw.domain.QwExternalContact;
+import com.fs.qw.domain.QwIpadServerLog;
+import com.fs.qw.domain.QwUser;
 import com.fs.qw.mapper.QwExternalContactMapper;
-import com.fs.qw.service.IQwCompanyService;
-import com.fs.qw.service.IQwExternalContactService;
-import com.fs.qw.service.IQwMaterialService;
+import com.fs.qw.mapper.QwUserMapper;
+import com.fs.qw.service.*;
 import com.fs.qwApi.domain.QwExternalContactResult;
 import com.fs.qwApi.service.QwApiService;
 import com.fs.sop.mapper.QwSopLogsMapper;
@@ -33,6 +34,8 @@ import com.fs.sop.mapper.SopUserLogsMapper;
 import com.fs.sop.service.*;
 import com.fs.sop.vo.QwSopLogsDoSendListTVO;
 import com.fs.store.service.IFsUserCourseCountService;
+import com.fs.wxwork.dto.WxWorkGetQrCodeDTO;
+import com.fs.wxwork.service.WxWorkService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
@@ -48,6 +51,7 @@ import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Date;
 import java.util.List;
 
 @Api("公共接口")
@@ -134,8 +138,77 @@ public class CommonController {
     @Autowired
     public RedisCache redisCache;
 
+    @Autowired
+    private QwUserMapper qwUserMapper;
+
+
+    @Autowired
+    IQwIpadServerService ipadServerService;
+
+    @Autowired
+    IQwIpadServerLogService qwIpadServerLogService;
+    @Autowired
+    IQwIpadServerUserService qwIpadServerUserService;
+
+    @Autowired
+    IQwExternalContactService externalContactService;
+    @Autowired
+    WxWorkService wxWorkService;
+
+    /**
+     *
+     */
+    @GetMapping("/selectQwUserByTest")
+    public void selectQwUserByTest() {
+        try {
+            List<QwUser> list = qwUserMapper.selectQwUserByTest();
+            for (QwUser qwUser : list) {
+                try {
+                    Integer serverStatus = qwUser.getServerStatus();
+                    Long serverId = qwUser.getServerId();
+                    if (serverStatus==0){
+                        log.error("不需要解绑");
+                    }
+                    if (serverId==null){
+                        log.error("serverId不存在");
+                    }
+                    QwUser u = new QwUser();
+                    u.setId(qwUser.getId());
+                    u.setServerId(null);
+                    u.setServerStatus(0);
+                    qwUserMapper.updateQwUser(u);
+                    ipadServerService.addServer(serverId);
+                    QwIpadServerLog qwIpadServerLog = new QwIpadServerLog();
+                    qwIpadServerLog.setType(2);
+                    qwIpadServerLog.setTilie("解绑");
+                    qwIpadServerLog.setServerId(serverId);
+                    qwIpadServerLog.setQwUserId(qwUser.getId());
+                    qwIpadServerLog.setCompanyUserId(qwUser.getCompanyUserId());
+                    qwIpadServerLog.setCompanyId(qwUser.getCompanyId());
+                    qwIpadServerLog.setCreateTime(new Date());
+                    qwIpadServerLogService.insertQwIpadServerLog(qwIpadServerLog);
+                    qwIpadServerUserService.deleteQwIpadServerUserByQwUserId(qwUser.getId());
+                    WxWorkGetQrCodeDTO wxWorkGetQrCodeDTO = new WxWorkGetQrCodeDTO();
+                    wxWorkGetQrCodeDTO.setUuid(qwUser.getUid());
+                    wxWorkService.LoginOut(wxWorkGetQrCodeDTO,qwUser.getServerId());
+                    updateIpadStatus(qwUser.getId(),0);
+                } catch (Exception e) {
+                    log.error("解绑ipad报错",e);
+                }
+            }
+        } catch (Exception e) {
+            log.error("定时处理未绑定员工企微异常",e);
+        }
 
+    }
 
+
+    void updateIpadStatus(Long id ,Integer status){
+        QwUser u = new QwUser();
+        u.setId(id);
+        u.setIpadStatus(status);
+        qwUserMapper.updateQwUser(u);
+    }
     /**
      *
      */

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

@@ -15,6 +15,7 @@ import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
+import com.fs.common.utils.CloudHostUtils;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.company.domain.CompanyTag;
@@ -776,6 +777,11 @@ public class FsUserCourseServiceImpl implements IFsUserCourseService
         link.setUpdateTime(calendar.getTime());
         int i = fsCourseLinkMapper.insertFsCourseLink(link);
         if (i > 0){
+            if (CloudHostUtils.hasCloudHostName("中康")){
+                String domainName = getDomainName(param.getCompanyUserId(), config);
+                String sortLink = domainName + link.getRealLink().replace("/#","");
+                return R.ok().put("url", sortLink).put("link", random);
+            }
             String domainName = getDomainName(param.getCompanyUserId(), config);
             String sortLink = domainName + appShortLink + link.getLink();
             return R.ok().put("url", sortLink).put("link", random);
@@ -783,6 +789,9 @@ public class FsUserCourseServiceImpl implements IFsUserCourseService
         return R.error("生成链接失败!");
     }
 
+    public static void main(String[] args) {
+        System.out.println(appRealLink.replace("/#", ""));
+    }
     /**
      * 修改课堂配置
      */

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

@@ -1400,7 +1400,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
 
         // 判断来源是否是app,如是app,则发放积分奖励
         int sourceApp = 3;
-        if(sourceApp == param.getSource()){
+        if(sourceApp == param.getSource()&&!CloudHostUtils.hasCloudHostName("中康")){
             return sendIntegralReward(param, user, log, config);
         }
 

+ 1 - 1
fs-service/src/main/java/com/fs/live/service/impl/LiveAfterSalesServiceImpl.java

@@ -882,7 +882,7 @@ public class LiveAfterSalesServiceImpl implements ILiveAfterSalesService {
                 orderMap.setOrderCode(orderSn);
                 liveOrderService.updateLiveOrder(orderMap);
                 //生成新的订单
-                List<LiveOrderPayment> payments = liveOrderPaymentMapper.selectLiveOrderPaymentByPay(2, order.getOrderId());
+                List<LiveOrderPayment> payments = liveOrderPaymentMapper.selectLiveOrderPaymentByPay(5, order.getOrderId());
                 for (LiveOrderPayment payment : payments) {
                     LiveOrderPayment livePayment = new LiveOrderPayment();
                     livePayment.setPaymentId(payment.getPaymentId());

+ 1 - 0
fs-service/src/main/java/com/fs/qw/mapper/QwUserMapper.java

@@ -487,4 +487,5 @@ public interface QwUserMapper extends BaseMapper<QwUser>
             "</script>")
     List<QwUser> selectQwUserByIds(@Param("qwUserIdList") List<Long> qwUserIdList);
 
+    List<QwUser> selectQwUserByTest();
 }

+ 3 - 0
fs-service/src/main/java/com/fs/sop/service/IQwSopTempContentService.java

@@ -1,5 +1,6 @@
 package com.fs.sop.service;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.fs.common.annotation.DataSource;
 import com.fs.common.enums.DataSourceType;
@@ -90,4 +91,6 @@ public interface IQwSopTempContentService extends IService<QwSopTempContent>{
     void removeByTempIds(Collection<String> tempIds);
 
     List<QwSopTempContent> listByTempIds(Collection<String> tempIds);
+
+    void removeByWrapper(LambdaQueryWrapper<QwSopTempContent> wrapper);
 }

+ 11 - 0
fs-service/src/main/java/com/fs/sop/service/IQwSopTempDayService.java

@@ -1,10 +1,15 @@
 package com.fs.sop.service;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.fs.sop.domain.QwSopTempDay;
 
+import java.sql.Wrapper;
 import java.util.Collection;
 import java.util.List;
+import java.util.Set;
 
 /**
  * sop任务模板规则Service接口
@@ -35,4 +40,10 @@ public interface IQwSopTempDayService extends IService<QwSopTempDay> {
     int getDayNumByIdLimitOne(String tempId);
 
     void removeByTempIds(Collection<String> tempIds);
+
+    void removeByWrapper(LambdaQueryWrapper<QwSopTempDay> wrapper);
+
+    List<QwSopTempDay> listByTempIds(LambdaQueryWrapper<QwSopTempDay> wrapper);
+
+    void updateByWrapper(UpdateWrapper<QwSopTempDay> wrapper);
 }

+ 3 - 0
fs-service/src/main/java/com/fs/sop/service/IQwSopTempRulesService.java

@@ -1,5 +1,6 @@
 package com.fs.sop.service;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.fs.common.annotation.DataSource;
 import com.fs.common.enums.DataSourceType;
@@ -94,4 +95,6 @@ public interface IQwSopTempRulesService extends IService<QwSopTempRules>{
     List<QwSopTempRules> listByCourseId(Long courseId);
 
     void removeByTempIds(Collection<String> tempIds);
+
+    void removeByWrapper(LambdaQueryWrapper<QwSopTempRules> wrapper);
 }

+ 7 - 0
fs-service/src/main/java/com/fs/sop/service/impl/QwSopTempContentServiceImpl.java

@@ -1,5 +1,6 @@
 package com.fs.sop.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fs.common.annotation.DataSource;
@@ -163,4 +164,10 @@ public class QwSopTempContentServiceImpl extends ServiceImpl<QwSopTempContentMap
     public List<QwSopTempContent> listByTempIds(Collection<String> tempIds) {
         return baseMapper.selectList(new QueryWrapper<QwSopTempContent>().in("temp_id", tempIds));
     }
+
+    @Override
+    @DataSource(DataSourceType.SOP)
+    public void removeByWrapper(LambdaQueryWrapper<QwSopTempContent> wrapper) {
+        this.remove(wrapper);
+    }
 }

+ 23 - 0
fs-service/src/main/java/com/fs/sop/service/impl/QwSopTempDayServiceImpl.java

@@ -2,6 +2,7 @@ package com.fs.sop.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fs.common.annotation.DataSource;
@@ -13,7 +14,9 @@ import lombok.AllArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.sql.Wrapper;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -24,6 +27,7 @@ import java.util.List;
  */
 @Service
 @AllArgsConstructor
+@DataSource(DataSourceType.SOP)
 public class QwSopTempDayServiceImpl extends ServiceImpl<QwSopTempDayMapper, QwSopTempDay> implements IQwSopTempDayService {
 
 
@@ -92,4 +96,23 @@ public class QwSopTempDayServiceImpl extends ServiceImpl<QwSopTempDayMapper, QwS
     public void removeByTempIds(Collection<String> tempIds) {
         this.remove(new QueryWrapper<QwSopTempDay>().in("temp_id", tempIds));
     }
+
+    @Override
+    @DataSource(DataSourceType.SOP)
+    public void removeByWrapper(LambdaQueryWrapper<QwSopTempDay> wrapper) {
+        this.remove(wrapper);
+    }
+
+    @Override
+    @DataSource(DataSourceType.SOP)
+    public List<QwSopTempDay> listByTempIds(LambdaQueryWrapper<QwSopTempDay> wrapper) {
+        return this.list(wrapper);
+    }
+
+    @Override
+    @DataSource(DataSourceType.SOP)
+    public void updateByWrapper(UpdateWrapper<QwSopTempDay> wrapper) {
+        this.update(wrapper);
+    }
+
 }

+ 7 - 0
fs-service/src/main/java/com/fs/sop/service/impl/QwSopTempRulesServiceImpl.java

@@ -1,6 +1,7 @@
 package com.fs.sop.service.impl;
 
 import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fs.common.annotation.DataSource;
@@ -252,4 +253,10 @@ public class QwSopTempRulesServiceImpl extends ServiceImpl<QwSopTempRulesMapper,
     public void removeByTempIds(Collection<String> tempIds) {
         this.remove(new QueryWrapper<QwSopTempRules>().in("temp_id", tempIds));
     }
+
+    @Override
+    @DataSource(DataSourceType.SOP)
+    public void removeByWrapper(LambdaQueryWrapper<QwSopTempRules> wrapper) {
+        this.remove(wrapper);
+    }
 }

+ 60 - 45
fs-service/src/main/java/com/fs/sop/service/impl/QwSopTempServiceImpl.java

@@ -2,7 +2,10 @@ package com.fs.sop.service.impl;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.common.annotation.DataSource;
 import com.fs.common.enums.DataSourceType;
 import com.fs.common.exception.base.BaseException;
@@ -46,7 +49,6 @@ import java.text.SimpleDateFormat;
 import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
-import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Consumer;
 import java.util.stream.Collectors;
@@ -425,6 +427,10 @@ public class QwSopTempServiceImpl implements IQwSopTempService {
         temp.setProject(fsUserCourse.getProject());
         qwSopTempMapper.updateQwSopTemp(temp);
         List<FsUserCourseVideo> videoList = fsUserCourseVideoMapper.selectVideoByCourseId(fsUserCourse.getCourseId());
+        createSopTempRules(temp, videoList, fsUserCourse);
+    }
+
+    private void createSopTempRules(QwSopTemp temp, List<FsUserCourseVideo> videoList, FsUserCourse fsUserCourse) {
         AtomicInteger i = new AtomicInteger(1);
         Integer gap = temp.getGap();
         List<QwSopTempDay> collect = videoList.stream().map(e -> {
@@ -627,67 +633,76 @@ public class QwSopTempServiceImpl implements IQwSopTempService {
         if (CollectionUtils.isEmpty(rulesList)) {
             return;
         }
-
         // 获取这些规则关联的模板ID集合
         Set<String> tempIds = rulesList.stream()
                 .map(QwSopTempRules::getTempId)
                 .filter(Objects::nonNull)
                 .collect(Collectors.toSet());
 
-        // 查询相关联的sop模板
-        if (CollectionUtils.isEmpty(tempIds)) {
-            return;
-        }
-        // 只弄课程模板的
+        FsUserCourse fsUserCourse = fsUserCourseMapper.selectFsUserCourseByCourseId(courseId);
+        List<FsUserCourseVideo> videoList = fsUserCourseVideoMapper.selectVideoByCourseId(fsUserCourse.getCourseId());
         List<QwSopTemp> tempList = qwSopTempMapper.selectListByIds(tempIds);
-        tempList = tempList.stream().filter(f -> Objects.equals(f.getStatus(), "1")).collect(Collectors.toList());
-        if (CollectionUtils.isEmpty(tempList)) {
-            return;
+        List<QwSopTempContent> contentList = qwSopTempContentService.listByTempIds(tempIds);
+        List<QwSopTempDay> dayList = qwSopTempDayService.listByTempIds(new LambdaQueryWrapper<QwSopTempDay>().in(QwSopTempDay::getTempId, tempIds));
+        List<Long> videoIdList = videoList.stream().map(FsUserCourseVideo::getVideoId).collect(Collectors.toList());
+        // videoList转Map key 为videoId value 为 courseSort
+        Map<Long, Long> videoSortMap = videoList.stream().collect(Collectors.toMap(FsUserCourseVideo::getVideoId, FsUserCourseVideo::getCourseSort));
+
+        // 将课程中已删除的视频在规则和日期中删除
+        Set<Long> dayIdList = rulesList.stream().filter(e -> !videoIdList.contains(e.getVideoId())).map(QwSopTempRules::getDayId).collect(Collectors.toSet());
+        if (CollectionUtils.isNotEmpty(dayIdList)) {
+            qwSopTempDayService.removeByWrapper(new LambdaQueryWrapper<QwSopTempDay>().in(QwSopTempDay::getId, dayIdList));
+            qwSopTempRulesService.removeByWrapper(new LambdaQueryWrapper<QwSopTempRules>().in(QwSopTempRules::getDayId, dayIdList));
+            qwSopTempContentService.removeByWrapper(new LambdaQueryWrapper<QwSopTempContent>().in(QwSopTempContent::getDayId, dayIdList));
         }
 
-        // 获取这些规则关联的模板ID集合
-        Set<String> sopTempIds = tempList.stream()
-                .map(QwSopTemp::getId)
-                .filter(Objects::nonNull)
-                .collect(Collectors.toSet());
+        // 需要添加的课程视频
+        List<FsUserCourseVideo> addVideoList = videoList.stream()
+                .filter(e -> rulesList.stream().noneMatch(f -> f.getVideoId().equals(e.getVideoId()))).collect(Collectors.toList());
 
-        List<QwSopTempContent> contentList = qwSopTempContentService.listByTempIds(sopTempIds);
+        if (CollectionUtils.isNotEmpty(addVideoList)) {
+            for (QwSopTemp temp : tempList) {
+                // 通过历史中的第一课的数据来构建
+                Optional<QwSopTempDay> first = dayList.stream().filter(e -> e.getTempId().equals(temp.getId())).findFirst();
+                if (!first.isPresent()) {
+                    break;
+                }
+                QwSopTempDay qwSopTempDay = first.get();
+                // 构造timeList timeDesc time
+                temp.setTime(LocalTime.now());
+
+                temp.setTimeList(rulesList.stream()
+                        .filter(e -> e.getTempId().equals(temp.getId()) && Objects.equals(e.getIsOfficial(), "0")
+                                && Objects.equals(e.getDayId(), qwSopTempDay.getId())
+                        ).map(QwSopTempRules::getTime)
+                        .collect(Collectors.toList()));
 
-        qwSopTempDayService.removeByTempIds(tempIds);
-        qwSopTempRulesService.removeByTempIds(tempIds);
-        qwSopTempContentService.removeByTempIds(tempIds);
-        // 对每个模板执行同步操作
-        for (QwSopTemp temp : tempList) {
-            // 构造timeList timeDesc time
-            rulesList.stream().filter(e -> e.getTempId().equals(temp.getId())).findFirst()
-                    .ifPresent(first -> temp.setTime(LocalTime.parse(first.getTime() + ":00")));
-
-            temp.setTimeList(rulesList.stream()
-                    .filter(e -> e.getTempId().equals(temp.getId()) && Objects.equals(e.getIsOfficial(), "0")
-                            && Objects.equals(e.getName(), "第1天")).map(QwSopTempRules::getTime)
-                    .collect(Collectors.toList()));
-            // 过滤并找到 dayId 最小的元素
-            Optional<QwSopTempContent> minDayEntity = contentList.stream()
-                    // 1. 过滤条件:tempId匹配 + isBindUrl为null
-                    .filter(e -> e.getTempId().equals(temp.getId())
-                            && Objects.isNull(e.getIsBindUrl()))
-                    // 2. 按 dayId 升序排序,取第一个(最小)
-                    .min(Comparator.comparingLong(QwSopTempContent::getDayId)); // 若dayId是Long,用comparingLong
-
-            if (minDayEntity.isPresent()) {
-                QwSopTempContent qwSopTempContent = minDayEntity.get();
                 temp.setTimeDesc(contentList.stream().filter(e -> e.getTempId().equals(temp.getId())
                                 && Objects.isNull(e.getIsBindUrl())
-                                && Objects.equals(qwSopTempContent.getDayId(), e.getDayId())
+                                && Objects.equals(qwSopTempDay.getId(), e.getDayId())
                         )
                         .map(m -> JSONObject.parseObject(m.getContent()).getString("value")).collect(Collectors.toList()));
+                temp.setProject(fsUserCourse.getProject());
+                temp.setCourseId(courseId);
+                temp.setOpenOfficial("1");
+                qwSopTempMapper.updateQwSopTemp(temp);
+                createSopTempRules(temp, addVideoList, fsUserCourse);
             }
+        }
 
-            // 插入课程id
-            temp.setCourseId(courseId);
-            temp.setOpenOfficial("1");
-            // 重新生成该模板的规则和内容
-            threadPoolTaskExecutor.execute(() -> createSopTempRules(temp));
+        // 整理排序
+        List<QwSopTempRules> afterRuleList = qwSopTempRulesService.listByCourseId(courseId);
+        for (QwSopTemp temp : tempList) {
+            Long[] dayIdArray = afterRuleList.stream().filter(e -> e.getTempId().equals(temp.getId())).sorted(Comparator.comparing(a -> videoSortMap.get(a.getVideoId())))
+                    .map(QwSopTempRules::getDayId).distinct().toArray(Long[]::new);
+            for (int i = 0; i < dayIdArray.length; i++) {
+                qwSopTempDayService.updateByWrapper(new UpdateWrapper<QwSopTempDay>()
+                        .eq("id", dayIdArray[i])
+                        .set("sorts", i + 1)
+                        .set("name", "第" + (i + 1) + "天")
+                        .set("day_num", i + 1)
+                );
+            }
         }
     }
 

+ 15 - 11
fs-service/src/main/resources/application-config-druid-bjczwh.yml

@@ -37,8 +37,8 @@ wx:
       port: 6379
       timeout: 2000
     configs:
-      - appId: wx090xxxx5456e # 第一个公众号的appid  //公众号名称:德瑞康
-        secret: dc70e9xxxx0aea6b7c52b7 # 公众号的appsecret--德瑞康
+      - appId: wx014d7c4fff877ea0 # 第一个公众号的appid  //公众号名称:食养美好生活
+        secret: ef574e8c66433cac1b158ea3a901650c # 公众号的appsecret--食养美好生活
         token: PPKOdAlCoMO # 接口配置里的Token值
         aesKey: Eswa6VjwtVMCcw03qZy6fWllgrv5aytIA1SZPEU0kU2 # 接口配置里的EncodingAESKey值
 aifabu:  #爱链接
@@ -55,8 +55,14 @@ watch:
   password3: v9xsKuqn_$d2y
 
 fs :
-  commonApi: http://127.0.0.1:7771
-  h5CommonApi: http://127.0.0.1:7771
+  commonApi: http://192.168.0.194:7771
+  h5CommonApi: http://192.168.0.194:7771
+  jwt:
+    # 加密秘钥
+    secret: bjczwh-bcdefg
+    # token有效时长,7天,单位秒
+    expire: 31536000
+    header: AppToken
 nuonuo:
   key: 10924508
   secret: A2EB20764D304D16
@@ -78,17 +84,15 @@ tmp_secret_config:
   proxy: fs
 cloud_host:
   company_name: 北京存在文化
-  projectCode: BJCZWH
+  projectCode: CZWH
 headerImg:
   imgUrl:
 
 ipad:
-  ipadUrl: http://ipad.cdwjyyh.com
-  aiApi: 1212121212
-  voiceApi:
-  commonApi:
+  ipadUrl: http://aipad.moonxiang.com
+  aiApi: http://49.232.181.28:3000/api
+  voiceApi: http://81.70.193.34:8667
+  commonApi: http://81.70.193.34:7771
 wx_miniapp_temp:
   pay_order_temp_id:
   inquiry_temp_id:
-
-

+ 3 - 0
fs-service/src/main/resources/application-dev.yml

@@ -178,6 +178,9 @@ headerImg:
 ipad:
     ipadUrl: http://admin.test.ylrztop.com/ipad
     aiApi: http://1.95.196.10:3000/api
+    voiceApi:
+    commonApi:
+    url:
 wx_miniapp_temp:
     pay_order_temp_id:
     inquiry_temp_id:

+ 159 - 150
fs-service/src/main/resources/application-druid-bjczwh.yml

@@ -1,158 +1,167 @@
 # 数据源配置
 spring:
-    profiles:
-        include: config-druid-bjczwh,common
-    # redis 配置
-    redis:
-        host: r-bp1ylqods7sqn8gs4b.redis.rds.aliyuncs.com
-        port: 6379
-        # 数据库索引
-        database: 0
-        # 密码
-        password: Ylrz_1q2w3e4r5t6y
-        # 连接超时时间
-        timeout: 10s
-        lettuce:
-            pool:
-                # 连接池中的最小空闲连接
-                min-idle: 0
-                # 连接池中的最大空闲连接
-                max-idle: 8
-                # 连接池的最大数据库连接数
-                max-active: 100
-                # #连接池最大阻塞等待时间(使用负值表示没有限制)
-                max-wait: -1ms
-    datasource:
-#        clickhouse:
-#            type: com.alibaba.druid.pool.DruidDataSource
-#            driverClassName: com.clickhouse.jdbc.ClickHouseDriver
-#            url: jdbc:clickhouse://1.14.104.71:8123/sop_test?compress=0&use_server_time_zone=true&use_client_time_zone=false&timezone=Asia/Shanghai
-#            username: rt_2024
-#            password: Yzx_19860213
-#            initialSize: 10
-#            maxActive: 100
-#            minIdle: 10
-#            maxWait: 6000
-        mysql:
-            type: com.alibaba.druid.pool.DruidDataSource
-            driverClassName: com.mysql.cj.jdbc.Driver
-            druid:
-                # 主库数据源
-                master:
-                  url: jdbc:mysql://rm-bp10925iw97l3b2hb.mysql.rds.aliyuncs.com:3306/fs_his?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
-                  username: root
-                  password: Ylrz_1q2w3e4r5t6y
-                # 从库数据源
-                slave:
-                    # 从数据源开关/默认关闭
-                    enabled: false
-                    url:
-                    username:
-                    password:
-                # 初始连接数
-                initialSize: 5
-                # 最小连接池数量
-                minIdle: 10
-                # 最大连接池数量
-                maxActive: 20
-                # 配置获取连接等待超时的时间
-                maxWait: 60000
-                # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
-                timeBetweenEvictionRunsMillis: 60000
-                # 配置一个连接在池中最小生存的时间,单位是毫秒
-                minEvictableIdleTimeMillis: 300000
-                # 配置一个连接在池中最大生存的时间,单位是毫秒
-                maxEvictableIdleTimeMillis: 900000
-                # 配置检测连接是否有效
-                validationQuery: SELECT 1 FROM DUAL
-                testWhileIdle: true
-                testOnBorrow: false
-                testOnReturn: false
-                webStatFilter:
-                    enabled: true
-                statViewServlet:
-                    enabled: true
-                    # 设置白名单,不填则允许所有访问
-                    allow:
-                    url-pattern: /druid/*
-                    # 控制台管理用户名和密码
-                    login-username: fs
-                    login-password: 123456
-                filter:
-                    stat:
-                        enabled: true
-                        # 慢SQL记录
-                        log-slow-sql: true
-                        slow-sql-millis: 1000
-                        merge-sql: true
-                    wall:
-                        config:
-                            multi-statement-allow: true
-        sop:
-            type: com.alibaba.druid.pool.DruidDataSource
-            driverClassName: com.mysql.cj.jdbc.Driver
-            druid:
-                # 主库数据源
-                master:
-                    url: jdbc:mysql://rm-bp10925iw97l3b2hb.mysql.rds.aliyuncs.com:3306/fs_his_sop?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
-                    username: root
-                    password: Ylrz_1q2w3e4r5t6y
-                # 初始连接数
-                initialSize: 5
-                # 最小连接池数量
-                minIdle: 10
-                # 最大连接池数量
-                maxActive: 20
-                # 配置获取连接等待超时的时间
-                maxWait: 60000
-                # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
-                timeBetweenEvictionRunsMillis: 60000
-                # 配置一个连接在池中最小生存的时间,单位是毫秒
-                minEvictableIdleTimeMillis: 300000
-                # 配置一个连接在池中最大生存的时间,单位是毫秒
-                maxEvictableIdleTimeMillis: 900000
-                # 配置检测连接是否有效
-                validationQuery: SELECT 1 FROM DUAL
-                testWhileIdle: true
-                testOnBorrow: false
-                testOnReturn: false
-                webStatFilter:
-                    enabled: true
-                statViewServlet:
-                    enabled: true
-                    # 设置白名单,不填则允许所有访问
-                    allow:
-                    url-pattern: /druid/*
-                    # 控制台管理用户名和密码
-                    login-username: fs
-                    login-password: 123456
-                filter:
-                    stat:
-                        enabled: true
-                        # 慢SQL记录
-                        log-slow-sql: true
-                        slow-sql-millis: 1000
-                        merge-sql: true
-                    wall:
-                        config:
-                            multi-statement-allow: true
+  profiles:
+    include: config-druid-bjczwh,common
+  # redis 配置
+  redis:
+    host: redis-b6d80cf4-3df9-43c8-8182-bfe3ace0098b.cn-southwest-2.dcs.myhuaweicloud.com
+    port: 6379
+    # 数据库索引
+    database: 0
+    # 密码
+    password:
+    # 连接超时时间
+    timeout: 10s
+    lettuce:
+      pool:
+        # 连接池中的最小空闲连接
+        min-idle: 0
+        # 连接池中的最大空闲连接
+        max-idle: 8
+        # 连接池的最大数据库连接数
+        max-active: 100
+        # #连接池最大阻塞等待时间(使用负值表示没有限制)
+        max-wait: -1ms
+  datasource:
+    #        clickhouse:
+    #            type: com.alibaba.druid.pool.DruidDataSource
+    #            driverClassName: com.clickhouse.jdbc.ClickHouseDriver
+    #            url: jdbc:clickhouse://1.14.104.71:8123/sop_test?compress=0&use_server_time_zone=true&use_client_time_zone=false&timezone=Asia/Shanghai
+    #            username: rt_2024
+    #            password: Yzx_19860213
+    #            initialSize: 10
+    #            maxActive: 100
+    #            minIdle: 10
+    #            maxWait: 6000
+    mysql:
+      type: com.alibaba.druid.pool.DruidDataSource
+      driverClassName: com.mysql.cj.jdbc.Driver
+      druid:
+        # 主库数据源
+        master:
+          url: jdbc:mysql://rds.czwh.lan:3306/fs_his?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+          username: czwh
+          password: Ylrz_1q2w3e4r5t6y
+        # 从库数据源
+        slave:
+          # 从数据源开关/默认关闭
+          enabled: false
+          url:
+          username:
+          password:
+        # 初始连接数
+        initialSize: 5
+        # 最小连接池数量
+        minIdle: 10
+        # 最大连接池数量
+        maxActive: 20
+        # 配置获取连接等待超时的时间
+        maxWait: 60000
+        # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+        timeBetweenEvictionRunsMillis: 60000
+        # 配置一个连接在池中最小生存的时间,单位是毫秒
+        minEvictableIdleTimeMillis: 300000
+        # 配置一个连接在池中最大生存的时间,单位是毫秒
+        maxEvictableIdleTimeMillis: 900000
+        # 配置检测连接是否有效
+        validationQuery: SELECT 1 FROM DUAL
+        testWhileIdle: true
+        testOnBorrow: false
+        testOnReturn: false
+        webStatFilter:
+          enabled: true
+        statViewServlet:
+          enabled: true
+          # 设置白名单,不填则允许所有访问
+          allow:
+          url-pattern: /druid/*
+          # 控制台管理用户名和密码
+          login-username: fs
+          login-password: 123456
+        filter:
+          stat:
+            enabled: true
+            # 慢SQL记录
+            log-slow-sql: true
+            slow-sql-millis: 1000
+            merge-sql: true
+          wall:
+            config:
+              multi-statement-allow: true
+    sop:
+      type: com.alibaba.druid.pool.DruidDataSource
+      driverClassName: com.mysql.cj.jdbc.Driver
+      druid:
+        # 主库数据源
+        master:
+          url: jdbc:mysql://rds.czwh.lan:3306/fs_his_sop?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+          username: czwh
+          password: Ylrz_1q2w3e4r5t6y
+        # 初始连接数
+        initialSize: 5
+        # 最小连接池数量
+        minIdle: 10
+        # 最大连接池数量
+        maxActive: 20
+        # 配置获取连接等待超时的时间
+        maxWait: 60000
+        # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+        timeBetweenEvictionRunsMillis: 60000
+        # 配置一个连接在池中最小生存的时间,单位是毫秒
+        minEvictableIdleTimeMillis: 300000
+        # 配置一个连接在池中最大生存的时间,单位是毫秒
+        maxEvictableIdleTimeMillis: 900000
+        # 配置检测连接是否有效
+        validationQuery: SELECT 1 FROM DUAL
+        testWhileIdle: true
+        testOnBorrow: false
+        testOnReturn: false
+        webStatFilter:
+          enabled: true
+        statViewServlet:
+          enabled: true
+          # 设置白名单,不填则允许所有访问
+          allow:
+          url-pattern: /druid/*
+          # 控制台管理用户名和密码
+          login-username: fs
+          login-password: 123456
+        filter:
+          stat:
+            enabled: true
+            # 慢SQL记录
+            log-slow-sql: true
+            slow-sql-millis: 1000
+            merge-sql: true
+          wall:
+            config:
+              multi-statement-allow: true
 rocketmq:
-    name-server: rmq-16xj8o92zp.rocketmq.cd.qcloud.tencenttdmq.com:8080
-    producer:
-        group: my-producer-group
-        access-key: ak16xj8o92zp984557f83ba2 # 替换为实际的 accessKey
-        secret-key: sk2ff1c6b15b74b888 # 替换为实际的 secretKey
-    consumer:
-        group: common-group
-        access-key: ak16xj8o92zp984557f83ba2 # 替换为实际的 accessKey
-        secret-key: sk2ff1c6b15b74b888 # 替换为实际的 secretKey
+  name-server: 192.168.0.124:8100
+  producer:
+    group: my-producer-group
+    access-key: default # 替换为实际的 accessKey
+    secret-key: O1VnW98G8Rmn0PoZ # 替换为实际的 secretKey
+  consumer:
+    topic: course-finish-notes
+    group: course-finish-group
+    access-key: default # 替换为实际的 accessKey
+    secret-key: O1VnW98G8Rmn0PoZ # 替换为实际的 secretKey
 openIM:
-    secret: openIM123
-    userID: imAdmin
-    url: https://web.im.fbylive.com/api
+  secret: openIM123
+  userID: imAdmin
+  url: https://web.im.fbylive.com/api
 #是否为新商户,新商户不走mpOpenId
-isNewWxMerchant: true
+isNewWxMerchant: false
 #是否使用新im
 im:
-    type: NONE
+  type: NONE
+
+qw:
+  enableAutoTag: 1
+tag:
+  thread:
+    num: 5
+  rate:
+    limit: 30
 

+ 5 - 0
fs-service/src/main/resources/mapper/qw/QwUserMapper.xml

@@ -304,4 +304,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         SELECT dept_id FROM sub_dept
     </select>
 
+    <select id="selectQwUserByTest" resultMap="QwUserResult">
+        <include refid="selectQwUserVo"/>
+        where status = 0 and server_status = 1
+    </select>
+
 </mapper>