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

@ -408,3 +408,12 @@ http_result_unauthorized=user authentication failure
http_result_forbidden=permission authentication failure
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=枚举值不合法,必须为
project_admin=添加项目管理员
project_member=添加项目成员
#system project
project_admin=项目管理员
project_member=项目成员
project=项目
add=添加
delete=删除
update=更新
project_is_not_exist=项目不存在

View File

@ -405,3 +405,12 @@ http_result_unauthorized=用戶認證失敗
http_result_forbidden=權限認證失敗
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.Translator;
import io.metersphere.system.dto.UserExtend;
import io.metersphere.system.request.ProjectAddMemberBatchRequest;
import io.metersphere.system.request.ProjectAddMemberRequest;
import io.metersphere.system.request.ProjectMemberRequest;
import io.metersphere.system.request.ProjectRequest;
@ -107,7 +108,10 @@ public class SystemProjectController {
@RequiresPermissions(PermissionConstants.SYSTEM_ORGANIZATION_PROJECT_READ_UPDATE)
@Operation(summary = "添加项目成员")
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"));
}

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

View File

@ -100,6 +100,14 @@ public class SystemProjectControllerTests extends BaseTest {
.andExpect(status().isOk()).andDo(print())
.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) {
try {
@ -338,10 +346,7 @@ public class SystemProjectControllerTests extends BaseTest {
this.requestPost(updateProject, project, BAD_REQUEST_MATCHER);
//项目不存在
project = this.generatorUpdate("organizationId", "1111","123", null, true, List.of("admin"));
MvcResult mvcResult = this.responsePost(updateProject, project);
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
Assertions.assertNull(resultHolder.getData());
this.requestPost(updateProject, project, ERROR_REQUEST_MATCHER);
}
@ -363,9 +368,7 @@ public class SystemProjectControllerTests extends BaseTest {
@Order(10)
public void testDeleteProjectError() throws Exception {
String id = "1111";
MvcResult mvcResult = this.responseGet(deleteProject + id);
int count = parseObjectFromMvcResult(mvcResult, Integer.class);
Assertions.assertTrue(count == 0);
this.responseGet(deleteProject + id, ERROR_REQUEST_MATCHER);
}
@Test
@ -386,9 +389,7 @@ public class SystemProjectControllerTests extends BaseTest {
@Order(12)
public void testRevokeProjectError() throws Exception {
String id = "1111";
MvcResult mvcResult = this.responseGet(revokeProject + id);
int count = parseObjectFromMvcResult(mvcResult, Integer.class);
Assertions.assertTrue(count == 0);
this.responseGet(revokeProject + id, ERROR_REQUEST_MATCHER);
}
@Test
@ -404,6 +405,7 @@ public class SystemProjectControllerTests extends BaseTest {
List<UserRoleRelation> userRoleRelations = userRoleRelationMapper.selectByExample(userRoleRelationExample);
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));
this.requestPost(addProjectMember, projectAddMemberRequest, status().isOk());
}
@Test