feat(接口测试): 接口测试报告列表
This commit is contained in:
parent
0a902b5781
commit
79bdb3eee2
|
@ -1,18 +1,39 @@
|
|||
import MSR from '@/api/http';
|
||||
import * as orgUrl from '@/api/requrls/setting/organizationAndProject';
|
||||
import * as reportUrl from '@/api/requrls/api-test/report';
|
||||
|
||||
import type { TableQueryParams } from '@/models/common';
|
||||
import { ReportEnum } from '@/enums/reportEnum';
|
||||
|
||||
// 报告列表
|
||||
export function reportList(data: TableQueryParams) {
|
||||
return MSR.post({ url: orgUrl.postProjectTableUrl, data });
|
||||
if (data.moduleType === ReportEnum.API_SCENARIO_REPORT) {
|
||||
return MSR.post({ url: reportUrl.ScenarioReportListUrl, data });
|
||||
}
|
||||
return MSR.post({ url: reportUrl.ApiReportListUrl, data });
|
||||
}
|
||||
|
||||
// 删除报告
|
||||
export function reportDelete(id: string) {}
|
||||
export function reportDelete(moduleType: string, id: string) {
|
||||
if (moduleType === ReportEnum.API_SCENARIO_REPORT) {
|
||||
return MSR.get({ url: `${reportUrl.ScenarioDeleteUrl}/${id}` });
|
||||
}
|
||||
return MSR.get({ url: `${reportUrl.ApiDeleteUrl}/${id}` });
|
||||
}
|
||||
|
||||
// 重命名
|
||||
export function reportRename(id: string, reportName: string) {}
|
||||
export function reportRename(moduleType: string, id: string, reportName: string) {
|
||||
if (moduleType === ReportEnum.API_SCENARIO_REPORT) {
|
||||
return MSR.get({ url: `${reportUrl.ScenarioReportRenameUrl}/${id}/${reportName}` });
|
||||
}
|
||||
return MSR.get({ url: `${reportUrl.ApiReportRenameUrl}/${id}/${reportName}` });
|
||||
}
|
||||
|
||||
// 批量删除
|
||||
export function reportBathDelete(ids: Array<string>) {}
|
||||
export function reportBathDelete(moduleType: string, data: TableQueryParams) {
|
||||
if (moduleType === ReportEnum.API_SCENARIO_REPORT) {
|
||||
return MSR.post({ url: reportUrl.ScenarioBatchDeleteUrl, data });
|
||||
}
|
||||
return MSR.post({ url: reportUrl.ApiBatchDeleteUrl, data });
|
||||
}
|
||||
|
||||
export default {};
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
// 场景报告列表
|
||||
export const ScenarioReportListUrl = '/api/report/scenario/page';
|
||||
// 场景报告重命名
|
||||
export const ScenarioReportRenameUrl = '/api/report/scenario/rename';
|
||||
// 删除场景报告
|
||||
export const ScenarioDeleteUrl = '/api/report/scenario/delete';
|
||||
// 批量删除场景报告
|
||||
export const ScenarioBatchDeleteUrl = '/api/report/scenario/batch/delete';
|
||||
|
||||
// 接口用例报告列表
|
||||
export const ApiReportListUrl = '/api/report/case/page';
|
||||
// 接口用例报告重命名
|
||||
export const ApiReportRenameUrl = '/api/report/case/rename';
|
||||
// 删除接口用例报告
|
||||
export const ApiDeleteUrl = '/api/report/case/delete';
|
||||
// 批量删除接口用例报告
|
||||
export const ApiBatchDeleteUrl = '/api/report/case/batch/delete';
|
|
@ -4,17 +4,11 @@ export enum ReportEnum {
|
|||
API_REPORT = 'API_REPORT',
|
||||
}
|
||||
|
||||
export enum ReportType {
|
||||
ALL = 'ALL',
|
||||
COLLECTION = 'COLLECTION',
|
||||
INDEPENDENT = 'INDEPENDENT',
|
||||
}
|
||||
|
||||
export enum TriggerModeLabel {
|
||||
SCHEDULE = 'project.taskCenter.scheduledTask', // 定时任务
|
||||
MANUAL = 'project.taskCenter.manualExecution', // 手动执行
|
||||
API = 'project.taskCenter.interfaceCall', // 接口调用
|
||||
BATCH = 'project.taskCenter.batchExecution', // 批量执行
|
||||
MANUAL = 'report.trigger.manual', // 手动执行
|
||||
SCHEDULE = 'report.trigger.scheduled', // 定时任务
|
||||
BATCH = 'report.trigger.batch.execution', // 批量执行
|
||||
API = 'report.trigger.interface', // 接口调用
|
||||
}
|
||||
|
||||
export const ReportStatus = {
|
||||
|
|
|
@ -10,6 +10,7 @@ export enum TableKeyEnum {
|
|||
API_TEST = 'apiTest',
|
||||
API_TEST_DEBUG_FORM_DATA = 'apiTestDebugFormData',
|
||||
API_TEST_DEBUG_FORM_URL_ENCODE = 'apiTestDebugFormUrlEncoded',
|
||||
API_TEST_REPORT = 'apiTestReport',
|
||||
SYSTEM_USER = 'systemUser',
|
||||
SYSTEM_RESOURCEPOOL = 'systemResourcePool',
|
||||
SYSTEM_AUTH = 'systemAuth',
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
<div class="mb-4 flex items-center justify-between">
|
||||
<a-radio-group v-model:model-value="showType" type="button" class="file-show-type" @change="changeShowType">
|
||||
<a-radio value="All">{{ t('report.all') }}</a-radio>
|
||||
<a-radio value="Independent">{{ t('report.independent') }}</a-radio>
|
||||
<a-radio value="Collection">{{ t('report.collection') }}</a-radio>
|
||||
<a-radio value="INDEPENDENT">{{ t('report.independent') }}</a-radio>
|
||||
<a-radio value="INTEGRATED">{{ t('report.collection') }}</a-radio>
|
||||
</a-radio-group>
|
||||
<a-input-search
|
||||
v-model:model-value="keyword"
|
||||
|
@ -13,6 +13,7 @@
|
|||
class="mx-[8px] w-[240px]"
|
||||
@search="searchList"
|
||||
@press-enter="searchList"
|
||||
@clear="searchList"
|
||||
/>
|
||||
</div>
|
||||
<!-- 报告列表 -->
|
||||
|
@ -23,21 +24,31 @@
|
|||
v-on="propsEvent"
|
||||
@batch-action="handleTableBatch"
|
||||
>
|
||||
<!-- 报告类型筛选 -->
|
||||
<template #typeFilter="{ columnConfig }">
|
||||
<a-trigger v-model:popup-visible="typeFilterVisible" trigger="click" @popup-visible-change="handleFilterHidden">
|
||||
<a-button type="text" class="arco-btn-text--secondary p-[8px_4px]" @click="typeFilterVisible = true">
|
||||
<!-- 报告类型 -->
|
||||
<template #integrated="{ record }">
|
||||
<MsTag theme="light" :type="record.integrated ? 'primary' : undefined">
|
||||
{{ record.integrated ? t('report.collection') : t('report.independent') }}
|
||||
</MsTag>
|
||||
</template>
|
||||
<!-- 报告触发方式筛选 -->
|
||||
<template #triggerModeFilter="{ columnConfig }">
|
||||
<a-trigger
|
||||
v-model:popup-visible="triggerModeFilterVisible"
|
||||
trigger="click"
|
||||
@popup-visible-change="handleFilterHidden"
|
||||
>
|
||||
<a-button type="text" class="arco-btn-text--secondary p-[8px_4px]" @click="triggerModeFilterVisible = true">
|
||||
<div class="font-medium">
|
||||
{{ t(columnConfig.title as string) }}
|
||||
</div>
|
||||
<icon-down :class="typeFilterVisible ? 'text-[rgb(var(--primary-5))]' : ''" />
|
||||
<icon-down :class="triggerModeFilterVisible ? 'text-[rgb(var(--primary-5))]' : ''" />
|
||||
</a-button>
|
||||
<template #content>
|
||||
<div class="arco-table-filters-content">
|
||||
<div class="flex items-center justify-center px-[6px] py-[2px]">
|
||||
<a-checkbox-group v-model:model-value="statusListFilters" direction="vertical" size="small">
|
||||
<a-checkbox v-for="key of statusFilters" :key="key" :value="key">
|
||||
<ExecutionStatus :module-type="props.moduleType" :status="key" />
|
||||
<a-checkbox-group v-model:model-value="triggerModeListFilters" direction="vertical" size="small">
|
||||
<a-checkbox v-for="(key, value) of TriggerModeLabel" :key="key" :value="value">
|
||||
<div class="font-medium">{{ t(key) }}</div>
|
||||
</a-checkbox>
|
||||
</a-checkbox-group>
|
||||
</div>
|
||||
|
@ -82,7 +93,12 @@
|
|||
<span>{{ dayjs(record.operationTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
|
||||
</template>
|
||||
<template #operation="{ record }">
|
||||
<MsButton class="!mr-0" @click="handleDelete(record)">{{ t('ms.comment.delete') }}</MsButton>
|
||||
<MsButton
|
||||
v-permission="['PROJECT_API_REPORT:READ+DELETE']"
|
||||
class="!mr-0"
|
||||
@click="handleDelete(record.id, record.name)"
|
||||
>{{ t('ms.comment.delete') }}</MsButton
|
||||
>
|
||||
</template>
|
||||
</ms-base-table>
|
||||
</div>
|
||||
|
@ -97,15 +113,25 @@
|
|||
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
||||
import type { BatchActionParams, BatchActionQueryParams, MsTableColumn } from '@/components/pure/ms-table/type';
|
||||
import useTable from '@/components/pure/ms-table/useTable';
|
||||
import ExecutionStatus from './reportStatus.vue';
|
||||
import MsTag from '@/components/pure/ms-tag/ms-tag.vue';
|
||||
import ExecutionStatus from '@/views/api-test/report/component/reportStatus.vue';
|
||||
|
||||
import { reportDelete, reportList, reportRename } from '@/api/modules/api-test/report';
|
||||
import { reportBathDelete, reportDelete, reportList, reportRename } from '@/api/modules/api-test/report';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import { useTableStore } from '@/store';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import { characterLimit } from '@/utils';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import { BatchApiParams } from '@/models/common';
|
||||
import { ReportEnum, ReportStatus, ReportType, TriggerModeLabel } from '@/enums/reportEnum';
|
||||
import { ColumnEditTypeEnum } from '@/enums/tableEnum';
|
||||
import { ReportEnum, ReportStatus, TriggerModeLabel } from '@/enums/reportEnum';
|
||||
import { ColumnEditTypeEnum, TableKeyEnum } from '@/enums/tableEnum';
|
||||
|
||||
const { openModal } = useModal();
|
||||
|
||||
const appStore = useAppStore();
|
||||
const tableStore = useTableStore();
|
||||
|
||||
const { t } = useI18n();
|
||||
const props = defineProps<{
|
||||
|
@ -114,11 +140,12 @@
|
|||
}>();
|
||||
const keyword = ref<string>('');
|
||||
const statusFilterVisible = ref(false);
|
||||
const typeFilterVisible = ref(false);
|
||||
const triggerModeFilterVisible = ref(false);
|
||||
|
||||
const statusListFilters = ref<string[]>(Object.keys(ReportStatus[props.moduleType]));
|
||||
const triggerModeListFilters = ref<string[]>(Object.keys(TriggerModeLabel));
|
||||
|
||||
type ReportShowType = 'All' | 'Independent' | 'Collection';
|
||||
type ReportShowType = 'All' | 'INDEPENDENT' | 'INTEGRATED';
|
||||
const showType = ref<ReportShowType>('All');
|
||||
|
||||
const columns: MsTableColumn = [
|
||||
|
@ -129,7 +156,7 @@
|
|||
width: 200,
|
||||
showInTable: true,
|
||||
showTooltip: true,
|
||||
editType: ColumnEditTypeEnum.INPUT, // hasAnyPermission(['API_TEST_REPORT:READ+UPDATE']) ? ColumnEditTypeEnum.INPUT : undefined,
|
||||
editType: hasAnyPermission(['PROJECT_API_REPORT:READ+UPDATE']) ? ColumnEditTypeEnum.INPUT : undefined,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
|
@ -140,16 +167,15 @@
|
|||
},
|
||||
{
|
||||
title: 'report.type',
|
||||
slotName: 'reportType',
|
||||
dataIndex: 'reportType',
|
||||
slotName: 'integrated',
|
||||
dataIndex: 'integrated',
|
||||
width: 150,
|
||||
showDrag: true,
|
||||
titleSlotName: 'typeFilter',
|
||||
},
|
||||
{
|
||||
title: 'report.result',
|
||||
dataIndex: 'reportResult',
|
||||
slotName: 'reportResult',
|
||||
dataIndex: 'status',
|
||||
slotName: 'status',
|
||||
titleSlotName: 'statusFilter',
|
||||
showInTable: true,
|
||||
width: 150,
|
||||
|
@ -162,33 +188,41 @@
|
|||
showInTable: true,
|
||||
width: 150,
|
||||
showDrag: true,
|
||||
titleSlotName: 'triggerModeFilter',
|
||||
},
|
||||
{
|
||||
title: 'report.operator',
|
||||
slotName: 'createUser',
|
||||
dataIndex: 'createUser',
|
||||
slotName: 'createUserName',
|
||||
dataIndex: 'createUserName',
|
||||
showInTable: true,
|
||||
width: 200,
|
||||
showDrag: true,
|
||||
},
|
||||
{
|
||||
title: 'report.operating',
|
||||
dataIndex: 'createTime',
|
||||
slotName: 'createTime',
|
||||
dataIndex: 'startTime',
|
||||
slotName: 'startTime',
|
||||
width: 180,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
showDrag: true,
|
||||
},
|
||||
{
|
||||
title: 'common.operation',
|
||||
slotName: 'operation',
|
||||
dataIndex: 'operation',
|
||||
width: 100,
|
||||
fixed: 'right',
|
||||
title: hasAnyPermission(['PROJECT_API_REPORT:READ+DELETE']) ? 'common.operation' : '',
|
||||
width: hasAnyPermission(['PROJECT_API_REPORT:READ+DELETE']) ? 130 : 50,
|
||||
},
|
||||
];
|
||||
|
||||
await tableStore.initColumn(TableKeyEnum.API_TEST_REPORT, columns, 'drawer');
|
||||
|
||||
const rename = async (record: any) => {
|
||||
try {
|
||||
await reportRename(record.id, record.name);
|
||||
await reportRename(props.moduleType, record.id, record.name);
|
||||
Message.success(t('common.updateSuccess'));
|
||||
return true;
|
||||
} catch (error) {
|
||||
|
@ -198,23 +232,32 @@
|
|||
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable(
|
||||
reportList,
|
||||
{
|
||||
columns,
|
||||
tableKey: TableKeyEnum.API_TEST_REPORT,
|
||||
scroll: {
|
||||
x: '100%',
|
||||
},
|
||||
showSetting: false,
|
||||
showSetting: true,
|
||||
selectable: true,
|
||||
heightUsed: 330,
|
||||
showSelectAll: true,
|
||||
showSelectorAll: false,
|
||||
},
|
||||
undefined,
|
||||
(item) => ({
|
||||
...item,
|
||||
startTime: dayjs(item.startTime).format('YYYY-MM-DD HH:mm:ss'),
|
||||
}),
|
||||
rename
|
||||
);
|
||||
|
||||
function initData() {
|
||||
setLoadListParams({
|
||||
keyword: keyword.value,
|
||||
projectId: appStore.currentProjectId,
|
||||
moduleType: props.moduleType,
|
||||
filter: { status: statusListFilters.value },
|
||||
filter: {
|
||||
status: statusListFilters.value,
|
||||
integrated: showType.value === 'All' ? undefined : Array.of((showType.value === 'INTEGRATED').toString()),
|
||||
triggerMode: triggerModeListFilters.value,
|
||||
},
|
||||
});
|
||||
loadList();
|
||||
}
|
||||
|
@ -224,9 +267,11 @@
|
|||
{
|
||||
label: 'report.batch.delete',
|
||||
eventTag: 'batchStop',
|
||||
permission: ['PROJECT_API_REPORT:READ+DELETE'],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const batchParams = ref<BatchApiParams>({
|
||||
selectIds: [],
|
||||
selectAll: false,
|
||||
|
@ -234,21 +279,68 @@
|
|||
condition: {},
|
||||
});
|
||||
|
||||
function handleTableBatch(event: BatchActionParams, params: BatchActionQueryParams) {
|
||||
batchParams.value = { ...params, selectIds: params?.selectedIds || [], condition: {} };
|
||||
if (event.eventTag === 'batchDelete') {
|
||||
// 批量删除
|
||||
}
|
||||
}
|
||||
// 批量删除
|
||||
const handleTableBatch = async (event: BatchActionParams, params: BatchActionQueryParams) => {
|
||||
batchParams.value = {
|
||||
...params,
|
||||
selectIds: params?.selectedIds || [],
|
||||
condition: {},
|
||||
projectId: appStore.currentProjectId,
|
||||
};
|
||||
|
||||
openModal({
|
||||
type: 'error',
|
||||
title: t('report.delete.tip', {
|
||||
count: params?.currentSelectCount || params?.selectedIds?.length,
|
||||
}),
|
||||
content: '',
|
||||
okText: t('common.confirmDelete'),
|
||||
cancelText: t('common.cancel'),
|
||||
okButtonProps: {
|
||||
status: 'danger',
|
||||
},
|
||||
onBeforeOk: async () => {
|
||||
try {
|
||||
await reportBathDelete(props.moduleType, batchParams.value);
|
||||
Message.success(t('apiTestDebug.deleteSuccess'));
|
||||
resetSelector();
|
||||
initData();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
hideCancel: false,
|
||||
});
|
||||
};
|
||||
|
||||
function searchList() {
|
||||
resetSelector();
|
||||
initData();
|
||||
}
|
||||
|
||||
function handleDelete(id: string) {
|
||||
Message.success(t('apiTestDebug.deleteSuccess'));
|
||||
}
|
||||
const handleDelete = async (id: string, currentName: string) => {
|
||||
openModal({
|
||||
type: 'error',
|
||||
title: t('apiTestManagement.deleteApiTipTitle', { name: characterLimit(currentName) }),
|
||||
content: '',
|
||||
okText: t('common.confirmDelete'),
|
||||
cancelText: t('common.cancel'),
|
||||
okButtonProps: {
|
||||
status: 'danger',
|
||||
},
|
||||
onBeforeOk: async () => {
|
||||
try {
|
||||
await reportDelete(props.moduleType, id);
|
||||
Message.success(t('apiTestDebug.deleteSuccess'));
|
||||
initData();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
hideCancel: false,
|
||||
});
|
||||
};
|
||||
|
||||
onBeforeMount(() => {
|
||||
initData();
|
||||
|
@ -257,6 +349,7 @@
|
|||
const statusFilters = computed(() => {
|
||||
return Object.keys(ReportStatus[props.moduleType]);
|
||||
});
|
||||
|
||||
function handleFilterHidden(val: boolean) {
|
||||
if (!val) {
|
||||
initData();
|
||||
|
@ -265,13 +358,7 @@
|
|||
|
||||
function changeShowType(val: string | number | boolean) {
|
||||
showType.value = val as ReportShowType;
|
||||
if (val === ReportType.COLLECTION) {
|
||||
console.log('Collection');
|
||||
} else if (val === ReportType.INDEPENDENT) {
|
||||
console.log('Independent');
|
||||
} else {
|
||||
console.log('All');
|
||||
}
|
||||
initData();
|
||||
}
|
||||
|
||||
watch(
|
||||
|
|
|
@ -18,4 +18,9 @@ export default {
|
|||
'report.status.rerunning': 'Rerunning',
|
||||
'report.status.pending': 'Pending',
|
||||
'report.stopped': 'Stopped',
|
||||
'report.trigger.scheduled': 'Schedule',
|
||||
'report.trigger.manual': 'Manual',
|
||||
'report.trigger.interface': 'API',
|
||||
'report.trigger.batch.execution': 'Batch',
|
||||
'report.delete.tip': 'Are you sure you want to delete {count} selected reports?',
|
||||
};
|
||||
|
|
|
@ -18,4 +18,9 @@ export default {
|
|||
'report.status.rerunning': '重跑中',
|
||||
'report.status.pending': '排队中',
|
||||
'report.stopped': '停止',
|
||||
'report.trigger.scheduled': '定时执行',
|
||||
'report.trigger.manual': '手工执行',
|
||||
'report.trigger.interface': 'API 执行',
|
||||
'report.trigger.batch.execution': '批量执行',
|
||||
'report.delete.tip': '确认删除已选中的 {count} 个报告吗?',
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue