fix(系统设置): 修复系统的任务中心没有显示全部项目的缺陷
--bug=1040246 --user=王孝刚 【系统设置】系统/组织-任务中心-所属项目-下拉应该显示所有组织下的所有项目 https://www.tapd.cn/55049933/s/1511602
This commit is contained in:
parent
b7e8340a7c
commit
840acafe6f
|
@ -175,4 +175,12 @@ public class SystemProjectController {
|
||||||
systemProjectService.rename(request, SessionUtils.getUserId());
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<select id="selectListProjectByOrg" resultType="io.metersphere.system.dto.sdk.OptionDTO">
|
<select id="selectListProjectByOrg" resultType="io.metersphere.system.dto.sdk.OptionDTO">
|
||||||
select id, name
|
select id, name
|
||||||
from project
|
from project
|
||||||
where deleted = 0
|
where enable = 1
|
||||||
and organization_id = #{organizationId}
|
and organization_id = #{organizationId}
|
||||||
<if test="keyword != null and keyword != ''">
|
<if test="keyword != null and keyword != ''">
|
||||||
and name LIKE CONCAT('%', #{keyword}, '%')
|
and name LIKE CONCAT('%', #{keyword}, '%')
|
||||||
|
|
|
@ -6,6 +6,7 @@ import io.metersphere.system.dto.ProjectDTO;
|
||||||
import io.metersphere.system.dto.ProjectResourcePoolDTO;
|
import io.metersphere.system.dto.ProjectResourcePoolDTO;
|
||||||
import io.metersphere.system.dto.request.ProjectMemberRequest;
|
import io.metersphere.system.dto.request.ProjectMemberRequest;
|
||||||
import io.metersphere.system.dto.request.ProjectRequest;
|
import io.metersphere.system.dto.request.ProjectRequest;
|
||||||
|
import io.metersphere.system.dto.sdk.OptionDTO;
|
||||||
import io.metersphere.system.dto.user.UserExtendDTO;
|
import io.metersphere.system.dto.user.UserExtendDTO;
|
||||||
import org.apache.ibatis.annotations.Param;
|
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<UserExtendDTO> getMemberByProjectId(@Param("projectId") String projectId, @Param("keyword") String keyword);
|
||||||
|
|
||||||
List<User> getProjectMemberByUserId(@Param("projectId") String projectId, @Param("userIds") List<String> userIds);
|
List<User> getProjectMemberByUserId(@Param("projectId") String projectId, @Param("userIds") List<String> userIds);
|
||||||
|
List<OptionDTO> getSystemProject(@Param("keyword") String keyword);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -224,4 +224,14 @@
|
||||||
</foreach>
|
</foreach>
|
||||||
</if>
|
</if>
|
||||||
</select>
|
</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>
|
</mapper>
|
|
@ -105,4 +105,9 @@ public class SystemProjectService {
|
||||||
public void rename(UpdateProjectNameRequest project, String userId) {
|
public void rename(UpdateProjectNameRequest project, String userId) {
|
||||||
commonProjectService.rename(project, userId);
|
commonProjectService.rename(project, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<OptionDTO> list(String keyword) {
|
||||||
|
return extSystemProjectMapper.getSystemProject(keyword);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import io.metersphere.system.controller.handler.ResultHolder;
|
||||||
import io.metersphere.system.domain.*;
|
import io.metersphere.system.domain.*;
|
||||||
import io.metersphere.system.dto.*;
|
import io.metersphere.system.dto.*;
|
||||||
import io.metersphere.system.dto.request.*;
|
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.CustomFieldOptionRequest;
|
||||||
import io.metersphere.system.dto.sdk.request.PosRequest;
|
import io.metersphere.system.dto.sdk.request.PosRequest;
|
||||||
import io.metersphere.system.dto.sdk.request.TemplateCustomFieldRequest;
|
import io.metersphere.system.dto.sdk.request.TemplateCustomFieldRequest;
|
||||||
|
@ -1217,4 +1218,19 @@ public class SystemProjectControllerTests extends BaseTest {
|
||||||
apiTestCaseMapper.deleteByPrimaryKey(anotherCase.getId());
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// 系统全局类的接口
|
// 系统全局类的接口
|
||||||
import MSR from '@/api/http/index';
|
import MSR from '@/api/http/index';
|
||||||
|
import { getSystemProjectListUrl } from '@/api/requrls/setting/member';
|
||||||
import {
|
import {
|
||||||
GetVersionUrl,
|
GetVersionUrl,
|
||||||
OrgOptionsUrl,
|
OrgOptionsUrl,
|
||||||
|
@ -32,3 +33,7 @@ export function getPackageType() {
|
||||||
export function getUserHasProjectPermission(userId: string) {
|
export function getUserHasProjectPermission(userId: string) {
|
||||||
return MSR.get({ url: `${userHasProjectPermissionUrl}/${userId}` });
|
return MSR.get({ url: `${userHasProjectPermissionUrl}/${userId}` });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getSystemProjectList(keyword: string) {
|
||||||
|
return MSR.get({ url: getSystemProjectListUrl, params: { keyword } });
|
||||||
|
}
|
||||||
|
|
|
@ -12,3 +12,4 @@ export const getUserGroupList = '/organization/user/role/list';
|
||||||
export const getUserList = '/organization/not-exist/user/list';
|
export const getUserList = '/organization/not-exist/user/list';
|
||||||
// 获取弹窗里边的穿梭项目列表
|
// 获取弹窗里边的穿梭项目列表
|
||||||
export const getProjectListUrl = '/organization/project/list';
|
export const getProjectListUrl = '/organization/project/list';
|
||||||
|
export const getSystemProjectListUrl = '/system/project/list'; // 获取系统项目列表
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {
|
||||||
getUserByProjectByOrg,
|
getUserByProjectByOrg,
|
||||||
} from '@/api/modules/setting/organizationAndProject';
|
} from '@/api/modules/setting/organizationAndProject';
|
||||||
import { getOrgUserGroupOption, getSystemUserGroupOption } from '@/api/modules/setting/usergroup';
|
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
|
// eslint-disable-next-line no-shadow
|
||||||
export enum UserRequestTypeEnum {
|
export enum UserRequestTypeEnum {
|
||||||
SYSTEM_USER_GROUP = 'SYSTEM_USER_GROUP',
|
SYSTEM_USER_GROUP = 'SYSTEM_USER_GROUP',
|
||||||
|
@ -25,6 +25,7 @@ export enum UserRequestTypeEnum {
|
||||||
PROJECT_PERMISSION_MEMBER = 'PROJECT_PERMISSION_MEMBER',
|
PROJECT_PERMISSION_MEMBER = 'PROJECT_PERMISSION_MEMBER',
|
||||||
PROJECT_USER_GROUP = 'PROJECT_USER_GROUP',
|
PROJECT_USER_GROUP = 'PROJECT_USER_GROUP',
|
||||||
SYSTEM_ORGANIZATION_LIST = 'SYSTEM_ORGANIZATION_LIST',
|
SYSTEM_ORGANIZATION_LIST = 'SYSTEM_ORGANIZATION_LIST',
|
||||||
|
SYSTEM_PROJECT_LIST = 'SYSTEM_PROJECT_LIST',
|
||||||
}
|
}
|
||||||
export default function initOptionsFunc(type: string, params: Record<string, any>) {
|
export default function initOptionsFunc(type: string, params: Record<string, any>) {
|
||||||
if (type === UserRequestTypeEnum.SYSTEM_USER_GROUP) {
|
if (type === UserRequestTypeEnum.SYSTEM_USER_GROUP) {
|
||||||
|
@ -71,4 +72,8 @@ export default function initOptionsFunc(type: string, params: Record<string, any
|
||||||
// 系统-组织
|
// 系统-组织
|
||||||
return getOrgOptions();
|
return getOrgOptions();
|
||||||
}
|
}
|
||||||
|
if (type === UserRequestTypeEnum.SYSTEM_PROJECT_LIST) {
|
||||||
|
// 系统-项目 获取系统下所有的项目
|
||||||
|
return getSystemProjectList(params.keyword);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,7 @@
|
||||||
// 初始化项目成员
|
// 初始化项目成员
|
||||||
const initProjectMemberOptions = async () => {
|
const initProjectMemberOptions = async () => {
|
||||||
try {
|
try {
|
||||||
if (lastProjectId) {
|
if (lastProjectId.value) {
|
||||||
const result = await getProjectMemberOptions(lastProjectId.value);
|
const result = await getProjectMemberOptions(lastProjectId.value);
|
||||||
memberList.value = result;
|
memberList.value = result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,7 +102,7 @@
|
||||||
</template>
|
</template>
|
||||||
</TableFilter>
|
</TableFilter>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="appStore.packageType === 'enterprise'" #orgFilterName="{ columnConfig }">
|
<template v-if="appStore.packageType === 'enterprise' && xPack" #orgFilterName="{ columnConfig }">
|
||||||
<TableFilter
|
<TableFilter
|
||||||
v-model:visible="orgFilterVisible"
|
v-model:visible="orgFilterVisible"
|
||||||
v-model:status-filters="orgFiltersMap[props.moduleType]"
|
v-model:status-filters="orgFiltersMap[props.moduleType]"
|
||||||
|
@ -110,13 +110,26 @@
|
||||||
mode="remote"
|
mode="remote"
|
||||||
value-key="id"
|
value-key="id"
|
||||||
label-key="name"
|
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')"
|
:placeholder-text="t('project.taskCenter.filterOrgPlaceholderText')"
|
||||||
@search="initData()"
|
@search="initData()"
|
||||||
>
|
>
|
||||||
</TableFilter>
|
</TableFilter>
|
||||||
</template>
|
</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
|
<TableFilter
|
||||||
v-model:visible="projectFilterVisible"
|
v-model:visible="projectFilterVisible"
|
||||||
v-model:status-filters="projectFiltersMap[props.moduleType]"
|
v-model:status-filters="projectFiltersMap[props.moduleType]"
|
||||||
|
@ -124,7 +137,11 @@
|
||||||
mode="remote"
|
mode="remote"
|
||||||
:load-option-params="{ organizationId: appStore.currentOrgId }"
|
:load-option-params="{ organizationId: appStore.currentOrgId }"
|
||||||
:placeholder-text="t('project.taskCenter.filterProPlaceholderText')"
|
: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()"
|
@search="initData()"
|
||||||
>
|
>
|
||||||
</TableFilter>
|
</TableFilter>
|
||||||
|
@ -179,7 +196,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { Message } from '@arco-design/web-vue';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
|
@ -208,6 +225,7 @@
|
||||||
import useModal from '@/hooks/useModal';
|
import useModal from '@/hooks/useModal';
|
||||||
import useOpenNewPage from '@/hooks/useOpenNewPage';
|
import useOpenNewPage from '@/hooks/useOpenNewPage';
|
||||||
import { useAppStore, useTableStore } from '@/store';
|
import { useAppStore, useTableStore } from '@/store';
|
||||||
|
import useLicenseStore from '@/store/modules/setting/license';
|
||||||
import { characterLimit } from '@/utils';
|
import { characterLimit } from '@/utils';
|
||||||
import { hasAnyPermission } from '@/utils/permission';
|
import { hasAnyPermission } from '@/utils/permission';
|
||||||
|
|
||||||
|
@ -455,6 +473,8 @@
|
||||||
API_CASE: projectApiCaseFilter.value,
|
API_CASE: projectApiCaseFilter.value,
|
||||||
API_SCENARIO: projectApiScenarioFilter.value,
|
API_SCENARIO: projectApiScenarioFilter.value,
|
||||||
});
|
});
|
||||||
|
const licenseStore = useLicenseStore();
|
||||||
|
const xPack = computed(() => licenseStore.hasLicense());
|
||||||
|
|
||||||
function initData() {
|
function initData() {
|
||||||
setLoadListParams({
|
setLoadListParams({
|
||||||
|
@ -469,7 +489,6 @@
|
||||||
});
|
});
|
||||||
loadList();
|
loadList();
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleFilterReset() {
|
function handleFilterReset() {
|
||||||
statusFiltersMap.value[props.moduleType] = [];
|
statusFiltersMap.value[props.moduleType] = [];
|
||||||
statusFilterVisible.value = false;
|
statusFilterVisible.value = false;
|
||||||
|
@ -517,7 +536,7 @@
|
||||||
await loadRealMap.value[props.group].batchStop({
|
await loadRealMap.value[props.group].batchStop({
|
||||||
moduleType: props.moduleType,
|
moduleType: props.moduleType,
|
||||||
selectIds: selectIds || [],
|
selectIds: selectIds || [],
|
||||||
selectAll: !!selectAll,
|
selectAll,
|
||||||
excludeIds: excludeIds || [],
|
excludeIds: excludeIds || [],
|
||||||
condition: {
|
condition: {
|
||||||
keyword: keyword.value,
|
keyword: keyword.value,
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
</a-option>
|
</a-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="appStore.packageType === 'enterprise'" #orgFilterName="{ columnConfig }">
|
<template v-if="appStore.packageType === 'enterprise' && xPack" #orgFilterName="{ columnConfig }">
|
||||||
<TableFilter
|
<TableFilter
|
||||||
v-model:visible="orgFilterVisible"
|
v-model:visible="orgFilterVisible"
|
||||||
v-model:status-filters="orgFiltersMap[props.moduleType]"
|
v-model:status-filters="orgFiltersMap[props.moduleType]"
|
||||||
|
@ -79,7 +79,16 @@
|
||||||
>
|
>
|
||||||
</TableFilter>
|
</TableFilter>
|
||||||
</template>
|
</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
|
<TableFilter
|
||||||
v-model:visible="projectFilterVisible"
|
v-model:visible="projectFilterVisible"
|
||||||
v-model:status-filters="projectFiltersMap[props.moduleType]"
|
v-model:status-filters="projectFiltersMap[props.moduleType]"
|
||||||
|
@ -87,7 +96,11 @@
|
||||||
mode="remote"
|
mode="remote"
|
||||||
:load-option-params="{ organizationId: appStore.currentOrgId }"
|
:load-option-params="{ organizationId: appStore.currentOrgId }"
|
||||||
:placeholder-text="t('project.taskCenter.filterProPlaceholderText')"
|
: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()"
|
@search="initData()"
|
||||||
>
|
>
|
||||||
</TableFilter>
|
</TableFilter>
|
||||||
|
@ -118,7 +131,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import { Message } from '@arco-design/web-vue';
|
import { Message } from '@arco-design/web-vue';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
|
@ -154,6 +167,7 @@
|
||||||
import useModal from '@/hooks/useModal';
|
import useModal from '@/hooks/useModal';
|
||||||
import useOpenNewPage from '@/hooks/useOpenNewPage';
|
import useOpenNewPage from '@/hooks/useOpenNewPage';
|
||||||
import { useAppStore, useTableStore } from '@/store';
|
import { useAppStore, useTableStore } from '@/store';
|
||||||
|
import useLicenseStore from '@/store/modules/setting/license';
|
||||||
import { hasAnyPermission } from '@/utils/permission';
|
import { hasAnyPermission } from '@/utils/permission';
|
||||||
|
|
||||||
import { BatchApiParams } from '@/models/common';
|
import { BatchApiParams } from '@/models/common';
|
||||||
|
@ -352,6 +366,9 @@
|
||||||
|
|
||||||
const hasJumpPermission = computed(() => hasAnyPermission(permissionsMap[props.group][props.moduleType].jump));
|
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(
|
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable(
|
||||||
loadRealMap.value[props.group].list,
|
loadRealMap.value[props.group].list,
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue