fix(项目管理): 项目与权限批量操作问题

--bug=1039710 --user=宋昌昌 【项目管理】项目与权限-成员-全选所有页-切换用户组/搜索框搜索-所选择数量错误 https://www.tapd.cn/55049933/s/1501228
This commit is contained in:
song-cc-rock 2024-04-18 18:10:39 +08:00 committed by 刘瑞斌
parent 6103b1abd2
commit 1e355322da
6 changed files with 76 additions and 25 deletions

View File

@ -3,10 +3,7 @@ package io.metersphere.project.controller;
import com.github.pagehelper.Page; import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import io.metersphere.project.dto.ProjectUserDTO; import io.metersphere.project.dto.ProjectUserDTO;
import io.metersphere.project.request.ProjectMemberAddRequest; import io.metersphere.project.request.*;
import io.metersphere.project.request.ProjectMemberBatchDeleteRequest;
import io.metersphere.project.request.ProjectMemberEditRequest;
import io.metersphere.project.request.ProjectMemberRequest;
import io.metersphere.project.service.ProjectMemberService; import io.metersphere.project.service.ProjectMemberService;
import io.metersphere.sdk.constants.PermissionConstants; import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.system.dto.CommentUserInfo; import io.metersphere.system.dto.CommentUserInfo;
@ -98,7 +95,7 @@ public class ProjectMemberController {
@Operation(summary = "项目管理-成员-批量添加至用户组") @Operation(summary = "项目管理-成员-批量添加至用户组")
@RequiresPermissions(PermissionConstants.PROJECT_USER_UPDATE) @RequiresPermissions(PermissionConstants.PROJECT_USER_UPDATE)
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project") @CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
public void addMemberRole(@RequestBody ProjectMemberAddRequest request) { public void addMemberRole(@RequestBody ProjectMemberAddRoleRequest request) {
projectMemberService.addRole(request, SessionUtils.getUserId()); projectMemberService.addRole(request, SessionUtils.getUserId());
} }

View File

@ -1,12 +1,12 @@
package io.metersphere.project.mapper; package io.metersphere.project.mapper;
import io.metersphere.project.dto.ProjectUserRoleDTO; import io.metersphere.project.dto.ProjectUserRoleDTO;
import io.metersphere.project.request.ProjectMemberBatchDeleteRequest;
import io.metersphere.project.request.ProjectUserRoleMemberRequest; import io.metersphere.project.request.ProjectUserRoleMemberRequest;
import io.metersphere.project.request.ProjectUserRoleRequest; import io.metersphere.project.request.ProjectUserRoleRequest;
import io.metersphere.system.domain.User; import io.metersphere.system.domain.User;
import io.metersphere.system.domain.UserRoleRelation; import io.metersphere.system.domain.UserRoleRelation;
import io.metersphere.system.dto.sdk.OptionDTO; import io.metersphere.system.dto.sdk.OptionDTO;
import io.metersphere.system.dto.table.TableBatchProcessDTO;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.util.List; import java.util.List;
@ -57,5 +57,10 @@ public interface ExtProjectUserRoleMapper {
*/ */
List<OptionDTO> getProjectUserSelectList(@Param("projectId") String projectId, @Param("keyword") String keyword); List<OptionDTO> getProjectUserSelectList(@Param("projectId") String projectId, @Param("keyword") String keyword);
List<String>getProjectRoleMemberIds(@Param("request") ProjectMemberBatchDeleteRequest request); /**
* 根据列表参数获取选中的用户ID集合
* @param request 列表请求参数
* @return 用户ID集合
*/
List<String> getProjectRoleMemberIds(@Param("request") TableBatchProcessDTO request);
} }

View File

@ -65,7 +65,7 @@
</select> </select>
<select id="getProjectRoleMemberIds" resultType="java.lang.String"> <select id="getProjectRoleMemberIds" resultType="java.lang.String">
select u.id, select distinct u.id
from `user` u from `user` u
left join user_role_relation urr on urr.user_id = u.id left join user_role_relation urr on urr.user_id = u.id
where urr.source_id = #{request.projectId} and u.deleted = false where urr.source_id = #{request.projectId} and u.deleted = false

View File

@ -0,0 +1,27 @@
package io.metersphere.project.request;
import io.metersphere.system.dto.table.TableBatchProcessDTO;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.List;
/**
* @author song-cc-rock
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class ProjectMemberAddRoleRequest extends TableBatchProcessDTO implements Serializable {
@Schema(description = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{project.id.not_blank}")
private String projectId;
@Schema(description = "用户组ID集合", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "{user_role.id.not_blank}")
private List<String> roleIds;
}

View File

@ -5,10 +5,7 @@ import io.metersphere.project.dto.ProjectUserDTO;
import io.metersphere.project.mapper.ExtProjectMemberMapper; import io.metersphere.project.mapper.ExtProjectMemberMapper;
import io.metersphere.project.mapper.ExtProjectUserRoleMapper; import io.metersphere.project.mapper.ExtProjectUserRoleMapper;
import io.metersphere.project.mapper.ProjectMapper; import io.metersphere.project.mapper.ProjectMapper;
import io.metersphere.project.request.ProjectMemberAddRequest; import io.metersphere.project.request.*;
import io.metersphere.project.request.ProjectMemberBatchDeleteRequest;
import io.metersphere.project.request.ProjectMemberEditRequest;
import io.metersphere.project.request.ProjectMemberRequest;
import io.metersphere.sdk.constants.HttpMethodConstants; import io.metersphere.sdk.constants.HttpMethodConstants;
import io.metersphere.sdk.constants.InternalUserRole; import io.metersphere.sdk.constants.InternalUserRole;
import io.metersphere.sdk.constants.UserRoleEnum; import io.metersphere.sdk.constants.UserRoleEnum;
@ -160,7 +157,12 @@ public class ProjectMemberService {
* @param currentUserId 当前用户ID * @param currentUserId 当前用户ID
*/ */
public void addMember(ProjectMemberAddRequest request, String currentUserId) { public void addMember(ProjectMemberAddRequest request, String currentUserId) {
addMemberRole(request, currentUserId, OperationLogType.ADD.name(), "/project/member/add"); ProjectMemberAddRoleRequest roleRequest = new ProjectMemberAddRoleRequest();
roleRequest.setProjectId(request.getProjectId());
roleRequest.setRoleIds(request.getRoleIds());
roleRequest.setSelectAll(false);
roleRequest.setSelectIds(request.getUserIds());
addMemberRole(roleRequest, currentUserId, OperationLogType.ADD.name(), "/project/member/add");
} }
/** /**
@ -250,7 +252,7 @@ public class ProjectMemberService {
* @param request 请求参数 * @param request 请求参数
* @param currentUserId 当前用户ID * @param currentUserId 当前用户ID
*/ */
public void addRole(ProjectMemberAddRequest request, String currentUserId) { public void addRole(ProjectMemberAddRoleRequest request, String currentUserId) {
// 添加用户用户组(已经添加的用户组不再添加) // 添加用户用户组(已经添加的用户组不再添加)
addMemberRole(request, currentUserId, OperationLogType.UPDATE.name(), "/project/member/add-role"); addMemberRole(request, currentUserId, OperationLogType.UPDATE.name(), "/project/member/add-role");
} }
@ -263,21 +265,34 @@ public class ProjectMemberService {
* @param operationType 操作记录类型 * @param operationType 操作记录类型
* @param path 操作记录路径 * @param path 操作记录路径
*/ */
public void addMemberRole(ProjectMemberAddRequest request, String currentUserId, String operationType, String path) { public void addMemberRole(ProjectMemberAddRoleRequest request, String currentUserId, String operationType, String path) {
// 操作记录 // 操作记录
List<LogDTO> logs = new ArrayList<>(); List<LogDTO> logs = new ArrayList<>();
// 项目不存在, 则不添加 // 项目不存在, 则不添加
Project project = checkProjectExist(request.getProjectId()); Project project = checkProjectExist(request.getProjectId());
if (!request.isSelectAll() && CollectionUtils.isEmpty(request.getSelectIds())) {
throw new MSException(Translator.get("user.not.empty"));
}
// 批量移除成员, 则移除该成员在该项目下的所有用户组
List<String> userIds;
if (request.isSelectAll()) {
userIds = extProjectUserRoleMapper.getProjectRoleMemberIds(request);
if (!CollectionUtils.isEmpty(request.getExcludeIds())) {
userIds.removeAll(request.getExcludeIds());
}
} else {
userIds = request.getSelectIds();
}
// 获取已经存在的用户组 // 获取已经存在的用户组
UserRoleRelationExample example = new UserRoleRelationExample(); UserRoleRelationExample example = new UserRoleRelationExample();
example.createCriteria().andSourceIdEqualTo(request.getProjectId()) example.createCriteria().andSourceIdEqualTo(request.getProjectId())
.andUserIdIn(request.getUserIds()).andRoleIdIn(request.getRoleIds()); .andUserIdIn(userIds).andRoleIdIn(request.getRoleIds());
List<UserRoleRelation> userRoleRelations = userRoleRelationMapper.selectByExample(example); List<UserRoleRelation> userRoleRelations = userRoleRelationMapper.selectByExample(example);
Map<String, List<String>> existUserRelations = userRoleRelations.stream().collect( Map<String, List<String>> existUserRelations = userRoleRelations.stream().collect(
Collectors.groupingBy(UserRoleRelation::getUserId, Collectors.mapping(UserRoleRelation::getRoleId, Collectors.toList()))); Collectors.groupingBy(UserRoleRelation::getUserId, Collectors.mapping(UserRoleRelation::getRoleId, Collectors.toList())));
// 比较用户组是否已经存在, 如果不存在则添加 // 比较用户组是否已经存在, 如果不存在则添加
List<UserRoleRelation> relations = new ArrayList<>(); List<UserRoleRelation> relations = new ArrayList<>();
request.getUserIds().forEach(userId -> { userIds.forEach(userId -> {
AtomicBoolean isLog = new AtomicBoolean(false); AtomicBoolean isLog = new AtomicBoolean(false);
// 追加的用户组ID, 操作记录使用 // 追加的用户组ID, 操作记录使用
List<String> roleIds = new ArrayList<>(); List<String> roleIds = new ArrayList<>();

View File

@ -1,10 +1,7 @@
package io.metersphere.project.controller; package io.metersphere.project.controller;
import io.metersphere.project.dto.ProjectUserDTO; import io.metersphere.project.dto.ProjectUserDTO;
import io.metersphere.project.request.ProjectMemberAddRequest; import io.metersphere.project.request.*;
import io.metersphere.project.request.ProjectMemberBatchDeleteRequest;
import io.metersphere.project.request.ProjectMemberEditRequest;
import io.metersphere.project.request.ProjectMemberRequest;
import io.metersphere.sdk.constants.PermissionConstants; import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.sdk.constants.SessionConstants; import io.metersphere.sdk.constants.SessionConstants;
import io.metersphere.sdk.util.JSON; import io.metersphere.sdk.util.JSON;
@ -202,10 +199,16 @@ public class ProjectMemberControllerTests extends BaseTest {
@Test @Test
@Order(13) @Order(13)
public void testAddMemberRoleSuccess() throws Exception { public void testAddMemberRoleSuccess() throws Exception {
ProjectMemberAddRequest request = new ProjectMemberAddRequest(); ProjectMemberAddRoleRequest request = new ProjectMemberAddRoleRequest();
request.setProjectId("default-project-member-test"); request.setProjectId("default-project-member-test");
request.setUserIds(List.of("default-project-member-user-1", "default-project-member-user-2")); request.setSelectIds(List.of("default-project-member-user-1", "default-project-member-user-2"));
request.setRoleIds(List.of("project_admin", "project_member")); request.setRoleIds(List.of("project_admin", "project_member"));
request.setSelectAll(false);
this.requestPost(ADD_ROLE, request, status().isOk());
request.setSelectAll(true);
request.setSelectIds(List.of());
this.requestPost(ADD_ROLE, request, status().isOk());
request.setExcludeIds(List.of("project_admin"));
this.requestPost(ADD_ROLE, request, status().isOk()); this.requestPost(ADD_ROLE, request, status().isOk());
// 权限校验 // 权限校验
request.setProjectId(DEFAULT_PROJECT_ID); request.setProjectId(DEFAULT_PROJECT_ID);
@ -215,11 +218,15 @@ public class ProjectMemberControllerTests extends BaseTest {
@Test @Test
@Order(14) @Order(14)
public void testAddMemberRoleError() throws Exception { public void testAddMemberRoleError() throws Exception {
ProjectMemberAddRequest request = new ProjectMemberAddRequest(); ProjectMemberAddRoleRequest request = new ProjectMemberAddRoleRequest();
request.setProjectId("default-project-member-x"); request.setProjectId("default-project-member-x");
request.setUserIds(List.of("default-project-member-user-1", "default-project-member-user-2")); request.setSelectAll(false);
request.setSelectIds(List.of("default-project-member-user-1", "default-project-member-user-2"));
request.setRoleIds(List.of("project_admin", "project_member")); request.setRoleIds(List.of("project_admin", "project_member"));
this.requestPost(ADD_ROLE, request, status().is5xxServerError()); this.requestPost(ADD_ROLE, request, status().is5xxServerError());
request.setProjectId("default-project-member-test");
request.setSelectIds(List.of());
this.requestPost(ADD_ROLE, request, status().is5xxServerError());
} }
@Test @Test