fix(接口测试): 场景列表页面增加权限

This commit is contained in:
wxg0103 2024-04-02 17:27:11 +08:00 committed by 刘瑞斌
parent cb4bad71d6
commit a4f567dc31
8 changed files with 115 additions and 21 deletions

View File

@ -1,3 +1,5 @@
import type { CaseLevel } from '@/components/business/ms-case-associate/types';
import MSR from '@/api/http/index';
import {
AddModuleUrl,
@ -34,6 +36,8 @@ import {
ScenarioTrashPageUrl,
ScenarioUploadTempFileUrl,
UpdateModuleUrl,
UpdateScenarioPriorityUrl,
UpdateScenarioStatusUrl,
UpdateScenarioUrl,
} from '@/api/requrls/api-test/scenario';
@ -58,6 +62,7 @@ import {
ScenarioHistoryPageParams,
} from '@/models/apiTest/scenario';
import { AddModuleParams, CommonList, ModuleTreeNode, MoveModules, TransferFileParams } from '@/models/common';
import { ApiScenarioStatus } from '@/enums/apiEnum';
import type { RequestParam as CaseRequestParam } from '@/views/api-test/components/requestComposition/index.vue';
import type { RequestParam } from '@/views/api-test/scenario/components/common/customApiDrawer.vue';
@ -264,3 +269,12 @@ export function getSystemRequest(data: GetSystemRequestParams) {
export function followScenario(id: string | number) {
return MSR.get({ url: FollowScenarioUrl, params: id });
}
// 更新场景状态
export function updateScenarioStatus(id: string | number, status: ApiScenarioStatus | undefined) {
return MSR.get({ url: `${UpdateScenarioStatusUrl}/${id}/${status}` });
}
export function updateScenarioPro(id: string | number, priority: CaseLevel | undefined) {
return MSR.get({ url: `${UpdateScenarioPriorityUrl}/${id}/${priority}` });
}

View File

@ -24,6 +24,8 @@ export const BatchMoveScenarioUrl = '/api/scenario/batch-operation/move'; // 批
export const BatchCopyScenarioUrl = '/api/scenario/batch-operation/copy'; // 批量复制接口场景
export const BatchEditScenarioUrl = '/api/scenario/batch-operation/edit'; // 批量编辑接口场景
export const BatchRunScenarioUrl = '/api/scenario/batch-operation/run'; // 批量执行接口场景
export const UpdateScenarioPriorityUrl = '/api/scenario/update-priority'; // 场景更新等级
export const UpdateScenarioStatusUrl = '/api/scenario/update-status'; // 场景更新状态
// 回收站相关
export const GetTrashModuleTreeUrl = '/api/scenario/module/trash/tree';

View File

@ -368,6 +368,7 @@
'PROJECT_API_DEFINITION:READ+DELETE',
'PROJECT_API_DEFINITION:READ+ADD',
'PROJECT_API_DEFINITION:READ+EXECUTE',
'PROJECT_API_DEFINITION:READ+UPDATE',
])
);
let columns: MsTableColumn = [
@ -465,9 +466,13 @@
scroll: { x: '100%' },
tableKey: props.readOnly ? undefined : TableKeyEnum.API_TEST,
showSetting: !props.readOnly,
selectable: true,
selectable: hasAnyPermission([
'PROJECT_API_DEFINITION:READ+DELETE',
'PROJECT_API_DEFINITION:READ+EXECUTE',
'PROJECT_API_DEFINITION:READ+UPDATE',
]),
showSelectAll: !props.readOnly,
draggable: props.readOnly ? undefined : { type: 'handle', width: 32 },
draggable: hasAnyPermission(['PROJECT_API_DEFINITION:READ+UPDATE']) ? { type: 'handle', width: 32 } : undefined,
heightUsed: 308,
showSubdirectory: true,
},

View File

@ -30,7 +30,11 @@
>
{{ t('apiTestManagement.execute') }}
</a-button>
<a-dropdown-button type="outline" @click="toEditDefinition">
<a-dropdown-button
v-permission="['PROJECT_API_DEFINITION:READ+UPDATE']"
type="outline"
@click="toEditDefinition"
>
{{ t('common.edit') }}
<template #icon>
<icon-down />
@ -63,7 +67,12 @@
@update-follow="activeApiTab.follow = !activeApiTab.follow"
/>
</a-tab-pane>
<a-tab-pane key="definition" :title="t('apiTestManagement.definition')" class="ms-api-tab-pane">
<a-tab-pane
v-if="hasAnyPermission(['PROJECT_API_DEFINITION:READ+UPDATE', 'PROJECT_API_DEFINITION:READ+ADD'])"
key="definition"
:title="t('apiTestManagement.definition')"
class="ms-api-tab-pane"
>
<requestComposition
ref="requestCompositionRef"
v-model:detail-loading="loading"
@ -88,7 +97,12 @@
@add-done="handleAddDone"
/>
</a-tab-pane>
<a-tab-pane v-if="!activeApiTab.isNew" key="case" :title="t('apiTestManagement.case')" class="ms-api-tab-pane">
<a-tab-pane
v-if="!activeApiTab.isNew && hasAnyPermission(['PROJECT_API_DEFINITION_CASE:READ'])"
key="case"
:title="t('apiTestManagement.case')"
class="ms-api-tab-pane"
>
<caseTable
ref="caseTableRef"
:is-api="true"
@ -126,6 +140,7 @@
import { useI18n } from '@/hooks/useI18n';
import useModal from '@/hooks/useModal';
import useAppStore from '@/store/modules/app';
import { hasAnyPermission } from '@/utils/permission';
import { ProtocolItem } from '@/models/apiTest/common';
import { ApiDefinitionDetail } from '@/models/apiTest/management';

View File

@ -562,9 +562,15 @@
scroll: { x: '100%' },
tableKey: TableKeyEnum.API_TEST_MANAGEMENT_CASE,
showSetting: true,
selectable: true,
selectable: hasAnyPermission([
'PROJECT_API_DEFINITION_CASE:READ+DELETE',
'PROJECT_API_DEFINITION_CASE:READ+EXECUTE',
'PROJECT_API_DEFINITION_CASE:READ+UPDATE',
]),
showSelectAll: true,
draggable: { type: 'handle', width: 32 },
draggable: hasAnyPermission(['PROJECT_API_DEFINITION_CASE:READ+UPDATE'])
? { type: 'handle', width: 32 }
: undefined,
heightUsed: props.isApi ? 356 : 308,
showSubdirectory: true,
});

View File

@ -101,7 +101,7 @@
const currentTab = ref('api');
const tabOptions = [
{ label: 'API', value: 'api' },
{ label: 'CASE', value: 'case' },
...(hasAnyPermission(['PROJECT_API_DEFINITION_CASE:READ']) ? [{ label: 'CASE', value: 'case' }] : []),
];
const apiRef = ref<InstanceType<typeof api>>();

View File

@ -61,6 +61,37 @@
</template>
</a-trigger>
</template>
<template #priorityFilter="{ columnConfig }">
<a-trigger
v-model:popup-visible="priorityFilterVisible"
trigger="click"
@popup-visible-change="handleFilterHidden"
>
<MsButton type="text" class="arco-btn-text--secondary ml-[10px]" @click="priorityFilterVisible = true">
{{ t(columnConfig.title as string) }}
<icon-down :class="priorityFilterVisible ? 'text-[rgb(var(--primary-5))]' : ''" />
</MsButton>
<template #content>
<div class="arco-table-filters-content">
<div class="ml-[6px] flex items-center justify-start px-[6px] py-[2px]">
<a-checkbox-group v-model:model-value="priorityFilters" direction="vertical" size="small">
<a-checkbox v-for="item of casePriorityOptions" :key="item.value" :value="item.value">
<caseLevel :case-level="item.label as CaseLevel" />
</a-checkbox>
</a-checkbox-group>
</div>
<div class="filter-button">
<a-button size="mini" class="mr-[8px]" @click="resetPriorityFilter">
{{ t('common.reset') }}
</a-button>
<a-button type="primary" size="mini" @click="handleFilterHidden(false)">
{{ t('system.orgTemplate.confirm') }}
</a-button>
</div>
</div>
</template>
</a-trigger>
</template>
<template #num="{ record }">
<div>
<MsButton type="text" class="float-left" style="margin-right: 4px" @click="openScenarioTab(record)">{{
@ -105,7 +136,9 @@
</template>
<template #status="{ record }">
<a-select
v-if="hasAnyPermission(['PROJECT_API_SCENARIO:READ+UPDATE'])"
v-model:model-value="record.status"
v-permission="['PROJECT_API_SCENARIO:READ+UPDATE']"
class="param-input w-full"
size="mini"
@change="() => handleStatusChange(record)"
@ -117,9 +150,11 @@
<apiStatus :status="item" size="small" />
</a-option>
</a-select>
<apiStatus v-else :status="record.status" size="small" />
</template>
<template #priority="{ record }">
<a-select
v-if="hasAnyPermission(['PROJECT_API_SCENARIO:READ+UPDATE'])"
v-model:model-value="record.priority"
:placeholder="t('common.pleaseSelect')"
class="param-input w-full"
@ -135,6 +170,7 @@
<caseLevel :case-level="item.text as CaseLevel" />
</a-option>
</a-select>
<span v-else class="text-[var(--color-text-2)]"> <caseLevel :case-level="record.priority" /></span>
</template>
<!-- 报告结果筛选 -->
<template #lastReportStatusFilter="{ columnConfig }">
@ -536,7 +572,8 @@
getScenarioPage,
recycleScenario,
scenarioScheduleConfig,
updateScenario,
updateScenarioPro,
updateScenarioStatus,
} from '@/api/modules/api-test/scenario';
import { useI18n } from '@/hooks/useI18n';
import useModal from '@/hooks/useModal';
@ -550,6 +587,8 @@
import { ReportEnum, ReportStatus } from '@/enums/reportEnum';
import { TableKeyEnum } from '@/enums/tableEnum';
import { casePriorityOptions } from '@/views/api-test/components/config';
const props = defineProps<{
class?: string;
activeModule: string;
@ -572,7 +611,8 @@
const { openModal } = useModal();
const tableRecord = ref<ApiScenarioTableItem>();
const scheduleModalTitle = ref('');
const priorityFilterVisible = ref(false);
const priorityFilters = ref<string[]>([]);
const scheduleConfig = ref<ApiScenarioScheduleConfig>({
scenarioId: '',
enable: false,
@ -647,7 +687,12 @@
dataIndex: 'priority',
slotName: 'priority',
showDrag: true,
width: 100,
sortable: {
sortDirections: ['ascend', 'descend'],
sorter: true,
},
titleSlotName: 'priorityFilter',
width: 140,
},
{
title: 'apiScenario.table.columns.status',
@ -748,9 +793,13 @@
scroll: { x: '100%' },
tableKey: TableKeyEnum.API_SCENARIO,
showSetting: !props.readOnly,
selectable: true,
selectable: hasAnyPermission([
'PROJECT_API_SCENARIO:READ+UPDATE',
'PROJECT_API_SCENARIO:READ+EXECUTE',
'PROJECT_API_SCENARIO:READ+DELETE',
]),
showSelectAll: !props.readOnly,
draggable: props.readOnly ? undefined : { type: 'handle', width: 32 },
draggable: hasAnyPermission(['PROJECT_API_SCENARIO:READ+UPDATE']) ? { type: 'handle', width: 32 } : undefined,
heightUsed: 374,
showSubdirectory: true,
},
@ -864,6 +913,7 @@
filter: {
lastReportStatus: lastReportStatusListFilters.value,
status: statusFilters.value,
priority: priorityFilters.value,
},
};
setLoadListParams(params);
@ -877,6 +927,7 @@
if (!val) {
lastReportStatusFilterVisible.value = false;
statusFilterVisible.value = false;
priorityFilterVisible.value = false;
loadScenarioList(false);
}
}
@ -887,6 +938,12 @@
loadScenarioList();
}
function resetPriorityFilter() {
priorityFilterVisible.value = false;
priorityFilters.value = [];
loadScenarioList();
}
function resetLastReportStatusFilter() {
lastReportStatusFilterVisible.value = false;
lastReportStatusListFilters.value = [];
@ -895,10 +952,7 @@
async function handleStatusChange(record: ApiScenarioUpdateDTO) {
try {
await updateScenario({
id: record.id,
status: record.status,
});
await updateScenarioStatus(record.id, record.status);
Message.success(t('common.updateSuccess'));
} catch (error) {
// eslint-disable-next-line no-console
@ -908,10 +962,7 @@
async function handlePriorityStatusChange(record: ApiScenarioUpdateDTO) {
try {
await updateScenario({
id: record.id,
priority: record.priority,
});
await updateScenarioPro(record.id, record.priority);
Message.success(t('common.updateSuccess'));
} catch (error) {
// eslint-disable-next-line no-console

View File

@ -4,6 +4,7 @@
<MsEditableTab
v-model:active-tab="activeScenarioTab"
v-model:tabs="scenarioTabs"
v-permission="['PROJECT_API_SCENARIO:READ+ADD']"
class="flex-1 overflow-hidden"
@add="() => newTab()"
>