feat: 支持 Skill 仓库扫描与批量导入
- 统一支持本地单包、多包和 Git 候选最多 50 项导入 - 固定提交并限制 SSRF、DNS、并发、频率、超时和仓库资源 - 增加导入对话框、接口契约和安全回归测试
This commit is contained in:
@@ -16,6 +16,8 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
import tech.easyflow.admin.controller.ai.support.AiResourceCreatorNameSupport;
|
||||
import tech.easyflow.admin.controller.skill.vo.SkillCopyRequest;
|
||||
import tech.easyflow.admin.controller.skill.vo.SkillDraftRequest;
|
||||
import tech.easyflow.admin.controller.skill.vo.SkillGitRepositoryPrepareRequest;
|
||||
import tech.easyflow.admin.controller.skill.vo.SkillGitRepositoryScanRequest;
|
||||
import tech.easyflow.admin.controller.skill.vo.SkillImportBatchResultView;
|
||||
import tech.easyflow.admin.controller.skill.vo.SkillView;
|
||||
import tech.easyflow.admin.controller.skill.vo.SkillToolBindingUpdateRequest;
|
||||
@@ -39,6 +41,8 @@ import tech.easyflow.skill.imports.SkillExportService;
|
||||
import tech.easyflow.skill.imports.SkillImportConfirmRequest;
|
||||
import tech.easyflow.skill.imports.SkillImportPreview;
|
||||
import tech.easyflow.skill.imports.SkillImportService;
|
||||
import tech.easyflow.skill.gitimport.SkillGitImportService;
|
||||
import tech.easyflow.skill.gitimport.SkillGitScanResult;
|
||||
import tech.easyflow.skill.publish.SkillPublishAppService;
|
||||
import tech.easyflow.skill.security.SkillVisibilityQueryHelper;
|
||||
import tech.easyflow.skill.service.SkillApprovalStateService;
|
||||
@@ -77,6 +81,7 @@ public class SkillController {
|
||||
private final SkillApprovalStateService skillApprovalStateService;
|
||||
private final SkillPublishAppService skillPublishAppService;
|
||||
private final SkillImportService skillImportService;
|
||||
private final SkillGitImportService skillGitImportService;
|
||||
private final SkillExportService skillExportService;
|
||||
private final SkillFileService skillFileService;
|
||||
private final SkillToolBindingService skillToolBindingService;
|
||||
@@ -93,6 +98,7 @@ public class SkillController {
|
||||
* @param skillApprovalStateService 审批状态服务
|
||||
* @param skillPublishAppService 发布服务
|
||||
* @param skillImportService 导入服务
|
||||
* @param skillGitImportService Git 仓库导入服务
|
||||
* @param skillExportService 导出服务
|
||||
* @param skillFileService 文件服务
|
||||
* @param skillToolBindingService Skill Tool 绑定服务
|
||||
@@ -106,6 +112,7 @@ public class SkillController {
|
||||
SkillApprovalStateService skillApprovalStateService,
|
||||
SkillPublishAppService skillPublishAppService,
|
||||
SkillImportService skillImportService,
|
||||
SkillGitImportService skillGitImportService,
|
||||
SkillExportService skillExportService,
|
||||
SkillFileService skillFileService,
|
||||
SkillToolBindingService skillToolBindingService,
|
||||
@@ -118,6 +125,7 @@ public class SkillController {
|
||||
this.skillApprovalStateService = skillApprovalStateService;
|
||||
this.skillPublishAppService = skillPublishAppService;
|
||||
this.skillImportService = skillImportService;
|
||||
this.skillGitImportService = skillGitImportService;
|
||||
this.skillExportService = skillExportService;
|
||||
this.skillFileService = skillFileService;
|
||||
this.skillToolBindingService = skillToolBindingService;
|
||||
@@ -447,10 +455,43 @@ public class SkillController {
|
||||
if (uploads.isEmpty()) {
|
||||
throw new BusinessException("请选择要导入的标准 Skill ZIP");
|
||||
}
|
||||
if (uploads.size() > 20) {
|
||||
throw new BusinessException("单次最多预检 20 个 Skill ZIP");
|
||||
if (uploads.size() > SkillImportService.MAX_BATCH_SKILL_COUNT) {
|
||||
throw new BusinessException("单次最多选择 "
|
||||
+ SkillImportService.MAX_BATCH_SKILL_COUNT + " 个 Skill ZIP");
|
||||
}
|
||||
return Result.ok(uploads.stream().map(skillImportService::preview).toList());
|
||||
return Result.ok(skillImportService.previewBatch(uploads));
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫描 HTTPS Git 仓库中的标准 Skill 候选。
|
||||
*
|
||||
* @param request 仓库地址请求
|
||||
* @return 固定提交的候选列表
|
||||
*/
|
||||
@PostMapping("/import/repository/scan")
|
||||
@SaCheckPermission("/api/v1/skill/import")
|
||||
public Result<SkillGitScanResult> scanGitRepository(
|
||||
@JsonBody(required = true, skipConvertError = false) SkillGitRepositoryScanRequest request) {
|
||||
if (request == null) {
|
||||
throw new BusinessException("请输入 Git 仓库地址");
|
||||
}
|
||||
return Result.ok(skillGitImportService.scan(request.repositoryUrl()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将选中的 Git Skill 候选转换为既有标准 ZIP 导入预览。
|
||||
*
|
||||
* @param request 扫描令牌与候选 ID
|
||||
* @return 与本地 ZIP 导入一致的预览列表
|
||||
*/
|
||||
@PostMapping("/import/repository/prepare")
|
||||
@SaCheckPermission("/api/v1/skill/import")
|
||||
public Result<List<SkillImportPreview>> prepareGitRepositoryImport(
|
||||
@JsonBody(required = true, skipConvertError = false) SkillGitRepositoryPrepareRequest request) {
|
||||
if (request == null) {
|
||||
throw new BusinessException("请选择要导入的 Git Skill");
|
||||
}
|
||||
return Result.ok(skillGitImportService.prepare(request.scanToken(), request.candidateIds()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -479,8 +520,9 @@ public class SkillController {
|
||||
if (requests == null || requests.isEmpty()) {
|
||||
throw new BusinessException("请选择要确认导入的 Skill");
|
||||
}
|
||||
if (requests.size() > 20) {
|
||||
throw new BusinessException("单次最多确认导入 20 个 Skill");
|
||||
if (requests.size() > SkillImportService.MAX_BATCH_SKILL_COUNT) {
|
||||
throw new BusinessException("单次最多确认导入 "
|
||||
+ SkillImportService.MAX_BATCH_SKILL_COUNT + " 个 Skill");
|
||||
}
|
||||
List<SkillImportBatchResultView> results = new java.util.ArrayList<>(requests.size());
|
||||
for (SkillImportConfirmRequest request : requests) {
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package tech.easyflow.admin.controller.skill.vo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 选中 Git Skill 候选的标准导入预览准备请求。
|
||||
*
|
||||
* @param scanToken 短期扫描令牌
|
||||
* @param candidateIds 选中的候选 ID
|
||||
*/
|
||||
public record SkillGitRepositoryPrepareRequest(String scanToken, List<String> candidateIds) {
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package tech.easyflow.admin.controller.skill.vo;
|
||||
|
||||
/**
|
||||
* Git 仓库 Skill 扫描请求。
|
||||
*
|
||||
* @param repositoryUrl HTTPS Git 仓库地址,可省略 .git 后缀
|
||||
*/
|
||||
public record SkillGitRepositoryScanRequest(String repositoryUrl) {
|
||||
}
|
||||
Reference in New Issue
Block a user