fix(接口测试): 场景列表页面增加权限
This commit is contained in:
parent
cb4bad71d6
commit
a4f567dc31
|
@ -1,3 +1,5 @@
|
||||||
|
import type { CaseLevel } from '@/components/business/ms-case-associate/types';
|
||||||
|
|
||||||
import MSR from '@/api/http/index';
|
import MSR from '@/api/http/index';
|
||||||
import {
|
import {
|
||||||
AddModuleUrl,
|
AddModuleUrl,
|
||||||
|
@ -34,6 +36,8 @@ import {
|
||||||
ScenarioTrashPageUrl,
|
ScenarioTrashPageUrl,
|
||||||
ScenarioUploadTempFileUrl,
|
ScenarioUploadTempFileUrl,
|
||||||
UpdateModuleUrl,
|
UpdateModuleUrl,
|
||||||
|
UpdateScenarioPriorityUrl,
|
||||||
|
UpdateScenarioStatusUrl,
|
||||||
UpdateScenarioUrl,
|
UpdateScenarioUrl,
|
||||||
} from '@/api/requrls/api-test/scenario';
|
} from '@/api/requrls/api-test/scenario';
|
||||||
|
|
||||||
|
@ -58,6 +62,7 @@ import {
|
||||||
ScenarioHistoryPageParams,
|
ScenarioHistoryPageParams,
|
||||||
} from '@/models/apiTest/scenario';
|
} from '@/models/apiTest/scenario';
|
||||||
import { AddModuleParams, CommonList, ModuleTreeNode, MoveModules, TransferFileParams } from '@/models/common';
|
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 as CaseRequestParam } from '@/views/api-test/components/requestComposition/index.vue';
|
||||||
import type { RequestParam } from '@/views/api-test/scenario/components/common/customApiDrawer.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) {
|
export function followScenario(id: string | number) {
|
||||||
return MSR.get({ url: FollowScenarioUrl, params: id });
|
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}` });
|
||||||
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@ export const BatchMoveScenarioUrl = '/api/scenario/batch-operation/move'; // 批
|
||||||
export const BatchCopyScenarioUrl = '/api/scenario/batch-operation/copy'; // 批量复制接口场景
|
export const BatchCopyScenarioUrl = '/api/scenario/batch-operation/copy'; // 批量复制接口场景
|
||||||
export const BatchEditScenarioUrl = '/api/scenario/batch-operation/edit'; // 批量编辑接口场景
|
export const BatchEditScenarioUrl = '/api/scenario/batch-operation/edit'; // 批量编辑接口场景
|
||||||
export const BatchRunScenarioUrl = '/api/scenario/batch-operation/run'; // 批量执行接口场景
|
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';
|
export const GetTrashModuleTreeUrl = '/api/scenario/module/trash/tree';
|
||||||
|
|
|
@ -368,6 +368,7 @@
|
||||||
'PROJECT_API_DEFINITION:READ+DELETE',
|
'PROJECT_API_DEFINITION:READ+DELETE',
|
||||||
'PROJECT_API_DEFINITION:READ+ADD',
|
'PROJECT_API_DEFINITION:READ+ADD',
|
||||||
'PROJECT_API_DEFINITION:READ+EXECUTE',
|
'PROJECT_API_DEFINITION:READ+EXECUTE',
|
||||||
|
'PROJECT_API_DEFINITION:READ+UPDATE',
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
let columns: MsTableColumn = [
|
let columns: MsTableColumn = [
|
||||||
|
@ -465,9 +466,13 @@
|
||||||
scroll: { x: '100%' },
|
scroll: { x: '100%' },
|
||||||
tableKey: props.readOnly ? undefined : TableKeyEnum.API_TEST,
|
tableKey: props.readOnly ? undefined : TableKeyEnum.API_TEST,
|
||||||
showSetting: !props.readOnly,
|
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,
|
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,
|
heightUsed: 308,
|
||||||
showSubdirectory: true,
|
showSubdirectory: true,
|
||||||
},
|
},
|
||||||
|
|
|
@ -30,7 +30,11 @@
|
||||||
>
|
>
|
||||||
{{ t('apiTestManagement.execute') }}
|
{{ t('apiTestManagement.execute') }}
|
||||||
</a-button>
|
</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') }}
|
{{ t('common.edit') }}
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<icon-down />
|
<icon-down />
|
||||||
|
@ -63,7 +67,12 @@
|
||||||
@update-follow="activeApiTab.follow = !activeApiTab.follow"
|
@update-follow="activeApiTab.follow = !activeApiTab.follow"
|
||||||
/>
|
/>
|
||||||
</a-tab-pane>
|
</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
|
<requestComposition
|
||||||
ref="requestCompositionRef"
|
ref="requestCompositionRef"
|
||||||
v-model:detail-loading="loading"
|
v-model:detail-loading="loading"
|
||||||
|
@ -88,7 +97,12 @@
|
||||||
@add-done="handleAddDone"
|
@add-done="handleAddDone"
|
||||||
/>
|
/>
|
||||||
</a-tab-pane>
|
</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
|
<caseTable
|
||||||
ref="caseTableRef"
|
ref="caseTableRef"
|
||||||
:is-api="true"
|
:is-api="true"
|
||||||
|
@ -126,6 +140,7 @@
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
import useModal from '@/hooks/useModal';
|
import useModal from '@/hooks/useModal';
|
||||||
import useAppStore from '@/store/modules/app';
|
import useAppStore from '@/store/modules/app';
|
||||||
|
import { hasAnyPermission } from '@/utils/permission';
|
||||||
|
|
||||||
import { ProtocolItem } from '@/models/apiTest/common';
|
import { ProtocolItem } from '@/models/apiTest/common';
|
||||||
import { ApiDefinitionDetail } from '@/models/apiTest/management';
|
import { ApiDefinitionDetail } from '@/models/apiTest/management';
|
||||||
|
|
|
@ -562,9 +562,15 @@
|
||||||
scroll: { x: '100%' },
|
scroll: { x: '100%' },
|
||||||
tableKey: TableKeyEnum.API_TEST_MANAGEMENT_CASE,
|
tableKey: TableKeyEnum.API_TEST_MANAGEMENT_CASE,
|
||||||
showSetting: true,
|
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,
|
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,
|
heightUsed: props.isApi ? 356 : 308,
|
||||||
showSubdirectory: true,
|
showSubdirectory: true,
|
||||||
});
|
});
|
||||||
|
|
|
@ -101,7 +101,7 @@
|
||||||
const currentTab = ref('api');
|
const currentTab = ref('api');
|
||||||
const tabOptions = [
|
const tabOptions = [
|
||||||
{ label: 'API', value: 'api' },
|
{ label: 'API', value: 'api' },
|
||||||
{ label: 'CASE', value: 'case' },
|
...(hasAnyPermission(['PROJECT_API_DEFINITION_CASE:READ']) ? [{ label: 'CASE', value: 'case' }] : []),
|
||||||
];
|
];
|
||||||
|
|
||||||
const apiRef = ref<InstanceType<typeof api>>();
|
const apiRef = ref<InstanceType<typeof api>>();
|
||||||
|
|
|
@ -61,6 +61,37 @@
|
||||||
</template>
|
</template>
|
||||||
</a-trigger>
|
</a-trigger>
|
||||||
</template>
|
</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 }">
|
<template #num="{ record }">
|
||||||
<div>
|
<div>
|
||||||
<MsButton type="text" class="float-left" style="margin-right: 4px" @click="openScenarioTab(record)">{{
|
<MsButton type="text" class="float-left" style="margin-right: 4px" @click="openScenarioTab(record)">{{
|
||||||
|
@ -105,7 +136,9 @@
|
||||||
</template>
|
</template>
|
||||||
<template #status="{ record }">
|
<template #status="{ record }">
|
||||||
<a-select
|
<a-select
|
||||||
|
v-if="hasAnyPermission(['PROJECT_API_SCENARIO:READ+UPDATE'])"
|
||||||
v-model:model-value="record.status"
|
v-model:model-value="record.status"
|
||||||
|
v-permission="['PROJECT_API_SCENARIO:READ+UPDATE']"
|
||||||
class="param-input w-full"
|
class="param-input w-full"
|
||||||
size="mini"
|
size="mini"
|
||||||
@change="() => handleStatusChange(record)"
|
@change="() => handleStatusChange(record)"
|
||||||
|
@ -117,9 +150,11 @@
|
||||||
<apiStatus :status="item" size="small" />
|
<apiStatus :status="item" size="small" />
|
||||||
</a-option>
|
</a-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
|
<apiStatus v-else :status="record.status" size="small" />
|
||||||
</template>
|
</template>
|
||||||
<template #priority="{ record }">
|
<template #priority="{ record }">
|
||||||
<a-select
|
<a-select
|
||||||
|
v-if="hasAnyPermission(['PROJECT_API_SCENARIO:READ+UPDATE'])"
|
||||||
v-model:model-value="record.priority"
|
v-model:model-value="record.priority"
|
||||||
:placeholder="t('common.pleaseSelect')"
|
:placeholder="t('common.pleaseSelect')"
|
||||||
class="param-input w-full"
|
class="param-input w-full"
|
||||||
|
@ -135,6 +170,7 @@
|
||||||
<caseLevel :case-level="item.text as CaseLevel" />
|
<caseLevel :case-level="item.text as CaseLevel" />
|
||||||
</a-option>
|
</a-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
|
<span v-else class="text-[var(--color-text-2)]"> <caseLevel :case-level="record.priority" /></span>
|
||||||
</template>
|
</template>
|
||||||
<!-- 报告结果筛选 -->
|
<!-- 报告结果筛选 -->
|
||||||
<template #lastReportStatusFilter="{ columnConfig }">
|
<template #lastReportStatusFilter="{ columnConfig }">
|
||||||
|
@ -536,7 +572,8 @@
|
||||||
getScenarioPage,
|
getScenarioPage,
|
||||||
recycleScenario,
|
recycleScenario,
|
||||||
scenarioScheduleConfig,
|
scenarioScheduleConfig,
|
||||||
updateScenario,
|
updateScenarioPro,
|
||||||
|
updateScenarioStatus,
|
||||||
} from '@/api/modules/api-test/scenario';
|
} from '@/api/modules/api-test/scenario';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
import useModal from '@/hooks/useModal';
|
import useModal from '@/hooks/useModal';
|
||||||
|
@ -550,6 +587,8 @@
|
||||||
import { ReportEnum, ReportStatus } from '@/enums/reportEnum';
|
import { ReportEnum, ReportStatus } from '@/enums/reportEnum';
|
||||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||||
|
|
||||||
|
import { casePriorityOptions } from '@/views/api-test/components/config';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
class?: string;
|
class?: string;
|
||||||
activeModule: string;
|
activeModule: string;
|
||||||
|
@ -572,7 +611,8 @@
|
||||||
const { openModal } = useModal();
|
const { openModal } = useModal();
|
||||||
const tableRecord = ref<ApiScenarioTableItem>();
|
const tableRecord = ref<ApiScenarioTableItem>();
|
||||||
const scheduleModalTitle = ref('');
|
const scheduleModalTitle = ref('');
|
||||||
|
const priorityFilterVisible = ref(false);
|
||||||
|
const priorityFilters = ref<string[]>([]);
|
||||||
const scheduleConfig = ref<ApiScenarioScheduleConfig>({
|
const scheduleConfig = ref<ApiScenarioScheduleConfig>({
|
||||||
scenarioId: '',
|
scenarioId: '',
|
||||||
enable: false,
|
enable: false,
|
||||||
|
@ -647,7 +687,12 @@
|
||||||
dataIndex: 'priority',
|
dataIndex: 'priority',
|
||||||
slotName: 'priority',
|
slotName: 'priority',
|
||||||
showDrag: true,
|
showDrag: true,
|
||||||
width: 100,
|
sortable: {
|
||||||
|
sortDirections: ['ascend', 'descend'],
|
||||||
|
sorter: true,
|
||||||
|
},
|
||||||
|
titleSlotName: 'priorityFilter',
|
||||||
|
width: 140,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'apiScenario.table.columns.status',
|
title: 'apiScenario.table.columns.status',
|
||||||
|
@ -748,9 +793,13 @@
|
||||||
scroll: { x: '100%' },
|
scroll: { x: '100%' },
|
||||||
tableKey: TableKeyEnum.API_SCENARIO,
|
tableKey: TableKeyEnum.API_SCENARIO,
|
||||||
showSetting: !props.readOnly,
|
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,
|
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,
|
heightUsed: 374,
|
||||||
showSubdirectory: true,
|
showSubdirectory: true,
|
||||||
},
|
},
|
||||||
|
@ -864,6 +913,7 @@
|
||||||
filter: {
|
filter: {
|
||||||
lastReportStatus: lastReportStatusListFilters.value,
|
lastReportStatus: lastReportStatusListFilters.value,
|
||||||
status: statusFilters.value,
|
status: statusFilters.value,
|
||||||
|
priority: priorityFilters.value,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
setLoadListParams(params);
|
setLoadListParams(params);
|
||||||
|
@ -877,6 +927,7 @@
|
||||||
if (!val) {
|
if (!val) {
|
||||||
lastReportStatusFilterVisible.value = false;
|
lastReportStatusFilterVisible.value = false;
|
||||||
statusFilterVisible.value = false;
|
statusFilterVisible.value = false;
|
||||||
|
priorityFilterVisible.value = false;
|
||||||
loadScenarioList(false);
|
loadScenarioList(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -887,6 +938,12 @@
|
||||||
loadScenarioList();
|
loadScenarioList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resetPriorityFilter() {
|
||||||
|
priorityFilterVisible.value = false;
|
||||||
|
priorityFilters.value = [];
|
||||||
|
loadScenarioList();
|
||||||
|
}
|
||||||
|
|
||||||
function resetLastReportStatusFilter() {
|
function resetLastReportStatusFilter() {
|
||||||
lastReportStatusFilterVisible.value = false;
|
lastReportStatusFilterVisible.value = false;
|
||||||
lastReportStatusListFilters.value = [];
|
lastReportStatusListFilters.value = [];
|
||||||
|
@ -895,10 +952,7 @@
|
||||||
|
|
||||||
async function handleStatusChange(record: ApiScenarioUpdateDTO) {
|
async function handleStatusChange(record: ApiScenarioUpdateDTO) {
|
||||||
try {
|
try {
|
||||||
await updateScenario({
|
await updateScenarioStatus(record.id, record.status);
|
||||||
id: record.id,
|
|
||||||
status: record.status,
|
|
||||||
});
|
|
||||||
Message.success(t('common.updateSuccess'));
|
Message.success(t('common.updateSuccess'));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
|
@ -908,10 +962,7 @@
|
||||||
|
|
||||||
async function handlePriorityStatusChange(record: ApiScenarioUpdateDTO) {
|
async function handlePriorityStatusChange(record: ApiScenarioUpdateDTO) {
|
||||||
try {
|
try {
|
||||||
await updateScenario({
|
await updateScenarioPro(record.id, record.priority);
|
||||||
id: record.id,
|
|
||||||
priority: record.priority,
|
|
||||||
});
|
|
||||||
Message.success(t('common.updateSuccess'));
|
Message.success(t('common.updateSuccess'));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
<MsEditableTab
|
<MsEditableTab
|
||||||
v-model:active-tab="activeScenarioTab"
|
v-model:active-tab="activeScenarioTab"
|
||||||
v-model:tabs="scenarioTabs"
|
v-model:tabs="scenarioTabs"
|
||||||
|
v-permission="['PROJECT_API_SCENARIO:READ+ADD']"
|
||||||
class="flex-1 overflow-hidden"
|
class="flex-1 overflow-hidden"
|
||||||
@add="() => newTab()"
|
@add="() => newTab()"
|
||||||
>
|
>
|
||||||
|
|
Loading…
Reference in New Issue