feat(测试计划): 测试计划详情-接口用例&接口场景-移动

This commit is contained in:
teukkk 2024-06-12 17:03:35 +08:00 committed by Craftsman
parent e5518e1c30
commit 727e7eb928
8 changed files with 224 additions and 67 deletions

View File

@ -11,6 +11,8 @@ import {
BatchDisassociateApiScenarioUrl,
BatchDisassociateCaseUrl,
BatchEditTestPlanUrl,
BatchMoveApiCaseUrl,
BatchMoveApiScenarioUrl,
batchMovePlanUrl,
BatchRunApiCaseUrl,
BatchRunApiScenarioUrl,
@ -82,6 +84,7 @@ import type {
BatchApiCaseParams,
BatchExecuteFeatureCaseParams,
BatchFeatureCaseParams,
BatchMoveApiCaseParams,
BatchUpdateApiCaseExecutorParams,
BatchUpdateCaseExecutorParams,
CreateTask,
@ -316,6 +319,10 @@ export function batchUpdateApiCaseExecutor(data: BatchUpdateApiCaseExecutorParam
export function batchRunApiCase(data: BatchApiCaseParams) {
return MSR.post({ url: BatchRunApiCaseUrl, data });
}
// 计划详情-接口用例列表-批量移动
export function batchMoveApiCase(data: BatchMoveApiCaseParams) {
return MSR.post({ url: BatchMoveApiCaseUrl, data });
}
// 计划详情-接口场景列表
export function getPlanDetailApiScenarioList(data: PlanDetailApiScenarioQueryParams) {
return MSR.post<CommonList<PlanDetailApiScenarioItem>>({ url: GetPlanDetailApiScenarioListUrl, data });
@ -352,6 +359,10 @@ export function batchUpdateApiScenarioExecutor(data: BatchUpdateApiCaseExecutorP
export function batchRunApiScenario(data: BatchApiCaseParams) {
return MSR.post({ url: BatchRunApiScenarioUrl, data });
}
// 计划详情-接口场景列表-批量移动
export function batchMoveApiScenario(data: BatchMoveApiCaseParams) {
return MSR.post({ url: BatchMoveApiScenarioUrl, data });
}
// 计划详情-执行历史 TODO 联调
export function getPlanDetailExecuteHistory(data: PlanDetailFeatureCaseListQueryParams) {
return MSR.post<CommonList<PlanDetailExecuteHistoryItem>>({ url: PlanDetailExecuteHistoryUrl, data });

View File

@ -117,6 +117,8 @@ export const BatchDisassociateApiCaseUrl = '/test-plan/api/case/batch/disassocia
export const BatchUpdateApiCaseExecutorUrl = '/test-plan/api/case/batch/update/executor';
// 计划详情-接口用例列表-批量执行
export const BatchRunApiCaseUrl = '/test-plan/api/case/batch/run';
// 计划详情-接口用例列表-批量移动
export const BatchMoveApiCaseUrl = '/test-plan/api/case/batch/move';
// 计划详情-接口场景列表
export const GetPlanDetailApiScenarioListUrl = '/test-plan/api/scenario/page';
@ -136,6 +138,8 @@ export const BatchDisassociateApiScenarioUrl = '/test-plan/api/scenario/batch/di
export const BatchUpdateApiScenarioExecutorUrl = '/test-plan/api/scenario/batch/update/executor';
// 计划详情-接口场景列表-批量执行
export const BatchRunApiScenarioUrl = '/test-plan/api/scenario/batch/run';
// 计划详情-接口场景列表-批量移动
export const BatchMoveApiScenarioUrl = '/test-plan/api/scenario/batch/move';
// 测试规划脑图
export const GetPlanMinderUrl = '/test-plan/mind/data';

View File

@ -307,6 +307,10 @@ export interface BatchUpdateApiCaseExecutorParams extends BatchApiCaseParams {
userId: string; // 执行人id
}
export interface BatchMoveApiCaseParams extends BatchApiCaseParams {
targetCollectionId: string; // 测试集id
}
export interface SortApiCaseParams extends DragSortParams {
testCollectionId: string; // 测试集id
}

View File

@ -0,0 +1,111 @@
<template>
<a-modal
v-model:visible="visible"
title-align="start"
body-class="p-0"
:cancel-button-props="{ disabled: batchLoading }"
@close="handleCancel"
>
<template #title>
{{ t('common.batchMove') }}
<div class="ml-1 text-[var(--color-text-4)]">
{{
t('testPlan.testPlanIndex.selectedCount', {
count: props.count,
})
}}
</div>
</template>
<a-form ref="formRef" :model="form" layout="vertical">
<a-form-item
:rules="[{ required: true, message: t('testPlan.api.testSetRequired') }]"
field="targetCollectionId"
:label="t('ms.minders.testSet')"
asterisk-position="end"
>
<MsSelect
v-model:modelValue="form.targetCollectionId"
mode="static"
:placeholder="t('common.pleaseSelect')"
:options="options"
:search-keys="['label']"
allow-search
/>
</a-form-item>
</a-form>
<template #footer>
<a-button type="secondary" @click="handleCancel">{{ t('common.cancel') }}</a-button>
<a-button class="ml-[12px]" type="primary" :loading="batchLoading" @click="handleMove">
{{ t('common.move') }}
</a-button>
</template>
</a-modal>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { FormInstance, Message } from '@arco-design/web-vue';
import MsSelect from '@/components/business/ms-select';
import { useI18n } from '@/hooks/useI18n';
import { ModuleTreeNode } from '@/models/common';
import type { BatchMoveApiCaseParams } from '@/models/testPlan/testPlan';
const props = defineProps<{
count: number;
params?: BatchMoveApiCaseParams;
batchMove: (...args: any) => Promise<any>; //
moduleTree: ModuleTreeNode[];
}>();
const emit = defineEmits<{
(e: 'loadList'): void;
}>();
const visible = defineModel<boolean>('visible', {
required: true,
});
const { t } = useI18n();
const formRef = ref<FormInstance>();
const batchLoading = ref(false);
const form = ref<{ targetCollectionId: string }>({ targetCollectionId: '' });
const options = computed(() =>
props.moduleTree.map((item) => {
return {
label: item.name,
value: item.id,
};
})
);
async function handleMove() {
formRef.value?.validate(async (errors) => {
if (!errors) {
try {
batchLoading.value = true;
await props.batchMove({
...props.params,
...form.value,
});
Message.success(t('common.moveSuccess'));
emit('loadList');
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
} finally {
batchLoading.value = false;
}
}
});
}
function handleCancel() {
visible.value = false;
form.value = { targetCollectionId: '' };
}
</script>

View File

@ -12,7 +12,7 @@
>
<template #title>
{{ t('testPlan.featureCase.batchChangeExecutor') }}
<div class="text-[var(--color-text-4)]">
<div class="ml-1 text-[var(--color-text-4)]">
{{
t('testPlan.testPlanIndex.selectedCount', {
count: props.count,

View File

@ -77,10 +77,19 @@
<BatchUpdateExecutorModal
v-model:visible="batchUpdateExecutorModalVisible"
:count="batchParams.currentSelectCount || tableSelected.length"
:params="batchUpdateExecutorParams"
:params="batchUpdateParams"
:batch-update-executor="batchUpdateApiCaseExecutor"
@load-list="resetSelectorAndCaseList"
/>
<!-- 批量移动 -->
<BatchApiMoveModal
v-model:visible="batchMoveModalVisible"
:module-tree="props.moduleTree"
:count="batchParams.currentSelectCount || tableSelected.length"
:params="batchUpdateParams"
:batch-move="batchMoveApiCase"
@load-list="resetCaseList"
/>
</div>
</template>
@ -104,10 +113,12 @@
import ApiMethodName from '@/views/api-test/components/apiMethodName.vue';
import apiStatus from '@/views/api-test/components/apiStatus.vue';
import CaseAndScenarioReportDrawer from '@/views/api-test/components/caseAndScenarioReportDrawer.vue';
import BatchApiMoveModal from '@/views/test-plan/testPlan/components/batchApiMoveModal.vue';
import BatchUpdateExecutorModal from '@/views/test-plan/testPlan/components/batchUpdateExecutorModal.vue';
import {
batchDisassociateApiCase,
batchMoveApiCase,
batchRunApiCase,
batchUpdateApiCaseExecutor,
disassociateApiCase,
@ -309,30 +320,30 @@
}
);
const batchActions = {
baseAction: [
{
label: 'common.execute',
eventTag: 'execute',
permission: ['PROJECT_TEST_PLAN:READ+EXECUTE'],
},
{
label: 'testPlan.featureCase.changeExecutor',
eventTag: 'changeExecutor',
permission: ['PROJECT_TEST_PLAN:READ+UPDATE'],
},
{
label: 'common.move',
eventTag: 'move',
permission: ['PROJECT_TEST_PLAN:READ+UPDATE'],
},
{
label: 'common.cancelLink',
eventTag: 'disassociate',
permission: ['PROJECT_TEST_PLAN:READ+ASSOCIATION'],
},
],
};
const batchActions = computed(() => {
return {
baseAction: [
{
label: 'common.execute',
eventTag: 'execute',
permission: ['PROJECT_TEST_PLAN:READ+EXECUTE'],
},
{
label: 'testPlan.featureCase.changeExecutor',
eventTag: 'changeExecutor',
permission: ['PROJECT_TEST_PLAN:READ+UPDATE'],
},
...(props.treeType === 'COLLECTION'
? [{ label: 'common.move', eventTag: 'move', permission: ['PROJECT_TEST_PLAN:READ+UPDATE'] }]
: []),
{
label: 'common.cancelLink',
eventTag: 'disassociate',
permission: ['PROJECT_TEST_PLAN:READ+ASSOCIATION'],
},
],
};
});
async function getModuleIds() {
let moduleIds: string[] = [];
@ -543,15 +554,22 @@
});
}
//
//
const batchUpdateParams = ref();
const batchUpdateExecutorModalVisible = ref(false);
const batchUpdateExecutorParams = ref();
const batchMoveModalVisible = ref(false);
//
async function handleTableBatch(event: BatchActionParams, params: BatchActionQueryParams) {
tableSelected.value = params?.selectedIds || [];
batchParams.value = { ...params, selectIds: params?.selectedIds };
const tableParams = await getTableParams(true);
batchUpdateParams.value = {
selectIds: tableSelected.value as string[],
selectAll: batchParams.value.selectAll,
excludeIds: batchParams.value?.excludeIds || [],
...tableParams,
};
switch (event.eventTag) {
case 'execute':
handleBatchRun();
@ -560,15 +578,10 @@
handleBatchDisassociateCase();
break;
case 'changeExecutor':
batchUpdateExecutorParams.value = {
selectIds: tableSelected.value as string[],
selectAll: batchParams.value.selectAll,
excludeIds: batchParams.value?.excludeIds || [],
...tableParams,
};
batchUpdateExecutorModalVisible.value = true;
break;
case 'move':
batchMoveModalVisible.value = true;
break;
default:
break;

View File

@ -72,10 +72,19 @@
<BatchUpdateExecutorModal
v-model:visible="batchUpdateExecutorModalVisible"
:count="batchParams.currentSelectCount || tableSelected.length"
:params="batchUpdateExecutorParams"
:params="batchUpdateParams"
:batch-update-executor="batchUpdateApiScenarioExecutor"
@load-list="resetSelectorAndCaseList"
/>
<!-- 批量移动 -->
<BatchApiMoveModal
v-model:visible="batchMoveModalVisible"
:module-tree="props.moduleTree"
:count="batchParams.currentSelectCount || tableSelected.length"
:params="batchUpdateParams"
:batch-move="batchMoveApiScenario"
@load-list="resetCaseList"
/>
</div>
</template>
@ -98,10 +107,12 @@
import ExecuteResult from '@/components/business/ms-case-associate/executeResult.vue';
import apiStatus from '@/views/api-test/components/apiStatus.vue';
import CaseAndScenarioReportDrawer from '@/views/api-test/components/caseAndScenarioReportDrawer.vue';
import BatchApiMoveModal from '@/views/test-plan/testPlan/components/batchApiMoveModal.vue';
import BatchUpdateExecutorModal from '@/views/test-plan/testPlan/components/batchUpdateExecutorModal.vue';
import {
batchDisassociateApiScenario,
batchMoveApiScenario,
batchRunApiScenario,
batchUpdateApiScenarioExecutor,
disassociateApiScenario,
@ -292,30 +303,30 @@
}
);
const batchActions = {
baseAction: [
{
label: 'common.execute',
eventTag: 'execute',
permission: ['PROJECT_TEST_PLAN:READ+EXECUTE'],
},
{
label: 'testPlan.featureCase.changeExecutor',
eventTag: 'changeExecutor',
permission: ['PROJECT_TEST_PLAN:READ+UPDATE'],
},
{
label: 'common.move',
eventTag: 'move',
permission: ['PROJECT_TEST_PLAN:READ+UPDATE'],
},
{
label: 'common.cancelLink',
eventTag: 'disassociate',
permission: ['PROJECT_TEST_PLAN:READ+ASSOCIATION'],
},
],
};
const batchActions = computed(() => {
return {
baseAction: [
{
label: 'common.execute',
eventTag: 'execute',
permission: ['PROJECT_TEST_PLAN:READ+EXECUTE'],
},
{
label: 'testPlan.featureCase.changeExecutor',
eventTag: 'changeExecutor',
permission: ['PROJECT_TEST_PLAN:READ+UPDATE'],
},
...(props.treeType === 'COLLECTION'
? [{ label: 'common.move', eventTag: 'move', permission: ['PROJECT_TEST_PLAN:READ+UPDATE'] }]
: []),
{
label: 'common.cancelLink',
eventTag: 'disassociate',
permission: ['PROJECT_TEST_PLAN:READ+ASSOCIATION'],
},
],
};
});
async function getModuleIds() {
let moduleIds: string[] = [];
@ -528,15 +539,22 @@
});
}
//
//
const batchUpdateParams = ref();
const batchUpdateExecutorModalVisible = ref(false);
const batchUpdateExecutorParams = ref();
const batchMoveModalVisible = ref(false);
//
async function handleTableBatch(event: BatchActionParams, params: BatchActionQueryParams) {
tableSelected.value = params?.selectedIds || [];
batchParams.value = { ...params, selectIds: params?.selectedIds };
const tableParams = await getTableParams(true);
batchUpdateParams.value = {
selectIds: tableSelected.value as string[],
selectAll: batchParams.value.selectAll,
excludeIds: batchParams.value?.excludeIds || [],
...tableParams,
};
switch (event.eventTag) {
case 'execute':
handleBatchRun();
@ -545,15 +563,10 @@
handleBatchDisassociateCase();
break;
case 'changeExecutor':
batchUpdateExecutorParams.value = {
selectIds: tableSelected.value as string[],
selectAll: batchParams.value.selectAll,
excludeIds: batchParams.value?.excludeIds || [],
...tableParams,
};
batchUpdateExecutorModalVisible.value = true;
break;
case 'move':
batchMoveModalVisible.value = true;
break;
default:
break;

View File

@ -106,6 +106,7 @@ export default {
'testPlan.featureCase.richTextDblclickPlaceholder': '双击可快速输入',
'testPlan.featureCase.autoNextTip1': '开启:提交结果后,跳转至下一条用例',
'testPlan.featureCase.autoNextTip2': '关闭:提交结果后,还在当前',
'testPlan.api.testSetRequired': '测试集不能为空',
'testPlan.executeHistory.executionStartAndEndTime': '执行起止时间',
'testPlan.testPlanGroup.seeArchived': '只看已归档',
'testPlan.testPlanGroup.planNamePlaceholder': '请输入测试计划组名称',