fix(系统设置): 修复系统的任务中心没有显示全部项目的缺陷

--bug=1040246 --user=王孝刚 【系统设置】系统/组织-任务中心-所属项目-下拉应该显示所有组织下的所有项目
https://www.tapd.cn/55049933/s/1511602
This commit is contained in:
wxg0103 2024-05-06 11:52:07 +08:00 committed by Craftsman
parent b7e8340a7c
commit 840acafe6f
12 changed files with 103 additions and 14 deletions

View File

@ -175,4 +175,12 @@ public class SystemProjectController {
systemProjectService.rename(request, SessionUtils.getUserId());
}
@GetMapping("/list")
@Operation(summary = "系统设置-系统-组织与项目-项目-获取所有项目")
@RequiresPermissions(PermissionConstants.SYSTEM_ORGANIZATION_PROJECT_READ)
public List<OptionDTO> getProjectList(@Schema(description = "查询关键字,根据项目名查询", requiredMode = Schema.RequiredMode.REQUIRED) @RequestParam(value = "keyword", required = false) String keyword) {
return systemProjectService.list(keyword);
}
}

View File

@ -5,7 +5,7 @@
<select id="selectListProjectByOrg" resultType="io.metersphere.system.dto.sdk.OptionDTO">
select id, name
from project
where deleted = 0
where enable = 1
and organization_id = #{organizationId}
<if test="keyword != null and keyword != ''">
and name LIKE CONCAT('%', #{keyword}, '%')

View File

@ -6,6 +6,7 @@ import io.metersphere.system.dto.ProjectDTO;
import io.metersphere.system.dto.ProjectResourcePoolDTO;
import io.metersphere.system.dto.request.ProjectMemberRequest;
import io.metersphere.system.dto.request.ProjectRequest;
import io.metersphere.system.dto.sdk.OptionDTO;
import io.metersphere.system.dto.user.UserExtendDTO;
import org.apache.ibatis.annotations.Param;
@ -34,4 +35,6 @@ public interface ExtSystemProjectMapper {
List<UserExtendDTO> getMemberByProjectId(@Param("projectId") String projectId, @Param("keyword") String keyword);
List<User> getProjectMemberByUserId(@Param("projectId") String projectId, @Param("userIds") List<String> userIds);
List<OptionDTO> getSystemProject(@Param("keyword") String keyword);
}

View File

@ -224,4 +224,14 @@
</foreach>
</if>
</select>
<select id="getSystemProject" resultType="io.metersphere.system.dto.sdk.OptionDTO">
select id, name
from project
where enable = 1
<if test="keyword != null and keyword != ''">
and name LIKE CONCAT('%', #{keyword}, '%')
</if>
order by update_time desc
limit 1000
</select>
</mapper>

View File

@ -105,4 +105,9 @@ public class SystemProjectService {
public void rename(UpdateProjectNameRequest project, String userId) {
commonProjectService.rename(project, userId);
}
public List<OptionDTO> list(String keyword) {
return extSystemProjectMapper.getSystemProject(keyword);
}
}

View File

@ -16,6 +16,7 @@ import io.metersphere.system.controller.handler.ResultHolder;
import io.metersphere.system.domain.*;
import io.metersphere.system.dto.*;
import io.metersphere.system.dto.request.*;
import io.metersphere.system.dto.sdk.OptionDTO;
import io.metersphere.system.dto.sdk.request.CustomFieldOptionRequest;
import io.metersphere.system.dto.sdk.request.PosRequest;
import io.metersphere.system.dto.sdk.request.TemplateCustomFieldRequest;
@ -1217,4 +1218,19 @@ public class SystemProjectControllerTests extends BaseTest {
apiTestCaseMapper.deleteByPrimaryKey(anotherCase.getId());
}
@Test
@Order(17)
public void getProjectListByOrgSuccess() throws Exception {
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get(prefix + "/list")
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
String contentAsString = mvcResult.getResponse().getContentAsString();
ResultHolder resultHolder = JSON.parseObject(contentAsString, ResultHolder.class);
List<OptionDTO> projectList = JSON.parseArray(JSON.toJSONString(resultHolder.getData()), OptionDTO.class);
Assertions.assertTrue(CollectionUtils.isNotEmpty(projectList));
}
}

View File

@ -1,5 +1,6 @@
// 系统全局类的接口
import MSR from '@/api/http/index';
import { getSystemProjectListUrl } from '@/api/requrls/setting/member';
import {
GetVersionUrl,
OrgOptionsUrl,
@ -32,3 +33,7 @@ export function getPackageType() {
export function getUserHasProjectPermission(userId: string) {
return MSR.get({ url: `${userHasProjectPermissionUrl}/${userId}` });
}
export function getSystemProjectList(keyword: string) {
return MSR.get({ url: getSystemProjectListUrl, params: { keyword } });
}

View File

@ -12,3 +12,4 @@ export const getUserGroupList = '/organization/user/role/list';
export const getUserList = '/organization/not-exist/user/list';
// 获取弹窗里边的穿梭项目列表
export const getProjectListUrl = '/organization/project/list';
export const getSystemProjectListUrl = '/system/project/list'; // 获取系统项目列表

View File

@ -8,7 +8,7 @@ import {
getUserByProjectByOrg,
} from '@/api/modules/setting/organizationAndProject';
import { getOrgUserGroupOption, getSystemUserGroupOption } from '@/api/modules/setting/usergroup';
import { getOrgOptions } from '@/api/modules/system';
import { getOrgOptions, getSystemProjectList } from '@/api/modules/system';
// eslint-disable-next-line no-shadow
export enum UserRequestTypeEnum {
SYSTEM_USER_GROUP = 'SYSTEM_USER_GROUP',
@ -25,6 +25,7 @@ export enum UserRequestTypeEnum {
PROJECT_PERMISSION_MEMBER = 'PROJECT_PERMISSION_MEMBER',
PROJECT_USER_GROUP = 'PROJECT_USER_GROUP',
SYSTEM_ORGANIZATION_LIST = 'SYSTEM_ORGANIZATION_LIST',
SYSTEM_PROJECT_LIST = 'SYSTEM_PROJECT_LIST',
}
export default function initOptionsFunc(type: string, params: Record<string, any>) {
if (type === UserRequestTypeEnum.SYSTEM_USER_GROUP) {
@ -71,4 +72,8 @@ export default function initOptionsFunc(type: string, params: Record<string, any
// 系统-组织
return getOrgOptions();
}
if (type === UserRequestTypeEnum.SYSTEM_PROJECT_LIST) {
// 系统-项目 获取系统下所有的项目
return getSystemProjectList(params.keyword);
}
}

View File

@ -107,7 +107,7 @@
//
const initProjectMemberOptions = async () => {
try {
if (lastProjectId) {
if (lastProjectId.value) {
const result = await getProjectMemberOptions(lastProjectId.value);
memberList.value = result;
}

View File

@ -102,7 +102,7 @@
</template>
</TableFilter>
</template>
<template v-if="appStore.packageType === 'enterprise'" #orgFilterName="{ columnConfig }">
<template v-if="appStore.packageType === 'enterprise' && xPack" #orgFilterName="{ columnConfig }">
<TableFilter
v-model:visible="orgFilterVisible"
v-model:status-filters="orgFiltersMap[props.moduleType]"
@ -110,13 +110,26 @@
mode="remote"
value-key="id"
label-key="name"
:type="UserRequestTypeEnum.SYSTEM_ORGANIZATION_LIST"
:type="
groupColumnsMap[props.group].key === TableKeyEnum.TASK_SCHEDULE_TASK_SYSTEM
? UserRequestTypeEnum.SYSTEM_PROJECT_LIST
: UserRequestTypeEnum.SYSTEM_ORGANIZATION_PROJECT
"
:placeholder-text="t('project.taskCenter.filterOrgPlaceholderText')"
@search="initData()"
>
</TableFilter>
</template>
<template #projectFilterName="{ columnConfig }">
<template
v-if="
hasAnyPermission(
groupColumnsMap[props.group].key === TableKeyEnum.TASK_API_CASE_SYSTEM
? ['SYSTEM_ORGANIZATION_PROJECT:READ']
: ['ORGANIZATION_PROJECT:READ']
)
"
#projectFilterName="{ columnConfig }"
>
<TableFilter
v-model:visible="projectFilterVisible"
v-model:status-filters="projectFiltersMap[props.moduleType]"
@ -124,7 +137,11 @@
mode="remote"
:load-option-params="{ organizationId: appStore.currentOrgId }"
:placeholder-text="t('project.taskCenter.filterProPlaceholderText')"
:type="UserRequestTypeEnum.SYSTEM_ORGANIZATION_PROJECT"
:type="
groupColumnsMap[props.group].key === TableKeyEnum.TASK_API_CASE_SYSTEM
? UserRequestTypeEnum.SYSTEM_PROJECT_LIST
: UserRequestTypeEnum.SYSTEM_ORGANIZATION_PROJECT
"
@search="initData()"
>
</TableFilter>
@ -179,7 +196,7 @@
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { computed, ref } from 'vue';
import { Message } from '@arco-design/web-vue';
import dayjs from 'dayjs';
@ -208,6 +225,7 @@
import useModal from '@/hooks/useModal';
import useOpenNewPage from '@/hooks/useOpenNewPage';
import { useAppStore, useTableStore } from '@/store';
import useLicenseStore from '@/store/modules/setting/license';
import { characterLimit } from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
@ -455,6 +473,8 @@
API_CASE: projectApiCaseFilter.value,
API_SCENARIO: projectApiScenarioFilter.value,
});
const licenseStore = useLicenseStore();
const xPack = computed(() => licenseStore.hasLicense());
function initData() {
setLoadListParams({
@ -469,7 +489,6 @@
});
loadList();
}
function handleFilterReset() {
statusFiltersMap.value[props.moduleType] = [];
statusFilterVisible.value = false;
@ -517,7 +536,7 @@
await loadRealMap.value[props.group].batchStop({
moduleType: props.moduleType,
selectIds: selectIds || [],
selectAll: !!selectAll,
selectAll,
excludeIds: excludeIds || [],
condition: {
keyword: keyword.value,

View File

@ -65,7 +65,7 @@
</a-option>
</a-select>
</template>
<template v-if="appStore.packageType === 'enterprise'" #orgFilterName="{ columnConfig }">
<template v-if="appStore.packageType === 'enterprise' && xPack" #orgFilterName="{ columnConfig }">
<TableFilter
v-model:visible="orgFilterVisible"
v-model:status-filters="orgFiltersMap[props.moduleType]"
@ -79,7 +79,16 @@
>
</TableFilter>
</template>
<template #projectFilterName="{ columnConfig }">
<template
v-if="
hasAnyPermission(
groupColumnsMap[props.group].key === TableKeyEnum.TASK_SCHEDULE_TASK_SYSTEM
? ['SYSTEM_ORGANIZATION_PROJECT:READ']
: ['ORGANIZATION_PROJECT:READ']
)
"
#projectFilterName="{ columnConfig }"
>
<TableFilter
v-model:visible="projectFilterVisible"
v-model:status-filters="projectFiltersMap[props.moduleType]"
@ -87,7 +96,11 @@
mode="remote"
:load-option-params="{ organizationId: appStore.currentOrgId }"
:placeholder-text="t('project.taskCenter.filterProPlaceholderText')"
:type="UserRequestTypeEnum.SYSTEM_ORGANIZATION_PROJECT"
:type="
groupColumnsMap[props.group].key === TableKeyEnum.TASK_SCHEDULE_TASK_SYSTEM
? UserRequestTypeEnum.SYSTEM_PROJECT_LIST
: UserRequestTypeEnum.SYSTEM_ORGANIZATION_PROJECT
"
@search="initData()"
>
</TableFilter>
@ -118,7 +131,7 @@
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { computed, ref } from 'vue';
import { Message } from '@arco-design/web-vue';
import dayjs from 'dayjs';
@ -154,6 +167,7 @@
import useModal from '@/hooks/useModal';
import useOpenNewPage from '@/hooks/useOpenNewPage';
import { useAppStore, useTableStore } from '@/store';
import useLicenseStore from '@/store/modules/setting/license';
import { hasAnyPermission } from '@/utils/permission';
import { BatchApiParams } from '@/models/common';
@ -352,6 +366,9 @@
const hasJumpPermission = computed(() => hasAnyPermission(permissionsMap[props.group][props.moduleType].jump));
const licenseStore = useLicenseStore();
const xPack = computed(() => licenseStore.hasLicense());
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable(
loadRealMap.value[props.group].list,
{