mirror of
https://gitee.com/fit2cloud-feizhiyun/MeterSphere.git
synced 2024-12-03 12:39:12 +08:00
feat(接口管理): 新增接口用例回收站页面
This commit is contained in:
parent
c5602b2033
commit
045092b13b
@ -7,9 +7,11 @@ import {
|
||||
BatchCleanOutApiUrl,
|
||||
BatchDeleteCaseUrl,
|
||||
BatchDeleteDefinitionUrl,
|
||||
BatchDeleteRecycleCaseUrl,
|
||||
BatchEditCaseUrl,
|
||||
BatchMoveDefinitionUrl,
|
||||
BatchRecoverApiUrl,
|
||||
BatchRecoverCaseUrl,
|
||||
BatchUpdateDefinitionUrl,
|
||||
CasePageUrl,
|
||||
CheckDefinitionScheduleUrl,
|
||||
@ -23,6 +25,7 @@ import {
|
||||
DeleteMockUrl,
|
||||
DeleteModuleUrl,
|
||||
DeleteRecycleApiUrl,
|
||||
DeleteRecycleCaseUrl,
|
||||
GetDefinitionDetailUrl,
|
||||
GetDefinitionScheduleUrl,
|
||||
GetEnvModuleUrl,
|
||||
@ -34,8 +37,10 @@ import {
|
||||
ImportDefinitionUrl,
|
||||
MoveModuleUrl,
|
||||
OperationHistoryUrl,
|
||||
RecoverCaseUrl,
|
||||
RecoverDefinitionUrl,
|
||||
RecoverOperationHistoryUrl,
|
||||
RecycleCasePageUrl,
|
||||
SaveOperationHistoryUrl,
|
||||
SortCaseUrl,
|
||||
SortDefinitionUrl,
|
||||
@ -345,6 +350,34 @@ export function dragSort(data: DragSortParams) {
|
||||
return MSR.post({ url: SortCaseUrl, data });
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口用例回收站
|
||||
*/
|
||||
// 获取回收站接口用例列表
|
||||
export function getRecycleCasePage(data: ApiCasePageParams) {
|
||||
return MSR.post<CommonList<ApiCaseDetail>>({ url: RecycleCasePageUrl, data });
|
||||
}
|
||||
|
||||
// 恢复接口用例
|
||||
export function recoverCase(id: string) {
|
||||
return MSR.get({ url: RecoverCaseUrl, params: id });
|
||||
}
|
||||
|
||||
// 批量恢复接口用例
|
||||
export function batchRecoverCase(data: ApiCaseBatchParams) {
|
||||
return MSR.post({ url: BatchRecoverCaseUrl, data });
|
||||
}
|
||||
|
||||
// 彻底删除接口用例
|
||||
export function deleteRecycleCase(id: string) {
|
||||
return MSR.get({ url: DeleteRecycleCaseUrl, params: id });
|
||||
}
|
||||
|
||||
// 批量彻底删除接口用例
|
||||
export function batchDeleteRecycleCase(data: ApiCaseBatchParams) {
|
||||
return MSR.post({ url: BatchDeleteRecycleCaseUrl, data });
|
||||
}
|
||||
|
||||
// 添加接口用例
|
||||
export function addCase(data: AddApiCaseParams) {
|
||||
return MSR.post({ url: AddCaseUrl, data });
|
||||
|
@ -57,8 +57,17 @@ export const GetTrashModuleCountUrl = '/api/definition/module/trash/count'; //
|
||||
export const CasePageUrl = '/api/case/page'; // 接口用例列表
|
||||
export const UpdateCaseStatusUrl = '/api/case/update-status'; // 接口用例更新状态
|
||||
export const UpdateCasePriorityUrl = '/api/case/update-priority'; // 接口用例更新等级
|
||||
export const DeleteCaseUrl = '/api/case/delete'; // 删除接口用例
|
||||
export const BatchDeleteCaseUrl = '/api/case/batch/delete'; // 批量删除接口用例
|
||||
export const DeleteCaseUrl = '/api/case/delete-to-gc'; // 删除接口用例
|
||||
export const BatchDeleteCaseUrl = '/api/case/batch/delete-to-gc'; // 批量删除接口用例
|
||||
export const BatchEditCaseUrl = '/api/case/batch/edit'; // 批量编辑接口用例
|
||||
export const SortCaseUrl = '/api/case/edit/pos'; // 接口用例拖拽
|
||||
|
||||
/**
|
||||
* 接口用例回收站
|
||||
*/
|
||||
export const RecycleCasePageUrl = '/api/case/trash/page'; // 接口用例回收站列表
|
||||
export const RecoverCaseUrl = '/api/case/recover'; // 接口用例恢复
|
||||
export const BatchRecoverCaseUrl = '/api/case/batch/recover'; // 接口用例批量恢复
|
||||
export const DeleteRecycleCaseUrl = '/api/case/delete'; // 接口用例彻底删除
|
||||
export const BatchDeleteRecycleCaseUrl = '/api/case/batch/delete'; // 接口用例批量彻底删除
|
||||
export const AddCaseUrl = '/api/case/add'; // 添加用例
|
||||
|
@ -0,0 +1,582 @@
|
||||
<template>
|
||||
<div class="p-[16px_22px]">
|
||||
<div class="mb-[16px] flex items-center justify-end">
|
||||
<div class="flex items-center gap-[8px]">
|
||||
<a-input-search
|
||||
v-model:model-value="keyword"
|
||||
:placeholder="t('apiTestManagement.searchPlaceholder')"
|
||||
allow-clear
|
||||
class="mr-[8px] w-[240px]"
|
||||
@search="loadCaseList"
|
||||
@press-enter="loadCaseList"
|
||||
/>
|
||||
<a-button type="outline" class="arco-btn-outline--secondary !p-[8px]" @click="loadCaseList">
|
||||
<template #icon>
|
||||
<icon-refresh class="text-[var(--color-text-4)]" />
|
||||
</template>
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<ms-base-table
|
||||
v-bind="propsRes"
|
||||
:action-config="batchActions"
|
||||
:first-column-width="44"
|
||||
no-disable
|
||||
filter-icon-align-left
|
||||
v-on="propsEvent"
|
||||
@selected-change="handleTableSelect"
|
||||
@batch-action="handleTableBatch"
|
||||
>
|
||||
<template #caseLevelFilter="{ columnConfig }">
|
||||
<a-trigger v-model:popup-visible="caseFilterVisible" trigger="click" @popup-visible-change="handleFilterHidden">
|
||||
<MsButton type="text" class="arco-btn-text--secondary ml-[10px]" @click="caseFilterVisible = true">
|
||||
{{ t(columnConfig.title as string) }}
|
||||
<icon-down :class="caseFilterVisible ? 'text-[rgb(var(--primary-5))]' : ''" />
|
||||
</MsButton>
|
||||
<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="caseFilters" direction="vertical" size="small">
|
||||
<a-checkbox v-for="item of caseLevelList" :key="item.text" :value="item.text">
|
||||
<caseLevel :case-level="item.text" />
|
||||
</a-checkbox>
|
||||
</a-checkbox-group>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</a-trigger>
|
||||
</template>
|
||||
<template #deleteTime="{ record }">
|
||||
{{ dayjs(record.deleteTime).format('YYYY-MM-DD HH:mm:ss') || '-' }}
|
||||
</template>
|
||||
<template #status="{ record }">
|
||||
<apiStatus :status="record.status" />
|
||||
</template>
|
||||
<template #statusFilter="{ columnConfig }">
|
||||
<a-trigger
|
||||
v-model:popup-visible="statusFilterVisible"
|
||||
trigger="click"
|
||||
@popup-visible-change="handleFilterHidden"
|
||||
>
|
||||
<MsButton type="text" class="arco-btn-text--secondary ml-[10px]" @click="statusFilterVisible = true">
|
||||
{{ t(columnConfig.title as string) }}
|
||||
<icon-down :class="statusFilterVisible ? 'text-[rgb(var(--primary-5))]' : ''" />
|
||||
</MsButton>
|
||||
<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="statusFilters" direction="vertical" size="small">
|
||||
<a-checkbox v-for="val of Object.values(RequestDefinitionStatus)" :key="val" :value="val">
|
||||
<apiStatus :status="val" />
|
||||
</a-checkbox>
|
||||
</a-checkbox-group>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</a-trigger>
|
||||
</template>
|
||||
<template #lastReportStatusFilter="{ columnConfig }">
|
||||
<a-trigger
|
||||
v-model:popup-visible="lastReportStatusFilterVisible"
|
||||
trigger="click"
|
||||
@popup-visible-change="handleFilterHidden"
|
||||
>
|
||||
<MsButton
|
||||
type="text"
|
||||
class="arco-btn-text--secondary ml-[10px]"
|
||||
@click="lastReportStatusFilterVisible = true"
|
||||
>
|
||||
{{ t(columnConfig.title as string) }}
|
||||
<icon-down :class="lastReportStatusFilterVisible ? 'text-[rgb(var(--primary-5))]' : ''" />
|
||||
</MsButton>
|
||||
<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="lastReportStatusFilters" direction="vertical" size="small">
|
||||
<a-checkbox v-for="val of lastReportStatusList" :key="val" :value="val">
|
||||
<span>{{ val }}</span>
|
||||
</a-checkbox>
|
||||
</a-checkbox-group>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</a-trigger>
|
||||
</template>
|
||||
<template #passRateColumn>
|
||||
<div class="flex items-center text-[var(--color-text-3)]">
|
||||
{{ t('case.passRate') }}
|
||||
<a-tooltip :content="t('case.passRateTip')" position="right">
|
||||
<icon-question-circle
|
||||
class="ml-[4px] text-[var(--color-text-4)] hover:text-[rgb(var(--primary-5))]"
|
||||
size="16"
|
||||
/>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
<template #action="{ record }">
|
||||
<MsButton
|
||||
v-permission="['PROJECT_API_DEFINITION_CASE:READ+DELETE']"
|
||||
type="text"
|
||||
class="!mr-0"
|
||||
@click="recover(record)"
|
||||
>
|
||||
{{ t('apiTestManagement.recycle.batchRecover') }}
|
||||
</MsButton>
|
||||
<a-divider
|
||||
v-permission="['PROJECT_API_DEFINITION_CASE:READ+DELETE']"
|
||||
direction="vertical"
|
||||
:margin="8"
|
||||
></a-divider>
|
||||
<MsButton
|
||||
v-permission="['PROJECT_API_DEFINITION_CASE:READ+DELETE']"
|
||||
type="text"
|
||||
class="!mr-0"
|
||||
@click="cleanOut(record)"
|
||||
>
|
||||
{{ t('apiTestManagement.recycle.batchCleanOut') }}
|
||||
</MsButton>
|
||||
</template>
|
||||
</ms-base-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||
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 caseLevel from '@/components/business/ms-case-associate/caseLevel.vue';
|
||||
import apiStatus from '@/views/api-test/components/apiStatus.vue';
|
||||
|
||||
import {
|
||||
batchDeleteRecycleCase,
|
||||
batchRecoverCase,
|
||||
deleteRecycleCase,
|
||||
getRecycleCasePage,
|
||||
recoverCase,
|
||||
} from '@/api/modules/api-test/management';
|
||||
import { getCaseDefaultFields } from '@/api/modules/case-management/featureCase';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import useTableStore from '@/hooks/useTableStore';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
|
||||
import { ApiCaseBatchParams, ApiCaseDetail } from '@/models/apiTest/management';
|
||||
import { RequestDefinitionStatus } from '@/enums/apiEnum';
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
|
||||
const props = defineProps<{
|
||||
activeModule: string;
|
||||
offspringIds: string[];
|
||||
protocol: string; // 查看的协议类型
|
||||
}>();
|
||||
|
||||
const appStore = useAppStore();
|
||||
const { t } = useI18n();
|
||||
const tableStore = useTableStore();
|
||||
const { openModal } = useModal();
|
||||
|
||||
const keyword = ref('');
|
||||
const refreshModuleTree: (() => Promise<any>) | undefined = inject('refreshModuleTree');
|
||||
|
||||
const columns: MsTableColumn = [
|
||||
{
|
||||
title: 'ID',
|
||||
dataIndex: 'num',
|
||||
slotName: 'num',
|
||||
sortIndex: 1,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
fixed: 'left',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: 'case.caseName',
|
||||
dataIndex: 'name',
|
||||
showTooltip: true,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: 'case.caseLevel',
|
||||
dataIndex: 'priority',
|
||||
slotName: 'caseLevel',
|
||||
titleSlotName: 'caseLevelFilter',
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: 'apiTestManagement.apiStatus',
|
||||
dataIndex: 'status',
|
||||
slotName: 'status',
|
||||
titleSlotName: 'statusFilter',
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: 'apiTestManagement.path',
|
||||
dataIndex: 'path',
|
||||
showTooltip: true,
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: 'common.tag',
|
||||
dataIndex: 'tags',
|
||||
isTag: true,
|
||||
isStringTag: true,
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: 'case.lastReportStatus',
|
||||
dataIndex: 'lastReportStatus',
|
||||
titleSlotName: 'lastReportStatusFilter',
|
||||
showInTable: false,
|
||||
showTooltip: true,
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: 'case.passRate',
|
||||
dataIndex: 'passRate',
|
||||
titleSlotName: 'passRateColumn',
|
||||
showInTable: false,
|
||||
showTooltip: true,
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: 'case.caseEnvironment',
|
||||
dataIndex: 'environmentName',
|
||||
showTooltip: true,
|
||||
showInTable: false,
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: 'case.tableColumnUpdateUser',
|
||||
dataIndex: 'updateUser',
|
||||
showInTable: true,
|
||||
showTooltip: true,
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: 'case.tableColumnUpdateTime',
|
||||
dataIndex: 'updateTime',
|
||||
showInTable: true,
|
||||
showTooltip: true,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: 'case.tableColumnCreateUser',
|
||||
dataIndex: 'createName',
|
||||
showTooltip: true,
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: 'case.tableColumnCreateTime',
|
||||
dataIndex: 'createTime',
|
||||
showTooltip: true,
|
||||
showInTable: true,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: 'apiTestManagement.deleteUser',
|
||||
dataIndex: 'deleteName',
|
||||
showInTable: true,
|
||||
showTooltip: true,
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: 'apiTestManagement.deleteTime',
|
||||
slotName: 'deleteTime',
|
||||
dataIndex: 'deleteTime',
|
||||
showInTable: true,
|
||||
showTooltip: true,
|
||||
sortable: {
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: true,
|
||||
},
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: 'common.operation',
|
||||
slotName: 'action',
|
||||
dataIndex: 'operation',
|
||||
fixed: 'right',
|
||||
width: 150,
|
||||
},
|
||||
];
|
||||
await tableStore.initColumn(TableKeyEnum.API_TEST_MANAGEMENT_CASE, columns, 'drawer');
|
||||
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable(getRecycleCasePage, {
|
||||
columns,
|
||||
scroll: { x: '100%' },
|
||||
tableKey: TableKeyEnum.API_TEST_MANAGEMENT_CASE,
|
||||
showSetting: true,
|
||||
selectable: true,
|
||||
showSelectAll: true,
|
||||
draggable: { type: 'handle', width: 32 },
|
||||
});
|
||||
const batchActions = {
|
||||
baseAction: [
|
||||
{
|
||||
label: 'apiTestManagement.recycle.batchRecover',
|
||||
eventTag: 'batchRecover',
|
||||
permission: ['PROJECT_API_DEFINITION_CASE:READ+DELETE'],
|
||||
},
|
||||
{
|
||||
label: 'apiTestManagement.recycle.batchCleanOut',
|
||||
eventTag: 'batchCleanOut',
|
||||
danger: true,
|
||||
permission: ['PROJECT_API_DEFINITION_CASE:READ+DELETE'],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const statusFilterVisible = ref(false);
|
||||
const statusFilters = ref(Object.keys(RequestDefinitionStatus));
|
||||
const caseLevelFields = ref<Record<string, any>>({});
|
||||
const caseFilterVisible = ref(false);
|
||||
const caseFilters = ref<string[]>([]);
|
||||
const caseLevelList = computed(() => {
|
||||
return caseLevelFields.value?.options || [];
|
||||
});
|
||||
const lastReportStatusFilterVisible = ref(false);
|
||||
const lastReportStatusList = ['error', 'FakeError', 'success'];
|
||||
const lastReportStatusFilters = ref<string[]>([...lastReportStatusList]);
|
||||
|
||||
const moduleIds = computed(() => {
|
||||
return props.activeModule === 'all' ? [] : [props.activeModule];
|
||||
});
|
||||
function loadCaseList() {
|
||||
const params = {
|
||||
keyword: keyword.value,
|
||||
projectId: appStore.currentProjectId,
|
||||
moduleIds: moduleIds.value,
|
||||
protocol: props.protocol,
|
||||
filter: {
|
||||
status: statusFilters.value,
|
||||
priority: caseFilters.value,
|
||||
lastReportStatus: lastReportStatusFilters.value,
|
||||
},
|
||||
};
|
||||
setLoadListParams(params);
|
||||
loadList();
|
||||
}
|
||||
function loadCaseListAndResetSelector() {
|
||||
resetSelector();
|
||||
loadCaseList();
|
||||
}
|
||||
|
||||
// 获取用例等级数据
|
||||
async function getCaseLevelFields() {
|
||||
const result = await getCaseDefaultFields(appStore.currentProjectId);
|
||||
caseLevelFields.value = result.customFields.find((item: any) => item.internal && item.fieldName === '用例等级');
|
||||
caseFilters.value = caseLevelFields.value?.options.map((item: any) => item.text);
|
||||
}
|
||||
|
||||
onBeforeMount(() => {
|
||||
getCaseLevelFields();
|
||||
loadCaseList();
|
||||
});
|
||||
|
||||
function handleFilterHidden(val: boolean) {
|
||||
if (!val) {
|
||||
loadCaseList();
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.activeModule,
|
||||
() => {
|
||||
loadCaseListAndResetSelector();
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.protocol,
|
||||
() => {
|
||||
loadCaseListAndResetSelector();
|
||||
}
|
||||
);
|
||||
|
||||
const tableSelected = ref<(string | number)[]>([]); // 表格选中的
|
||||
const batchParams = ref<BatchActionQueryParams>({
|
||||
selectedIds: [],
|
||||
selectAll: false,
|
||||
excludeIds: [],
|
||||
currentSelectCount: 0,
|
||||
});
|
||||
|
||||
// 列表彻底删除
|
||||
async function cleanOut(record: ApiCaseDetail) {
|
||||
openModal({
|
||||
type: 'error',
|
||||
title: t('case.batchDeleteCaseTipTitle', { name: record?.name }),
|
||||
content: t('case.recycle.cleanOutDeleteOnRecycleTip'),
|
||||
okText: t('common.confirmDelete'),
|
||||
cancelText: t('common.cancel'),
|
||||
okButtonProps: {
|
||||
status: 'danger',
|
||||
},
|
||||
onBeforeOk: async () => {
|
||||
try {
|
||||
await deleteRecycleCase(record.id);
|
||||
Message.success(t('common.deleteSuccess'));
|
||||
loadCaseListAndResetSelector();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
hideCancel: false,
|
||||
});
|
||||
}
|
||||
|
||||
async function recover(record: ApiCaseDetail) {
|
||||
openModal({
|
||||
type: 'info',
|
||||
title: t('case.batchRecoverCaseTipTitle', { name: record?.name }),
|
||||
content: t('case.recycle.recoverCaseTip'),
|
||||
okText: t('case.recycle.confirmRecovery'),
|
||||
cancelText: t('common.cancel'),
|
||||
okButtonProps: {
|
||||
status: 'normal',
|
||||
},
|
||||
onBeforeOk: async () => {
|
||||
try {
|
||||
await recoverCase(record.id);
|
||||
Message.success(t('apiTestManagement.recycle.recoveredSuccessfully'));
|
||||
loadCaseListAndResetSelector();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
hideCancel: false,
|
||||
});
|
||||
}
|
||||
|
||||
// 批量操作参数
|
||||
function getBatchParams(): ApiCaseBatchParams {
|
||||
return {
|
||||
excludeIds: batchParams.value.excludeIds,
|
||||
selectAll: batchParams.value.selectAll,
|
||||
selectIds: batchParams.value.selectedIds as string[],
|
||||
moduleIds: moduleIds.value,
|
||||
projectId: appStore.currentProjectId,
|
||||
protocol: props.protocol,
|
||||
condition: {
|
||||
keyword: keyword.value,
|
||||
filter: propsRes.value.filter,
|
||||
combine: batchParams.value.condition,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// 批量恢复
|
||||
async function batchRecover() {
|
||||
openModal({
|
||||
type: 'info',
|
||||
title: t('case.batchRecoverCaseTip', {
|
||||
count: batchParams.value.currentSelectCount || tableSelected.value.length,
|
||||
}),
|
||||
content: t('case.recycle.recoverCaseTip'),
|
||||
okText: t('case.recycle.confirmRecovery'),
|
||||
cancelText: t('common.cancel'),
|
||||
okButtonProps: {
|
||||
status: 'normal',
|
||||
},
|
||||
onBeforeOk: async () => {
|
||||
try {
|
||||
await batchRecoverCase(getBatchParams());
|
||||
Message.success(t('apiTestManagement.recycle.recoveredSuccessfully'));
|
||||
loadCaseListAndResetSelector();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
hideCancel: false,
|
||||
});
|
||||
}
|
||||
|
||||
// 批量彻底删除
|
||||
async function batchCleanOut() {
|
||||
const title = t('case.batchDeleteCaseTip', {
|
||||
count: batchParams.value.currentSelectCount || tableSelected.value.length,
|
||||
});
|
||||
openModal({
|
||||
type: 'error',
|
||||
title,
|
||||
content: t('case.recycle.cleanOutDeleteOnRecycleTip'),
|
||||
okText: t('common.confirmDelete'),
|
||||
cancelText: t('common.cancel'),
|
||||
okButtonProps: {
|
||||
status: 'danger',
|
||||
},
|
||||
onBeforeOk: async () => {
|
||||
try {
|
||||
await batchDeleteRecycleCase(getBatchParams());
|
||||
Message.success(t('common.deleteSuccess'));
|
||||
loadCaseListAndResetSelector();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
hideCancel: false,
|
||||
});
|
||||
}
|
||||
|
||||
function handleTableSelect(arr: (string | number)[]) {
|
||||
tableSelected.value = arr;
|
||||
}
|
||||
|
||||
// 处理表格选中后批量操作
|
||||
function handleTableBatch(event: BatchActionParams, params: BatchActionQueryParams) {
|
||||
tableSelected.value = params?.selectedIds || [];
|
||||
batchParams.value = params;
|
||||
switch (event.eventTag) {
|
||||
case 'batchRecover':
|
||||
batchRecover();
|
||||
break;
|
||||
case 'batchCleanOut':
|
||||
batchCleanOut();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
:deep(.param-input:not(.arco-input-focus, .arco-select-view-focus)) {
|
||||
&:not(:hover) {
|
||||
border-color: transparent !important;
|
||||
.arco-input::placeholder {
|
||||
@apply invisible;
|
||||
}
|
||||
.arco-select-view-icon {
|
||||
@apply invisible;
|
||||
}
|
||||
.arco-select-view-value {
|
||||
color: var(--color-text-brand);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -9,12 +9,15 @@
|
||||
:protocol="protocol"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="case" title="CASE" class="ms-api-tab-pane"></a-tab-pane>
|
||||
<a-tab-pane key="case" title="CASE" class="ms-api-tab-pane">
|
||||
<api-case :active-module="props.activeModule" :offspring-ids="props.offspringIds" :protocol="protocol"></api-case>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import api from './api/apiTable.vue';
|
||||
import apiCase from './case/caseTable.vue';
|
||||
|
||||
import useAppStore from '@/store/modules/app';
|
||||
|
||||
|
@ -165,9 +165,16 @@ export default {
|
||||
'case.passRate': 'Pass Rate',
|
||||
'case.passRateTip': 'Number of success case executions/Total number of case executions *%',
|
||||
'case.batchModalSubTitle': '({count} cases selected)',
|
||||
'case.batchDeleteCaseTipTitle': 'Are you sure you want to delete {name} ?',
|
||||
'case.batchRecoverCaseTipTitle': 'Are you sure you want to recover {name} ?',
|
||||
'case.batchDeleteCaseTip': 'Are you sure you want to delete {count} selected cases?',
|
||||
'case.recycle.cleanOutDeleteOnRecycleTip':
|
||||
'After deletion, the case cannot be restored. Please operate with caution!',
|
||||
'case.deleteCaseTip':
|
||||
'Deleting an case will result in the execution failure of the test task that references the use case. Please be cautious!',
|
||||
'apiTestManagement.click': 'Click',
|
||||
'apiTestManagement.getResponse': 'Get response content',
|
||||
'case.batchRecoverCaseTip': 'Are you sure you want to recover {count} selected cases?',
|
||||
'case.recycle.recoverCaseTip': 'When restoring the case, the deleted API will be restored simultaneously.',
|
||||
'case.recycle.confirmRecovery': 'Confirm recovery',
|
||||
};
|
||||
|
@ -162,5 +162,11 @@ export default {
|
||||
'case.passRateTip': '用例执行success数/用例执行总数*%',
|
||||
'case.batchModalSubTitle': '(已选 {count} 个用例)',
|
||||
'case.batchDeleteCaseTip': '确认删除已选中的 {count} 个用例吗?',
|
||||
'case.batchDeleteCaseTipTitle': '确认删除 {name} 吗?',
|
||||
'case.batchRecoverCaseTipTitle': '确认恢复 {name} 吗?',
|
||||
'case.recycle.cleanOutDeleteOnRecycleTip': '删除后,用例无法恢复,请谨慎操作!',
|
||||
'case.deleteCaseTip': '删除用例会导致引用了该用例的测试任务执行失败,请谨慎操作!',
|
||||
'case.batchRecoverCaseTip': '确认恢复已选中的 {count} 个用例吗?',
|
||||
'case.recycle.recoverCaseTip': '恢复case时会同步恢复被删除的api',
|
||||
'case.recycle.confirmRecovery': '确认恢复',
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user