fix(通用功能): 修复跨项目禁用模块显示问题

--bug=1039611 --user=郭雨琦 https://www.tapd.cn/55049933/bugtrace/bugs/view/1155049933001039611
This commit is contained in:
guoyuqi 2024-04-19 16:43:07 +08:00 committed by 刘瑞斌
parent c0a1686213
commit ce8d123e58
7 changed files with 131 additions and 22 deletions

View File

@ -820,6 +820,7 @@ public class FunctionalCaseService {
functional.setPos(nextOrder.get()); functional.setPos(nextOrder.get());
functional.setLastExecuteResult(FunctionalCaseExecuteResult.UN_EXECUTED.name()); functional.setLastExecuteResult(FunctionalCaseExecuteResult.UN_EXECUTED.name());
functional.setCreateUser(userId); functional.setCreateUser(userId);
functional.setUpdateUser(userId);
functional.setCreateTime(System.currentTimeMillis()); functional.setCreateTime(System.currentTimeMillis());
functional.setUpdateTime(System.currentTimeMillis()); functional.setUpdateTime(System.currentTimeMillis());
functionalCaseMapper.insert(functional); functionalCaseMapper.insert(functional);

View File

@ -47,6 +47,13 @@ public class ProjectController {
return projectService.getUserProject(organizationId, SessionUtils.getUserId()); return projectService.getUserProject(organizationId, SessionUtils.getUserId());
} }
@GetMapping("/list/options/{organizationId}/{module}")
@Operation(summary = "根据组织ID获取所有开启某个模块的所有权限的项目")
@CheckOwner(resourceId = "#organizationId", resourceType = "organization")
public List<Project> getUserProjectWidthModule(@PathVariable String organizationId, @PathVariable String module) {
return projectService.getUserProjectWidthModule(organizationId, module, SessionUtils.getUserId());
}
@PostMapping("/switch") @PostMapping("/switch")
@Operation(summary = "切换项目") @Operation(summary = "切换项目")
@RequiresPermissions(PermissionConstants.PROJECT_BASE_INFO_READ) @RequiresPermissions(PermissionConstants.PROJECT_BASE_INFO_READ)

View File

@ -28,5 +28,8 @@ public interface ExtProjectMapper {
List<Project> getAllProject(@Param("organizationId") String organizationId); List<Project> getAllProject(@Param("organizationId") String organizationId);
List<TestResourcePool> getResourcePoolOption(@Param("projectId") String projectId, @Param("type") String type); List<TestResourcePool> getResourcePoolOption(@Param("projectId") String projectId, @Param("type") String type);
List<Project> getAllProjectWidthModule(@Param("organizationId") String organizationId, @Param("module") String module);
List<Project> getUserProjectWidthModule(@Param("organizationId") String organizationId, @Param("userId") String userId, @Param("module") String module);
} }

View File

@ -94,4 +94,28 @@
and t.deleted = 0 and t.deleted = 0
and t.${type} = 1 and t.${type} = 1
</select> </select>
<select id="getAllProjectWidthModule" resultType="io.metersphere.project.domain.Project">
select *
from project
where enable = 1 and
organization_id = #{organizationId}
AND module_setting like concat('%', #{module},'%')
order by
CONVERT( name USING GBK) ASC
</select>
<select id="getUserProjectWidthModule" resultType="io.metersphere.project.domain.Project">
SELECT DISTINCT p.*
FROM user_role u
JOIN user_role_relation urr ON u.id = urr.role_id
JOIN project p ON p.id = urr.source_id
JOIN user on urr.user_id = user.id
where urr.user_id = #{userId} and u.type = 'PROJECT'
AND p.organization_id = #{organizationId} and p.enable = 1 and user.deleted = 0
AND p.module_setting like concat('%', #{module},'%')
order by
CONVERT( p.name USING GBK) ASC
</select>
</mapper> </mapper>

View File

@ -68,9 +68,7 @@ public class ProjectService {
public List<Project> getUserProject(String organizationId, String userId) { public List<Project> getUserProject(String organizationId, String userId) {
if (organizationMapper.selectByPrimaryKey(organizationId) == null) { checkOrg(organizationId);
throw new MSException(Translator.get("organization_not_exist"));
}
//查询用户当前的项目 如果存在默认排在第一个 //查询用户当前的项目 如果存在默认排在第一个
User user = baseUserMapper.selectById(userId); User user = baseUserMapper.selectById(userId);
String projectId; String projectId;
@ -100,6 +98,12 @@ public class ProjectService {
.orElse(allProject); .orElse(allProject);
} }
private void checkOrg(String organizationId) {
if (organizationMapper.selectByPrimaryKey(organizationId) == null) {
throw new MSException(Translator.get("organization_not_exist"));
}
}
public UserDTO switchProject(ProjectSwitchRequest request, String currentUserId) { public UserDTO switchProject(ProjectSwitchRequest request, String currentUserId) {
if (!StringUtils.equals(currentUserId, request.getUserId())) { if (!StringUtils.equals(currentUserId, request.getUserId())) {
throw new MSException(Translator.get("not_authorized")); throw new MSException(Translator.get("not_authorized"));
@ -245,5 +249,37 @@ public class ProjectService {
} }
return extSystemProjectMapper.getMemberByProjectId(projectId, keyword); return extSystemProjectMapper.getMemberByProjectId(projectId, keyword);
} }
public List<Project> getUserProjectWidthModule(String organizationId, String module, String userId) {
checkOrg(organizationId);
//查询用户当前的项目 如果存在默认排在第一个
User user = baseUserMapper.selectById(userId);
String projectId;
if (user != null && StringUtils.isNotBlank(user.getLastProjectId())) {
projectId = user.getLastProjectId();
} else {
projectId = null;
}
//判断用户是否是系统管理员
List<Project> allProject;
UserRoleRelationExample userRoleRelationExample = new UserRoleRelationExample();
userRoleRelationExample.createCriteria().andUserIdEqualTo(userId).andRoleIdEqualTo(InternalUserRole.ADMIN.name());
if (userRoleRelationMapper.countByExample(userRoleRelationExample) > 0) {
allProject = extProjectMapper.getAllProjectWidthModule(organizationId, module);
} else {
allProject = extProjectMapper.getUserProjectWidthModule(organizationId, userId, module);
}
List<Project> temp = allProject;
return allProject.stream()
.filter(project -> StringUtils.equals(project.getId(), projectId))
.findFirst()
.map(project -> {
temp.remove(project);
temp.add(0, project);
return temp;
})
.orElse(allProject);
}
} }

View File

@ -53,6 +53,7 @@ public class ProjectControllerTests extends BaseTest {
private static final String prefix = "/project"; private static final String prefix = "/project";
private static final String getOptions = prefix + "/list/options/"; private static final String getOptions = prefix + "/list/options/";
private final static String updateProject = prefix + "/update"; private final static String updateProject = prefix + "/update";
private static final String getOptionsWidthModule = prefix + "/list/options/";
private static final String getPoolOptions = prefix + "/pool-options/"; private static final String getPoolOptions = prefix + "/pool-options/";
@ -214,6 +215,20 @@ public class ProjectControllerTests extends BaseTest {
example.createCriteria().andOrganizationIdEqualTo(DEFAULT_ORGANIZATION_ID).andEnableEqualTo(true); example.createCriteria().andOrganizationIdEqualTo(DEFAULT_ORGANIZATION_ID).andEnableEqualTo(true);
Assertions.assertEquals(projectMapper.countByExample(example), list.size()); Assertions.assertEquals(projectMapper.countByExample(example), list.size());
MvcResult mvcResultModule = this.responseGet(getOptionsWidthModule + DEFAULT_ORGANIZATION_ID +"/apiTest");
List<Project> listModule = parseObjectFromMvcResult(mvcResultModule, List.class);
Assertions.assertNotNull(listModule);
ProjectExample exampleWidthModule = new ProjectExample();
exampleWidthModule.createCriteria().andOrganizationIdEqualTo(DEFAULT_ORGANIZATION_ID).andEnableEqualTo(true);
List<Project> projects = projectMapper.selectByExample(exampleWidthModule);
int a = 0;
for (Project project : projects) {
if (StringUtils.isNotBlank(project.getModuleSetting()) && project.getModuleSetting().contains("apiTest")) {
a = a+1;
}
}
Assertions.assertEquals(a, listModule.size());
UserRoleRelation userRoleRelation = new UserRoleRelation(); UserRoleRelation userRoleRelation = new UserRoleRelation();
userRoleRelation.setUserId("admin1"); userRoleRelation.setUserId("admin1");
userRoleRelation.setOrganizationId(DEFAULT_ORGANIZATION_ID); userRoleRelation.setOrganizationId(DEFAULT_ORGANIZATION_ID);
@ -244,6 +259,15 @@ public class ProjectControllerTests extends BaseTest {
list = parseObjectFromMvcResult(mvcResult, List.class); list = parseObjectFromMvcResult(mvcResult, List.class);
Assertions.assertNotNull(list); Assertions.assertNotNull(list);
mvcResult = mockMvc.perform(MockMvcRequestBuilders.get(getOptions + DEFAULT_ORGANIZATION_ID+"/apiTest")
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
listModule = parseObjectFromMvcResult(mvcResult, List.class);
Assertions.assertNotNull(listModule);
//被删除的用户 查出来的是空的 //被删除的用户 查出来的是空的
mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/login") mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/login")
.content(String.format("{\"username\":\"%s\",\"password\":\"%s\"}", "delete", "deleted@metersphere.io")) .content(String.format("{\"username\":\"%s\",\"password\":\"%s\"}", "delete", "deleted@metersphere.io"))
@ -262,6 +286,17 @@ public class ProjectControllerTests extends BaseTest {
list = parseObjectFromMvcResult(mvcResult, List.class); list = parseObjectFromMvcResult(mvcResult, List.class);
//断言list是空的 //断言list是空的
Assertions.assertEquals(0, list.size()); Assertions.assertEquals(0, list.size());
mvcResult = mockMvc.perform(MockMvcRequestBuilders.get(getOptions + DEFAULT_ORGANIZATION_ID+"/apiTest")
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
listModule = parseObjectFromMvcResult(mvcResult, List.class);
Assertions.assertNotNull(listModule);
//断言list是空的
Assertions.assertEquals(0, listModule.size());
} }
@Test @Test

View File

@ -89,7 +89,6 @@
getPublicLinkCaseList, getPublicLinkCaseList,
getPublicLinkModuleTree, getPublicLinkModuleTree,
} from '@/api/modules/case-management/featureCase'; } from '@/api/modules/case-management/featureCase';
import { postTabletList } from '@/api/modules/project-management/menuManagement';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { useAppStore } from '@/store'; import { useAppStore } from '@/store';
import useFeatureCaseStore from '@/store/modules/case/featureCase'; import useFeatureCaseStore from '@/store/modules/case/featureCase';
@ -212,8 +211,8 @@
setLoadListParams({ setLoadListParams({
keyword: keyword.value, keyword: keyword.value,
sourceId: props.caseId, sourceId: props.caseId,
projectId: currentProjectId.value, // projectId: currentProjectId.value, //
sourceType: currentSelectCase.value, // sourceType: currentSelectCase.value, //
condition: { condition: {
keyword: keyword.value, keyword: keyword.value,
}, },
@ -247,25 +246,29 @@
label: t('caseManagement.featureCase.sceneCase'), label: t('caseManagement.featureCase.sceneCase'),
}, },
], ],
uiTest: [ // uiTest: [
{ // {
value: 'UI', // value: 'UI',
label: t('caseManagement.featureCase.uiCase'), // label: t('caseManagement.featureCase.uiCase'),
}, // },
], // ],
loadTest: [ // loadTest: [
{ // {
value: 'PERFORMANCE', // value: 'PERFORMANCE',
label: t('caseManagement.featureCase.propertyCase'), // label: t('caseManagement.featureCase.propertyCase'),
}, // },
], // ],
}; };
async function getEnabledModules() { async function getEnabledModules() {
const result = await postTabletList({ projectId: currentProjectId.value }); // const result = await postTabletList({ projectId: currentProjectId.value });
const caseArr = result.filter((item) => Object.keys(moduleMaps).includes(item.module)); // const caseArr = result.filter((item) => Object.keys(moduleMaps).includes(item.module));
caseArr.forEach((item: any) => { // caseArr.forEach((item: any) => {
const currentModule = moduleMaps[item.module]; // const currentModule = moduleMaps[item.module];
// caseTypeOptions.value.push(...currentModule);
// });
Object.keys(moduleMaps).forEach((item: any) => {
const currentModule = moduleMaps[item];
caseTypeOptions.value.push(...currentModule); caseTypeOptions.value.push(...currentModule);
}); });
currentSelectCase.value = caseTypeOptions.value[0].value; currentSelectCase.value = caseTypeOptions.value[0].value;