|
|
@@ -136,10 +136,10 @@ public class FeiShuService {
|
|
|
//有视频短链+外部联系人id,需要缓存docId和account
|
|
|
if (fsCourseLink.getQwExternalId()!=null){
|
|
|
String docIdKey=FEISHU_DOC_ID + fsCourseLink.getQwExternalId()+ "_" + videoId;
|
|
|
- redisCache.setCacheObject(docIdKey, docId);
|
|
|
+ redisCache.setCacheObject(docIdKey, docId,30,TimeUnit.DAYS);
|
|
|
String accountKey = FEISHU_CLIENT+docId;
|
|
|
account.setDocumentIdFillFlag(Boolean.TRUE);//这里要记录一下文档内容已填充
|
|
|
- redisCache.setCacheObject(accountKey, account);
|
|
|
+ redisCache.setCacheObject(accountKey, account,30,TimeUnit.DAYS);
|
|
|
}
|
|
|
}
|
|
|
return "https://www.feishu.cn/docx/" + docId;
|
|
|
@@ -184,10 +184,10 @@ public class FeiShuService {
|
|
|
if (fsCourseLink.getQwExternalId()!=null){
|
|
|
String docIdKey=FEISHU_DOC_ID + fsCourseLink.getQwExternalId()+ "_" + videoId;
|
|
|
log.error("公共账号池 外部联系人id不为空,缓存飞书docId,key:{}",docIdKey);
|
|
|
- redisCache.setCacheObject(docIdKey, docId);
|
|
|
+ redisCache.setCacheObject(docIdKey, docId,30,TimeUnit.DAYS);
|
|
|
String accountKey = FEISHU_CLIENT+docId;
|
|
|
account.setDocumentIdFillFlag(Boolean.TRUE);//这里要记录一下文档内容已填充
|
|
|
- redisCache.setCacheObject(accountKey, account);
|
|
|
+ redisCache.setCacheObject(accountKey, account,30,TimeUnit.DAYS);
|
|
|
}
|
|
|
}
|
|
|
return "https://www.feishu.cn/docx/" + docId;
|
|
|
@@ -215,6 +215,127 @@ public class FeiShuService {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+ // ==================== 生成新版飞书课程链接(无授权流程,直接是看课界面) ====================
|
|
|
+
|
|
|
+ public String getFeishuCoursePageLink(FeishuLinkParam param) {
|
|
|
+ String courseLinkKey = String.format("feishu:course_link:%d:%d:%d:%d:%d:%s",
|
|
|
+ param.getCompanyId(), param.getCompanyUserId(),
|
|
|
+ param.getCourseId(), param.getVideoId(),
|
|
|
+ param.getUserId(), param.getLink());
|
|
|
+ String cached = redisCache.getCacheObject(courseLinkKey);
|
|
|
+ if (StringUtils.isNotBlank(cached)) {
|
|
|
+ return cached;
|
|
|
+ }
|
|
|
+
|
|
|
+ FsUserCourseVideo userCourseVideo = videoMapper.selectFsUserCourseVideoByVideoId(param.getVideoId());
|
|
|
+ if (userCourseVideo == null) {
|
|
|
+ throw new CustomException("视频不存在: " + param.getVideoId());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 1. 尝试个人账号
|
|
|
+ List<FeishuAccount> personalAccounts = getFeishuAccountCompanyUser(param.getCompanyId(), param.getCompanyUserId());
|
|
|
+ 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 courseUrl = buildCourseNewLink(param.getCompanyId(), param.getCompanyUserId(),
|
|
|
+ param.getCourseId(), param.getVideoId(), param.getUserId(), param.getLink());
|
|
|
+ docApiService.createIframeBlock(client, docId, courseUrl);
|
|
|
+ docApiService.changeDocumentPermissions(client, docId);
|
|
|
+
|
|
|
+ FsCourseLink fsCourseLink = courseLinkMapper.selectFsCourseLinkByLink(param.getLink());
|
|
|
+ //有视频短链+外部联系人id,需要缓存docId和account
|
|
|
+ if (fsCourseLink.getQwExternalId()!=null){
|
|
|
+ String docIdKey=FEISHU_DOC_ID + fsCourseLink.getQwExternalId()+ "_" + param.getVideoId();
|
|
|
+ redisCache.setCacheObject(docIdKey, docId,30,TimeUnit.DAYS);//30天过期
|
|
|
+ String accountKey = FEISHU_CLIENT+docId;
|
|
|
+ account.setCourseFillFlag(Boolean.TRUE);//这里要记录一下课程内容已填充
|
|
|
+ redisCache.setCacheObject(accountKey, account,30,TimeUnit.DAYS);;//30天过期
|
|
|
+ }
|
|
|
+ String result = "https://www.feishu.cn/docx/" + docId;
|
|
|
+ redisCache.setCacheObject(courseLinkKey, result, 72, TimeUnit.HOURS);
|
|
|
+ return result;
|
|
|
+ } catch (CustomException e) {
|
|
|
+ Integer code = e.getCode();
|
|
|
+ if (code == null) {
|
|
|
+ recordLinkError(param.getVideoId(), param.getCompanyId(), param.getCourseId(),
|
|
|
+ param.getCompanyUserId(), param.getLink(), e.getMessage(), 2);
|
|
|
+ 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(param.getVideoId(), param.getCompanyId(), param.getCourseId(),
|
|
|
+ param.getCompanyUserId(), param.getLink(), e.getMessage(), 2);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ recordLinkError(param.getVideoId(), param.getCompanyId(), param.getCourseId(),
|
|
|
+ param.getCompanyUserId(), param.getLink(), e.getMessage(), 2);
|
|
|
+ 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 courseUrl = buildCourseNewLink(param.getCompanyId(), param.getCompanyUserId(),
|
|
|
+ param.getCourseId(), param.getVideoId(), param.getUserId(), param.getLink());
|
|
|
+ docApiService.createIframeBlock(client, docId, courseUrl);
|
|
|
+ docApiService.changeDocumentPermissions(client, docId);
|
|
|
+ FsCourseLink fsCourseLink = courseLinkMapper.selectFsCourseLinkByLink(param.getLink());
|
|
|
+ if (fsCourseLink.getQwExternalId()!=null){
|
|
|
+ String docIdKey=FEISHU_DOC_ID + fsCourseLink.getQwExternalId()+ "_" + param.getVideoId();
|
|
|
+ redisCache.setCacheObject(docIdKey, docId,30,TimeUnit.DAYS);
|
|
|
+ String accountKey = FEISHU_CLIENT+docId;
|
|
|
+ account.setCourseFillFlag(Boolean.TRUE);//这里要记录一下课程内容已填充
|
|
|
+ redisCache.setCacheObject(accountKey, account,30,TimeUnit.DAYS);
|
|
|
+ }
|
|
|
+ String result = "https://www.feishu.cn/docx/" + docId;
|
|
|
+ redisCache.setCacheObject(courseLinkKey, result, 72, TimeUnit.HOURS);
|
|
|
+ return result;
|
|
|
+ } catch (CustomException e) {
|
|
|
+ Integer code = e.getCode();
|
|
|
+ if (code == null) {
|
|
|
+ recordLinkError(param.getVideoId(), param.getCompanyId(), param.getCourseId(),
|
|
|
+ param.getCompanyUserId(), param.getLink(), e.getMessage(), 2);
|
|
|
+ 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(param.getVideoId(), param.getCompanyId(), param.getCourseId(),
|
|
|
+ param.getCompanyUserId(), param.getLink(), e.getMessage(), 2);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ recordLinkError(param.getVideoId(), param.getCompanyId(), param.getCourseId(),
|
|
|
+ param.getCompanyUserId(), param.getLink(), e.getMessage(), 2);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ recordLinkError(param.getVideoId(), param.getCompanyId(), param.getCourseId(),
|
|
|
+ param.getCompanyUserId(), param.getLink(), "所有公共账号不可用", 2);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
// ==================== 生成飞书课程链接 ====================
|
|
|
|
|
|
public String getFeishuCourseNewLink(FeishuLinkParam param) {
|
|
|
@@ -234,8 +355,6 @@ public class FeiShuService {
|
|
|
if (userCourseVideo == null) {
|
|
|
throw new CustomException("视频不存在: " + param.getVideoId());
|
|
|
}
|
|
|
- Integer questionFlag = (StringUtils.isNotBlank(userCourseVideo.getQuestionBankId()) &&
|
|
|
- !"null".equals(userCourseVideo.getQuestionBankId())) ? 1 : 0;
|
|
|
|
|
|
// 1. 尝试个人账号
|
|
|
List<FeishuAccount> personalAccounts = getFeishuAccountCompanyUser(param.getCompanyId(), param.getCompanyUserId());
|
|
|
@@ -246,11 +365,11 @@ public class FeiShuService {
|
|
|
try {
|
|
|
String docId = docApiService.createDocument(client, userCourseVideo.getTitle());
|
|
|
String courseUrl = buildCourseNewLink(param.getCompanyId(), param.getCompanyUserId(),
|
|
|
- param.getCourseId(), param.getVideoId(), param.getUserId(), param.getLink(), questionFlag);
|
|
|
+ param.getCourseId(), param.getVideoId(), param.getUserId(), param.getLink());
|
|
|
docApiService.createIframeBlock(client, docId, courseUrl);
|
|
|
docApiService.changeDocumentPermissions(client, docId);
|
|
|
String result = "https://www.feishu.cn/docx/" + docId;
|
|
|
- redisCache.setCacheObject(cacheKey, result, 24, TimeUnit.HOURS);
|
|
|
+ redisCache.setCacheObject(cacheKey, result, 72, TimeUnit.HOURS);
|
|
|
return result;
|
|
|
} catch (CustomException e) {
|
|
|
Integer code = e.getCode();
|
|
|
@@ -287,11 +406,11 @@ public class FeiShuService {
|
|
|
try {
|
|
|
String docId = docApiService.createDocument(client, userCourseVideo.getTitle());
|
|
|
String courseUrl = buildCourseNewLink(param.getCompanyId(), param.getCompanyUserId(),
|
|
|
- param.getCourseId(), param.getVideoId(), param.getUserId(), param.getLink(), questionFlag);
|
|
|
+ param.getCourseId(), param.getVideoId(), param.getUserId(), param.getLink());
|
|
|
docApiService.createIframeBlock(client, docId, courseUrl);
|
|
|
docApiService.changeDocumentPermissions(client, docId);
|
|
|
String result = "https://www.feishu.cn/docx/" + docId;
|
|
|
- redisCache.setCacheObject(cacheKey, result, 24, TimeUnit.HOURS);
|
|
|
+ redisCache.setCacheObject(cacheKey, result, 72, TimeUnit.HOURS);
|
|
|
return result;
|
|
|
} catch (CustomException e) {
|
|
|
Integer code = e.getCode();
|
|
|
@@ -369,7 +488,7 @@ public class FeiShuService {
|
|
|
// ==================== URL构建 ====================
|
|
|
|
|
|
private String buildCourseNewLink(Long companyId, Long companyUserId, Long courseId,
|
|
|
- Long videoId, Long userId, String link, Integer questionFlag) {
|
|
|
+ Long videoId, Long userId, String link) {
|
|
|
CourseConfig config = getCourseConfig();
|
|
|
Map<String, Object> courseParam = new LinkedHashMap<>();
|
|
|
courseParam.put("companyUserId", companyUserId);
|
|
|
@@ -377,7 +496,6 @@ public class FeiShuService {
|
|
|
courseParam.put("companyId", companyId);
|
|
|
courseParam.put("courseId", courseId);
|
|
|
courseParam.put("link", link);
|
|
|
- courseParam.put("questionFlag", questionFlag);
|
|
|
FsCourseLink fsCourseLink = courseLinkMapper.selectFsCourseLinkByLink(link);
|
|
|
if (fsCourseLink == null) {
|
|
|
throw new CustomException("课程链接已过期");
|