|
|
@@ -98,113 +98,6 @@ public class FeiShuService {
|
|
|
}
|
|
|
return "https://www.feishu.cn/docx/"+shortLink;
|
|
|
}
|
|
|
- // ==================== 生成飞书注册链接 ====================
|
|
|
-
|
|
|
- public String getFeishuRegisterLink(Long videoId, Long companyId, Long courseId,
|
|
|
- Long companyUserId, String shortLink) {
|
|
|
- CourseConfig config = getCourseConfig();
|
|
|
- if (!Boolean.TRUE.equals(config.getEnableFeishuNewLink())) {
|
|
|
- throw new CustomException("未开启飞书看课");
|
|
|
- }
|
|
|
- FsUserCourseVideo userCourseVideo = videoMapper.selectFsUserCourseVideoByVideoId(videoId);
|
|
|
- if (userCourseVideo == null) {
|
|
|
- throw new CustomException("视频不存在: " + videoId);
|
|
|
- }
|
|
|
- // 1. 尝试销售个人账号创建文档
|
|
|
- List<FeishuAccount> personalAccounts = getFeishuAccountCompanyUser(companyId, companyUserId);
|
|
|
- if (!personalAccounts.isEmpty()) {
|
|
|
- for (FeishuAccount account : personalAccounts) {
|
|
|
- if (account.getStatus() != 1) continue;
|
|
|
- Client client = buildClient(account);
|
|
|
- try {
|
|
|
- String docId = docApiService.createDocument(client, userCourseVideo.getTitle() + "-注册");
|
|
|
- String authUrl = buildAuthLink(companyId, companyUserId, courseId, videoId, shortLink);
|
|
|
- docApiService.createTextLinkBlock(client, docId, authUrl);
|
|
|
- docApiService.changeDocumentPermissions(client, docId);
|
|
|
- if (StringUtils.isNotBlank(shortLink)){
|
|
|
- FsCourseLink fsCourseLink = courseLinkMapper.selectFsCourseLinkByLink(shortLink);
|
|
|
- //有视频短链+外部联系人id,需要缓存docId和account
|
|
|
- if (fsCourseLink.getQwExternalId()!=null){
|
|
|
- String docIdKey=FEISHU_DOC_ID + fsCourseLink.getQwExternalId()+ "_" + videoId;
|
|
|
- redisCache.setCacheObject(docIdKey, docId);
|
|
|
- String accountKey = FEISHU_CLIENT+docId;
|
|
|
- account.setDocumentIdFillFlag(Boolean.TRUE);//这里要记录一下文档内容已填充
|
|
|
- redisCache.setCacheObject(accountKey, account);
|
|
|
- }
|
|
|
- }
|
|
|
- return "https://www.feishu.cn/docx/" + docId;
|
|
|
- } catch (CustomException e) {
|
|
|
- Integer code = e.getCode();
|
|
|
- if (code == null) {
|
|
|
- recordLinkError(videoId, companyId, courseId, companyUserId, shortLink, e.getMessage(), 1);
|
|
|
- return null;
|
|
|
- }
|
|
|
- if (FeishuErrorCode.isAccountDisable(code)) {
|
|
|
- disablePersonalAccount(account, e.getMessage());
|
|
|
- log.warn("个人账号[{}]被禁用,尝试下一个", account.getAppId());
|
|
|
- } else if (FeishuErrorCode.isRateLimit(code) || FeishuErrorCode.isInternalRetryable(code)) {
|
|
|
- log.warn("个人账号[{}]可重试错误,切换下一个", account.getAppId());
|
|
|
- } else {
|
|
|
- // 业务错误或其他,记录失败并返回
|
|
|
- recordLinkError(videoId, companyId, courseId, companyUserId, shortLink, e.getMessage(), 1);
|
|
|
- return null;
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- recordLinkError(videoId, companyId, courseId, companyUserId, shortLink, e.getMessage(), 1);
|
|
|
- return null;
|
|
|
- }
|
|
|
- }
|
|
|
- log.warn("所有个人账号失败,降级到公共账号池");
|
|
|
- }
|
|
|
-
|
|
|
- // 2. 公共账号池
|
|
|
- int retries = clientPool.getAvailableCount();
|
|
|
- for (int i = 0; i < retries; i++) {
|
|
|
- ClientWrapper wrapper = clientPool.getClientWrapper();
|
|
|
- Client client = wrapper.getClient();
|
|
|
- FeishuAccount account = wrapper.getAccount();
|
|
|
- try {
|
|
|
- String docId = docApiService.createDocument(client, userCourseVideo.getTitle() + "-注册");
|
|
|
- String authUrl = buildAuthLink(companyId, companyUserId, courseId, videoId, shortLink);
|
|
|
- docApiService.createTextLinkBlock(client, docId, authUrl);
|
|
|
- docApiService.changeDocumentPermissions(client, docId);
|
|
|
- if (StringUtils.isNotBlank(shortLink)){
|
|
|
- FsCourseLink fsCourseLink = courseLinkMapper.selectFsCourseLinkByLink(shortLink);
|
|
|
- //有视频短链+外部联系人id,需要缓存docId和account
|
|
|
- if (fsCourseLink.getQwExternalId()!=null){
|
|
|
- String docIdKey=FEISHU_DOC_ID + fsCourseLink.getQwExternalId()+ "_" + videoId;
|
|
|
- log.error("公共账号池 外部联系人id不为空,缓存飞书docId,key:{}",docIdKey);
|
|
|
- redisCache.setCacheObject(docIdKey, docId);
|
|
|
- String accountKey = FEISHU_CLIENT+docId;
|
|
|
- account.setDocumentIdFillFlag(Boolean.TRUE);//这里要记录一下文档内容已填充
|
|
|
- redisCache.setCacheObject(accountKey, account);
|
|
|
- }
|
|
|
- }
|
|
|
- return "https://www.feishu.cn/docx/" + docId;
|
|
|
- } catch (CustomException e) {
|
|
|
- Integer code = e.getCode();
|
|
|
- if (code == null) {
|
|
|
- recordLinkError(videoId, companyId, courseId, companyUserId, shortLink, e.getMessage(), 1);
|
|
|
- return null;
|
|
|
- }
|
|
|
- if (FeishuErrorCode.isAccountDisable(code)) {
|
|
|
- clientPool.disableAccount(account, e.getMessage());
|
|
|
- log.warn("公共账号被禁用,尝试下一个");
|
|
|
- } else if (FeishuErrorCode.isRateLimit(code) || FeishuErrorCode.isInternalRetryable(code)) {
|
|
|
- log.warn("公共账号可重试错误,切换下一个");
|
|
|
- } else {
|
|
|
- recordLinkError(videoId, companyId, courseId, companyUserId, shortLink, e.getMessage(), 1);
|
|
|
- return null;
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- recordLinkError(videoId, companyId, courseId, companyUserId, shortLink, e.getMessage(), 1);
|
|
|
- return null;
|
|
|
- }
|
|
|
- }
|
|
|
- recordLinkError(videoId, companyId, courseId, companyUserId, shortLink, "所有公共账号不可用", 1);
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
|
|
|
|
|
|
// ==================== 生成新版飞书课程链接(无授权流程,进入即是看课界面) ====================
|
|
|
@@ -520,23 +413,4 @@ public class FeiShuService {
|
|
|
throw new CustomException("看课URL拼接失败", e);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- private String buildAuthLink(Long companyId, Long companyUserId, Long courseId,
|
|
|
- Long videoId, String shortLink) {
|
|
|
- CourseConfig config = getCourseConfig();
|
|
|
- Map<String, Object> authParam = new LinkedHashMap<>();
|
|
|
- authParam.put("companyUserId", companyUserId);
|
|
|
- authParam.put("videoId", videoId);
|
|
|
- authParam.put("companyId", companyId);
|
|
|
- authParam.put("courseId", courseId);
|
|
|
- authParam.put("link", shortLink);
|
|
|
- try {
|
|
|
- String encodedJson = URLEncoder.encode(JSONUtil.toJsonStr(authParam), "UTF-8");
|
|
|
- String fullUrl = config.getFeishuAuthDomain() +
|
|
|
- "/feishuAuth/pages/wxauth?course=" + encodedJson;
|
|
|
- return URLEncoder.encode(fullUrl, "UTF-8");
|
|
|
- } catch (UnsupportedEncodingException e) {
|
|
|
- throw new CustomException("授权URL拼接失败", e);
|
|
|
- }
|
|
|
- }
|
|
|
}
|