Sfoglia il codice sorgente

Merge remote-tracking branch 'origin/master'

caoliqin 1 giorno fa
parent
commit
398599cbc1
41 ha cambiato i file con 686 aggiunte e 135 eliminazioni
  1. 111 17
      fs-admin/src/main/java/com/fs/course/controller/FsUserVideoController.java
  2. 10 2
      fs-admin/src/main/resources/application.yml
  3. 4 2
      fs-company-app/src/main/resources/application.yml
  4. 9 3
      fs-company/src/main/resources/application.yml
  5. 1 0
      fs-framework/src/main/java/com/fs/framework/config/SecurityConfig.java
  6. 0 34
      fs-qw-api-msg/src/main/java/com/fs/app/controller/test.java
  7. 0 53
      fs-qw-api/src/main/java/com/fs/app/controller/testTask.java
  8. 4 2
      fs-qw-api/src/main/resources/application.yml
  9. 8 0
      fs-qw-task/src/main/resources/application.yml
  10. 6 2
      fs-qwhook-msg/src/main/resources/application.yml
  11. 10 2
      fs-qwhook-sop/src/main/resources/application.yml
  12. 10 2
      fs-qwhook/src/main/resources/application.yml
  13. 10 0
      fs-service/src/main/java/com/fs/course/param/VideoActivityResItemParam.java
  14. 12 0
      fs-service/src/main/java/com/fs/course/param/VideoActivityResultSetParam.java
  15. 10 0
      fs-service/src/main/java/com/fs/course/param/VideoCosInputInfoParam.java
  16. 9 0
      fs-service/src/main/java/com/fs/course/param/VideoInputInfoParam.java
  17. 8 0
      fs-service/src/main/java/com/fs/course/param/VideoOutputParam.java
  18. 16 0
      fs-service/src/main/java/com/fs/course/param/VideoScheduleTaskEventParam.java
  19. 10 0
      fs-service/src/main/java/com/fs/course/param/VideoTranscodeParam.java
  20. 18 0
      fs-service/src/main/java/com/fs/course/param/VideoTranscodeTaskParam.java
  21. 7 0
      fs-service/src/main/java/com/fs/course/service/IFsUserCourseVideoService.java
  22. 8 0
      fs-service/src/main/java/com/fs/course/service/IFsVideoResourceService.java
  23. 1 1
      fs-service/src/main/java/com/fs/course/service/impl/FsCourseWatchLogServiceImpl.java
  24. 123 0
      fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java
  25. 13 0
      fs-service/src/main/java/com/fs/course/service/impl/FsVideoResourceServiceImpl.java
  26. 3 0
      fs-service/src/main/java/com/fs/qw/vo/QwSopRuleTimeVO.java
  27. 0 1
      fs-service/src/main/resources/application-config-druid-fcky.yml
  28. 3 0
      fs-service/src/main/resources/application-config-druid-hcl.yml
  29. 3 1
      fs-service/src/main/resources/application-config-druid-hdt.yml
  30. 3 1
      fs-service/src/main/resources/application-config-druid-hzyy.yml
  31. 0 1
      fs-service/src/main/resources/application-config-druid-jnmy.yml
  32. 3 1
      fs-service/src/main/resources/application-config-druid-jzzx.yml
  33. 73 0
      fs-service/src/main/resources/application-config-druid-sft.yml
  34. 3 1
      fs-service/src/main/resources/application-config-druid-sxjz.yml
  35. 3 1
      fs-service/src/main/resources/application-config-druid-yzt.yml
  36. 3 0
      fs-service/src/main/resources/application-config-druid.yml
  37. 0 1
      fs-service/src/main/resources/application-config-myhk.yml
  38. 137 0
      fs-service/src/main/resources/application-druid-sft.yml
  39. 16 1
      fs-user-app/src/main/java/com/fs/app/controller/CourseController.java
  40. 8 2
      fs-user-app/src/main/java/com/fs/app/controller/WxUserController.java
  41. 10 4
      fs-user-app/src/main/resources/application.yml

+ 111 - 17
fs-admin/src/main/java/com/fs/course/controller/FsUserVideoController.java

@@ -1,35 +1,38 @@
 package com.fs.course.controller;
 package com.fs.course.controller;
 
 
-import java.io.*;
-import java.util.Date;
-import java.util.List;
-import java.util.UUID;
-
+import com.alibaba.fastjson.JSON;
+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.R;
-import com.fs.course.param.FsUserVideoAddParam;
-import com.fs.course.param.FsUserVideoAuditParam;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.utils.StringUtils;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.course.domain.FsUserVideo;
+import com.fs.course.domain.FsVideoResource;
+import com.fs.course.param.*;
+import com.fs.course.service.IFsUserVideoService;
+import com.fs.course.service.IFsVideoResourceService;
+import com.fs.course.service.impl.TencentCloudCosService;
 import com.fs.course.vo.FsUserVideoListPVO;
 import com.fs.course.vo.FsUserVideoListPVO;
 import com.fs.course.vo.FsUserVideoPVO;
 import com.fs.course.vo.FsUserVideoPVO;
-import com.fs.course.param.FsUserVideoParam;
 import com.fs.his.service.IFsPackageService;
 import com.fs.his.service.IFsPackageService;
 import com.fs.his.vo.FsPackageVO;
 import com.fs.his.vo.FsPackageVO;
 import com.fs.system.oss.CloudStorageService;
 import com.fs.system.oss.CloudStorageService;
 import com.fs.system.oss.OSSFactory;
 import com.fs.system.oss.OSSFactory;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.io.FilenameUtils;
-import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.annotation.*;
-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.FsUserVideo;
-import com.fs.course.service.IFsUserVideoService;
-import com.fs.common.utils.poi.ExcelUtil;
-import com.fs.common.core.page.TableDataInfo;
 import org.springframework.web.multipart.MultipartFile;
 import org.springframework.web.multipart.MultipartFile;
 
 
+import java.io.*;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
 /**
 /**
  * 课堂视频Controller
  * 课堂视频Controller
  *
  *
@@ -43,9 +46,15 @@ public class FsUserVideoController extends BaseController
 {
 {
     @Autowired
     @Autowired
     private IFsUserVideoService fsUserVideoService;
     private IFsUserVideoService fsUserVideoService;
+
+    @Autowired
+    private TencentCloudCosService tencentCloudCosService;
     @Autowired
     @Autowired
     private IFsPackageService fsPackageService;
     private IFsPackageService fsPackageService;
 
 
+    @Autowired
+    private IFsVideoResourceService iFsVideoResourceService;
+
     /**
     /**
      * 查询课堂视频列表
      * 查询课堂视频列表
      */
      */
@@ -265,4 +274,89 @@ public class FsUserVideoController extends BaseController
         }
         }
         return R.ok();
         return R.ok();
     }
     }
+
+    /**
+     * 点播编排转码
+     * @return
+     */
+    @PostMapping("/videoTranscode")
+    public R videoTranscode(@RequestBody String rawBody) {
+        try {
+            // 解析输入JSON
+            VideoTranscodeParam videoTranscodeParam = JSON.parseObject(rawBody, VideoTranscodeParam.class);
+            if (videoTranscodeParam == null || videoTranscodeParam.getScheduleTaskEvent() == null) {
+                log.error("请求体格式无效或缺少scheduleTaskEvent信息");
+                return R.error("请求格式无效");
+            }
+
+            // 检查错误码
+            VideoScheduleTaskEventParam event = videoTranscodeParam.getScheduleTaskEvent();
+            if (!Integer.valueOf(0).equals(event.getErrCode())) {
+                log.warn("收到转码事件非零错误码: {}", event.getErrCode());
+                return R.ok(); // 仍然返回ok确认已处理通知
+            }
+
+            // 验证输入路径
+            if (event.getInputInfo() == null || event.getInputInfo().getCosInputInfo() == null) {
+                log.error("转码事件中缺少输入信息");
+                return R.error("缺少输入信息");
+            }
+
+            String inputPaths = event.getInputInfo().getCosInputInfo().getObject();
+            if (StringUtils.isBlank(inputPaths)) {
+                log.error("转码事件中的输入路径为空");
+                return R.error("输入路径为空");
+            }
+
+            // 移除可能的前导斜杠
+            String inputPath = inputPaths.startsWith("/") ? inputPaths.substring(1) : inputPaths;
+
+            // 查找视频资源
+            FsVideoResource video = iFsVideoResourceService.selectByFileKey(inputPath);
+            if (video == null) {
+                log.warn("未找到文件键对应的视频资源: {}", inputPath);
+                return R.ok();
+            }
+
+            // 验证输出路径
+            if (event.getActivityResultSet() == null || event.getActivityResultSet().isEmpty()) {
+                log.error("转码事件中缺少活动结果集");
+                return R.error("缺少活动结果");
+            }
+
+            VideoActivityResItemParam activityResItem = event.getActivityResultSet().get(0).getActivityResItem();
+            if (activityResItem == null || activityResItem.getTranscodeTask() == null ||
+                    activityResItem.getTranscodeTask().getOutput() == null) {
+                log.error("转码任务信息不完整");
+                return R.error("转码任务不完整");
+            }
+
+            String outputPath = activityResItem.getTranscodeTask().getOutput().getPath();
+            if (StringUtils.isBlank(outputPath)) {
+                log.error("转码事件中的输出路径为空");
+                return R.error("输出路径为空");
+            }
+
+            // 移除可能的前导斜杠
+            String transcodeFileKey = outputPath.startsWith("/") ? outputPath.substring(1) : outputPath;
+
+            // 提交转码作业
+            log.info("开始提交转码作业,输入路径: {}, 输出路径: {}", inputPaths, outputPath);
+            tencentCloudCosService.submitTranscodeJob(inputPaths, outputPath);
+
+            // 更新视频资源
+            FsVideoResource videoMap = new FsVideoResource();
+            videoMap.setId(video.getId());
+            videoMap.setIsTranscode(1);
+            videoMap.setLine1(video.getLine1().replace(inputPath,transcodeFileKey));
+            videoMap.setTranscodeFileKey(transcodeFileKey);
+            iFsVideoResourceService.updateById(videoMap);
+            log.info("成功更新视频转码状态,视频ID: {}", video.getId());
+
+            return R.ok();
+        } catch (Exception e) {
+            log.error("处理视频转码请求时发生异常", e);
+            return R.error("服务器内部错误");
+        }
+    }
 }
 }

+ 10 - 2
fs-admin/src/main/resources/application.yml

@@ -4,6 +4,14 @@ server:
 # Spring配置
 # Spring配置
 spring:
 spring:
   profiles:
   profiles:
-    active: dev
-    include: common,config-myhk
+#    active: dev
+#    include: common,config-myhk
+#    active: druid-hdt
+#    include: common,config-druid-hdt
+#    active: druid-yzt
+#    include: common,config-druid-yzt
+#    active: druid-sxjz
+#    include: common,config-druid-sxjz
+    active: druid-sft
+    include: common,config-druid-sft
 
 

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

@@ -5,5 +5,7 @@ server:
 # Spring配置
 # Spring配置
 spring:
 spring:
   profiles:
   profiles:
-    active: dev
-    include: common,config-dev
+#    active: dev
+#    include: common,config-dev
+    active: druid-sxjz
+    include: common,config-druid-sxjz

+ 9 - 3
fs-company/src/main/resources/application.yml

@@ -3,11 +3,17 @@ server:
 # Spring配置
 # Spring配置
 spring:
 spring:
   profiles:
   profiles:
-    active: dev
-    include: common,config-dev
+#    active: dev
+#    include: common,config-dev
 #    active: druid-jzzx
 #    active: druid-jzzx
 #    include: common,config-druid-jzzx
 #    include: common,config-druid-jzzx
 #    active: druid-hdt
 #    active: druid-hdt
-#    include: common,config-druid-
+#    include: common,config-druid-hdt
 #    active: druid-sxjz
 #    active: druid-sxjz
 #    include: common,config-druid-sxjz
 #    include: common,config-druid-sxjz
+#    active: druid-yzt
+#    include: common,config-druid-yzt
+#    active: druid-myhk
+#    include: common,config-myhk
+    active: druid-sft
+    include: common,config-druid-sft

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

@@ -142,6 +142,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                 .antMatchers("/webjars/**").anonymous()
                 .antMatchers("/webjars/**").anonymous()
                 .antMatchers("/*/api-docs").anonymous()
                 .antMatchers("/*/api-docs").anonymous()
                 .antMatchers("/druid/**").anonymous()
                 .antMatchers("/druid/**").anonymous()
+                .antMatchers("/course/userVideo/videoTranscode").anonymous()
                 // 除上面外的所有请求全部需要鉴权认证
                 // 除上面外的所有请求全部需要鉴权认证
                 .anyRequest().authenticated()
                 .anyRequest().authenticated()
                 .and()
                 .and()

+ 0 - 34
fs-qw-api-msg/src/main/java/com/fs/app/controller/test.java

@@ -1,34 +0,0 @@
-package com.fs.app.controller;
-
-import com.alibaba.fastjson.JSON;
-import com.fs.common.annotation.Excel;
-import com.fs.fastGpt.domain.FastGptChatSession;
-import com.fs.fastgptApi.util.AiImgUtil;
-import com.fs.qw.domain.QwExternalContactInfo;
-import com.fs.wxwork.dto.WxwSilkVoceDTO;
-import com.fs.wxwork.utils.WxWorkHttpUtil;
-
-import javax.validation.constraints.Null;
-import java.lang.reflect.Field;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class test {
-    public static void main(String[] args) {
-        AiImgUtil aiImgUtil = new AiImgUtil();
-        String imageParse = aiImgUtil.getImageParse("https://wework.qpic.cn/wwpic3az/wwwx_3cf5c3be937316fcad124d8fb1b1f1b2/0");
-        System.out.println(imageParse);
-    }
-
-
-
-
-    void voice(){
-        String  url="http://162.14.193.126:8009/app/common/voice?voice="+"你好"+"&id="+2020;
-        String json = WxWorkHttpUtil.get(url);
-        System.out.println(json);
-        WxwSilkVoceDTO wxwSilkVoceDTO = JSON.parseObject(json, WxwSilkVoceDTO.class);
-    }
-}

+ 0 - 53
fs-qw-api/src/main/java/com/fs/app/controller/testTask.java

@@ -1,53 +0,0 @@
-package com.fs.app.controller;//package com.fs.app.controller;
-//
-//import com.alibaba.fastjson.JSON;
-//import com.fs.app.service.QwDataCallbackService;
-//import com.fs.common.core.redis.RedisCache;
-//import com.fs.fastGpt.service.AiNewService;
-//import com.fs.fastGpt.service.AiService;
-//import com.fs.qw.domain.QwMessageGather;
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.scheduling.annotation.Scheduled;
-//import org.springframework.stereotype.Service;
-//
-//import java.util.List;
-//
-//@Service
-//public class testTask {
-//
-//    @Autowired
-//    QwDataCallbackService qwDataCallbackService;
-//    @Autowired
-//    private AiNewService aiService;
-//
-//    @Scheduled(fixedRate = 5000) // 每10执行一次
-//    public void getMsg(){
-//        // 拉取会话存档内容
-//        List<String> chatContents = qwDataCallbackService.getChatData("wweb0666cc79d79da5");
-//        for (String chatContent : chatContents) {
-//            QwMessageGather qwMessageGather = JSON.parseObject(chatContent, QwMessageGather.class);
-//            if (!qwMessageGather.getAction().equals("send")){
-//                System.out.println("非send");
-//                continue;
-//            }
-//            if (!qwMessageGather.getMsgtype().equals("text")){
-//                System.out.println("非text");
-//                continue;
-//            }
-//            if (qwMessageGather.getRoomid()!=null&&!qwMessageGather.getRoomid().equals("")){
-//                System.out.println("群聊消息");
-//                continue;
-//            }
-//            String from = qwMessageGather.getFrom();
-//            if (from.startsWith("wo")||from.startsWith("wm")){
-//                System.out.println("用户发消息");
-//                aiService.qwHookNotifyAiReply(qwMessageGather,"wweb0666cc79d79da5");
-//            }else {
-//                aiService.qwHookNotifyAddMsg(qwMessageGather,"wweb0666cc79d79da5");
-//                System.out.println("客服发送消息");
-//            }
-//            QwMessageGather.TextContent text = qwMessageGather.getText();
-//            System.out.println(text.getContent());
-//        }
-//    }
-//}

+ 4 - 2
fs-qw-api/src/main/resources/application.yml

@@ -7,5 +7,7 @@ spring:
   profiles:
   profiles:
 #    active: dev
 #    active: dev
 #    include: common,config-dev
 #    include: common,config-dev
-    active: druid-hdt
-    include: common,config-druid-hdt,mq-hdt
+#    active: druid-hdt
+#    include: common,config-druid-hdt
+    active: druid-sft
+    include: common,config-druid-sft

+ 8 - 0
fs-qw-task/src/main/resources/application.yml

@@ -6,5 +6,13 @@ server:
 # Spring配置
 # Spring配置
 spring:
 spring:
   profiles:
   profiles:
+#    active: dev
+#    include: common,config-dev
+#    active: druid-hcl
+#    include: common,config-druid-hcl
+#    active: druid-sxjz
+#    include: common,config-druid-sxjz
+#    active: druid-hdt
+#    include: common,config-druid-hdt
     active: druid-myhk
     active: druid-myhk
     include: common,config-myhk
     include: common,config-myhk

+ 6 - 2
fs-qwhook-msg/src/main/resources/application.yml

@@ -5,5 +5,9 @@ server:
 # Spring配置
 # Spring配置
 spring:
 spring:
   profiles:
   profiles:
-    active: dev
-    include: common,config-dev
+#    active: dev
+#    include: common,config-dev
+#    active: druid-sxjz
+#    include: common,config-druid-sxjz
+    active: druid-hdt
+    include: common,config-druid-hdt

+ 10 - 2
fs-qwhook-sop/src/main/resources/application.yml

@@ -6,5 +6,13 @@ server:
 # Spring配置
 # Spring配置
 spring:
 spring:
   profiles:
   profiles:
-    active: dev
-    include: common,config-dev
+#    active: dev
+#    include: common,config-dev
+#    active: druid-yzt
+#    include: common,config-druid-yzt
+#    active: druid-hdt
+#    include: common,config-druid-hdt
+#    active: druid-sxjz
+#    include: common,config-druid-sxjz
+    active: druid-sft
+    include: common,config-druid-sft

+ 10 - 2
fs-qwhook/src/main/resources/application.yml

@@ -6,5 +6,13 @@ server:
 # Spring配置
 # Spring配置
 spring:
 spring:
   profiles:
   profiles:
-    active: dev
-    include: common,config-dev
+#    active: dev
+#    include: common,config-dev
+#    active: druid-yzt
+#    include: common,config-druid-yzt
+#    active: druid-hdt
+#    include: common,config-druid-hdt
+#    active: druid-sxjz
+#    include: common,config-druid-sxjz
+    active: druid-sft
+    include: common,config-druid-sft

+ 10 - 0
fs-service/src/main/java/com/fs/course/param/VideoActivityResItemParam.java

@@ -0,0 +1,10 @@
+package com.fs.course.param;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class VideoActivityResItemParam implements Serializable {
+    private VideoTranscodeTaskParam TranscodeTask;
+}

+ 12 - 0
fs-service/src/main/java/com/fs/course/param/VideoActivityResultSetParam.java

@@ -0,0 +1,12 @@
+package com.fs.course.param;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class VideoActivityResultSetParam implements Serializable {
+    private String ActivityType;
+    private VideoActivityResItemParam ActivityResItem;
+
+}

+ 10 - 0
fs-service/src/main/java/com/fs/course/param/VideoCosInputInfoParam.java

@@ -0,0 +1,10 @@
+package com.fs.course.param;
+
+import lombok.Data;
+
+@Data
+public class VideoCosInputInfoParam {
+    private String bucket;
+    private String region;
+    private String object;
+}

+ 9 - 0
fs-service/src/main/java/com/fs/course/param/VideoInputInfoParam.java

@@ -0,0 +1,9 @@
+package com.fs.course.param;
+
+import lombok.Data;
+@Data
+public class VideoInputInfoParam {
+    private String type;
+    private VideoCosInputInfoParam cosInputInfo;
+
+}

+ 8 - 0
fs-service/src/main/java/com/fs/course/param/VideoOutputParam.java

@@ -0,0 +1,8 @@
+package com.fs.course.param;
+
+import lombok.Data;
+
+@Data
+public class VideoOutputParam {
+    private String path;
+}

+ 16 - 0
fs-service/src/main/java/com/fs/course/param/VideoScheduleTaskEventParam.java

@@ -0,0 +1,16 @@
+package com.fs.course.param;
+
+import lombok.Data;
+
+import java.util.List;
+@Data
+public class VideoScheduleTaskEventParam {
+    private String TaskId;
+    private String Status;
+    private Integer ErrCode;
+    private String Message;
+    private VideoInputInfoParam InputInfo;
+    private List<VideoActivityResultSetParam> ActivityResultSet;
+
+
+}

+ 10 - 0
fs-service/src/main/java/com/fs/course/param/VideoTranscodeParam.java

@@ -0,0 +1,10 @@
+package com.fs.course.param;
+
+import lombok.Data;
+
+@Data
+public class VideoTranscodeParam {
+    private String EventType;
+    private VideoScheduleTaskEventParam ScheduleTaskEvent;
+
+}

+ 18 - 0
fs-service/src/main/java/com/fs/course/param/VideoTranscodeTaskParam.java

@@ -0,0 +1,18 @@
+package com.fs.course.param;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class VideoTranscodeTaskParam implements Serializable {
+    private String Status;
+    private Integer ErrCode;
+    private String ErrCodeExt;
+    private String Message;
+    private String BeginProcessTime;
+    private String FinishTime;
+    private VideoOutputParam Output;
+    private Integer Progress;
+
+}

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

@@ -163,4 +163,11 @@ public interface IFsUserCourseVideoService
 
 
     R createMiniLink(FsCourseLinkMiniParam param);
     R createMiniLink(FsCourseLinkMiniParam param);
     R createCartLink(FsCourseLinkMiniParam param);
     R createCartLink(FsCourseLinkMiniParam param);
+
+    /**
+     * 校验时长
+     * @param param
+     * @return
+     */
+    R isAllowAnswer(FsUserCourseVideoFinishUParam param);
 }
 }

+ 8 - 0
fs-service/src/main/java/com/fs/course/service/IFsVideoResourceService.java

@@ -16,4 +16,12 @@ public interface IFsVideoResourceService extends IService<FsVideoResource> {
      * @return  list
      * @return  list
      */
      */
     List<FsVideoResourceVO> selectVideoResourceListByMap(Map<String, Object> params);
     List<FsVideoResourceVO> selectVideoResourceListByMap(Map<String, Object> params);
+
+    /**
+     * 通过filekey查询数据信息
+     *
+     * @param fileKey
+     * @return
+     */
+    FsVideoResource selectByFileKey(String fileKey);
 }
 }

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

@@ -684,7 +684,7 @@ public class FsCourseWatchLogServiceImpl extends ServiceImpl<FsCourseWatchLogMap
         if (videoDuration==null){
         if (videoDuration==null){
             FsUserCourseVideo video = courseVideoMapper.selectFsUserCourseVideoByVideoId(videoId);
             FsUserCourseVideo video = courseVideoMapper.selectFsUserCourseVideoByVideoId(videoId);
             videoDuration=video.getDuration();
             videoDuration=video.getDuration();
-            redisCache.setCacheObject(videoRedisKey,video.getDuration().toString());
+            redisCache.setCacheObject(videoRedisKey,video.getDuration());
         }
         }
         return videoDuration;
         return videoDuration;
     }
     }

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

@@ -1321,6 +1321,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
 
 
     }
     }
 
 
+
     //插入观看记录
     //插入观看记录
     private void addWatchLogIfNeeded(Long videoId, Long courseId,
     private void addWatchLogIfNeeded(Long videoId, Long courseId,
                                      Long fsUserId, QwUser qwUser,Long externalId) {
                                      Long fsUserId, QwUser qwUser,Long externalId) {
@@ -1422,4 +1423,126 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
         // 设置 Redis 记录的过期时间(例如 5 分钟)
         // 设置 Redis 记录的过期时间(例如 5 分钟)
         redisCache.expire(redisKey, 300, TimeUnit.SECONDS);
         redisCache.expire(redisKey, 300, TimeUnit.SECONDS);
     }
     }
+
+
+    @Override
+    public R isAllowAnswer(FsUserCourseVideoFinishUParam param) {
+        try {
+            // 参数校验
+            if (param.getVideoId() == null || param.getDuration() == null) {
+                return R.error("参数不完整,缺少videoId或duration");
+            }
+
+            // 获取视频时长(优先从Redis缓存获取)
+            Long videoDuration = getVideoDuration(param.getVideoId());
+
+            // 校验总时长
+            return checkTotalDuration(param.getDuration(), videoDuration);
+        } catch (IllegalArgumentException e) {
+            return R.error(e.getMessage());
+        } catch (Exception e) {
+            log.error("检查总时长异常, 参数: {}", param, e);
+            return R.error("系统异常,请稍后重试");
+        }
+    }
+    /**
+     * 获取视频时长(优先从Redis获取,不存在则查数据库)
+     */
+    private Long getVideoDuration(Long videoId) {
+        String redisKey = "h5user:video:duration:" + videoId;
+        Long duration = redisCache.getCacheObject(redisKey);
+
+        if (duration == null) {
+            FsUserCourseVideoQVO videoInfo = selectFsUserCourseVideoByVideoIdVO(videoId);
+            if (videoInfo == null || videoInfo.getDuration() == null) {
+                throw new IllegalArgumentException("视频时长信息不存在");
+            }
+            duration = videoInfo.getDuration();
+
+            // 将查询结果缓存到Redis,设置适当过期时间
+            redisCache.setCacheObject(redisKey, duration);
+        }
+
+        return duration;
+    }
+
+    /**
+     * 时长校验服务实现
+     *
+     * @param duration1
+     * @param duration2
+     * @return
+     */
+    public R checkTotalDuration(Long duration1, Long duration2) {
+        // 参数校验
+        if (duration1 == null || duration2 == null) {
+            throw new IllegalArgumentException("时长参数不能为null");
+        }
+
+        if (duration1 < 0 || duration2 < 0) {
+            throw new IllegalArgumentException("时长不能为负数");
+        }
+        // 获取并验证配置
+        CourseConfig config = getValidatedConfig();
+
+        // 根据配置模式进行校验
+        switch (config.getCompletionMode()) {
+            case 1: // 百分比模式
+                return checkPercentageMode(duration1, duration2, config);
+            case 2: // 分钟数模式
+                return checkMinutesMode(duration1, config);
+            default:
+                return R.error("无效的完成模式配置");
+        }
+    }
+
+    /**
+     * 获取并验证课程配置
+     */
+    private CourseConfig getValidatedConfig() {
+        String json = configService.selectConfigByKey("course.config");
+        if (StringUtils.isBlank(json)) {
+            throw new IllegalStateException("课程配置不存在");
+        }
+
+        try {
+            CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
+            if (config == null || config.getCompletionMode() == null) {
+                throw new IllegalStateException("课程配置不完整");
+            }
+            return config;
+        } catch (Exception e) {
+            throw new IllegalStateException("解析课程配置失败");
+        }
+    }
+
+    /**
+     * 百分比模式校验
+     */
+    private R checkPercentageMode(long duration1, long duration2, CourseConfig config) {
+        if (config.getAnswerRate() == null) {
+            return R.error("百分比模式未配置达标比例");
+        }
+        long percentage = (duration1 * 100 / duration2);
+
+        boolean isPassed = percentage >= config.getAnswerRate();
+        return isPassed ? R.ok() : R.error(String.format("观看进度%d%%未达标(需%d%%)",
+                percentage,config.getAnswerRate()));
+    }
+
+    /**
+     * 分钟数模式校验
+     */
+    private R checkMinutesMode(long videoDuration, CourseConfig config) {
+        if (config.getMinutesNum() == null) {
+            return R.error("分钟数模式未配置达标分钟数");
+        }
+
+        int i = config.getMinutesNum() * 60;
+        boolean isPassed = videoDuration > i;
+
+        return isPassed ? R.ok() : R.error(String.format("观看时长%d分钟未达标(需大于%d分钟)",
+                videoDuration/60, config.getMinutesNum()));
+    }
+
 }
 }

+ 13 - 0
fs-service/src/main/java/com/fs/course/service/impl/FsVideoResourceServiceImpl.java

@@ -1,5 +1,6 @@
 package com.fs.course.service.impl;
 package com.fs.course.service.impl;
 
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fs.course.domain.FsVideoResource;
 import com.fs.course.domain.FsVideoResource;
 import com.fs.course.mapper.FsVideoResourceMapper;
 import com.fs.course.mapper.FsVideoResourceMapper;
@@ -23,4 +24,16 @@ public class FsVideoResourceServiceImpl extends ServiceImpl<FsVideoResourceMappe
     public List<FsVideoResourceVO> selectVideoResourceListByMap(Map<String, Object> params) {
     public List<FsVideoResourceVO> selectVideoResourceListByMap(Map<String, Object> params) {
         return baseMapper.selectVideoResourceListByMap(params);
         return baseMapper.selectVideoResourceListByMap(params);
     }
     }
+
+    /**
+     * 通过fileKey查询数据信息
+     *
+     * @param fileKey
+     * @return
+     */
+    @Override
+    public FsVideoResource selectByFileKey(String fileKey) {
+        FsVideoResource fsVideoResource = baseMapper.selectOne(new LambdaQueryWrapper<FsVideoResource>().eq(FsVideoResource::getFileKey, fileKey));
+        return fsVideoResource;
+    }
 }
 }

+ 3 - 0
fs-service/src/main/java/com/fs/qw/vo/QwSopRuleTimeVO.java

@@ -89,4 +89,7 @@ public class QwSopRuleTimeVO extends BaseEntity {
     */
     */
     private Integer tempGap;
     private Integer tempGap;
 
 
+    // 是否固定营期
+    private Integer isFixed;
+
 }
 }

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

@@ -79,4 +79,3 @@ wx_miniapp_temp:
   inquiry_temp_id:
   inquiry_temp_id:
 
 
 
 
-

+ 3 - 0
fs-service/src/main/resources/application-config-druid-hcl.yml

@@ -75,3 +75,6 @@ headerImg:
   imgUrl: https://jz-cos-1356808054.cos.ap-chengdu.myqcloud.com/fs/20250515/0877754b59814ea8a428fa3697b20e68.png
   imgUrl: https://jz-cos-1356808054.cos.ap-chengdu.myqcloud.com/fs/20250515/0877754b59814ea8a428fa3697b20e68.png
 ipad:
 ipad:
   ipadUrl: http://ipad.cdwjyyh.com
   ipadUrl: http://ipad.cdwjyyh.com
+wx_miniapp_temp:
+  pay_order_temp_id:
+  inquiry_temp_id:

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

@@ -67,5 +67,7 @@ headerImg:
   imgUrl: https://jz-cos-1356808054.cos.ap-chengdu.myqcloud.com/fs/20250515/0877754b59814ea8a428fa3697b20e68.png
   imgUrl: https://jz-cos-1356808054.cos.ap-chengdu.myqcloud.com/fs/20250515/0877754b59814ea8a428fa3697b20e68.png
 ipad:
 ipad:
   ipadUrl: http://ipad.cdwjyyh.com
   ipadUrl: http://ipad.cdwjyyh.com
-
+wx_miniapp_temp:
+  pay_order_temp_id:
+  inquiry_temp_id:
 
 

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

@@ -75,4 +75,6 @@ headerImg:
   imgUrl: https://jz-cos-1356808054.cos.ap-chengdu.myqcloud.com/fs/20250515/0877754b59814ea8a428fa3697b20e68.png
   imgUrl: https://jz-cos-1356808054.cos.ap-chengdu.myqcloud.com/fs/20250515/0877754b59814ea8a428fa3697b20e68.png
 ipad:
 ipad:
   ipadUrl: http://ipad.cdwjyyh.com
   ipadUrl: http://ipad.cdwjyyh.com
-
+wx_miniapp_temp:
+  pay_order_temp_id:
+  inquiry_temp_id:

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

@@ -79,4 +79,3 @@ wx_miniapp_temp:
   inquiry_temp_id: hwFXVh0AWqeasBsZpa0-urb3CrPeYEwBiy3P6AMMGFQ
   inquiry_temp_id: hwFXVh0AWqeasBsZpa0-urb3CrPeYEwBiy3P6AMMGFQ
 
 
 
 
-

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

@@ -74,4 +74,6 @@ headerImg:
   imgUrl: https://jz-cos-1356808054.cos.ap-chengdu.myqcloud.com/fs/20250515/0877754b59814ea8a428fa3697b20e68.png
   imgUrl: https://jz-cos-1356808054.cos.ap-chengdu.myqcloud.com/fs/20250515/0877754b59814ea8a428fa3697b20e68.png
 ipad:
 ipad:
   ipadUrl: http://ipad.cdwjyyh.com
   ipadUrl: http://ipad.cdwjyyh.com
-
+wx_miniapp_temp:
+  pay_order_temp_id:
+  inquiry_temp_id:

+ 73 - 0
fs-service/src/main/resources/application-config-druid-sft.yml

@@ -0,0 +1,73 @@
+baidu:
+  token: 1231321232
+#配置
+logging:
+  level:
+    org.springframework.web: INFO
+    com.github.binarywang.demo.wx.cp: DEBUG
+    me.chanjar.weixin: DEBUG
+wx:
+  cp:
+    corpId: wwb2a10556a7c2
+    appConfigs:
+      - agentId: 100005
+        secret: ec7okROXJqkNafq66aKNasTzQIG0CYrj3vyBbo
+        token: PPKOdAlMO
+        aesKey: PKvaxtpSvNGpfT7VUHIK8Wok2ESyYX24qpXJAdMP
+  pay:
+    appId: wx292bf58b269bbb8c #微信公众号或者小程序等的appid
+    mchId: 1717412669 #微信支付商户号
+    mchKey: a3f0bec59cebeb60553ec80bbfd5dfdf #微信支付商户密钥
+    subAppId:  #服务商模式下的子商户公众账号ID
+    subMchId:  #服务商模式下的子商户号
+    keyPath: c:\\cert\\apiclient_cert.p12 # p12证书的位置,可以指定绝对路径,也可以指定类路径(以classpath:开头)
+    notifyUrl: https://usepp.his.runtzh.com/app/wxpay/wxPayNotify
+  mp:
+    useRedis: false
+    redisConfig:
+      host: 127.0.0.1
+      port: 6379
+      timeout: 2000
+    configs:
+      - appId: wx73aadc283984a8ee # 第一个公众号的appid  //公众号名称:四福堂商城
+        secret: 50c5fee7d107ecbeda4328ef4976a6a0 # 公众号的appsecret
+        token: PPKOdAlCoMO # 接口配置里的Token值
+        aesKey: Eswa6VjwtVcw03qZy6Wllgrv5aytIA1SZPEU0kU2 # 接口配置里的EncodingAESKey值
+aifabu:  #爱链接
+  appKey: 7b471be905ab17ef358c0dd117601d008
+watch:
+  watchUrl: watch.ylrzcloud.com/prod-api
+#  account: tcloud
+#  password: mdf-m2h_6yw2$hq
+  account1: ccif #866655060138751
+  password1: cp-t5or_6xw7$mt
+  account2: tcloud #rt500台
+  password2: mdf-m2h_6yw2$hq
+  account3: whr
+  password3: v9xsKuqn_$d2y
+
+fs :
+  commonApi: http://172.16.0.16:8010
+  h5CommonApi: http://119.29.195.254:8010
+nuonuo:
+  key: 10924508
+  secret: A2EB20764D304D16
+# 存储捅配置
+tencent_cloud_config:
+  secret_id: AKIDiMq9lDf2EOM9lIfqqfKo7FNgM5meD0sT
+  secret_key: u5SuS80342xzx8FRBukza9lVNHKNMSaB
+  bucket: sft-1323137866
+  app_id: 1323137866
+  region: ap-chongqing
+  proxy: sft
+cloud_host:
+  company_name: 四福堂
+#看课授权时显示的头像
+headerImg:
+  imgUrl: https://cos.his.cdwjyyh.com/fs/20250606/fdf4b41abc0741758ab6c2c70dafb5be.png
+ipad:
+  ipadUrl: http://ipad.cdwjyyh.com
+wx_miniapp_temp:
+  pay_order_temp_id: V
+  inquiry_temp_id: 9
+

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

@@ -67,5 +67,7 @@ headerImg:
   imgUrl: https://jz-cos-1356808054.cos.ap-chengdu.myqcloud.com/fs/20250515/0877754b59814ea8a428fa3697b20e68.png
   imgUrl: https://jz-cos-1356808054.cos.ap-chengdu.myqcloud.com/fs/20250515/0877754b59814ea8a428fa3697b20e68.png
 ipad:
 ipad:
   ipadUrl: http://ipad.cdwjyyh.com
   ipadUrl: http://ipad.cdwjyyh.com
-
+wx_miniapp_temp:
+  pay_order_temp_id:
+  inquiry_temp_id:
 
 

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

@@ -67,5 +67,7 @@ headerImg:
   imgUrl: https://cos.his.cdwjyyh.com/fs/20250522/28c3d8d5c42a4bcdb85292c2e5eb2a37.png
   imgUrl: https://cos.his.cdwjyyh.com/fs/20250522/28c3d8d5c42a4bcdb85292c2e5eb2a37.png
 ipad:
 ipad:
   ipadUrl: http://ipad.cdwjyyh.com
   ipadUrl: http://ipad.cdwjyyh.com
-
+wx_miniapp_temp:
+  pay_order_temp_id:
+  inquiry_temp_id:
 
 

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

@@ -56,3 +56,6 @@ headerImg:
   imgUrl: https://jz-cos-1356808054.cos.ap-chengdu.myqcloud.com/fs/20250515/0877754b59814ea8a428fa3697b20e68.png
   imgUrl: https://jz-cos-1356808054.cos.ap-chengdu.myqcloud.com/fs/20250515/0877754b59814ea8a428fa3697b20e68.png
 ipad:
 ipad:
   ipadUrl: http://ipad.cdwjyyh.com
   ipadUrl: http://ipad.cdwjyyh.com
+wx_miniapp_temp:
+  pay_order_temp_id:
+  inquiry_temp_id:

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

@@ -76,4 +76,3 @@ wx_miniapp_temp:
   inquiry_temp_id: 9POPYeqhI48LOPvq-Rfoklze7H-9SlunJKh10Qt4_2I
   inquiry_temp_id: 9POPYeqhI48LOPvq-Rfoklze7H-9SlunJKh10Qt4_2I
 
 
 
 
-

+ 137 - 0
fs-service/src/main/resources/application-druid-sft.yml

@@ -0,0 +1,137 @@
+
+# 数据源配置
+spring:
+    # redis 配置
+    redis:
+        host: 172.30.0.13
+        port: 6379
+        # 数据库索引
+        database: 0
+        # 密码
+        password: Sft13245600*
+        # 连接超时时间
+        timeout: 10s
+        lettuce:
+            pool:
+                # 连接池中的最小空闲连接
+                min-idle: 0
+                # 连接池中的最大空闲连接
+                max-idle: 8
+                # 连接池的最大数据库连接数
+                max-active: 80
+                # #连接池最大阻塞等待时间(使用负值表示没有限制)
+                max-wait: -1ms
+    datasource:
+        mysql:
+            type: com.alibaba.druid.pool.DruidDataSource
+            driverClassName: com.mysql.cj.jdbc.Driver
+            druid:
+                # 主库数据源
+                master:
+                    url: jdbc:mysql://172.30.0.15:3306/fs_his?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: root
+                    password: Sft13245600*
+                # 从库数据源
+                slave:
+                    # 从数据源开关/默认关闭
+                    enabled: false
+                    url:
+                    username:
+                    password:
+                # 初始连接数
+                initialSize: 5
+                # 最小连接池数量
+                minIdle: 10
+                # 最大连接池数量
+                maxActive: 2000
+                # 配置获取连接等待超时的时间
+                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://172.30.0.15:3306/fs_his_sop?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: root
+                    password: Sft13245600*
+                # 初始连接数
+                initialSize: 5
+                # 最小连接池数量
+                minIdle: 10
+                # 最大连接池数量
+                maxActive: 200
+                # 配置获取连接等待超时的时间
+                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-1243b25nj.rocketmq.gz.public.tencenttdmq.com:8080 # RocketMQ NameServer 地址
+    producer:
+        group: my-producer-group
+        access-key: ak1243b25nj17d4b2dc1a03 # 替换为实际的 accessKey
+        secret-key: sk08a7ea1f9f4b0237 # 替换为实际的 secretKey
+    consumer:
+        group: voice-group
+        access-key: ak1243b25nj17d4b2dc1a03 # 替换为实际的 accessKey
+        secret-key: sk08a7ea1f9f4b0237 # 替换为实际的 secretKey

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

@@ -40,6 +40,9 @@ import springfox.documentation.spring.web.readers.operation.CachingOperationName
 
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequest;
 import java.util.*;
 import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+import static com.fs.framework.datasource.DynamicDataSourceContextHolder.log;
 
 
 @Api("课堂接口")
 @Api("课堂接口")
 @RestController
 @RestController
@@ -408,6 +411,7 @@ public class CourseController extends  AppBaseController{
         String videoRedisKey = "h5user:video:duration:" + param.getVideoId();
         String videoRedisKey = "h5user:video:duration:" + param.getVideoId();
         Long videoDuration = redisCache.getCacheObject(videoRedisKey);
         Long videoDuration = redisCache.getCacheObject(videoRedisKey);
         if (videoDuration==null){
         if (videoDuration==null){
+
             redisCache.setCacheObject(videoRedisKey,course.getDuration());
             redisCache.setCacheObject(videoRedisKey,course.getDuration());
         }
         }
         // 返回是否开启评论/弹幕。优先获取sop任务配置的是否开启评论/弹幕,如果没有配置就取总后台的配置;
         // 返回是否开启评论/弹幕。优先获取sop任务配置的是否开启评论/弹幕,如果没有配置就取总后台的配置;
@@ -419,7 +423,6 @@ public class CourseController extends  AppBaseController{
         return R.ok().put("course",course).put("questions",questionVOList).put("config",config).put("playDuration",duration).put("tipsTime",tipsTime).put("isFinish",isFinish);
         return R.ok().put("course",course).put("questions",questionVOList).put("config",config).put("playDuration",duration).put("tipsTime",tipsTime).put("isFinish",isFinish);
     }
     }
 
 
-
     @ApiOperation("答题")
     @ApiOperation("答题")
     @PostMapping("/courseAnswer")
     @PostMapping("/courseAnswer")
     @Login
     @Login
@@ -575,4 +578,16 @@ public class CourseController extends  AppBaseController{
         return R.ok().put("data", pageInfo);
         return R.ok().put("data", pageInfo);
     }
     }
 
 
+
+    /**
+     * 校验是否可以答题
+     *
+     * @param param
+     * @return
+     */
+    @PostMapping("/isAllowAnswer")
+    public R isAllowAnswer(@RequestBody FsUserCourseVideoFinishUParam param) {
+        return courseVideoService.isAllowAnswer(param);
+    }
+
 }
 }

+ 8 - 2
fs-user-app/src/main/java/com/fs/app/controller/WxUserController.java

@@ -191,9 +191,15 @@ public class WxUserController extends AppBaseController{
     @PostMapping("/courseLogin")
     @PostMapping("/courseLogin")
     @Transactional
     @Transactional
     public R courseLogin(@RequestBody LoginParam param) {
     public R courseLogin(@RequestBody LoginParam param) {
+        SysConfig sysConfig3 = sysConfigMapper.selectConfigByConfigKey("courseMa.config");
+        List<CourseMaConfig> courseMaConfigs = JSON.parseArray(sysConfig3.getConfigValue(), CourseMaConfig.class);
+        if (courseMaConfigs.isEmpty()){
+            return R.error("小程序配置为空");
+        }
+        CourseMaConfig courseMaConfig = courseMaConfigs.get(0);
         return handleCourseLogin(param,
         return handleCourseLogin(param,
-                () -> WxMaConfiguration.getMaService("wxc84c6f789ba7f176"),
-                "木易华康在线");
+                () -> WxMaConfiguration.getMaService(courseMaConfig.getAppid()),
+                courseMaConfig.getName());
     }
     }
 
 
     /**
     /**

+ 10 - 4
fs-user-app/src/main/resources/application.yml

@@ -6,11 +6,17 @@ server:
 # Spring配置
 # Spring配置
 spring:
 spring:
   profiles:
   profiles:
-    active: dev
-    include: common,config-dev
+#    active: dev
+#    include: common,config-dev
 #    active: druid-jzzx
 #    active: druid-jzzx
 #    include: common,config-druid-jzzx
 #    include: common,config-druid-jzzx
+#    active: druid-yzt
+#    include: common,config-druid-yzt
 #    active: druid-hdt
 #    active: druid-hdt
 #    include: common,config-druid-hdt
 #    include: common,config-druid-hdt
-#    active: druid-jnmy
-#    include: common,config-druid-jnmy
+#    active: druid-sxjz
+#    include: common,config-druid-sxjz
+#    active: druid-yzt
+#    include: common,config-druid-yzt
+    active: druid-sft
+    include: common,config-druid-sft