feat(permission): 新增对象权限API接口及实现

- 定义ObjectPermissionApi接口提供对象作用域权限查询功能
- 实现ObjectPermissionApiImpl提供角色权限查询和转换逻辑
- 添加ObjectMenuRespDTO、ObjectRoleRespDTO和ObjectRolePermissionRespDTO数据传输对象
- 实现按角色ID、角色编码查询对象作用域角色及权限的功能
- 提供获取对象作用域角色菜单与权限聚合结果的方法
- 添加完整单元测试覆盖对象权限API的主要业务场景
This commit is contained in:
2026-04-23 09:23:33 +08:00
parent 156728b1b9
commit 0a6d70f7cf
7 changed files with 924 additions and 0 deletions

View File

@@ -0,0 +1,166 @@
package com.njcn.rdms.module.project.service.product;
import com.njcn.rdms.framework.common.exception.ServiceException;
import com.njcn.rdms.framework.test.core.ut.BaseMockitoUnitTest;
import com.njcn.rdms.module.project.controller.admin.product.vo.member.ProductMemberRespVO;
import com.njcn.rdms.module.project.controller.admin.product.vo.member.ProductMemberSaveReqVO;
import com.njcn.rdms.module.project.controller.admin.product.vo.member.ProductMemberUpdateReqVO;
import com.njcn.rdms.module.project.dal.dataobject.audit.BizAuditLogDO;
import com.njcn.rdms.module.project.dal.dataobject.member.UserObjectRoleDO;
import com.njcn.rdms.module.project.dal.dataobject.product.ProductDO;
import com.njcn.rdms.module.project.dal.mysql.audit.BizAuditLogMapper;
import com.njcn.rdms.module.project.dal.mysql.member.UserObjectRoleMapper;
import com.njcn.rdms.module.project.dal.mysql.product.ProductMapper;
import com.njcn.rdms.module.project.enums.ErrorCodeConstants;
import com.njcn.rdms.module.system.api.permission.ObjectPermissionApi;
import com.njcn.rdms.module.system.api.permission.dto.ObjectRoleRespDTO;
import com.njcn.rdms.module.system.api.user.AdminUserApi;
import com.njcn.rdms.module.system.api.user.dto.AdminUserRespDTO;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static com.njcn.rdms.framework.common.pojo.CommonResult.success;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
class ProductMemberServiceImplTest extends BaseMockitoUnitTest {
@InjectMocks
private ProductMemberServiceImpl productMemberService;
@Mock
private ProductMapper productMapper;
@Mock
private UserObjectRoleMapper userObjectRoleMapper;
@Mock
private ObjectPermissionApi objectPermissionApi;
@Mock
private BizAuditLogMapper bizAuditLogMapper;
@Mock
private AdminUserApi adminUserApi;
@Test
void getProductMemberList_shouldFillRoleNameAndRoleCodeFromObjectPermissionApi() {
Long productId = 1001L;
ProductDO product = createProduct(productId, 2001L);
UserObjectRoleDO manager = createMember(9001L, productId, 2001L, 3101L, 0);
UserObjectRoleDO member = createMember(9002L, productId, 2002L, 3102L, 0);
when(productMapper.selectById(productId)).thenReturn(product);
when(userObjectRoleMapper.selectListByObject("product", productId)).thenReturn(List.of(manager, member));
when(objectPermissionApi.getObjectRoleList(Set.of(3101L, 3102L), "object", "product"))
.thenReturn(success(List.of(
createRole(3101L, "product_manager", "产品经理"),
createRole(3102L, "product_member", "产品成员")
)));
when(adminUserApi.getUserMap(Set.of(2001L, 2002L))).thenReturn(Map.of(
2001L, createUser("经理甲"),
2002L, createUser("成员乙")
));
List<ProductMemberRespVO> respVOList = productMemberService.getProductMemberList(productId);
assertEquals(2, respVOList.size());
assertEquals("产品经理", respVOList.get(0).getRoleName());
assertEquals("product_manager", respVOList.get(0).getRoleCode());
assertEquals(Boolean.TRUE, respVOList.get(0).getManagerFlag());
assertEquals("产品成员", respVOList.get(1).getRoleName());
assertEquals("product_member", respVOList.get(1).getRoleCode());
assertFalse(respVOList.get(1).getManagerFlag());
}
@Test
void createProductMember_whenRoleSummaryMissing_shouldThrowRoleInvalid() {
Long productId = 1002L;
ProductMemberSaveReqVO reqVO = new ProductMemberSaveReqVO();
reqVO.setUserId(2003L);
reqVO.setRoleId(3999L);
when(productMapper.selectById(productId)).thenReturn(createProduct(productId, 2001L));
when(objectPermissionApi.getObjectRoleById(3999L, "object", "product")).thenReturn(success(null));
ServiceException ex = assertThrows(ServiceException.class,
() -> productMemberService.createProductMember(productId, reqVO));
assertEquals(ErrorCodeConstants.PRODUCT_MEMBER_ROLE_INVALID.getCode(), ex.getCode());
verify(userObjectRoleMapper, never()).selectByObjectAndUserId(any(), any(), any());
}
@Test
void updateProductMember_whenPreviousManagerRoleCodeStillManager_shouldThrowException() {
Long productId = 1003L;
Long memberId = 9003L;
Long currentManagerUserId = 2001L;
Long targetManagerRoleId = 3201L;
Long previousManagerRoleId = 3202L;
ProductMemberUpdateReqVO reqVO = new ProductMemberUpdateReqVO();
reqVO.setRoleId(targetManagerRoleId);
reqVO.setPreviousManagerUserId(currentManagerUserId);
reqVO.setPreviousManagerRoleId(previousManagerRoleId);
reqVO.setReason("角色交接");
ProductDO product = createProduct(productId, currentManagerUserId);
UserObjectRoleDO member = createMember(memberId, productId, 2002L, 3203L, 0);
when(productMapper.selectById(productId)).thenReturn(product);
when(userObjectRoleMapper.selectByIdAndObject(memberId, "product", productId)).thenReturn(member);
when(objectPermissionApi.getObjectRoleById(targetManagerRoleId, "object", "product"))
.thenReturn(success(createRole(targetManagerRoleId, "product_manager", "产品经理")));
when(objectPermissionApi.getObjectRoleById(previousManagerRoleId, "object", "product"))
.thenReturn(success(createRole(previousManagerRoleId, "product_manager", "产品经理")));
ServiceException ex = assertThrows(ServiceException.class,
() -> productMemberService.updateProductMember(productId, memberId, reqVO));
assertEquals(ErrorCodeConstants.PRODUCT_MANAGER_TRANSFER_ROLE_INVALID.getCode(), ex.getCode());
verify(userObjectRoleMapper).updateById(member);
verify(productMapper, never()).updateById(any(ProductDO.class));
verify(bizAuditLogMapper, never()).insert(any(BizAuditLogDO.class));
}
private ProductDO createProduct(Long productId, Long managerUserId) {
ProductDO product = new ProductDO();
product.setId(productId);
product.setManagerUserId(managerUserId);
product.setStatusCode("active");
product.setName("测试产品");
product.setCode("CNPD2026001");
return product;
}
private UserObjectRoleDO createMember(Long memberId, Long productId, Long userId, Long roleId, Integer status) {
UserObjectRoleDO member = new UserObjectRoleDO();
member.setId(memberId);
member.setObjectType("product");
member.setObjectId(productId);
member.setUserId(userId);
member.setRoleId(roleId);
member.setStatus(status);
member.setJoinedTime(LocalDateTime.now());
return member;
}
private ObjectRoleRespDTO createRole(Long roleId, String roleCode, String roleName) {
ObjectRoleRespDTO role = new ObjectRoleRespDTO();
role.setId(roleId);
role.setCode(roleCode);
role.setName(roleName);
role.setScopeType("object");
role.setObjectType("product");
return role;
}
private AdminUserRespDTO createUser(String nickname) {
AdminUserRespDTO user = new AdminUserRespDTO();
user.setNickname(nickname);
return user;
}
}