feat(系统设置): 项目功能开发

This commit is contained in:
wxg0103 2023-06-14 17:46:48 +08:00 committed by f2c-ci-robot[bot]
parent e90c17012a
commit a3d3e43865
12 changed files with 170 additions and 55 deletions

View File

@ -5,10 +5,15 @@ import io.metersphere.validation.groups.Updated;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserRoleRelation implements Serializable {
@Schema(title = "用户组关系ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{user_role_relation.id.not_blank}", groups = {Created.class, Updated.class})

View File

@ -1,18 +1,15 @@
package io.metersphere.sdk.dto;
import io.metersphere.project.domain.Project;
import io.metersphere.system.domain.User;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
@Data
@EqualsAndHashCode(callSuper = false)
public class ProjectDTO extends Project {
@Schema(title = "项目成员数量", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String number;
@Schema(title = "项目成员", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private List<User> projectMemberList;
@Schema(title = "所属组织", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String organizationName;
}

View File

@ -13,12 +13,13 @@ import io.metersphere.sdk.util.PageUtils;
import io.metersphere.sdk.util.Pager;
import io.metersphere.sdk.util.SessionUtils;
import io.metersphere.system.domain.User;
import io.metersphere.system.request.ProjectMemberRequest;
import io.metersphere.system.request.ProjectRequest;
import io.metersphere.system.service.SystemProjectService;
import io.metersphere.system.service.TestResourcePoolService;
import io.metersphere.validation.groups.Created;
import io.metersphere.validation.groups.Updated;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -33,8 +34,7 @@ public class SystemProjectController {
@PostMapping("/add")
@RequiresPermissions(PermissionConstants.SYSTEM_PROJECT_READ_ADD)
@RequestLog(isBefore = true, type = OperationLogType.UPDATE, module = OperationLogModule.SYSTEM_PROJECT,
details = "#msClass.getLogDetails(#testResourcePoolId)", msClass = TestResourcePoolService.class)
@RequestLog(type = OperationLogType.ADD, module = OperationLogModule.SYSTEM_PROJECT, details = "#project.name")
public Project addProject(@RequestBody @Validated({Created.class}) Project project) {
project.setCreateUser(SessionUtils.getUserId());
return systemProjectService.add(project);
@ -50,44 +50,53 @@ public class SystemProjectController {
@PostMapping("/page")
@RequiresPermissions(PermissionConstants.SYSTEM_PROJECT_READ)
public Pager<List<ProjectDTO>> getProjectList(@Validated @RequestBody ProjectRequest request) {
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize());
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "create_time desc");
return PageUtils.setPageInfo(page, systemProjectService.getProjectList(request));
}
@PostMapping("/update")
@RequestLog(isBefore = true, type = OperationLogType.UPDATE, module = OperationLogModule.SYSTEM_PROJECT,
details = "#msClass.getLogDetails(#testResourcePoolId)", msClass = TestResourcePoolService.class)
@RequestLog(type = OperationLogType.UPDATE, module = OperationLogModule.SYSTEM_PROJECT,
sourceId = "#project.id", details = "#project.name")
@RequiresPermissions(PermissionConstants.SYSTEM_PROJECT_READ_UPDATE)
public void updateProject(@RequestBody @Validated({Updated.class}) Project project) {
project.setUpdateUser(SessionUtils.getUserId());
systemProjectService.update(project);
}
@PostMapping("/delete")
@GetMapping("/delete/{id}")
@RequiresPermissions(PermissionConstants.SYSTEM_PROJECT_READ_DELETE)
public void deleteProject(@RequestBody @Validated({Updated.class}) Project project) {
@RequestLog(isBefore = true, type = OperationLogType.DELETE, module = OperationLogModule.SYSTEM_PROJECT,
details = "#msClass.getLogDetails(#id)", msClass = SystemProjectService.class, sourceId = "#id")
public void deleteProject(@PathVariable String id) {
Project project = new Project();
project.setId(id);
project.setDeleteUser(SessionUtils.getUserId());
systemProjectService.delete(project);
}
@PostMapping("/revoke")
@GetMapping("/revoke/{id}")
@RequiresPermissions(PermissionConstants.SYSTEM_PROJECT_READ_DELETE)
public void revokeProject(@RequestBody @Validated({Updated.class}) Project project) {
systemProjectService.revoke(project);
@RequestLog(isBefore = true, type = OperationLogType.UPDATE, module = OperationLogModule.SYSTEM_PROJECT,
details = "#msClass.getLogDetails(#id)", msClass = SystemProjectService.class, sourceId = "#id")
public void revokeProject(@PathVariable String id) {
systemProjectService.revoke(id);
}
@PostMapping("/member-list")
@RequiresPermissions(PermissionConstants.SYSTEM_PROJECT_READ_ADD_USER)
public Pager<List<User>> getProjectMember(@Validated @RequestBody ProjectRequest request) {
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize());
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "create_time desc");
return PageUtils.setPageInfo(page, systemProjectService.getProjectMember(request));
}
/* @PostMapping("/addMember/{projectId}")
@PostMapping("/add-member")
@RequiresPermissions(PermissionConstants.SYSTEM_PROJECT_READ_ADD_USER)
public void addProjectMember(@PathVariable String projectId, @RequestBody List<UserDTO> userDTOList) {
systemProjectService.addProjectMember(projectId, userDTOList);
}*/
public void addProjectMember(@Validated @RequestBody ProjectMemberRequest request) {
request.setCreateUser(SessionUtils.getUserId());
systemProjectService.addProjectMember(request);
}
@GetMapping("/remove-member/{projectId}/{userId}")
@RequiresPermissions(PermissionConstants.SYSTEM_PROJECT_READ_DELETE_USER)

View File

@ -33,12 +33,18 @@
p.delete_time,
p.deleted,
p.delete_user,
p.enable, count(u.id) as number
p.enable,
count(u.id) as number,
o.name as organizationName
FROM project p
LEFT JOIN user_role_relation u on p.id = u.source_id
INNER JOIN organization o on p.organization_id = o.id
<where>
<if test="request.organizationId != null">
p.organizationId = #{request.organizationId}
</if>
<if test="request.keyword != null">
(p.name like CONCAT('%', #{request.keyword},'%')
and (p.name like CONCAT('%', #{request.keyword},'%')
or p.num like CONCAT('%', #{request.keyword},'%'))
</if>
</where>

View File

@ -0,0 +1,23 @@
package io.metersphere.system.request;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import java.util.List;
@Data
public class ProjectMemberRequest {
@Schema(title = "项目ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{project.id.not_blank}")
private String projectId;
@Schema(title = "用户ID集合", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "{user.ids.not_blank}")
private List<String> userIds;
@Schema(title = "当前用户")
private String createUser;
}

View File

@ -3,11 +3,13 @@ package io.metersphere.system.request;
import io.metersphere.sdk.dto.BasePageRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public class ProjectRequest extends BasePageRequest {
@Schema(title = "组织id", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
@Schema(title = "组织id")
private String organizationId;
@Schema(title = "项目ID", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
@Schema(title = "项目ID")
private String projectId;
}

View File

@ -3,19 +3,21 @@ package io.metersphere.system.service;
import io.metersphere.project.domain.Project;
import io.metersphere.project.domain.ProjectExample;
import io.metersphere.project.mapper.ProjectMapper;
import io.metersphere.sdk.constants.UserRoleConstants;
import io.metersphere.sdk.dto.ProjectDTO;
import io.metersphere.sdk.dto.UserDTO;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.SessionUtils;
import io.metersphere.sdk.util.Translator;
import io.metersphere.system.domain.User;
import io.metersphere.system.domain.UserRoleRelation;
import io.metersphere.system.domain.UserRoleRelationExample;
import io.metersphere.system.mapper.ExtSystemProjectMapper;
import io.metersphere.system.mapper.UserMapper;
import io.metersphere.system.mapper.UserRoleRelationMapper;
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.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -52,7 +54,6 @@ public class SystemProjectService {
project.setId(UUID.randomUUID().toString());
project.setCreateTime(System.currentTimeMillis());
project.setUpdateTime(System.currentTimeMillis());
project.setCreateUser(SessionUtils.getUser().getId());
projectMapper.insertSelective(project);
return project;
}
@ -73,6 +74,8 @@ public class SystemProjectService {
}
public void update(Project project) {
project.setCreateUser(null);
project.setCreateTime(null);
project.setUpdateTime(System.currentTimeMillis());
checkProjectExist(project);
projectMapper.updateByPrimaryKeySelective(project);
@ -81,6 +84,8 @@ public class SystemProjectService {
public void delete(Project project) {
//TODO 删除项目删除全部资源 这里的删除只是假删除
project.setDeleted(true);
project.setCreateUser(null);
project.setCreateTime(null);
project.setDeleteTime(System.currentTimeMillis());
projectMapper.updateByPrimaryKeySelective(project);
}
@ -93,7 +98,19 @@ public class SystemProjectService {
return projectMemberList;
}
public void addProjectMember(String projectId, List<UserDTO> userDTOList) {
public void addProjectMember(ProjectMemberRequest request) {
//TODO 添加项目成员需要检查配额 这个需要等后续定下来补全逻辑
request.getUserIds().forEach(userId -> {
UserRoleRelation userRoleRelation = new UserRoleRelation(
UUID.randomUUID().toString(),
userId,
UserRoleConstants.PROJECT_MEMBER,
request.getProjectId(),
System.currentTimeMillis(),
request.getCreateUser());
userRoleRelationMapper.insertSelective(userRoleRelation);
});
}
@ -109,9 +126,14 @@ public class SystemProjectService {
userRoleRelationMapper.deleteByExample(userRoleRelationExample);
}
public void revoke(Project project) {
public void revoke(String id) {
Project project = new Project();
project.setId(id);
project.setDeleted(false);
project.setDeleteTime(null);
project.setCreateUser(null);
project.setCreateTime(null);
project.setDeleteUser(null);
projectMapper.updateByPrimaryKeySelective(project);
}
@ -120,4 +142,12 @@ public class SystemProjectService {
example.createCriteria().andOrganizationIdEqualTo(organizationId);
return projectMapper.selectByExample(example);
}
public String getLogDetails(String id) {
Project project = projectMapper.selectByPrimaryKey(id);
if (ObjectUtils.isNotEmpty(project)) {
return project.getName();
}
return null;
}
}

View File

@ -8,6 +8,7 @@ import io.metersphere.sdk.dto.ProjectDTO;
import io.metersphere.sdk.util.JSON;
import io.metersphere.sdk.util.Pager;
import io.metersphere.system.domain.User;
import io.metersphere.system.request.ProjectMemberRequest;
import io.metersphere.system.request.ProjectRequest;
import io.metersphere.utils.JsonUtils;
import jakarta.annotation.Resource;
@ -23,6 +24,7 @@ import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import java.util.ArrayList;
import java.util.List;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
@ -70,6 +72,9 @@ public class SystemProjectControllerTests extends BaseTest {
@Test
@Order(1)
/**
* 测试添加项目成功的情况
*/
public void testAddProjectSuccess() throws Exception {
String url = prefix + "/add";
final Project project = new Project();
@ -89,6 +94,34 @@ public class SystemProjectControllerTests extends BaseTest {
@Test
@Order(2)
/**
* 测试添加项目500的情况
*/
public void testAddProjectError500() throws Exception {
String url = prefix + "/add";
final Project project = new Project();
project.setId("projectId");
project.setOrganizationId("organizationId");
project.setName("name");
project.setDescription("description");
project.setCreateTime(System.currentTimeMillis());
project.setUpdateTime(System.currentTimeMillis());
project.setCreateUser("admin");
project.setUpdateUser("admin");
project.setEnable(true);
project.setDeleted(false);
this.requestPost(url, project, status().is5xxServerError());
}
@Test
@Order(3)
/**
* 测试添加项目失败的情况 400
*/
@Sql(scripts = {"/dml/init_project.sql"},
config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED),
executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
public void testAddProjectError() throws Exception {
final Project project = new Project();
project.setId(null);
@ -107,7 +140,7 @@ public class SystemProjectControllerTests extends BaseTest {
}
@Test
@Order(3)
@Order(4)
public void testGetProject() throws Exception {
String projectId = "projectId";
MvcResult mvcResult = this.responseGet(prefix + "/get/" + projectId);
@ -118,14 +151,11 @@ public class SystemProjectControllerTests extends BaseTest {
}
@Test
@Order(4)
@Sql(scripts = {"/sql/init_project.sql"},
config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED),
executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Order(5)
public void testGetProjectList() throws Exception {
ProjectRequest projectRequest = new ProjectRequest();
projectRequest.setCurrent(1);
projectRequest.setPageSize(5);
projectRequest.setPageSize(10);
MvcResult mvcResult = this.responsePost(prefix + "/page", projectRequest);
@ -148,7 +178,7 @@ public class SystemProjectControllerTests extends BaseTest {
}
@Test
@Order(5)
@Order(6)
public void testUpdateProject() throws Exception {
String url = prefix + "/update";
final Project project = new Project();
@ -164,25 +194,23 @@ public class SystemProjectControllerTests extends BaseTest {
this.requestPost(url, project, status().isOk());
}
@Test
@Order(6)
public void testDeleteProject() throws Exception {
Project project = new Project();
project.setId("projectId");
this.requestPost(prefix + "/delete", project, status().isOk());
}
@Test
@Order(7)
public void revoke() throws Exception {
Project project = new Project();
project.setId("projectId");
this.requestPost(prefix + "/revoke", project, status().isOk());
public void testDeleteProject() throws Exception {
String id = "projectId";
this.responseGet(prefix + "/delete/" + id);
}
@Test
@Order(8)
@Sql(scripts = {"/sql/init_user_test.sql"},
public void revoke() throws Exception {
String id = "projectId";
this.responseGet(prefix + "/delete/" + id);
}
@Test
@Order(9)
@Sql(scripts = {"/dml/init_user_test.sql"},
config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED),
executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
public void testGetMember() throws Exception {
@ -210,7 +238,7 @@ public class SystemProjectControllerTests extends BaseTest {
}
@Test
@Order(9)
@Order(10)
public void testGetProjectListByOrg() throws Exception{
String organizationId = "organizationId";
MvcResult mvcResult = this.responseGet(prefix + "/list/" + organizationId);
@ -222,7 +250,7 @@ public class SystemProjectControllerTests extends BaseTest {
}
@Test
@Order(10)
@Order(11)
public void testGetProjectListByOrgError() throws Exception{
String organizationId = "organizationId";
MvcResult mvcResult = this.responseGet(prefix + "/list/" + organizationId);
@ -234,7 +262,7 @@ public class SystemProjectControllerTests extends BaseTest {
}
@Test
@Order(11)
@Order(12)
public void testRemoveProjectMember() throws Exception{
String projectId = "projectId";
String userId = "admin1";
@ -245,5 +273,18 @@ public class SystemProjectControllerTests extends BaseTest {
.andExpect(status().isOk()).andDo(print());
}
@Test
@Order(13)
public void testAddProjectMember() throws Exception{
ProjectMemberRequest projectMemberRequest = new ProjectMemberRequest();
projectMemberRequest.setProjectId("projectId");
List<String> userIds = new ArrayList<>();
userIds.add("admin1");
userIds.add("admin2");
projectMemberRequest.setUserIds(userIds);
this.requestPost(prefix + "/add-member", projectMemberRequest, status().isOk());
}
}

View File

@ -138,7 +138,7 @@ class TestResourcePoolControllerTest extends BaseTest {
}
@Test
@Sql(scripts = {"/sql/init_test_resource_pool.sql"},
@Sql(scripts = {"/dml/init_test_resource_pool.sql"},
config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED),
executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Order(6)

View File

@ -1,4 +1,6 @@
# 插入测试数据
INSERT INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time) VALUES ('projectId', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000);
INSERT INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time) VALUES ('projectId', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000);
INSERT INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time) VALUES ('projectId1', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目1', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000);
INSERT INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time) VALUES ('projectId2', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目2', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000);
INSERT INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time) VALUES ('projectId3', null, (SELECT id FROM organization WHERE name LIKE '默认组织'), '默认项目3', '系统默认创建的项目', 'admin', 'admin', unix_timestamp() * 1000, unix_timestamp() * 1000);