refactor(系统设置): 优化项目批量添加成员的逻辑

This commit is contained in:
wxg0103 2023-07-28 15:33:17 +08:00 committed by 刘瑞斌
parent 5d06e1a82d
commit dd89cf0905
7 changed files with 144 additions and 68 deletions

View File

@ -407,4 +407,13 @@ http_result_validate=parameter validate failure
http_result_unauthorized=user authentication failure http_result_unauthorized=user authentication failure
http_result_forbidden=permission authentication failure http_result_forbidden=permission authentication failure
enum_value_valid_message=The enumeration value is invalid, must be enum_value_valid_message=The enumeration value is invalid, must be
#system project
project_admin=Project admin
project_member=Project member
project=Project
add=Add
delete=Delete
update=Update
project_is_not_exist=Project is not exist

View File

@ -407,9 +407,11 @@ http_result_forbidden=权限认证失败
enum_value_valid_message=枚举值不合法,必须为 enum_value_valid_message=枚举值不合法,必须为
project_admin=添加项目管理员 #system project
project_member=添加项目成员 project_admin=项目管理员
project_member=项目成员
project=项目 project=项目
add=添加 add=添加
delete=删除 delete=删除
update=更新 update=更新
project_is_not_exist=项目不存在

View File

@ -404,4 +404,13 @@ http_result_validate=參數校驗失敗
http_result_unauthorized=用戶認證失敗 http_result_unauthorized=用戶認證失敗
http_result_forbidden=權限認證失敗 http_result_forbidden=權限認證失敗
enum_value_valid_message=枚舉值不合法,必須為 enum_value_valid_message=枚舉值不合法,必須為
#system project
project_admin=項目管理員
project_member=項目成員
project=項目
add=添加
delete=删除
update=更新
project_is_not_exist=項目不存在

View File

@ -16,6 +16,7 @@ import io.metersphere.sdk.util.Pager;
import io.metersphere.sdk.util.SessionUtils; import io.metersphere.sdk.util.SessionUtils;
import io.metersphere.sdk.util.Translator; import io.metersphere.sdk.util.Translator;
import io.metersphere.system.dto.UserExtend; import io.metersphere.system.dto.UserExtend;
import io.metersphere.system.request.ProjectAddMemberBatchRequest;
import io.metersphere.system.request.ProjectAddMemberRequest; import io.metersphere.system.request.ProjectAddMemberRequest;
import io.metersphere.system.request.ProjectMemberRequest; import io.metersphere.system.request.ProjectMemberRequest;
import io.metersphere.system.request.ProjectRequest; import io.metersphere.system.request.ProjectRequest;
@ -107,7 +108,10 @@ public class SystemProjectController {
@RequiresPermissions(PermissionConstants.SYSTEM_ORGANIZATION_PROJECT_READ_UPDATE) @RequiresPermissions(PermissionConstants.SYSTEM_ORGANIZATION_PROJECT_READ_UPDATE)
@Operation(summary = "添加项目成员") @Operation(summary = "添加项目成员")
public void addProjectMember(@Validated @RequestBody ProjectAddMemberRequest request) { public void addProjectMember(@Validated @RequestBody ProjectAddMemberRequest request) {
systemProjectService.addProjectMember(request, SessionUtils.getUserId(), false, "/system/project/add-member", ProjectAddMemberBatchRequest batchRequest = new ProjectAddMemberBatchRequest();
batchRequest.setProjectIds(List.of(request.getProjectId()));
batchRequest.setUserIds(request.getUserIds());
systemProjectService.addProjectMember(batchRequest, SessionUtils.getUserId(), false, "/system/project/add-member",
OperationLogType.ADD.name(), HttpMethodConstants.POST.name(), Translator.get("add")); OperationLogType.ADD.name(), HttpMethodConstants.POST.name(), Translator.get("add"));
} }

View File

@ -0,0 +1,15 @@
package io.metersphere.system.request;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import java.util.List;
@Data
public class ProjectAddMemberBatchRequest extends ProjectAddMemberRequest{
@Schema(title = "项目ID集合", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{project.id.not_blank}")
private List<String> projectIds;
}

View File

@ -25,13 +25,17 @@ import io.metersphere.system.dto.UserExtend;
import io.metersphere.system.mapper.ExtSystemProjectMapper; import io.metersphere.system.mapper.ExtSystemProjectMapper;
import io.metersphere.system.mapper.UserMapper; import io.metersphere.system.mapper.UserMapper;
import io.metersphere.system.mapper.UserRoleRelationMapper; import io.metersphere.system.mapper.UserRoleRelationMapper;
import io.metersphere.system.request.ProjectAddMemberRequest; import io.metersphere.system.request.ProjectAddMemberBatchRequest;
import io.metersphere.system.request.ProjectMemberRequest; import io.metersphere.system.request.ProjectMemberRequest;
import io.metersphere.system.request.ProjectRequest; import io.metersphere.system.request.ProjectRequest;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -57,6 +61,8 @@ public class SystemProjectService {
private OperationLogService operationLogService; private OperationLogService operationLogService;
private final ProjectServiceInvoker serviceInvoker; private final ProjectServiceInvoker serviceInvoker;
@Resource
private SqlSessionFactory sqlSessionFactory;
private final static String prefix = "/system/project"; private final static String prefix = "/system/project";
private final static String addProject = prefix + "/add"; private final static String addProject = prefix + "/add";
@ -73,19 +79,16 @@ public class SystemProjectService {
} }
/** /**
* * @param addProjectDTO 添加项目的时候 默认给用户组添加管理员和成员的权限
* @param addProjectDTO
* 添加项目的时候 默认给用户组添加管理员和成员的权限
* @return * @return
*/ */
public Project add(AddProjectRequest addProjectDTO , String createUser) { public Project add(AddProjectRequest addProjectDTO, String createUser) {
//TODO 添加项目需要检查配额 这个需要等后续定下来补全逻辑
Project project = new Project(); Project project = new Project();
project.setId(UUID.randomUUID().toString()); project.setId(UUID.randomUUID().toString());
project.setName(addProjectDTO.getName()); project.setName(addProjectDTO.getName());
project.setOrganizationId(addProjectDTO.getOrganizationId()); project.setOrganizationId(addProjectDTO.getOrganizationId());
checkProjectExist(project); checkProjectExistByName(project);
project.setCreateTime(System.currentTimeMillis()); project.setCreateTime(System.currentTimeMillis());
project.setUpdateTime(System.currentTimeMillis()); project.setUpdateTime(System.currentTimeMillis());
project.setUpdateUser(createUser); project.setUpdateUser(createUser);
@ -93,14 +96,14 @@ public class SystemProjectService {
project.setEnable(addProjectDTO.getEnable()); project.setEnable(addProjectDTO.getEnable());
project.setDescription(addProjectDTO.getDescription()); project.setDescription(addProjectDTO.getDescription());
projectMapper.insertSelective(project); projectMapper.insertSelective(project);
ProjectAddMemberRequest memberRequest = new ProjectAddMemberRequest(); ProjectAddMemberBatchRequest memberRequest = new ProjectAddMemberBatchRequest();
memberRequest.setProjectId(project.getId()); memberRequest.setProjectIds(List.of(project.getId()));
memberRequest.setUserIds(addProjectDTO.getUserIds()); memberRequest.setUserIds(addProjectDTO.getUserIds());
this.addProjectMember(memberRequest, createUser, true, addProject, OperationLogType.ADD.name(), HttpMethodConstants.POST.name(), Translator.get("add")); this.addProjectMember(memberRequest, createUser, true, addProject, OperationLogType.ADD.name(), HttpMethodConstants.POST.name(), Translator.get("add"));
return project; return project;
} }
private void checkProjectExist(Project project) { private void checkProjectExistByName(Project project) {
ProjectExample example = new ProjectExample(); ProjectExample example = new ProjectExample();
example.createCriteria().andNameEqualTo(project.getName()).andOrganizationIdEqualTo(project.getOrganizationId()); example.createCriteria().andNameEqualTo(project.getName()).andOrganizationIdEqualTo(project.getOrganizationId());
if (projectMapper.selectByExample(example).size() > 0) { if (projectMapper.selectByExample(example).size() > 0) {
@ -108,6 +111,17 @@ public class SystemProjectService {
} }
} }
/**
* 检查项目是否存在
*
* @param id
*/
private void checkProjectNotExist(String id) {
if (projectMapper.selectByPrimaryKey(id) == null) {
throw new MSException(Translator.get("project_is_not_exist"));
}
}
public List<ProjectDTO> getProjectList(ProjectRequest request) { public List<ProjectDTO> getProjectList(ProjectRequest request) {
List<ProjectDTO> projectList = extSystemProjectMapper.getProjectList(request); List<ProjectDTO> projectList = extSystemProjectMapper.getProjectList(request);
return buildUserInfo(projectList); return buildUserInfo(projectList);
@ -132,10 +146,8 @@ public class SystemProjectService {
project.setCreateUser(null); project.setCreateUser(null);
project.setCreateTime(null); project.setCreateTime(null);
project.setUpdateTime(System.currentTimeMillis()); project.setUpdateTime(System.currentTimeMillis());
checkProjectExist(project); checkProjectExistByName(project);
if (ObjectUtils.isEmpty(projectMapper.selectByPrimaryKey(project.getId()))) { checkProjectNotExist(project.getId());
return null;
}
UserRoleRelationExample example = new UserRoleRelationExample(); UserRoleRelationExample example = new UserRoleRelationExample();
example.createCriteria().andSourceIdEqualTo(project.getId()).andRoleIdEqualTo(InternalUserRole.PROJECT_ADMIN.getValue()); example.createCriteria().andSourceIdEqualTo(project.getId()).andRoleIdEqualTo(InternalUserRole.PROJECT_ADMIN.getValue());
List<UserRoleRelation> userRoleRelations = userRoleRelationMapper.selectByExample(example); List<UserRoleRelation> userRoleRelations = userRoleRelationMapper.selectByExample(example);
@ -154,8 +166,8 @@ public class SystemProjectService {
userRoleRelationMapper.deleteByExample(deleteExample); userRoleRelationMapper.deleteByExample(deleteExample);
} }
if (CollectionUtils.isNotEmpty(insertIds)) { if (CollectionUtils.isNotEmpty(insertIds)) {
ProjectAddMemberRequest memberRequest = new ProjectAddMemberRequest(); ProjectAddMemberBatchRequest memberRequest = new ProjectAddMemberBatchRequest();
memberRequest.setProjectId(project.getId()); memberRequest.setProjectIds(List.of(project.getId()));
memberRequest.setUserIds(insertIds); memberRequest.setUserIds(insertIds);
this.addProjectMember(memberRequest, updateUser, true, updateProject, OperationLogType.UPDATE.name(), this.addProjectMember(memberRequest, updateUser, true, updateProject, OperationLogType.UPDATE.name(),
HttpMethodConstants.POST.name(), Translator.get("update")); HttpMethodConstants.POST.name(), Translator.get("update"));
@ -167,6 +179,7 @@ public class SystemProjectService {
public int delete(String id, String deleteUser) { public int delete(String id, String deleteUser) {
//TODO 删除项目删除全部资源 这里的删除只是假删除 //TODO 删除项目删除全部资源 这里的删除只是假删除
checkProjectNotExist(id);
Project project = new Project(); Project project = new Project();
project.setId(id); project.setId(id);
project.setDeleteUser(deleteUser); project.setDeleteUser(deleteUser);
@ -180,41 +193,62 @@ public class SystemProjectService {
return projectMemberList; return projectMemberList;
} }
public void addProjectMember(ProjectAddMemberRequest request, String createUser, boolean isAdmin, String path, String type, /***
* 添加项目成员
* @param request
* @param createUser
* @param isAdmin 是否需要创建管理员
* @param path 请求路径
* @param type 操作类型
* @param method 请求方法
* @param content 操作内容
*/
public void addProjectMember(ProjectAddMemberBatchRequest request, String createUser, boolean isAdmin, String path, String type,
String method, String content) { String method, String content) {
List<LogDTO> logDTOList = new ArrayList<>(); List<LogDTO> logDTOList = new ArrayList<>();
//TODO 添加项目成员需要检查配额 这个需要等后续定下来补全逻辑 SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
request.getUserIds().forEach(userId -> { UserRoleRelationMapper batchMapper = sqlSession.getMapper(UserRoleRelationMapper.class);
User user = userMapper.selectByPrimaryKey(userId); request.getProjectIds().forEach(projectId -> {
if (ObjectUtils.isEmpty(user)) { checkProjectNotExist(projectId);
throw new MSException(Translator.get("user_not_exist")); request.getUserIds().forEach(userId -> {
} User user = userMapper.selectByPrimaryKey(userId);
if (isAdmin) { if (ObjectUtils.isEmpty(user)) {
UserRoleRelation adminRole = new UserRoleRelation( throw new MSException(Translator.get("user_not_exist"));
UUID.randomUUID().toString(), }
userId, if (isAdmin) {
InternalUserRole.PROJECT_ADMIN.getValue(), UserRoleRelationExample userRoleRelationExample = new UserRoleRelationExample();
request.getProjectId(), userRoleRelationExample.createCriteria().andUserIdEqualTo(userId)
System.currentTimeMillis(), .andSourceIdEqualTo(projectId).andRoleIdEqualTo(InternalUserRole.PROJECT_MEMBER.getValue());
createUser); if (userRoleRelationMapper.selectByExample(userRoleRelationExample).size() == 0) {
userRoleRelationMapper.insertSelective(adminRole); UserRoleRelation adminRole = new UserRoleRelation(
setLog(request.getProjectId(), path, content + Translator.get("project_admin") +": "+ user.getName(), createUser, "", type, method, logDTOList); UUID.randomUUID().toString(),
} userId,
UserRoleRelationExample userRoleRelationExample = new UserRoleRelationExample(); InternalUserRole.PROJECT_ADMIN.getValue(),
userRoleRelationExample.createCriteria().andUserIdEqualTo(userId) projectId,
.andSourceIdEqualTo(request.getProjectId()).andRoleIdEqualTo(InternalUserRole.PROJECT_MEMBER.getValue()); System.currentTimeMillis(),
if (userRoleRelationMapper.selectByExample(userRoleRelationExample).size() == 0) { createUser);
UserRoleRelation memberRole = new UserRoleRelation( batchMapper.insert(adminRole);
UUID.randomUUID().toString(), setLog(projectId, path, content + Translator.get("project_admin") + ": " + user.getName(), createUser, "", type, method, logDTOList);
userId, }
InternalUserRole.PROJECT_MEMBER.getValue(), }
request.getProjectId(), UserRoleRelationExample userRoleRelationExample = new UserRoleRelationExample();
System.currentTimeMillis(), userRoleRelationExample.createCriteria().andUserIdEqualTo(userId)
createUser); .andSourceIdEqualTo(projectId).andRoleIdEqualTo(InternalUserRole.PROJECT_MEMBER.getValue());
userRoleRelationMapper.insertSelective(memberRole); if (userRoleRelationMapper.selectByExample(userRoleRelationExample).size() == 0) {
setLog(request.getProjectId(), path, content + Translator.get("project_member")+": "+ user.getName(), createUser, "", type, method, logDTOList); UserRoleRelation memberRole = new UserRoleRelation(
} UUID.randomUUID().toString(),
userId,
InternalUserRole.PROJECT_MEMBER.getValue(),
projectId,
System.currentTimeMillis(),
createUser);
batchMapper.insert(memberRole);
setLog(projectId, path, content + Translator.get("project_member") + ": " + user.getName(), createUser, "", type, method, logDTOList);
}
});
sqlSession.flushStatements();
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
}); });
operationLogService.batchAdd(logDTOList); operationLogService.batchAdd(logDTOList);
} }
@ -229,14 +263,15 @@ public class SystemProjectService {
userMapper.updateByPrimaryKeySelective(user); userMapper.updateByPrimaryKeySelective(user);
} }
List<LogDTO> logDTOList = new ArrayList<>(); List<LogDTO> logDTOList = new ArrayList<>();
setLog(projectId, removeProjectMember + "/" + projectId + "/" +userId, setLog(projectId, removeProjectMember + "/" + projectId + "/" + userId,
Translator.get("delete") + Translator.get("project_member") +": "+ user.getName(), Translator.get("delete") + Translator.get("project_member") + ": " + user.getName(),
userId, "", OperationLogType.DELETE.name() , HttpMethodConstants.GET.name(), logDTOList); userId, "", OperationLogType.DELETE.name(), HttpMethodConstants.GET.name(), logDTOList);
operationLogService.batchAdd(logDTOList); operationLogService.batchAdd(logDTOList);
return userRoleRelationMapper.deleteByExample(userRoleRelationExample); return userRoleRelationMapper.deleteByExample(userRoleRelationExample);
} }
public int revoke(String id) { public int revoke(String id) {
checkProjectNotExist(id);
Project project = new Project(); Project project = new Project();
project.setId(id); project.setId(id);
project.setDeleted(false); project.setDeleted(false);
@ -271,7 +306,7 @@ public class SystemProjectService {
return extSystemProjectMapper.selectProjectOptions(); return extSystemProjectMapper.selectProjectOptions();
} }
private static void setLog( String projectId, String path, String content, String userId, Object originalValue, private static void setLog(String projectId, String path, String content, String userId, Object originalValue,
String type, String method, List<LogDTO> logDTOList) { String type, String method, List<LogDTO> logDTOList) {
LogDTO dto = new LogDTO( LogDTO dto = new LogDTO(
"system", "system",

View File

@ -100,6 +100,14 @@ public class SystemProjectControllerTests extends BaseTest {
.andExpect(status().isOk()).andDo(print()) .andExpect(status().isOk()).andDo(print())
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn(); .andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
} }
private void responseGet(String url, ResultMatcher resultMatcher) throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get(url)
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(resultMatcher).andDo(print())
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
}
public static <T> T parseObjectFromMvcResult(MvcResult mvcResult, Class<T> parseClass) { public static <T> T parseObjectFromMvcResult(MvcResult mvcResult, Class<T> parseClass) {
try { try {
@ -338,10 +346,7 @@ public class SystemProjectControllerTests extends BaseTest {
this.requestPost(updateProject, project, BAD_REQUEST_MATCHER); this.requestPost(updateProject, project, BAD_REQUEST_MATCHER);
//项目不存在 //项目不存在
project = this.generatorUpdate("organizationId", "1111","123", null, true, List.of("admin")); project = this.generatorUpdate("organizationId", "1111","123", null, true, List.of("admin"));
MvcResult mvcResult = this.responsePost(updateProject, project); this.requestPost(updateProject, project, ERROR_REQUEST_MATCHER);
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
Assertions.assertNull(resultHolder.getData());
} }
@ -363,9 +368,7 @@ public class SystemProjectControllerTests extends BaseTest {
@Order(10) @Order(10)
public void testDeleteProjectError() throws Exception { public void testDeleteProjectError() throws Exception {
String id = "1111"; String id = "1111";
MvcResult mvcResult = this.responseGet(deleteProject + id); this.responseGet(deleteProject + id, ERROR_REQUEST_MATCHER);
int count = parseObjectFromMvcResult(mvcResult, Integer.class);
Assertions.assertTrue(count == 0);
} }
@Test @Test
@ -386,9 +389,7 @@ public class SystemProjectControllerTests extends BaseTest {
@Order(12) @Order(12)
public void testRevokeProjectError() throws Exception { public void testRevokeProjectError() throws Exception {
String id = "1111"; String id = "1111";
MvcResult mvcResult = this.responseGet(revokeProject + id); this.responseGet(revokeProject + id, ERROR_REQUEST_MATCHER);
int count = parseObjectFromMvcResult(mvcResult, Integer.class);
Assertions.assertTrue(count == 0);
} }
@Test @Test
@ -404,6 +405,7 @@ public class SystemProjectControllerTests extends BaseTest {
List<UserRoleRelation> userRoleRelations = userRoleRelationMapper.selectByExample(userRoleRelationExample); List<UserRoleRelation> userRoleRelations = userRoleRelationMapper.selectByExample(userRoleRelationExample);
Assertions.assertEquals(userRoleRelations.stream().map(UserRoleRelation::getUserId).collect(Collectors.toList()).containsAll(userIds), true); Assertions.assertEquals(userRoleRelations.stream().map(UserRoleRelation::getUserId).collect(Collectors.toList()).containsAll(userIds), true);
Assertions.assertTrue(userRoleRelations.stream().map(UserRoleRelation::getUserId).collect(Collectors.toList()).containsAll(userIds)); Assertions.assertTrue(userRoleRelations.stream().map(UserRoleRelation::getUserId).collect(Collectors.toList()).containsAll(userIds));
this.requestPost(addProjectMember, projectAddMemberRequest, status().isOk());
} }
@Test @Test