feat: 完善 Skill 管理与发布治理

- 实现标准资源存储、能力绑定及双格式导入导出

- 接入分类、可见范围、审批发布与资源权限校验

- 补充并发、租户隔离、安全边界和迁移契约测试
This commit is contained in:
2026-07-27 18:54:20 +08:00
parent aedefe6b5e
commit 2a9e882ac6
165 changed files with 23737 additions and 1088 deletions

View File

@@ -2,13 +2,43 @@ package tech.easyflow.system.permission.resource;
import java.math.BigInteger;
/**
* 可由统一资源权限服务判定可见性与动作权限的资源契约。
*/
public interface VisibilityResource {
/**
* 获取资源所属租户。
*
* @return 租户 ID
*/
BigInteger getTenantId();
/**
* 获取资源创建者。
*
* @return 创建者账号 ID
*/
BigInteger getCreatedBy();
/**
* 获取资源所属部门。
*
* @return 部门 ID
*/
BigInteger getDeptId();
/**
* 获取资源所属分类。
*
* @return 分类 ID未分类时可为空
*/
BigInteger getCategoryId();
/**
* 获取资源可见范围。
*
* @return 可见范围编码
*/
String getVisibilityScope();
}

View File

@@ -119,7 +119,7 @@ public class CategoryPermissionServiceImpl implements CategoryPermissionService
@Override
public void assertCategoryResourceVisible(String resourceType, BigInteger createdBy, BigInteger categoryId, String message) {
if (!canAccessCategory(resourceType, createdBy, categoryId)) {
throw new BusinessException(message == null ? "无权限访问该资源" : message);
throw new BusinessException(403, 403, message == null ? "无权限访问该资源" : message);
}
}

View File

@@ -53,6 +53,10 @@ public class ResourceAccessServiceImpl implements ResourceAccessService {
if (loginAccount == null || loginAccount.getId() == null) {
return false;
}
if (loginAccount.getTenantId() == null || resource.getTenantId() == null
|| !loginAccount.getTenantId().equals(resource.getTenantId())) {
return false;
}
BigInteger accountId = loginAccount.getId();
// 分享访问需要先完成密钥校验与审计,即使当前账号同时也是资源创建者或超管。
if (hasExtendedGrant(loginAccount, resourceType, resource, action)) {
@@ -67,6 +71,10 @@ public class ResourceAccessServiceImpl implements ResourceAccessService {
if (ResourceAction.MANAGE == action) {
return false;
}
if (CategoryResourceType.SKILL == resourceType && resource.getCategoryId() == null
&& categoryPermissionService.getAccess(resourceType.getCode(), loginAccount).isAllAccess()) {
return true;
}
if (!categoryPermissionService.canAccessCategory(loginAccount, resourceType.getCode(), resource.getCreatedBy(), resource.getCategoryId())) {
return false;
}