fix(项目管理): 修复项目成员批量移除失败以及功能用例批量操作报错问题

--bug=1039613 --user=郭雨琦 https://www.tapd.cn/55049933/bugtrace/bugs/view/1155049933001039613
This commit is contained in:
guoyuqi 2024-04-18 14:52:51 +08:00 committed by 刘瑞斌
parent b3a71ef600
commit df60bef5f6
6 changed files with 65 additions and 15 deletions

View File

@ -63,8 +63,8 @@
</if> </if>
<if test="request.condition.keyword != null"> <if test="request.condition.keyword != null">
and ( and (
case_review.name like concat('%', #{request.keyword},'%') case_review.name like concat('%', #{request.condition.keyword},'%')
or case_review.num like concat('%', #{request.keyword},'%') or case_review.num like concat('%', #{request.condition.keyword},'%')
) )
</if> </if>
<if test="request.createByMe != null"> <if test="request.createByMe != null">

View File

@ -1,11 +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.dto.sdk.OptionDTO;
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 org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.util.List; import java.util.List;
@ -55,4 +56,6 @@ public interface ExtProjectUserRoleMapper {
* @return List<User> * @return List<User>
*/ */
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);
} }

View File

@ -63,4 +63,42 @@
order by u.update_time desc order by u.update_time desc
limit 100 limit 100
</select> </select>
<select id="getProjectRoleMemberIds" resultType="java.lang.String">
select u.id,
from `user` u
left join user_role_relation urr on urr.user_id = u.id
where urr.source_id = #{request.projectId} and u.deleted = false
<include refid="queryWhereConditionByBaseQueryRequest"/>
</select>
<sql id="queryWhereConditionByBaseQueryRequest">
<if test="request.condition.keyword != null and request.condition.keyword != ''">
and (
u.name like concat('%', #{request.condition.keyword}, '%')
or u.email like concat('%', #{request.condition.keyword}, '%')
or u.phone like concat('%', #{request.condition.keyword}, '%')
)
</if>
<include refid="filters">
<property name="filter" value="request.condition.filter"/>
</include>
</sql>
<sql id="filters">
<if test="${filter} != null and ${filter}.size() > 0">
<foreach collection="${filter}.entrySet()" index="key" item="values">
<if test="values != null and values.size() > 0">
<choose>
<!-- 评审状态 -->
<when test="key=='roleIds'">
and urr.role_id in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
</when>
</choose>
</if>
</foreach>
</if>
</sql>
</mapper> </mapper>

View File

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

View File

@ -3,6 +3,7 @@ package io.metersphere.project.service;
import io.metersphere.project.domain.Project; import io.metersphere.project.domain.Project;
import io.metersphere.project.dto.ProjectUserDTO; 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.ProjectMapper; import io.metersphere.project.mapper.ProjectMapper;
import io.metersphere.project.request.ProjectMemberAddRequest; import io.metersphere.project.request.ProjectMemberAddRequest;
import io.metersphere.project.request.ProjectMemberBatchDeleteRequest; import io.metersphere.project.request.ProjectMemberBatchDeleteRequest;
@ -56,6 +57,8 @@ public class ProjectMemberService {
private ExtProjectMemberMapper extProjectMemberMapper; private ExtProjectMemberMapper extProjectMemberMapper;
@Resource @Resource
private OperationLogService operationLogService; private OperationLogService operationLogService;
@Resource
private ExtProjectUserRoleMapper extProjectUserRoleMapper;
/** /**
* 获取成员列表 * 获取成员列表
@ -325,13 +328,25 @@ public class ProjectMemberService {
List<LogDTO> logs = new ArrayList<>(); List<LogDTO> logs = new ArrayList<>();
// 项目不存在, 则不移除 // 项目不存在, 则不移除
checkProjectExist(request.getProjectId()); 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()); .andUserIdIn(userIds);
userRoleRelationMapper.deleteByExample(example); userRoleRelationMapper.deleteByExample(example);
// 操作记录 // 操作记录
request.getUserIds().forEach(userId -> { userIds.forEach(userId -> {
// 操作记录 // 操作记录
setLog(request.getProjectId(), userId, currentUserId, OperationLogType.DELETE.name(), "/project/member/remove", HttpMethodConstants.GET.name(), null, null, logs); setLog(request.getProjectId(), userId, currentUserId, OperationLogType.DELETE.name(), "/project/member/remove", HttpMethodConstants.GET.name(), null, null, logs);
}); });

View File

@ -227,7 +227,7 @@ public class ProjectMemberControllerTests extends BaseTest {
public void testBatchRemoveMemberSuccess() throws Exception { public void testBatchRemoveMemberSuccess() throws Exception {
ProjectMemberBatchDeleteRequest request = new ProjectMemberBatchDeleteRequest(); ProjectMemberBatchDeleteRequest request = new ProjectMemberBatchDeleteRequest();
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"));
this.requestPost(BATCH_REMOVE_MEMBER, request, status().isOk()); this.requestPost(BATCH_REMOVE_MEMBER, request, status().isOk());
// 权限校验 // 权限校验
request.setProjectId(DEFAULT_PROJECT_ID); request.setProjectId(DEFAULT_PROJECT_ID);
@ -239,7 +239,7 @@ public class ProjectMemberControllerTests extends BaseTest {
public void testBatchRemoveMember() throws Exception { public void testBatchRemoveMember() throws Exception {
ProjectMemberBatchDeleteRequest request = new ProjectMemberBatchDeleteRequest(); ProjectMemberBatchDeleteRequest request = new ProjectMemberBatchDeleteRequest();
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.setSelectIds(List.of("default-project-member-user-1", "default-project-member-user-2"));
this.requestPost(BATCH_REMOVE_MEMBER, request, status().is5xxServerError()); this.requestPost(BATCH_REMOVE_MEMBER, request, status().is5xxServerError());
} }