feat(security): 添加权限检查的可见性兜底功能
- 在 CheckObjectPermission 注解中新增 visibilityFallback 属性,用于读路径的成员/可见性兜底 - 实现 checkPermissionOrVisibility 方法,支持成员权限码验证或用户可见性配置兜底两种方式 - 修改 ObjectPermissionAspect 切面逻辑,增加 visibilityFallback 条件分支处理 - 更新项目执行和任务相关的服务类,在查询注解中启用 visibilityFallback 功能 - 添加完整的单元测试覆盖 visibilityFallback 的各种场景,包括成员权限、可见性配置等 - 集成用户可见性配置 API,支持按方向代码进行可见性判断
This commit is contained in:
@@ -38,4 +38,11 @@ public @interface CheckObjectPermission {
|
||||
*/
|
||||
boolean accessible() default false;
|
||||
|
||||
/**
|
||||
* 读路径专用:成员凭 {@link #permission()} 查询权限码,否则凭「用户可见性配置」(system_user_visibility_config) 兜底。
|
||||
* 为 true 时切面调用 checkPermissionOrVisibility,需与 permission 同时给值。
|
||||
* 优先级:accessible > visibilityFallback > memberOnly > permission。仅用于读接口,写路径禁用。
|
||||
*/
|
||||
boolean visibilityFallback() default false;
|
||||
|
||||
}
|
||||
|
||||
@@ -41,9 +41,11 @@ public class ObjectPermissionAspect {
|
||||
throw invalidParamException("暂不支持对象类型:{}", checkObjectPermission.objectType());
|
||||
}
|
||||
Long objectId = resolveObjectId(joinPoint, checkObjectPermission.objectId());
|
||||
// 分发优先级:accessible(可访问性门禁)> memberOnly / permission(权限码)
|
||||
// 分发优先级:accessible(可访问性门禁)> visibilityFallback(读路径成员/可见性兜底)> memberOnly / permission(权限码)
|
||||
if (checkObjectPermission.accessible()) {
|
||||
permissionService.checkAccessible(objectId);
|
||||
} else if (checkObjectPermission.visibilityFallback()) {
|
||||
permissionService.checkPermissionOrVisibility(objectId, checkObjectPermission.permission());
|
||||
} else {
|
||||
permissionService.checkPermission(objectId, checkObjectPermission.permission(),
|
||||
checkObjectPermission.memberOnly());
|
||||
|
||||
@@ -39,4 +39,15 @@ public interface ObjectPermissionService {
|
||||
*/
|
||||
void checkAccessible(Long objectId);
|
||||
|
||||
/**
|
||||
* 读路径鉴权(成员 OR 可见性配置兜底):
|
||||
* 成员凭 permission 权限码放行;非成员 / 成员无该权限码时,凭用户可见性配置(通道 3,
|
||||
* type=all 或方向命中)放行;都不满足抛 ..._OBJECT_PERMISSION_DENIED。
|
||||
* 仅用于对象内读接口,不调超管短路 / 组织负责人通道 / 完整数据范围。
|
||||
*
|
||||
* @param objectId 对象编号(如 projectId)
|
||||
* @param permission 权限码,如 {@code project:task:query}
|
||||
*/
|
||||
void checkPermissionOrVisibility(Long objectId, String permission);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.njcn.rdms.module.project.framework.security.service;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.njcn.rdms.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import com.njcn.rdms.module.project.constant.ObjectRoleConstants;
|
||||
import com.njcn.rdms.module.project.constant.ProductObjectConstants;
|
||||
@@ -11,6 +12,8 @@ import com.njcn.rdms.module.project.enums.ErrorCodeConstants;
|
||||
import com.njcn.rdms.module.project.service.datascope.ObjectDataScope;
|
||||
import com.njcn.rdms.module.project.service.datascope.ObjectDataScopeService;
|
||||
import com.njcn.rdms.module.system.api.permission.ObjectPermissionApi;
|
||||
import com.njcn.rdms.module.system.api.permission.UserVisibilityConfigApi;
|
||||
import com.njcn.rdms.module.system.api.permission.dto.UserVisibilityConfigRespDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -40,6 +43,8 @@ public class ProductObjectPermissionService implements ObjectPermissionService {
|
||||
private ProductMapper productMapper;
|
||||
@Resource
|
||||
private ObjectDataScopeService objectDataScopeService;
|
||||
@Resource
|
||||
private UserVisibilityConfigApi userVisibilityConfigApi;
|
||||
|
||||
@Override
|
||||
public String getObjectType() {
|
||||
@@ -55,6 +60,49 @@ public class ProductObjectPermissionService implements ObjectPermissionService {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkPermissionOrVisibility(Long objectId, String permission) {
|
||||
if (objectId == null) {
|
||||
throw invalidParamException("对象编号不能为空");
|
||||
}
|
||||
Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
|
||||
// 1) 成员 + 权限码
|
||||
List<UserObjectRoleDO> userRoles = userObjectRoleMapper
|
||||
.selectActiveListByObjectAndUserId(ProductObjectConstants.OBJECT_TYPE, objectId, loginUserId);
|
||||
if (!userRoles.isEmpty()) {
|
||||
String normalizedPermission = normalizePermission(permission);
|
||||
boolean allowed = userRoles.stream()
|
||||
.map(UserObjectRoleDO::getRoleId)
|
||||
.distinct()
|
||||
.anyMatch(roleId -> getRolePermissions(roleId).contains(normalizedPermission));
|
||||
if (allowed) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 2) 用户可见性配置兜底(按产品方向命中)
|
||||
if (visibleByUserVisibilityConfig(loginUserId, objectId)) {
|
||||
return;
|
||||
}
|
||||
// 3) 脱敏抛异常
|
||||
log.warn("[checkPermissionOrVisibility] 无读权限,objectId={}, permission={}", objectId, permission);
|
||||
throw exception(ErrorCodeConstants.PRODUCT_OBJECT_PERMISSION_DENIED);
|
||||
}
|
||||
|
||||
private boolean visibleByUserVisibilityConfig(Long loginUserId, Long productId) {
|
||||
UserVisibilityConfigRespDTO cfg = userVisibilityConfigApi.getConfig(loginUserId).getCheckedData();
|
||||
if (cfg == null) {
|
||||
return false;
|
||||
}
|
||||
if ("all".equals(cfg.getType())) {
|
||||
return true;
|
||||
}
|
||||
if ("directions".equals(cfg.getType()) && CollUtil.isNotEmpty(cfg.getDirectionCodes())) {
|
||||
ProductDO product = productMapper.selectById(productId);
|
||||
return product != null && cfg.getDirectionCodes().contains(product.getDirectionCode());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkPermission(Long objectId, String permission, boolean memberOnly) {
|
||||
if (objectId == null) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.njcn.rdms.module.project.framework.security.service;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.njcn.rdms.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import com.njcn.rdms.module.project.constant.ObjectRoleConstants;
|
||||
@@ -12,6 +13,8 @@ import com.njcn.rdms.module.project.enums.ErrorCodeConstants;
|
||||
import com.njcn.rdms.module.project.service.datascope.ObjectDataScope;
|
||||
import com.njcn.rdms.module.project.service.datascope.ObjectDataScopeService;
|
||||
import com.njcn.rdms.module.system.api.permission.ObjectPermissionApi;
|
||||
import com.njcn.rdms.module.system.api.permission.UserVisibilityConfigApi;
|
||||
import com.njcn.rdms.module.system.api.permission.dto.UserVisibilityConfigRespDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -41,6 +44,8 @@ public class ProjectObjectPermissionService implements ObjectPermissionService {
|
||||
private ProjectMapper projectMapper;
|
||||
@Resource
|
||||
private ObjectDataScopeService objectDataScopeService;
|
||||
@Resource
|
||||
private UserVisibilityConfigApi userVisibilityConfigApi;
|
||||
|
||||
@Override
|
||||
public String getObjectType() {
|
||||
@@ -129,6 +134,53 @@ public class ProjectObjectPermissionService implements ObjectPermissionService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkPermissionOrVisibility(Long objectId, String permission) {
|
||||
if (objectId == null) {
|
||||
throw invalidParamException("对象编号不能为空");
|
||||
}
|
||||
Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
|
||||
// 1) 成员 + 权限码:沿用 checkPermission 口径(成员里仍按 query 权限码细分)
|
||||
List<UserObjectRoleDO> userRoles = userObjectRoleMapper
|
||||
.selectActiveListByObjectAndUserId(ProjectObjectConstants.OBJECT_TYPE, objectId, loginUserId);
|
||||
if (!userRoles.isEmpty()) {
|
||||
String normalizedPermission = normalizePermission(permission);
|
||||
boolean allowed = userRoles.stream()
|
||||
.map(UserObjectRoleDO::getRoleId)
|
||||
.distinct()
|
||||
.anyMatch(roleId -> getRolePermissions(roleId).contains(normalizedPermission));
|
||||
if (allowed) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 2) 非成员 / 成员无该权限码:落用户可见性配置兜底(只查通道 3,不开超管短路 / 组织负责人 / 完整 scope)
|
||||
if (visibleByUserVisibilityConfig(loginUserId, objectId)) {
|
||||
return;
|
||||
}
|
||||
// 3) 都不满足:脱敏抛异常(权限码 / 配置只进日志,见 用户可见错误文案规范)
|
||||
log.warn("[checkPermissionOrVisibility] 无读权限,objectId={}, permission={}", objectId, permission);
|
||||
throw exception(ErrorCodeConstants.PROJECT_OBJECT_PERMISSION_DENIED);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户可见性配置(通道 3)兜底:type=all 直接放行;type=directions 时项目方向命中放行。
|
||||
* 不消费 type=projects(与现有数据范围口径一致)。
|
||||
*/
|
||||
private boolean visibleByUserVisibilityConfig(Long loginUserId, Long projectId) {
|
||||
UserVisibilityConfigRespDTO cfg = userVisibilityConfigApi.getConfig(loginUserId).getCheckedData();
|
||||
if (cfg == null) {
|
||||
return false;
|
||||
}
|
||||
if ("all".equals(cfg.getType())) {
|
||||
return true;
|
||||
}
|
||||
if ("directions".equals(cfg.getType()) && CollUtil.isNotEmpty(cfg.getDirectionCodes())) {
|
||||
ProjectDO project = projectMapper.selectById(projectId);
|
||||
return project != null && cfg.getDirectionCodes().contains(project.getDirectionCode());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Set<String> getRolePermissions(Long roleId) {
|
||||
Set<String> permissions = objectPermissionApi
|
||||
.getObjectRolePermissions(roleId, ObjectRoleConstants.ROLE_SCOPE_OBJECT, ProjectObjectConstants.OBJECT_TYPE)
|
||||
|
||||
@@ -46,7 +46,7 @@ public class ProjectStatusBoardServiceImpl implements ProjectStatusBoardService
|
||||
|
||||
@Override
|
||||
@CheckObjectPermission(objectType = ProjectObjectConstants.OBJECT_TYPE, objectId = "#projectId",
|
||||
permission = ProjectExecutionConstants.PERMISSION_QUERY)
|
||||
permission = ProjectExecutionConstants.PERMISSION_QUERY, visibilityFallback = true)
|
||||
public ProjectExecutionStatusBoardRespVO getExecutionStatusBoard(Long projectId, ProjectExecutionStatusBoardReqVO reqVO) {
|
||||
List<ObjectStatusModelDO> statusModels = objectStatusModelMapper.selectListByObjectTypeEnabled(ProjectExecutionConstants.OBJECT_TYPE);
|
||||
return buildExecutionStatusBoard(projectId, reqVO, statusModels);
|
||||
@@ -54,7 +54,7 @@ public class ProjectStatusBoardServiceImpl implements ProjectStatusBoardService
|
||||
|
||||
@Override
|
||||
@CheckObjectPermission(objectType = ProjectObjectConstants.OBJECT_TYPE, objectId = "#projectId",
|
||||
permission = ProjectTaskConstants.PERMISSION_QUERY)
|
||||
permission = ProjectTaskConstants.PERMISSION_QUERY, visibilityFallback = true)
|
||||
public ProjectTaskStatusBoardRespVO getTaskStatusBoard(Long projectId, Long executionId, ProjectTaskStatusBoardReqVO reqVO) {
|
||||
List<ObjectStatusModelDO> statusModels = objectStatusModelMapper.selectListByObjectTypeEnabled(ProjectTaskConstants.OBJECT_TYPE);
|
||||
return buildTaskStatusBoard(projectId, executionId, reqVO, statusModels);
|
||||
@@ -62,7 +62,7 @@ public class ProjectStatusBoardServiceImpl implements ProjectStatusBoardService
|
||||
|
||||
@Override
|
||||
@CheckObjectPermission(objectType = ProjectObjectConstants.OBJECT_TYPE, objectId = "#projectId",
|
||||
permission = ProjectTaskConstants.PERMISSION_QUERY)
|
||||
permission = ProjectTaskConstants.PERMISSION_QUERY, visibilityFallback = true)
|
||||
public ProjectTaskBoardPageRespVO getTaskBoardPage(Long projectId, Long executionId, ProjectTaskBoardPageReqVO reqVO) {
|
||||
List<ObjectStatusModelDO> statusModels = objectStatusModelMapper
|
||||
.selectListByObjectTypeEnabled(ProjectTaskConstants.OBJECT_TYPE);
|
||||
|
||||
@@ -79,7 +79,7 @@ public class ProjectExecutionAssigneeServiceImpl implements ProjectExecutionAssi
|
||||
|
||||
@Override
|
||||
@CheckObjectPermission(objectType = ProjectObjectConstants.OBJECT_TYPE, objectId = "#projectId",
|
||||
permission = ProjectExecutionConstants.PERMISSION_QUERY)
|
||||
permission = ProjectExecutionConstants.PERMISSION_QUERY, visibilityFallback = true)
|
||||
public List<ExecutionAssigneeRespVO> getExecutionAssigneeList(Long projectId, Long executionId) {
|
||||
validateProjectExists(projectId);
|
||||
validateExecutionExists(projectId, executionId);
|
||||
@@ -153,7 +153,7 @@ public class ProjectExecutionAssigneeServiceImpl implements ProjectExecutionAssi
|
||||
|
||||
@Override
|
||||
@CheckObjectPermission(objectType = ProjectObjectConstants.OBJECT_TYPE, objectId = "#projectId",
|
||||
permission = ProjectExecutionConstants.PERMISSION_QUERY)
|
||||
permission = ProjectExecutionConstants.PERMISSION_QUERY, visibilityFallback = true)
|
||||
public PageResult<ExecutionAssigneeLogRespVO> getExecutionAssigneeLogPage(Long projectId, Long executionId,
|
||||
ExecutionAssigneeLogPageReqVO reqVO) {
|
||||
validateProjectExists(projectId);
|
||||
|
||||
@@ -212,7 +212,7 @@ public class ProjectExecutionServiceImpl implements ProjectExecutionService {
|
||||
|
||||
@Override
|
||||
@CheckObjectPermission(objectType = ProjectObjectConstants.OBJECT_TYPE, objectId = "#projectId",
|
||||
permission = ProjectExecutionConstants.PERMISSION_QUERY)
|
||||
permission = ProjectExecutionConstants.PERMISSION_QUERY, visibilityFallback = true)
|
||||
public PageResult<ProjectExecutionDO> getExecutionPage(Long projectId, ProjectExecutionPageReqVO reqVO) {
|
||||
validateProjectExists(projectId);
|
||||
// "我参与 / 所有"视角完全由前端发不发 reqVO.involveUserId 决定。
|
||||
@@ -227,7 +227,7 @@ public class ProjectExecutionServiceImpl implements ProjectExecutionService {
|
||||
|
||||
@Override
|
||||
@CheckObjectPermission(objectType = ProjectObjectConstants.OBJECT_TYPE, objectId = "#projectId",
|
||||
permission = ProjectExecutionConstants.PERMISSION_QUERY)
|
||||
permission = ProjectExecutionConstants.PERMISSION_QUERY, visibilityFallback = true)
|
||||
public ProjectExecutionRespVO getExecutionRespVO(Long projectId, Long executionId) {
|
||||
ProjectExecutionDO execution = getExecution(projectId, executionId);
|
||||
ProjectExecutionRespVO respVO = BeanUtils.toBean(execution, ProjectExecutionRespVO.class);
|
||||
@@ -241,7 +241,7 @@ public class ProjectExecutionServiceImpl implements ProjectExecutionService {
|
||||
|
||||
@Override
|
||||
@CheckObjectPermission(objectType = ProjectObjectConstants.OBJECT_TYPE, objectId = "#projectId",
|
||||
permission = ProjectExecutionConstants.PERMISSION_QUERY)
|
||||
permission = ProjectExecutionConstants.PERMISSION_QUERY, visibilityFallback = true)
|
||||
public PageResult<ProjectExecutionRespVO> getExecutionRespVOPage(Long projectId, ProjectExecutionPageReqVO reqVO) {
|
||||
PageResult<ProjectExecutionDO> pageResult = getExecutionPage(projectId, reqVO);
|
||||
PageResult<ProjectExecutionRespVO> voPageResult = BeanUtils.toBean(pageResult, ProjectExecutionRespVO.class);
|
||||
|
||||
@@ -68,7 +68,7 @@ public class ProjectTaskAggregateServiceImpl implements ProjectTaskAggregateServ
|
||||
|
||||
@Override
|
||||
@CheckObjectPermission(objectType = ProjectObjectConstants.OBJECT_TYPE, objectId = "#projectId",
|
||||
permission = ProjectTaskConstants.PERMISSION_QUERY)
|
||||
permission = ProjectTaskConstants.PERMISSION_QUERY, visibilityFallback = true)
|
||||
public PageResult<ProjectTaskRespVO> getAggregateTaskPage(Long projectId, ProjectTaskAggregatePageReqVO reqVO) {
|
||||
// 空数组语义短路:前端明确"按 0 个执行状态/执行 id 过滤" → 返空集合,不让 MyBatis 退化成"不过滤"
|
||||
if ((reqVO.getExecutionStatusCodes() != null && reqVO.getExecutionStatusCodes().isEmpty())
|
||||
@@ -91,7 +91,7 @@ public class ProjectTaskAggregateServiceImpl implements ProjectTaskAggregateServ
|
||||
|
||||
@Override
|
||||
@CheckObjectPermission(objectType = ProjectObjectConstants.OBJECT_TYPE, objectId = "#projectId",
|
||||
permission = ProjectTaskConstants.PERMISSION_QUERY)
|
||||
permission = ProjectTaskConstants.PERMISSION_QUERY, visibilityFallback = true)
|
||||
public ProjectTaskStatusBoardRespVO getAggregateTaskStatusBoard(Long projectId, ProjectTaskAggregateStatusBoardReqVO reqVO) {
|
||||
// 空数组语义短路:跳过 SQL,但保留状态列骨架(前端看板依赖全列表渲染),count 全部 0
|
||||
if ((reqVO.getExecutionStatusCodes() != null && reqVO.getExecutionStatusCodes().isEmpty())
|
||||
@@ -148,7 +148,7 @@ public class ProjectTaskAggregateServiceImpl implements ProjectTaskAggregateServ
|
||||
|
||||
@Override
|
||||
@CheckObjectPermission(objectType = ProjectObjectConstants.OBJECT_TYPE, objectId = "#projectId",
|
||||
permission = ProjectTaskConstants.PERMISSION_QUERY)
|
||||
permission = ProjectTaskConstants.PERMISSION_QUERY, visibilityFallback = true)
|
||||
public ProjectTaskBoardPageRespVO getAggregateTaskBoardPage(Long projectId, ProjectTaskAggregateBoardPageReqVO reqVO) {
|
||||
// 空数组语义短路:executionStatusCodes 或 executionIds 为空数组 → 该范围明确为空,跳过 SQL,保留列骨架(每列 list=[] / total=0)
|
||||
boolean emptyExecScope = (reqVO.getExecutionStatusCodes() != null && reqVO.getExecutionStatusCodes().isEmpty())
|
||||
@@ -238,7 +238,7 @@ public class ProjectTaskAggregateServiceImpl implements ProjectTaskAggregateServ
|
||||
|
||||
@Override
|
||||
@CheckObjectPermission(objectType = ProjectObjectConstants.OBJECT_TYPE, objectId = "#projectId",
|
||||
permission = ProjectTaskConstants.PERMISSION_QUERY)
|
||||
permission = ProjectTaskConstants.PERMISSION_QUERY, visibilityFallback = true)
|
||||
public ProjectTaskSummaryRespVO getAggregateTaskSummary(Long projectId, ProjectTaskSummaryReqVO reqVO) {
|
||||
LocalDate today = today();
|
||||
LocalDate weekStart = weekStart(today);
|
||||
|
||||
@@ -432,7 +432,7 @@ public class ProjectTaskServiceImpl implements ProjectTaskService {
|
||||
|
||||
@Override
|
||||
@CheckObjectPermission(objectType = ProjectObjectConstants.OBJECT_TYPE, objectId = "#projectId",
|
||||
permission = ProjectTaskConstants.PERMISSION_QUERY)
|
||||
permission = ProjectTaskConstants.PERMISSION_QUERY, visibilityFallback = true)
|
||||
public PageResult<ProjectTaskDO> getTaskPage(Long projectId, Long executionId, ProjectTaskPageReqVO reqVO) {
|
||||
validateExecutionExists(projectId, executionId);
|
||||
// 进得来 = 看执行下全部任务,"我参与 / 所有"由前端发不发 reqVO.ownerId / involveUserId 决定。
|
||||
@@ -443,7 +443,7 @@ public class ProjectTaskServiceImpl implements ProjectTaskService {
|
||||
|
||||
@Override
|
||||
@CheckObjectPermission(objectType = ProjectObjectConstants.OBJECT_TYPE, objectId = "#projectId",
|
||||
permission = ProjectTaskConstants.PERMISSION_QUERY)
|
||||
permission = ProjectTaskConstants.PERMISSION_QUERY, visibilityFallback = true)
|
||||
public ProjectTaskRespVO getTaskRespVO(Long projectId, Long executionId, Long taskId) {
|
||||
// 内联 validate,便于接住 execution 供前端 executionOwnerId 字段使用
|
||||
ProjectExecutionDO execution = validateExecutionExists(projectId, executionId);
|
||||
@@ -467,7 +467,7 @@ public class ProjectTaskServiceImpl implements ProjectTaskService {
|
||||
|
||||
@Override
|
||||
@CheckObjectPermission(objectType = ProjectObjectConstants.OBJECT_TYPE, objectId = "#projectId",
|
||||
permission = ProjectTaskConstants.PERMISSION_QUERY)
|
||||
permission = ProjectTaskConstants.PERMISSION_QUERY, visibilityFallback = true)
|
||||
public PageResult<ProjectTaskRespVO> getTaskRespVOPage(Long projectId, Long executionId, ProjectTaskPageReqVO reqVO) {
|
||||
PageResult<ProjectTaskDO> pageResult = getTaskPage(projectId, executionId, reqVO);
|
||||
return assembleTaskRespVOPage(projectId, executionId, pageResult);
|
||||
|
||||
@@ -70,7 +70,7 @@ public class TaskAssigneeServiceImpl implements TaskAssigneeService {
|
||||
|
||||
@Override
|
||||
@CheckObjectPermission(objectType = ProjectObjectConstants.OBJECT_TYPE, objectId = "#projectId",
|
||||
permission = ProjectTaskConstants.PERMISSION_QUERY)
|
||||
permission = ProjectTaskConstants.PERMISSION_QUERY, visibilityFallback = true)
|
||||
public List<TaskAssigneeRespVO> getAssigneeList(Long projectId, Long executionId, Long taskId) {
|
||||
validateExecutionAndTaskExists(projectId, executionId, taskId);
|
||||
List<TaskAssigneeDO> activeList = taskAssigneeMapper.selectActiveListByTaskId(taskId);
|
||||
@@ -124,7 +124,7 @@ public class TaskAssigneeServiceImpl implements TaskAssigneeService {
|
||||
|
||||
@Override
|
||||
@CheckObjectPermission(objectType = ProjectObjectConstants.OBJECT_TYPE, objectId = "#projectId",
|
||||
permission = ProjectTaskConstants.PERMISSION_QUERY)
|
||||
permission = ProjectTaskConstants.PERMISSION_QUERY, visibilityFallback = true)
|
||||
public PageResult<TaskAssigneeLogRespVO> getAssigneeLogPage(Long projectId, Long executionId, Long taskId,
|
||||
TaskAssigneeLogPageReqVO reqVO) {
|
||||
validateExecutionAndTaskExists(projectId, executionId, taskId);
|
||||
|
||||
@@ -80,7 +80,7 @@ public class TaskWorklogServiceImpl implements TaskWorklogService {
|
||||
|
||||
@Override
|
||||
@CheckObjectPermission(objectType = ProjectObjectConstants.OBJECT_TYPE, objectId = "#projectId",
|
||||
permission = ProjectTaskConstants.PERMISSION_QUERY)
|
||||
permission = ProjectTaskConstants.PERMISSION_QUERY, visibilityFallback = true)
|
||||
public PageResult<TaskWorklogRespVO> getWorklogPage(Long projectId, Long executionId, Long taskId,
|
||||
TaskWorklogPageReqVO reqVO) {
|
||||
validateExecutionAndTaskExists(projectId, executionId, taskId);
|
||||
|
||||
Reference in New Issue
Block a user