浏览代码

Merge remote-tracking branch 'origin/master'

yfh 6 小时之前
父节点
当前提交
243fba20e2

+ 3 - 8
fs-admin/src/main/java/com/fs/FSApplication.java

@@ -1,11 +1,8 @@
 package com.fs;
 
-import com.qiniu.common.Zone;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
-import org.springframework.core.io.Resource;
-import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
 import org.springframework.scheduling.annotation.EnableAsync;
 import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.transaction.annotation.Transactional;
@@ -13,14 +10,12 @@ import org.springframework.transaction.annotation.Transactional;
 /**
  * 启动程序
  */
-@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
+@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
 @Transactional
 @EnableAsync
 @EnableScheduling
-public class FSApplication
-{
-    public static void main(String[] args)
-    {
+public class FSApplication {
+    public static void main(String[] args) {
         // System.setProperty("spring.devtools.restart.enabled", "false");
         SpringApplication.run(FSApplication.class, args);
         System.out.println("admin启动成功");

+ 61 - 75
fs-admin/src/main/java/com/fs/course/controller/FsUserCourseController.java

@@ -1,39 +1,33 @@
 package com.fs.course.controller;
 
-import java.util.List;
-
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.json.JSONUtil;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.model.LoginUser;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.ServletUtils;
+import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.course.config.CourseConfig;
+import com.fs.course.domain.FsUserCourse;
 import com.fs.course.params.FsUserCourseConfigParam;
+import com.fs.course.service.IFsUserCourseService;
 import com.fs.course.service.IFsUserCourseVideoService;
 import com.fs.course.vo.FsUserCourseListPVO;
 import com.fs.framework.web.service.TokenService;
 import com.fs.his.utils.RedisCacheUtil;
 import com.fs.his.vo.OptionsVO;
 import com.fs.qw.param.FsUserCourseRedPageParam;
+import com.fs.sop.service.IQwSopTempService;
 import com.fs.system.service.ISysConfigService;
-import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-import com.fs.common.annotation.Log;
-import com.fs.common.core.controller.BaseController;
-import com.fs.common.core.domain.AjaxResult;
-import com.fs.common.enums.BusinessType;
-import com.fs.course.domain.FsUserCourse;
-import com.fs.course.service.IFsUserCourseService;
-import com.fs.common.utils.poi.ExcelUtil;
-import com.fs.common.core.page.TableDataInfo;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
 
 /**
  * 课程Controller
@@ -43,8 +37,7 @@ import com.fs.common.core.page.TableDataInfo;
  */
 @RestController
 @RequestMapping("/course/userCourse")
-public class FsUserCourseController extends BaseController
-{
+public class FsUserCourseController extends BaseController {
     @Autowired
     private IFsUserCourseService fsUserCourseService;
 
@@ -60,19 +53,21 @@ public class FsUserCourseController extends BaseController
     @Autowired
     private ISysConfigService configService;
 
+    @Autowired
+    private IQwSopTempService sopTempService;
+
     /**
      * 查询课程列表
      */
     @PreAuthorize("@ss.hasPermi('course:userCourse:list')")
     @GetMapping("/list")
-    public TableDataInfo list(FsUserCourse fsUserCourse)
-    {
+    public TableDataInfo list(FsUserCourse fsUserCourse) {
         startPage();
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         Long userId = loginUser.getUser().getUserId();
         String json = configService.selectConfigByKey("course.config");
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
-        if (ObjectUtil.isNotEmpty(config.getIsBound())&&config.getIsBound()){
+        if (ObjectUtil.isNotEmpty(config.getIsBound()) && config.getIsBound()) {
             fsUserCourse.setUserId(userId);
         }
         List<FsUserCourseListPVO> list = fsUserCourseService.selectFsUserCourseListPVO(fsUserCourse);
@@ -84,14 +79,13 @@ public class FsUserCourseController extends BaseController
      */
     @PreAuthorize("@ss.hasPermi('course:userCourse:publicList')")
     @GetMapping("/publicList")
-    public TableDataInfo publicList(FsUserCourse fsUserCourse)
-    {
+    public TableDataInfo publicList(FsUserCourse fsUserCourse) {
         startPage();
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         Long userId = loginUser.getUser().getUserId();
         String json = configService.selectConfigByKey("course.config");
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
-        if (ObjectUtil.isNotEmpty(config.getIsBound())&&config.getIsBound()){
+        if (ObjectUtil.isNotEmpty(config.getIsBound()) && config.getIsBound()) {
             fsUserCourse.setUserId(userId);
         }
         List<FsUserCourseListPVO> list = fsUserCourseService.selectFsUserCourseListPVO(fsUserCourse);
@@ -104,13 +98,12 @@ public class FsUserCourseController extends BaseController
     @PreAuthorize("@ss.hasPermi('course:userCourse:export')")
     @Log(title = "课程", businessType = BusinessType.EXPORT)
     @GetMapping("/export")
-    public AjaxResult export(FsUserCourse fsUserCourse)
-    {
+    public AjaxResult export(FsUserCourse fsUserCourse) {
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         Long userId = loginUser.getUser().getUserId();
         String json = configService.selectConfigByKey("course.config");
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
-        if (ObjectUtil.isNotEmpty(config.getIsBound())&&config.getIsBound()){
+        if (ObjectUtil.isNotEmpty(config.getIsBound()) && config.getIsBound()) {
             fsUserCourse.setUserId(userId);
         }
         List<FsUserCourse> list = fsUserCourseService.selectFsUserCourseList(fsUserCourse);
@@ -124,13 +117,12 @@ public class FsUserCourseController extends BaseController
     @PreAuthorize("@ss.hasPermi('course:userCourse:publicExport')")
     @Log(title = "课程", businessType = BusinessType.EXPORT)
     @GetMapping("/publicExport")
-    public AjaxResult publicExport(FsUserCourse fsUserCourse)
-    {
+    public AjaxResult publicExport(FsUserCourse fsUserCourse) {
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         Long userId = loginUser.getUser().getUserId();
         String json = configService.selectConfigByKey("course.config");
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
-        if (ObjectUtil.isNotEmpty(config.getIsBound())&&config.getIsBound()){
+        if (ObjectUtil.isNotEmpty(config.getIsBound()) && config.getIsBound()) {
             fsUserCourse.setUserId(userId);
         }
         List<FsUserCourse> list = fsUserCourseService.selectFsUserCourseList(fsUserCourse);
@@ -143,8 +135,7 @@ public class FsUserCourseController extends BaseController
      */
     @PreAuthorize("@ss.hasPermi('course:userCourse:query')")
     @GetMapping(value = "/{courseId}")
-    public AjaxResult getInfo(@PathVariable("courseId") Long courseId)
-    {
+    public AjaxResult getInfo(@PathVariable("courseId") Long courseId) {
         return AjaxResult.success(fsUserCourseService.selectFsUserCourseByCourseId(courseId));
     }
 
@@ -153,8 +144,7 @@ public class FsUserCourseController extends BaseController
      */
     @PreAuthorize("@ss.hasPermi('course:userCourse:publicQuery')")
     @GetMapping(value = "/public/{courseId}")
-    public AjaxResult publicGetInfo(@PathVariable("courseId") Long courseId)
-    {
+    public AjaxResult publicGetInfo(@PathVariable("courseId") Long courseId) {
         return AjaxResult.success(fsUserCourseService.selectFsUserCourseByCourseId(courseId));
     }
 
@@ -164,13 +154,12 @@ public class FsUserCourseController extends BaseController
     @PreAuthorize("@ss.hasPermi('course:userCourse:add')")
     @Log(title = "课程", businessType = BusinessType.INSERT)
     @PostMapping
-    public AjaxResult add(@RequestBody FsUserCourse fsUserCourse)
-    {
+    public AjaxResult add(@RequestBody FsUserCourse fsUserCourse) {
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         Long userId = loginUser.getUser().getUserId();
         String json = configService.selectConfigByKey("course.config");
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
-        if (ObjectUtil.isNotEmpty(config.getIsBound())&&config.getIsBound()){
+        if (ObjectUtil.isNotEmpty(config.getIsBound()) && config.getIsBound()) {
             fsUserCourse.setUserId(userId);
         }
         fsUserCourseService.insertFsUserCourse(fsUserCourse);
@@ -185,13 +174,12 @@ public class FsUserCourseController extends BaseController
     @PreAuthorize("@ss.hasPermi('course:userCourse:publicAdd')")
     @Log(title = "课程", businessType = BusinessType.INSERT)
     @PostMapping("/public")
-    public AjaxResult publicAdd(@RequestBody FsUserCourse fsUserCourse)
-    {
+    public AjaxResult publicAdd(@RequestBody FsUserCourse fsUserCourse) {
         LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
         Long userId = loginUser.getUser().getUserId();
         String json = configService.selectConfigByKey("course.config");
         CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
-        if (ObjectUtil.isNotEmpty(config.getIsBound())&&config.getIsBound()){
+        if (ObjectUtil.isNotEmpty(config.getIsBound()) && config.getIsBound()) {
             fsUserCourse.setUserId(userId);
         }
         fsUserCourseService.insertFsUserCourse(fsUserCourse);
@@ -206,8 +194,7 @@ public class FsUserCourseController extends BaseController
     @PreAuthorize("@ss.hasPermi('course:userCourse:edit')")
     @Log(title = "课程", businessType = BusinessType.UPDATE)
     @PutMapping
-    public AjaxResult edit(@RequestBody FsUserCourse fsUserCourse)
-    {
+    public AjaxResult edit(@RequestBody FsUserCourse fsUserCourse) {
         fsUserCourseService.updateFsUserCourse(fsUserCourse);
         redisCacheUtil.delRedisKey("getCourseList");
         return toAjax(1);
@@ -219,8 +206,7 @@ public class FsUserCourseController extends BaseController
     @PreAuthorize("@ss.hasPermi('course:userCourse:editRedPage')")
     @Log(title = "修改课程红包", businessType = BusinessType.UPDATE)
     @PostMapping("/editRedPage")
-    public AjaxResult editRedPage(@RequestBody FsUserCourseRedPageParam redPageParam)
-    {
+    public AjaxResult editRedPage(@RequestBody FsUserCourseRedPageParam redPageParam) {
         courseVideoService.updateFsUserCourseRedPage(redPageParam);
         return toAjax(1);
     }
@@ -231,8 +217,7 @@ public class FsUserCourseController extends BaseController
     @PreAuthorize("@ss.hasPermi('course:userCourse:publicEdit')")
     @Log(title = "课程", businessType = BusinessType.UPDATE)
     @PutMapping("/public")
-    public AjaxResult publicEdit(@RequestBody FsUserCourse fsUserCourse)
-    {
+    public AjaxResult publicEdit(@RequestBody FsUserCourse fsUserCourse) {
         fsUserCourseService.updateFsUserCourse(fsUserCourse);
         redisCacheUtil.delRedisKey("getCourseList");
         return toAjax(1);
@@ -244,8 +229,7 @@ public class FsUserCourseController extends BaseController
     @PreAuthorize("@ss.hasPermi('course:userCourse:copy')")
     @Log(title = "课程", businessType = BusinessType.DELETE)
     @GetMapping("/copy/{courseId}")
-    public AjaxResult copy(@PathVariable Long courseId)
-    {
+    public AjaxResult copy(@PathVariable Long courseId) {
         int i = fsUserCourseService.copyFsUserCourse(courseId);
         return toAjax(i);
     }
@@ -255,8 +239,8 @@ public class FsUserCourseController extends BaseController
      */
     @PreAuthorize("@ss.hasPermi('course:userCourse:remove')")
     @Log(title = "课程", businessType = BusinessType.DELETE)
-	@DeleteMapping("/{courseIds}")
-    public AjaxResult remove(@PathVariable Long[] courseIds){
+    @DeleteMapping("/{courseIds}")
+    public AjaxResult remove(@PathVariable Long[] courseIds) {
         fsUserCourseService.deleteFsUserCourseByCourseIds(courseIds);
         redisCacheUtil.delRedisKey("getCourseList");
         return toAjax(1);
@@ -268,8 +252,7 @@ public class FsUserCourseController extends BaseController
     @PreAuthorize("@ss.hasPermi('course:userCourse:publicRemove')")
     @Log(title = "课程", businessType = BusinessType.DELETE)
     @DeleteMapping("/public/{courseIds}")
-    public AjaxResult publicRemove(@PathVariable Long[] courseIds)
-    {
+    public AjaxResult publicRemove(@PathVariable Long[] courseIds) {
         fsUserCourseService.deleteFsUserCourseByCourseIds(courseIds);
         redisCacheUtil.delRedisKey("getCourseList");
         return toAjax(1);
@@ -277,8 +260,7 @@ public class FsUserCourseController extends BaseController
 
 
     @GetMapping("/getAllList")
-    public R getAllList()
-    {
+    public R getAllList() {
         List<OptionsVO> list = fsUserCourseService.selectFsUserCourseAllList();
         return R.ok().put("data", list);
     }
@@ -286,18 +268,16 @@ public class FsUserCourseController extends BaseController
     @PreAuthorize("@ss.hasPermi('course:userCourse:updateIsShow')")
     @Log(title = "课程上架", businessType = BusinessType.UPDATE)
     @PostMapping("/updateIsShow")
-    public AjaxResult updateIsShow(@RequestBody FsUserCourse fsUserCourse)
-    {
+    public AjaxResult updateIsShow(@RequestBody FsUserCourse fsUserCourse) {
         fsUserCourseService.updateFsUserCourse(fsUserCourse);
         redisCacheUtil.delRedisKey("getCourseList");
-       return toAjax(1);
+        return toAjax(1);
     }
 
     @PreAuthorize("@ss.hasPermi('course:userCourse:publicUpdateIsShow')")
     @Log(title = "课程上架", businessType = BusinessType.UPDATE)
     @PostMapping("/publicUpdateIsShow")
-    public AjaxResult publicUpdateIsShow(@RequestBody FsUserCourse fsUserCourse)
-    {
+    public AjaxResult publicUpdateIsShow(@RequestBody FsUserCourse fsUserCourse) {
         fsUserCourseService.updateFsUserCourse(fsUserCourse);
         redisCacheUtil.delRedisKey("getCourseList");
         return toAjax(1);
@@ -306,9 +286,8 @@ public class FsUserCourseController extends BaseController
     @PreAuthorize("@ss.hasPermi('course:userCourse:putOn')")
     @Log(title = "课程批量上架", businessType = BusinessType.UPDATE)
     @PostMapping("/putOn/{courseIds}")
-    public AjaxResult putOn(@PathVariable Long[] courseIds)
-    {
-        fsUserCourseService.updateFsUserCourseIsShow(courseIds,1);
+    public AjaxResult putOn(@PathVariable Long[] courseIds) {
+        fsUserCourseService.updateFsUserCourseIsShow(courseIds, 1);
         redisCacheUtil.delRedisKey("getCourseList");
         return toAjax(1);
     }
@@ -316,9 +295,8 @@ public class FsUserCourseController extends BaseController
     @PreAuthorize("@ss.hasPermi('course:userCourse:publicPutOn')")
     @Log(title = "课程批量上架", businessType = BusinessType.UPDATE)
     @PostMapping("/publicPutOn/{courseIds}")
-    public AjaxResult publicPutOn(@PathVariable Long[] courseIds)
-    {
-        fsUserCourseService.updateFsUserCourseIsShow(courseIds,1);
+    public AjaxResult publicPutOn(@PathVariable Long[] courseIds) {
+        fsUserCourseService.updateFsUserCourseIsShow(courseIds, 1);
         redisCacheUtil.delRedisKey("getCourseList");
         return toAjax(1);
     }
@@ -326,9 +304,8 @@ public class FsUserCourseController extends BaseController
     @PreAuthorize("@ss.hasPermi('course:userCourse:putOn')")
     @Log(title = "课程批量下架", businessType = BusinessType.UPDATE)
     @PostMapping("/pullOff/{courseIds}")
-    public AjaxResult pullOff(@PathVariable Long[] courseIds)
-    {
-        fsUserCourseService.updateFsUserCourseIsShow(courseIds,0);
+    public AjaxResult pullOff(@PathVariable Long[] courseIds) {
+        fsUserCourseService.updateFsUserCourseIsShow(courseIds, 0);
         redisCacheUtil.delRedisKey("getCourseList");
         return toAjax(1);
     }
@@ -336,9 +313,8 @@ public class FsUserCourseController extends BaseController
     @PreAuthorize("@ss.hasPermi('course:userCourse:publicPutOff')")
     @Log(title = "课程批量下架", businessType = BusinessType.UPDATE)
     @PostMapping("/publicPutOff/{courseIds}")
-    public AjaxResult publicPutOff(@PathVariable Long[] courseIds)
-    {
-        fsUserCourseService.updateFsUserCourseIsShow(courseIds,0);
+    public AjaxResult publicPutOff(@PathVariable Long[] courseIds) {
+        fsUserCourseService.updateFsUserCourseIsShow(courseIds, 0);
         redisCacheUtil.delRedisKey("getCourseList");
         return toAjax(1);
     }
@@ -349,7 +325,7 @@ public class FsUserCourseController extends BaseController
     @PreAuthorize("@ss.hasPermi('course:userCourse:editConfig')")
     @Log(title = "课程配置", businessType = BusinessType.UPDATE)
     @PostMapping("/editConfig")
-    public R editConfig(@RequestBody FsUserCourseConfigParam params){
+    public R editConfig(@RequestBody FsUserCourseConfigParam params) {
         fsUserCourseService.editConfig(params.getId(), params.getConfigJson());
         redisCacheUtil.delRedisKey("getCourseList");
         redisCacheUtil.delRedisKey("h5user:course:video:list:all");
@@ -357,4 +333,14 @@ public class FsUserCourseController extends BaseController
         redisCacheUtil.delRedisKey("cache:video");
         return R.ok();
     }
+
+    /**
+     * 同步课程模板
+     */
+    @Log(title = "同步课程模板", businessType = BusinessType.UPDATE)
+    @PostMapping("/syncTemplate/{courseId}")
+    public AjaxResult syncTemplate(@PathVariable Long courseId) {
+        sopTempService.syncTemplate(courseId);
+        return toAjax(1);
+    }
 }

+ 2 - 0
fs-admin/src/main/java/com/fs/qw/controller/QwSopTempController.java

@@ -1,5 +1,6 @@
 package com.fs.qw.controller;
 
+import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
@@ -9,6 +10,7 @@ import com.fs.common.core.domain.model.LoginUser;
 import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.ServletUtils;
+import com.fs.common.utils.TimeUtils;
 import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.framework.web.service.TokenService;
 import com.fs.qw.vo.SortDayVo;

+ 1 - 0
fs-company/src/main/java/com/fs/company/controller/qw/QwSopTempController.java

@@ -1,5 +1,6 @@
 package com.fs.company.controller.qw;
 
+import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;

+ 1 - 1
fs-service/src/main/java/com/fs/course/domain/FsCourseLink.java

@@ -53,7 +53,7 @@ public class FsCourseLink extends BaseEntity
     */
     private Long qwExternalId;
 
-    private Integer linkType; //链接类型 0:正常链接  1:应急链接  2:小程序链接
+    private Integer linkType; //链接类型 0:正常链接  1:应急链接  3:小程序链接 4:APP
 
     private Integer isRoom;//是否发群
     private String chatId;//是否发群

+ 6 - 9
fs-service/src/main/java/com/fs/course/service/IFsUserCourseService.java

@@ -1,10 +1,5 @@
 package com.fs.course.service;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.List;
-import java.util.Map;
-
 import com.fs.common.core.domain.R;
 import com.fs.course.domain.FsUserCourse;
 import com.fs.course.param.*;
@@ -13,8 +8,11 @@ import com.fs.course.vo.*;
 import com.fs.course.vo.newfs.FsUserCourseListVO;
 import com.fs.his.vo.OptionsVO;
 
-import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotNull;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
 
 /**
  * 课程Service接口
@@ -22,8 +20,7 @@ import javax.validation.constraints.NotNull;
  * @author fs
  * @date 2024-05-15
  */
-public interface IFsUserCourseService
-{
+public interface IFsUserCourseService {
     /**
      * 查询课程
      *
@@ -110,7 +107,7 @@ public interface IFsUserCourseService
 
     List<FsUserCourseListVO> getFsUserCourseList(FsUserCourseListParam param);
 
-    void  processQwSopCourseMaterialTimer();
+    void processQwSopCourseMaterialTimer();
 
     List<FsCourseListBySidebarVO> getFsCourseListBySidebar(FsCourseListBySidebarParam param);
 

+ 1 - 0
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStorePaymentScrmServiceImpl.java

@@ -890,6 +890,7 @@ public class FsStorePaymentScrmServiceImpl implements IFsStorePaymentScrmService
         storePayment.setOpenId(user.getMaOpenId());
         storePayment.setUserId(user.getUserId());
         storePayment.setPayMode("hf");//目前微信收款仅支持汇付
+        storePayment.setAppId(param.getAppId());
         fsStorePaymentMapper.insertFsStorePayment(storePayment);
 
         //汇付支付

+ 2 - 1
fs-service/src/main/java/com/fs/sop/mapper/QwSopTempMapper.java

@@ -6,6 +6,7 @@ import com.fs.common.enums.DataSourceType;
 import com.fs.sop.domain.QwSopTemp;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.Collection;
 import java.util.List;
 
 /**
@@ -70,5 +71,5 @@ public interface QwSopTempMapper extends BaseMapper<QwSopTemp> {
 
     List<QwSopTemp> listTemp();
 
-    List<QwSopTemp> selectListByIds(@Param("ids") List<String> ids);
+    List<QwSopTemp> selectListByIds(@Param("ids") Collection<String> ids);
 }

+ 6 - 1
fs-service/src/main/java/com/fs/sop/mapper/QwSopTempRulesMapper.java

@@ -6,6 +6,7 @@ import com.fs.common.enums.DataSourceType;
 import com.fs.sop.domain.QwSopTempRules;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
+import org.springframework.stereotype.Repository;
 
 import java.util.List;
 
@@ -16,7 +17,8 @@ import java.util.List;
  * @date 2025-02-06
  */
 @DataSource(DataSourceType.SOP)
-public interface QwSopTempRulesMapper extends BaseMapper<QwSopTempRules>{
+@Repository
+public interface QwSopTempRulesMapper extends BaseMapper<QwSopTempRules> {
     /**
      * 查询sop任务模板规则
      *
@@ -78,4 +80,7 @@ public interface QwSopTempRulesMapper extends BaseMapper<QwSopTempRules>{
     List<QwSopTempRules> listByTempIdAndNameAndDayNum(@Param("id") String id, @Param("dayNum") Integer dayNum);
 
     void deleteByIdList(@Param("ids") List<String> ids);
+
+    @Select("select * from qw_sop_temp_rules where course_id = #{courseId} ")
+    List<QwSopTempRules> selectQwSopTempRulesListByCourseId(@Param("courseId")Long courseId);
 }

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

@@ -5,7 +5,9 @@ import com.fs.common.annotation.DataSource;
 import com.fs.common.enums.DataSourceType;
 import com.fs.sop.domain.QwSopTempContent;
 
+import java.util.Collection;
 import java.util.List;
+import java.util.Set;
 
 /**
  * sop任务模板内容Service接口
@@ -84,4 +86,8 @@ public interface IQwSopTempContentService extends IService<QwSopTempContent>{
     void updateDay(QwSopTempContent content);
 
     List<QwSopTempContent> selectQwSopTempContentByTempId(String tempId);
+
+    void removeByTempIds(Collection<String> tempIds);
+
+    List<QwSopTempContent> listByTempIds(Collection<String> tempIds);
 }

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

@@ -3,6 +3,7 @@ package com.fs.sop.service;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.fs.sop.domain.QwSopTempDay;
 
+import java.util.Collection;
 import java.util.List;
 
 /**
@@ -11,7 +12,7 @@ import java.util.List;
  * @author fs
  * @date 2025-02-06
  */
-public interface IQwSopTempDayService extends IService<QwSopTempDay>{
+public interface IQwSopTempDayService extends IService<QwSopTempDay> {
 
     void saveList(List<QwSopTempDay> list);
 
@@ -26,9 +27,12 @@ public interface IQwSopTempDayService extends IService<QwSopTempDay>{
     boolean saveOrUpdate(QwSopTempDay day);
 
     void addOrUpdateBatch(List<QwSopTempDay> days);
+
     void removeById(Long id);
 
     List<QwSopTempDay> listById(List<Long> dayIds);
 
     int getDayNumByIdLimitOne(String tempId);
+
+    void removeByTempIds(Collection<String> tempIds);
 }

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

@@ -6,7 +6,9 @@ import com.fs.common.enums.DataSourceType;
 import com.fs.sop.domain.QwSopTempDay;
 import com.fs.sop.domain.QwSopTempRules;
 
+import java.util.Collection;
 import java.util.List;
+import java.util.Set;
 
 /**
  * sop任务模板规则Service接口
@@ -88,4 +90,8 @@ public interface IQwSopTempRulesService extends IService<QwSopTempRules>{
     List<QwSopTempRules> listById(List<Long> rulesIds);
 
     void updateSiFenTemp();
+
+    List<QwSopTempRules> listByCourseId(Long courseId);
+
+    void removeByTempIds(Collection<String> tempIds);
 }

+ 5 - 3
fs-service/src/main/java/com/fs/sop/service/IQwSopTempService.java

@@ -6,6 +6,7 @@ import com.fs.sop.domain.QwSopTempDay;
 import com.fs.sop.params.QwSopShareTempParam;
 import com.fs.sop.vo.QwSopTempRedPackageVo;
 
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
@@ -15,8 +16,7 @@ import java.util.Map;
  * @author fs
  * @date 2024-09-26
  */
-public interface IQwSopTempService
-{
+public interface IQwSopTempService {
     /**
      * 查询sop模板
      *
@@ -58,7 +58,7 @@ public interface IQwSopTempService
     public int deleteQwSopTempByIds(String[] ids);
 
     /**
-     *分享sop模板
+     * 分享sop模板
      */
     public int shareQwSopTemp(QwSopShareTempParam param);
 
@@ -99,4 +99,6 @@ public interface IQwSopTempService
     void updateRedPackage(List<QwSopTempRedPackageVo> list);
 
     List<String> getSelectableRange();
+
+    void syncTemplate(Long courseId);
 }

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

@@ -5,10 +5,13 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fs.common.annotation.DataSource;
 import com.fs.common.enums.DataSourceType;
 import com.fs.sop.domain.QwSopTempContent;
+import com.fs.sop.domain.QwSopTempDay;
 import com.fs.sop.mapper.QwSopTempContentMapper;
 import com.fs.sop.service.IQwSopTempContentService;
 import org.springframework.stereotype.Service;
 
+import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -148,4 +151,16 @@ public class QwSopTempContentServiceImpl extends ServiceImpl<QwSopTempContentMap
     public List<QwSopTempContent> selectQwSopTempContentByTempId(String tempId) {
         return baseMapper.selectQwSopTempContentByTempId(tempId);
     }
+
+    @Override
+    @DataSource(DataSourceType.SOP)
+    public void removeByTempIds(Collection<String> tempIds) {
+        this.remove(new QueryWrapper<QwSopTempContent>().in("temp_id", tempIds));
+    }
+
+    @Override
+    @DataSource(DataSourceType.SOP)
+    public List<QwSopTempContent> listByTempIds(Collection<String> tempIds) {
+        return baseMapper.selectList(new QueryWrapper<QwSopTempContent>().in("temp_id", tempIds));
+    }
 }

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

@@ -1,6 +1,8 @@
 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.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fs.common.annotation.DataSource;
 import com.fs.common.enums.DataSourceType;
@@ -11,6 +13,7 @@ import lombok.AllArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.Collection;
 import java.util.List;
 
 /**
@@ -83,4 +86,10 @@ public class QwSopTempDayServiceImpl extends ServiceImpl<QwSopTempDayMapper, QwS
     public int getDayNumByIdLimitOne(String tempId) {
         return  qwSopTempDayMapper.getDayNumByIdLimitOne(tempId);
     }
+
+    @Override
+    @DataSource(DataSourceType.SOP)
+    public void removeByTempIds(Collection<String> tempIds) {
+        this.remove(new QueryWrapper<QwSopTempDay>().in("temp_id", tempIds));
+    }
 }

+ 26 - 19
fs-service/src/main/java/com/fs/sop/service/impl/QwSopTempRulesServiceImpl.java

@@ -25,6 +25,7 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -59,8 +60,7 @@ public class QwSopTempRulesServiceImpl extends ServiceImpl<QwSopTempRulesMapper,
      * @return sop任务模板规则
      */
     @Override
-    public QwSopTempRules selectQwSopTempRulesById(String id)
-    {
+    public QwSopTempRules selectQwSopTempRulesById(String id) {
         return baseMapper.selectQwSopTempRulesById(id);
     }
 
@@ -71,8 +71,7 @@ public class QwSopTempRulesServiceImpl extends ServiceImpl<QwSopTempRulesMapper,
      * @return sop任务模板规则
      */
     @Override
-    public List<QwSopTempRules> selectQwSopTempRulesList(QwSopTempRules qwSopTempRules)
-    {
+    public List<QwSopTempRules> selectQwSopTempRulesList(QwSopTempRules qwSopTempRules) {
         return baseMapper.selectQwSopTempRulesList(qwSopTempRules);
     }
 
@@ -83,8 +82,7 @@ public class QwSopTempRulesServiceImpl extends ServiceImpl<QwSopTempRulesMapper,
      * @return 结果
      */
     @Override
-    public int insertQwSopTempRules(QwSopTempRules qwSopTempRules)
-    {
+    public int insertQwSopTempRules(QwSopTempRules qwSopTempRules) {
         return baseMapper.insertQwSopTempRules(qwSopTempRules);
     }
 
@@ -95,8 +93,7 @@ public class QwSopTempRulesServiceImpl extends ServiceImpl<QwSopTempRulesMapper,
      * @return 结果
      */
     @Override
-    public int updateQwSopTempRules(QwSopTempRules qwSopTempRules)
-    {
+    public int updateQwSopTempRules(QwSopTempRules qwSopTempRules) {
         return baseMapper.updateQwSopTempRules(qwSopTempRules);
     }
 
@@ -107,8 +104,7 @@ public class QwSopTempRulesServiceImpl extends ServiceImpl<QwSopTempRulesMapper,
      * @return 结果
      */
     @Override
-    public int deleteQwSopTempRulesByIds(String[] ids)
-    {
+    public int deleteQwSopTempRulesByIds(String[] ids) {
         return baseMapper.deleteQwSopTempRulesByIds(ids);
     }
 
@@ -119,8 +115,7 @@ public class QwSopTempRulesServiceImpl extends ServiceImpl<QwSopTempRulesMapper,
      * @return 结果
      */
     @Override
-    public int deleteQwSopTempRulesById(String id)
-    {
+    public int deleteQwSopTempRulesById(String id) {
         return baseMapper.deleteQwSopTempRulesById(id);
     }
 
@@ -140,7 +135,7 @@ public class QwSopTempRulesServiceImpl extends ServiceImpl<QwSopTempRulesMapper,
     @DataSource(DataSourceType.SOP)
     public List<QwSopTempRules> listByTempId(String id) {
         List<QwSopTempDay> dayList = qwSopTempDayService.list(new QueryWrapper<QwSopTempDay>().eq("temp_id", id).orderByAsc("day_num"));
-        if(dayList.isEmpty()) return Collections.emptyList();
+        if (dayList.isEmpty()) return Collections.emptyList();
         Map<Long, Integer> collect = dayList.stream().collect(Collectors.toMap(QwSopTempDay::getId, QwSopTempDay::getDayNum));
         List<QwSopTempRules> rulesList = list(new QueryWrapper<QwSopTempRules>().in("day_id", PubFun.listToNewList(dayList, QwSopTempDay::getId)));
         rulesList.forEach(r -> {
@@ -148,7 +143,7 @@ public class QwSopTempRulesServiceImpl extends ServiceImpl<QwSopTempRulesMapper,
         });
         List<QwSopTempContent> ts = qwSopTempContentService.list(new QueryWrapper<QwSopTempContent>().in("rules_id", PubFun.listToNewList(rulesList, QwSopTempRules::getId)));
         Map<Long, List<QwSopTempContent>> map = PubFun.listToMapByGroupList(ts, QwSopTempContent::getRulesId);
-        rulesList.stream().filter( e -> map.containsKey(e.getId())).forEach(e -> e.setSettingList(map.get(e.getId())));
+        rulesList.stream().filter(e -> map.containsKey(e.getId())).forEach(e -> e.setSettingList(map.get(e.getId())));
         return rulesList;
     }
 
@@ -202,9 +197,9 @@ public class QwSopTempRulesServiceImpl extends ServiceImpl<QwSopTempRulesMapper,
     public void updateRulesDayNumIsNull() {
         List<QwSopTempRules> rules = qwSopTempRulesMapper.rulesNull();
         log.info("时间为空的有:{}", rules.size());
-        for (QwSopTempRules rule : rules){
+        for (QwSopTempRules rule : rules) {
             QwSopTempDay day = dayMapper.info(rule.getDayId());
-            if (day!=null){
+            if (day != null) {
                 QwSopTempRules rules1 = new QwSopTempRules();
                 rules1.setDayNum(day.getDayNum());
                 rules1.setId(rule.getId());
@@ -226,14 +221,14 @@ public class QwSopTempRulesServiceImpl extends ServiceImpl<QwSopTempRulesMapper,
     @Override
     public void updateSiFenTemp() {
         List<QwSopTempContentVO> contents = contentMapper.updateSiFenTemp();
-        for(QwSopTempContentVO content : contents){
-            if (content.getVideoId()==null){
+        for (QwSopTempContentVO content : contents) {
+            if (content.getVideoId() == null) {
                 continue;
             }
             QwSopTempContent content1 = new QwSopTempContent();
             FsUserCourseVideo video = videoMapper.selectFsUserCourseVideoByVideoId(content.getVideoId());
             QwSopTempSetting.Content.Setting settingMap = new QwSopTempSetting.Content.Setting();
-            QwSopTempSetting.Content.Setting setting = JSON.parseObject(content.getContent(),QwSopTempSetting.Content.Setting.class);
+            QwSopTempSetting.Content.Setting setting = JSON.parseObject(content.getContent(), QwSopTempSetting.Content.Setting.class);
             settingMap.setContentType("4");
             settingMap.setMiniprogramAppid("wx73f85f8d62769119");
             settingMap.setMiniprogramPicUrl(setting.getLinkImageUrl());
@@ -245,4 +240,16 @@ public class QwSopTempRulesServiceImpl extends ServiceImpl<QwSopTempRulesMapper,
             contentMapper.updateQwSopTempContent(content1);
         }
     }
+
+    @Override
+    @DataSource(DataSourceType.SOP)
+    public List<QwSopTempRules> listByCourseId(Long courseId) {
+        return qwSopTempRulesMapper.selectQwSopTempRulesListByCourseId(courseId);
+    }
+
+    @Override
+    @DataSource(DataSourceType.SOP)
+    public void removeByTempIds(Collection<String> tempIds) {
+        this.remove(new QueryWrapper<QwSopTempRules>().in("temp_id", tempIds));
+    }
 }

+ 140 - 62
fs-service/src/main/java/com/fs/sop/service/impl/QwSopTempServiceImpl.java

@@ -9,7 +9,6 @@ import com.fs.common.exception.base.BaseException;
 import com.fs.common.utils.PubFun;
 import com.fs.company.domain.Company;
 import com.fs.company.service.ICompanyService;
-import com.fs.company.service.impl.CompanyServiceImpl;
 import com.fs.config.cloud.CloudHostProper;
 import com.fs.course.config.CourseConfig;
 import com.fs.course.domain.FsUserCourse;
@@ -30,16 +29,16 @@ import com.fs.sop.mapper.QwSopTempMapper;
 import com.fs.sop.params.QwSopShareTempParam;
 import com.fs.sop.service.*;
 import com.fs.sop.vo.QwSopTempRedPackageVo;
-import com.fs.sop.vo.VoiceVo;
 import com.fs.system.domain.SysConfig;
 import com.fs.system.service.ISysConfigService;
 import io.netty.util.internal.StringUtil;
 import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.beanutils.ConvertUtils;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.rocketmq.spring.core.RocketMQTemplate;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
@@ -47,6 +46,7 @@ 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;
@@ -59,8 +59,8 @@ import java.util.stream.Collectors;
  */
 @Service
 @AllArgsConstructor
-public class QwSopTempServiceImpl implements IQwSopTempService
-{
+@Slf4j
+public class QwSopTempServiceImpl implements IQwSopTempService {
 
     @Autowired
     private CloudHostProper cloudHostProper;
@@ -79,6 +79,7 @@ public class QwSopTempServiceImpl implements IQwSopTempService
     private final IQwSopService qwSopService;
     private final IQwUserService qwUserService;
     private final ICompanyService companyService;
+    private final ThreadPoolTaskExecutor threadPoolTaskExecutor;
 
     /**
      * 查询sop模板
@@ -87,7 +88,7 @@ public class QwSopTempServiceImpl implements IQwSopTempService
      * @return sop模板
      */
     @Override
-    public QwSopTemp selectQwSopTempById(String id){
+    public QwSopTemp selectQwSopTempById(String id) {
 //        QwSopTemp qwSopTemp = qwSopTempMapper.selectQwSopTempById(id);
         QwSopTemp qwSopTemp = qwSopTempMapper.selectQwSopTempById(id);
         List<QwSopTempDay> qwSopTempDays = qwSopTempDayService.listByTempId(id);
@@ -117,8 +118,7 @@ public class QwSopTempServiceImpl implements IQwSopTempService
      * @return sop模板
      */
     @Override
-    public List<QwSopTemp> selectQwSopTempList(QwSopTemp qwSopTemp)
-    {
+    public List<QwSopTemp> selectQwSopTempList(QwSopTemp qwSopTemp) {
         return qwSopTempMapper.selectQwSopTempList(qwSopTemp);
     }
 
@@ -129,7 +129,7 @@ public class QwSopTempServiceImpl implements IQwSopTempService
      * @return 结果
      */
     @Override
-    public int insertQwSopTemp(QwSopTemp qwSopTemp){
+    public int insertQwSopTemp(QwSopTemp qwSopTemp) {
         qwSopTemp.setId(UUID.randomUUID().toString());
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         qwSopTemp.setCreateTime(sdf.format(new Date()));
@@ -155,7 +155,7 @@ public class QwSopTempServiceImpl implements IQwSopTempService
      * @return 结果
      */
     @Override
-    public int updateQwSopTemp(QwSopTemp qwSopTemp){
+    public int updateQwSopTemp(QwSopTemp qwSopTemp) {
         return qwSopTempMapper.updateQwSopTemp(qwSopTemp);
     }
 
@@ -166,8 +166,7 @@ public class QwSopTempServiceImpl implements IQwSopTempService
      * @return 结果
      */
     @Override
-    public int deleteQwSopTempByIds(String[] ids)
-    {
+    public int deleteQwSopTempByIds(String[] ids) {
         return qwSopTempMapper.deleteQwSopTempByIds(ids);
     }
 
@@ -196,8 +195,7 @@ public class QwSopTempServiceImpl implements IQwSopTempService
      * @return 结果
      */
     @Override
-    public int deleteQwSopTempById(String id)
-    {
+    public int deleteQwSopTempById(String id) {
         return qwSopTempMapper.deleteQwSopTempById(id);
     }
 
@@ -214,7 +212,7 @@ public class QwSopTempServiceImpl implements IQwSopTempService
     public int update(QwSopTemp qwSopTemp) {
         QwSopTemp temp = qwSopTempMapper.selectById(qwSopTemp.getId());
         int i = qwSopTempMapper.updateById(qwSopTemp);
-        if(!Objects.equals(temp.getGap(), qwSopTemp.getGap())){
+        if (!Objects.equals(temp.getGap(), qwSopTemp.getGap())) {
             // 重新排序
             reorder(qwSopTemp.getId());
         }
@@ -233,7 +231,7 @@ public class QwSopTempServiceImpl implements IQwSopTempService
         qwSopTempRulesService.removeByDayId(day.getId());
         qwSopTempContentService.removeByDayId(day.getId());
 
-        list.forEach(item-> item.setDayId(day.getId()));
+        list.forEach(item -> item.setDayId(day.getId()));
         processAndReplaceContent(list);
         QwSopTempRules rules = list.get(0);
         String tempId = rules.getTempId();
@@ -251,29 +249,29 @@ public class QwSopTempServiceImpl implements IQwSopTempService
         reorder(day.getTempId());
         Map<String, Object> map = new HashMap<>();
         map.put("id", day.getId());
-        if(!voiceList.isEmpty()){
+        if (!voiceList.isEmpty()) {
             for (QwSopTempContent qwSopTempContent : voiceList) {
                 String content = qwSopTempContent.getContent();
                 JSONObject jsonObject = JSONObject.parseObject(content);
                 String text = jsonObject.getString("value");
                 List<QwSop> qwSopList = qwSopService.selectQwSopByTempId(tempId);//通过tempId查询出所有sop
-                if(qwSopList != null && !qwSopList.isEmpty()){
+                if (qwSopList != null && !qwSopList.isEmpty()) {
                     for (QwSop qwSop : qwSopList) {
-                        if(qwSop != null && qwSop.getQwUserIds() != null){
+                        if (qwSop != null && qwSop.getQwUserIds() != null) {
                             //查询出所有的tempContent来筛选文字
                             List<QwSopTempContent> qwSopTempContentList = qwSopTempContentService.selectQwSopTempContentByTempId(tempId);
-                            if(qwSopTempContentList != null && !qwSopTempContentList.isEmpty()){
+                            if (qwSopTempContentList != null && !qwSopTempContentList.isEmpty()) {
                                 for (QwSopTempContent qwSopTemp : qwSopTempContentList) {
-                                    if(qwSopTemp != null && qwSopTemp.getContentType() == 7){
+                                    if (qwSopTemp != null && qwSopTemp.getContentType() == 7) {
                                         String[] split = qwSop.getQwUserIds().split(",");
                                         Long[] qwUserIds = (Long[]) ConvertUtils.convert(split, Long.class);
                                         List<QwUserVO> qwUserVOS = qwUserService.selectQwUserVOByIds(qwUserIds);
-                                        if(qwUserVOS != null){
+                                        if (qwUserVOS != null) {
                                             for (QwUserVO qwUserVO : qwUserVOS) {
                                                 Long companyUserId = qwUserVO.getCompanyUserId();
-                                                QwSopTempVoice qwSopTempVoice = qwSopTempVoiceService.selectQwSopTempVoiceByCompanyUserIdAndVoiceTxt(companyUserId,text);
-                                                if(qwSopTempVoice == null){
-                                                    if(companyUserId != null && text != null){
+                                                QwSopTempVoice qwSopTempVoice = qwSopTempVoiceService.selectQwSopTempVoiceByCompanyUserIdAndVoiceTxt(companyUserId, text);
+                                                if (qwSopTempVoice == null) {
+                                                    if (companyUserId != null && text != null) {
                                                         QwSopTempVoice sopTempVoice = new QwSopTempVoice();
                                                         sopTempVoice.setCompanyUserId(companyUserId);
                                                         sopTempVoice.setVoiceTxt(text);
@@ -298,12 +296,12 @@ public class QwSopTempServiceImpl implements IQwSopTempService
         return map;
     }
 
-    private void processAndReplaceContent(List<QwSopTempRules> tempSettings){
+    private void processAndReplaceContent(List<QwSopTempRules> tempSettings) {
         List<FastGptChatReplaceWords> words = fastGptChatReplaceWordsMapper.selectAllFastGptChatReplaceWords();
         //循环天
-        tempSettings.forEach(settingList->{
+        tempSettings.forEach(settingList -> {
             //循环单日
-            settingList.getSettingList().forEach(item->{
+            settingList.getSettingList().forEach(item -> {
                 JSONObject obj = JSON.parseObject(item.getContent());
                 List<String> list = Arrays.asList("linkTitle", "linkDescribe", "desc", "nickname", "value");
                 list.stream().filter(obj::containsKey).forEach(key -> {
@@ -316,23 +314,24 @@ public class QwSopTempServiceImpl implements IQwSopTempService
 
     @Override
     public void delRules(Long id) {
-        if(id == null) return;
+        if (id == null) return;
         QwSopTempDay day = qwSopTempDayService.info(id);
-        if(day == null) return;
+        if (day == null) return;
         qwSopTempDayService.removeById(day.getId());
         qwSopTempContentService.removeByDayId(day.getId());
         reorder(day.getTempId());
     }
+
     @Override
     public QwSopTempDay selectRulesInfo(Long id) {
         QwSopTempDay day = qwSopTempDayService.info(id);
         List<QwSopTempRules> rulesList = qwSopTempRulesService.listByDayId(id);
-        if(!rulesList.isEmpty()){
+        if (!rulesList.isEmpty()) {
             List<QwSopTempContent> contentList = qwSopTempContentService.listByRulesIds(PubFun.listToNewList(rulesList, QwSopTempRules::getId));
             Map<Long, List<QwSopTempContent>> contentMap = PubFun.listToMapByGroupList(contentList, QwSopTempContent::getRulesId);
             rulesList.forEach(e -> {
                 List<QwSopTempContent> contents = contentMap.get(e.getId());
-                if (CollectionUtils.isNotEmpty(contents)){
+                if (CollectionUtils.isNotEmpty(contents)) {
                     e.setSetting(contents.stream().map(c -> JSON.parseObject(c.getContent())).collect(Collectors.toList()));
                 }
             });
@@ -353,14 +352,14 @@ public class QwSopTempServiceImpl implements IQwSopTempService
         qwSopTemp.setId(newId);
         qwSopTempMapper.insertQwSopTemp(qwSopTemp);
         List<QwSopTempDay> dayList = qwSopTempRulesService.listByTempIdAll(oldId);
-        if(dayList.isEmpty()) return;
+        if (dayList.isEmpty()) return;
 //        List<QwSopTempRules> rulesList = qwSopTempRulesService.listByTempId(oldId);
         dayList.forEach(day -> {
             day.setTempId(newId);
-            if(day.getList() != null && !day.getList().isEmpty()){
+            if (day.getList() != null && !day.getList().isEmpty()) {
                 day.getList().forEach(e -> {
                     e.setTempId(newId);
-                    if(e.getSettingList() != null && !e.getSettingList().isEmpty()){
+                    if (e.getSettingList() != null && !e.getSettingList().isEmpty()) {
                         e.getSettingList().forEach(item -> {
                             item.setTempId(newId);
                         });
@@ -376,7 +375,7 @@ public class QwSopTempServiceImpl implements IQwSopTempService
             item.setRulesId(e.getId());
             item.setDayId(e.getDayId());
         }));
-        qwSopTempContentService.insertBatch(collect.stream().flatMap(e ->e.getSettingList().stream()).collect(Collectors.toList()));
+        qwSopTempContentService.insertBatch(collect.stream().flatMap(e -> e.getSettingList().stream()).collect(Collectors.toList()));
     }
 
     @Override
@@ -390,7 +389,7 @@ public class QwSopTempServiceImpl implements IQwSopTempService
     public void sortDay(List<SortDayVo> list) {
         Collection<QwSopTempDay> days = qwSopTempDayService.listByIds(PubFun.listToNewList(list, SortDayVo::getId));
         Map<Long, Integer> dayMap = list.stream().collect(Collectors.toMap(SortDayVo::getId, SortDayVo::getDayNum));
-        if(days.stream().anyMatch(e -> !dayMap.containsKey(e.getId()))){
+        if (days.stream().anyMatch(e -> !dayMap.containsKey(e.getId()))) {
             throw new BaseException("数据错误!");
         }
         days.forEach(day -> day.setDayNum(dayMap.get(day.getId())));
@@ -404,10 +403,10 @@ public class QwSopTempServiceImpl implements IQwSopTempService
 
 
     @DataSource(DataSourceType.SOP)
-    private void reorder(String tempId){
+    private void reorder(String tempId) {
         QwSopTemp qwSopTemp = qwSopTempMapper.selectQwSopTempById(tempId);
         List<QwSopTempDay> days = qwSopTempDayService.listByTempId(tempId);
-        if(days.isEmpty()) return;
+        if (days.isEmpty()) return;
         for (int i = 0; i < days.size(); i++) {
             QwSopTempDay entity = days.get(i);
             entity.setSorts(i);
@@ -418,7 +417,7 @@ public class QwSopTempServiceImpl implements IQwSopTempService
 
     @Override
     public void createSopTempRules(QwSopTemp temp) {
-        if(temp.getTime() == null){
+        if (temp.getTime() == null) {
             return;
         }
 
@@ -436,11 +435,11 @@ public class QwSopTempServiceImpl implements IQwSopTempService
             day.setSorts(day.getDayNum());
             day.setList(new ArrayList<>());
             List<String> timeList = new ArrayList<>();
-            if(temp.getTimeList() != null){
+            if (temp.getTimeList() != null) {
                 timeList = JSON.parseArray(JSON.toJSONString(temp.getTimeList()), String.class);
             }
             DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
-            if(temp.getTime() != null){
+            if (temp.getTime() != null) {
                 timeList.add(0, temp.getTime().format(formatter));
             }
             AtomicInteger sorts = new AtomicInteger(0);
@@ -448,15 +447,15 @@ public class QwSopTempServiceImpl implements IQwSopTempService
                 QwSopTempRules rules = new QwSopTempRules();
                 rules.setTempId(temp.getId());
                 rules.setName(day.getName());
-                if (temp.getOpenOfficial().equals("1")){
+                if (temp.getOpenOfficial().equals("1")) {
                     rules.setIsOfficial(sorts.get() == 0 ? "1" : "0");
-                }else {
+                } else {
                     rules.setIsOfficial("0");
                 }
 
-                if (day.getDayNum()==1 && sorts.get() == 0 && temp.getOpenOfficial().equals("1")){
+                if (day.getDayNum() == 1 && sorts.get() == 0 && temp.getOpenOfficial().equals("1")) {
                     rules.setTime("01:05");
-                }else {
+                } else {
                     rules.setTime(time);
                 }
 
@@ -475,10 +474,10 @@ public class QwSopTempServiceImpl implements IQwSopTempService
                 setting.setMiniprogramTitle(e.getTitle());
 
                 //用课节图片做封面
-                if("今正科技".equals(cloudHostProper.getCompanyName())){
-                    setting.setMiniprogramPicUrl(!StringUtil.isNullOrEmpty(e.getThumbnail())?e.getThumbnail():fsUserCourse.getImgUrl());
-                    setting.setLinkImageUrl(!StringUtil.isNullOrEmpty(e.getThumbnail())?e.getThumbnail():fsUserCourse.getImgUrl());
-                }else {
+                if ("今正科技".equals(cloudHostProper.getCompanyName())) {
+                    setting.setMiniprogramPicUrl(!StringUtil.isNullOrEmpty(e.getThumbnail()) ? e.getThumbnail() : fsUserCourse.getImgUrl());
+                    setting.setLinkImageUrl(!StringUtil.isNullOrEmpty(e.getThumbnail()) ? e.getThumbnail() : fsUserCourse.getImgUrl());
+                } else {
                     setting.setMiniprogramPicUrl(fsUserCourse.getImgUrl());
                     setting.setLinkImageUrl(fsUserCourse.getImgUrl());
 
@@ -489,7 +488,7 @@ public class QwSopTempServiceImpl implements IQwSopTempService
                 setting.setContentType("4");
                 content.setContent(JSON.toJSONString(setting));
                 content.setIsBindUrl(1);
-                List<QwSopTempContent> qwSopTempContents = new ArrayList<>() ;
+                List<QwSopTempContent> qwSopTempContents = new ArrayList<>();
                 qwSopTempContents.add(content);
                 if (sorts.get() == 0 && !StringUtil.isNullOrEmpty(temp.getModeContent())) {
                     QwSopTempContent content2 = new QwSopTempContent();
@@ -501,13 +500,13 @@ public class QwSopTempServiceImpl implements IQwSopTempService
                     content2.setContent(JSON.toJSONString(setting2));
                     qwSopTempContents.add(content2);
                 }
-                if (sorts.get() > 0){
+                if (sorts.get() > 0) {
 
                     QwSopTempContent content3 = new QwSopTempContent();
                     content3.setTempId(temp.getId());
                     content3.setContentType(3);
                     QwSopTempSetting2.Content.Setting setting3 = new QwSopTempSetting2.Content.Setting();
-                    setting3.setValue(temp.getTimeDesc().get(sorts.get()-1));
+                    setting3.setValue(temp.getTimeDesc().get(sorts.get() - 1));
                     setting3.setContentType("1");
                     content3.setContent(JSON.toJSONString(setting3));
                     qwSopTempContents.add(content3);
@@ -515,11 +514,11 @@ public class QwSopTempServiceImpl implements IQwSopTempService
                 }
 
                 rules.setSorts(sorts.getAndIncrement());
-                if(rules.getSorts() == 0){
+                if (rules.getSorts() == 0) {
                     rules.setCourseType(0);
-                }else if(rules.getSorts() == 1){
+                } else if (rules.getSorts() == 1) {
                     rules.setCourseType(1);
-                }else{
+                } else {
                     rules.setCourseType(4);
                 }
                 rules.setList(qwSopTempContents);
@@ -540,10 +539,10 @@ public class QwSopTempServiceImpl implements IQwSopTempService
         CourseConfig courseConfig = JSON.parseObject(sysConfig.getConfigValue(), CourseConfig.class);
         List<Long> videoIdList = PubFun.listToNewList(ruleList, QwSopTempRules::getVideoId);
         Map<Long, Optional<BigDecimal>> redMap;
-        if(!videoIdList.isEmpty()){
+        if (!videoIdList.isEmpty()) {
             List<FsUserCourseVideoRedPackage> redPackageList = fsUserCourseVideoRedPackageService.listByCompanyIdAndVideoIds(temp.getCompanyId(), videoIdList);
             redMap = redPackageList.stream().collect(Collectors.groupingBy(FsUserCourseVideoRedPackage::getVideoId, Collectors.mapping(FsUserCourseVideoRedPackage::getRedPacketMoney, Collectors.reducing((e1, e2) -> e1))));
-        }else{
+        } else {
             redMap = new HashMap<>();
         }
 
@@ -562,15 +561,15 @@ public class QwSopTempServiceImpl implements IQwSopTempService
     @Override
     public List<QwSopTempRedPackageVo> redList(String id) {
         List<QwSopTempDay> dayList = qwSopTempRulesService.listByTempIdAll(id);
-        if(CollectionUtils.isEmpty(dayList)){
+        if (CollectionUtils.isEmpty(dayList)) {
             return Collections.emptyList();
         }
         List<QwSopTempRules> rules = dayList.stream()
-                .filter(e->e!= null && e.getList()!=null)
+                .filter(e -> e != null && e.getList() != null)
                 .flatMap(e -> e.getList().stream())
                 .filter(Objects::nonNull)
                 .collect(Collectors.toList());
-        if(rules.isEmpty()){
+        if (rules.isEmpty()) {
             return Collections.emptyList();
         }
         List<FsUserCourseVideoRedPackage> redPackageList = fsUserCourseVideoRedPackageService.listByRuleIds(PubFun.listToNewList(rules, QwSopTempRules::getId));
@@ -608,14 +607,93 @@ public class QwSopTempServiceImpl implements IQwSopTempService
         }).collect(Collectors.toList());
         fsUserCourseVideoRedPackageService.batchSaveFsUserCourseVideoRedPackage(redPackage);
     }
+
     @Override
     public List<String> getSelectableRange() {
         SysConfig sysConfig = sysConfigService.selectConfigByConfigKey("course.config");
         CourseConfig courseConfig = JSON.parseObject(sysConfig.getConfigValue(), CourseConfig.class);
         List<CourseConfig.DisabledTimeVo> disabledTimeList = courseConfig.getDisabledTimeList();
-        if(disabledTimeList == null){
+        if (disabledTimeList == null) {
             return Collections.emptyList();
         }
         return TimeCalculator.calculateAvailableTimes(disabledTimeList);
     }
+
+
+    @Override
+    public void syncTemplate(Long courseId) {
+        // 根据courseId查询所有相关的sop模板规则
+        List<QwSopTempRules> rulesList = qwSopTempRulesService.listByCourseId(courseId);
+        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;
+        }
+        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);
+
+        CountDownLatch latch = new CountDownLatch(tempList.size());
+        // 对每个模板执行同步操作
+        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())
+                        )
+                        .map(m -> JSONObject.parseObject(m.getContent()).getString("value")).collect(Collectors.toList()));
+            }
+
+            // 插入课程id
+            temp.setCourseId(courseId);
+            temp.setOpenOfficial("1");
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+            temp.setCreateTime(sdf.format(new Date()));
+            temp.setId(UUID.randomUUID().toString());
+            qwSopTempMapper.insertQwSopTemp(temp);
+            // 重新生成该模板的规则和内容
+            threadPoolTaskExecutor.execute(() -> createSopTempRules(temp));
+            latch.countDown();
+        }
+
+        try {
+            latch.await();
+            qwSopTempMapper.deleteQwSopTempByIds(tempIds.toArray(new String[0]));
+            qwSopTempDayService.removeByTempIds(tempIds);
+            qwSopTempRulesService.removeByTempIds(tempIds);
+            qwSopTempContentService.removeByTempIds(tempIds);
+        } catch (InterruptedException e) {
+            log.error("等待线程执行完成时被中断", e);
+        }
+    }
+
 }