xw 3 часов назад
Родитель
Сommit
0387545685

+ 18 - 0
fs-company/src/main/java/com/fs/company/controller/course/FsCourseLinkController.java

@@ -182,4 +182,22 @@ public class FsCourseLinkController extends BaseController
         return fsUserCourseVideoService.createRoomMiniLinkByCourse(param);
     }
 
+    /**
+     * 提取飞书免授权看课链接
+     */
+    @PostMapping("/createFeishuLink")
+    @ApiOperation("提取飞书免授权看课链接")
+    public R createFeishuLink(@RequestBody FsCourseLinkRoomNewParam param) {
+        if (param.getCourseId() == null) {
+            return R.error("课程id不能为空");
+        }
+        if (param.getVideoId() == null) {
+            return R.error("视频id不能为空");
+        }
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        param.setCompanyUserId(loginUser.getUser().getUserId());
+        param.setCompanyId(loginUser.getCompany().getCompanyId());
+        return fsUserCourseVideoService.createFeishuLinkByCourse(param);
+    }
+
 }

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

@@ -18,4 +18,8 @@ public class FsCourseLinkRoomNewParam {
 
     private String title;//视频标题
 
+    private Long companyUserId;
+
+    private Long companyId;
+
 }

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

@@ -255,6 +255,11 @@ public interface IFsUserCourseVideoService extends IService<FsUserCourseVideo> {
 
     R createRoomMiniLinkByCourse(FsCourseLinkRoomNewParam param);
 
+    /**
+     * 课程目录提取飞书免授权看课链接
+     */
+    R createFeishuLinkByCourse(FsCourseLinkRoomNewParam param);
+
     void updateMediaPublishStatus(String vid);
 
     /**

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

@@ -4827,6 +4827,45 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
         return R.ok().put("link", link);
     }
 
+    @Override
+    public R createFeishuLinkByCourse(FsCourseLinkRoomNewParam param) {
+        if (param.getCompanyUserId() == null || param.getCompanyId() == null) {
+            return R.error("销售信息不存在");
+        }
+
+        String json = configService.selectConfigByKey("course.config");
+        CourseConfig config = JSON.parseObject(json, CourseConfig.class);
+        if (config == null) {
+            return R.error().put("msg", "课程默认配置为空,请联系管理员");
+        }
+
+        Date createTime = DateUtils.getNowDate();
+        FsCourseLink link = createFsCourseLink(null, createTime,
+                param.getCourseId().intValue(), param.getVideoId().intValue(),
+                null, param.getCompanyUserId(), param.getCompanyId(), null, 3, null);
+        link.setFeishuNeedAuth(0);
+        FsCourseRealLink courseMap = new FsCourseRealLink();
+        BeanUtils.copyProperties(link, courseMap);
+        String courseJson = JSON.toJSONString(courseMap);
+        String realLinkFull = feishuMiniappLink + courseJson;
+        if (StringUtils.isNotEmpty(config.getRealLinkGjDomainName())) {
+            realLinkFull = config.getRealLinkGjDomainName() + realLinkFull;
+        }
+        link.setRealLink(realLinkFull);
+        LocalDate tomorrow = LocalDate.now().plusDays(1);
+        LocalDateTime expireDateTime = LocalDateTime.of(tomorrow, LocalTime.of(23, 59, 59));
+        Date expireDate = Date.from(expireDateTime.atZone(ZoneId.systemDefault()).toInstant());
+        link.setUpdateTime(expireDate);
+        fsCourseLinkMapper.insertFsCourseLink(link);
+
+        String feishuLink = feiShuService.createManualFeishuDirectCourseLink(param.getVideoId(), param.getCompanyId(),
+                param.getCourseId(), param.getCompanyUserId(), link.getLink());
+        if (StringUtils.isEmpty(feishuLink)) {
+            return R.error("生成飞书链接失败");
+        }
+        return R.ok().put("link", feishuLink);
+    }
+
     private final ExecutorService uploadExecutor = new ThreadPoolExecutor(
             8,  // core
             16, // max

+ 50 - 0
fs-service/src/main/java/com/fs/feishu/service/FeiShuService.java

@@ -208,6 +208,56 @@ public class FeiShuService {
         throw new CustomException("当前销售没有可用的飞书账号,请先配置或更换账号");
     }
 
+    /**
+     * 手动飞书发课:每次新建飞书文档(风控后直接重新生成即可)。
+     */
+    public String createManualFeishuDirectCourseLink(Long videoId, Long companyId, Long courseId,
+                                                     Long companyUserId, String shortLink) {
+        CourseConfig config = getCourseConfig();
+        if (!Boolean.TRUE.equals(config.getEnableFeishuNewLink())) {
+            throw new CustomException("未开启飞书看课");
+        }
+        if (companyUserId == null) {
+            throw new CustomException("销售ID不能为空");
+        }
+        Long feishuAccountId = feishuAccountService.resolveSendAccountId(companyUserId, null);
+
+        FsUserCourseVideo userCourseVideo = videoMapper.selectFsUserCourseVideoByVideoId(videoId);
+        if (userCourseVideo == null) {
+            throw new CustomException("视频不存在: " + videoId);
+        }
+        int questionFlag = resolveQuestionFlag(userCourseVideo);
+
+        List<FeishuAccount> accounts = clientPool.listEnabledAccounts(companyUserId, feishuAccountId);
+        CustomException lastError = null;
+        for (FeishuAccount account : accounts) {
+            FeishuClientHolder holder = clientPool.getClient(companyUserId, account.getId());
+            try {
+                String iframeUrl = buildCoursePageLink(companyId, companyUserId, courseId, videoId, 0L, shortLink, questionFlag);
+                String documentId = createDirectCourseDocumentWithRetry(holder, userCourseVideo.getTitle(), iframeUrl);
+                feishuAccountMapper.incrementNumberUse(account.getId());
+                updateCourseLinkFeishuAccount(shortLink, account.getId());
+                String resultUrl = FEISHU_DOC_URL_PREFIX + documentId;
+                log.info("手动飞书发课新建文档: companyUserId={}, videoId={}, docUrl={}",
+                        companyUserId, videoId, resultUrl);
+                return resultUrl;
+            } catch (CustomException e) {
+                lastError = e;
+                if (isAccountUnavailable(e)) {
+                    log.warn("销售[{}]飞书账号[{}]不可用,尝试下一个", companyUserId, account.getId());
+                    continue;
+                }
+                throw e;
+            } catch (Exception e) {
+                throw new CustomException("创建飞书免授权看课链接失败: " + e.getMessage(), e);
+            }
+        }
+        if (lastError != null) {
+            throw lastError;
+        }
+        throw new CustomException("当前销售没有可用的飞书账号,请先配置或更换账号");
+    }
+
     /**
      * 生成飞书初始链接(注册授权链接)。
      */