feat(测试计划): 测试计划详情-功能用例取消关联用例联调
This commit is contained in:
parent
7110f47191
commit
0c3ed10966
|
@ -5,9 +5,11 @@ import {
|
|||
archivedPlanUrl,
|
||||
batchCopyPlanUrl,
|
||||
batchDeletePlanUrl,
|
||||
BatchDisassociateCaseUrl,
|
||||
batchMovePlanUrl,
|
||||
deletePlanUrl,
|
||||
DeleteTestPlanModuleUrl,
|
||||
DisassociateCaseUrl,
|
||||
GetFeatureCaseModuleCountUrl,
|
||||
GetFeatureCaseModuleUrl,
|
||||
GetPlanDetailFeatureCaseListUrl,
|
||||
|
@ -27,6 +29,8 @@ import type { CommonList, MoveModules, TableQueryParams } from '@/models/common'
|
|||
import { ModuleTreeNode } from '@/models/common';
|
||||
import type {
|
||||
AddTestPlanParams,
|
||||
BatchFeatureCaseParams,
|
||||
DisassociateCaseParams,
|
||||
PlanDetailBugItem,
|
||||
PlanDetailFeatureCaseItem,
|
||||
PlanDetailFeatureCaseListQueryParams,
|
||||
|
@ -124,3 +128,11 @@ export function getFeatureCaseModuleCount(data: PlanDetailFeatureCaseListQueryPa
|
|||
export function getFeatureCaseModule(planId: string) {
|
||||
return MSR.get<ModuleTreeNode[]>({ url: `${GetFeatureCaseModuleUrl}/${planId}` });
|
||||
}
|
||||
// 计划详情-功能用例列表-取消关联用例
|
||||
export function disassociateCase(data: DisassociateCaseParams) {
|
||||
return MSR.post({ url: DisassociateCaseUrl, data });
|
||||
}
|
||||
// 计划详情-功能用例列表-批量取消关联用例
|
||||
export function batchDisassociateCase(data: BatchFeatureCaseParams) {
|
||||
return MSR.post({ url: BatchDisassociateCaseUrl, data });
|
||||
}
|
||||
|
|
|
@ -38,3 +38,7 @@ export const GetPlanDetailFeatureCaseListUrl = '/test-plan/functional/case/page'
|
|||
export const GetFeatureCaseModuleCountUrl = '/test-plan/functional/case/module/count';
|
||||
// 计划详情-功能用例模块树
|
||||
export const GetFeatureCaseModuleUrl = '/test-plan/functional/case/tree';
|
||||
// 计划详情-功能用例-取消关联用例
|
||||
export const DisassociateCaseUrl = '/test-plan/functional/case/disassociate';
|
||||
// 计划详情-功能用例-批量取消关联用例
|
||||
export const BatchDisassociateCaseUrl = '/test-plan/functional/case/batch/disassociate';
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import type { BatchActionQueryParams } from '@/components/pure/ms-table/type';
|
||||
|
||||
import type { customFieldsItem } from '@/models/caseManagement/featureCase';
|
||||
import type { TableQueryParams } from '@/models/common';
|
||||
import { LastExecuteResults } from '@/enums/caseEnum';
|
||||
|
@ -148,5 +150,14 @@ export interface PlanDetailFeatureCaseListQueryParams extends TableQueryParams {
|
|||
testPlanId: string;
|
||||
projectId: string;
|
||||
}
|
||||
export interface DisassociateCaseParams {
|
||||
testPlanId: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
export interface BatchFeatureCaseParams extends BatchActionQueryParams {
|
||||
testPlanId: string;
|
||||
moduleIds?: string[];
|
||||
}
|
||||
|
||||
export default {};
|
||||
|
|
|
@ -46,14 +46,23 @@
|
|||
</a-select>
|
||||
<span v-else class="text-[var(--color-text-2)]"><ExecuteResult :execute-result="record.lastExecResult" /></span>
|
||||
</template>
|
||||
<template #operation>
|
||||
<template #operation="{ record }">
|
||||
<MsButton v-permission="['PROJECT_API_DEFINITION_CASE:READ+EXECUTE']" type="text" class="!mr-0">
|
||||
{{ t('common.execute') }}
|
||||
</MsButton>
|
||||
<a-divider v-permission="['PROJECT_TEST_PLAN:READ+ASSOCIATION']" direction="vertical" :margin="8"></a-divider>
|
||||
<MsButton v-permission="['PROJECT_TEST_PLAN:READ+ASSOCIATION']" type="text" class="!mr-0">
|
||||
{{ t('common.cancelLink') }}
|
||||
</MsButton>
|
||||
<MsPopconfirm
|
||||
:title="t('testPlan.featureCase.disassociateTip', { name: record.name })"
|
||||
:sub-title-tip="t('testPlan.featureCase.disassociateTipContent')"
|
||||
:ok-text="t('common.confirm')"
|
||||
:loading="disassociateLoading"
|
||||
type="error"
|
||||
@confirm="(val, done) => handleDisassociateCase(record, done)"
|
||||
>
|
||||
<MsButton v-permission="['PROJECT_TEST_PLAN:READ+ASSOCIATION']" type="text" class="!mr-0">
|
||||
{{ t('common.cancelLink') }}
|
||||
</MsButton>
|
||||
</MsPopconfirm>
|
||||
<!-- TODO: 修改permission -->
|
||||
<a-divider
|
||||
v-permission="['PROJECT_API_DEFINITION_CASE:READ+EXECUTE']"
|
||||
|
@ -71,16 +80,23 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, onBeforeMount, ref } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
|
||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||
import MsPopconfirm from '@/components/pure/ms-popconfirm/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 ExecuteResult from '@/components/business/ms-case-associate/executeResult.vue';
|
||||
|
||||
import { getPlanDetailFeatureCaseList } from '@/api/modules/test-plan/testPlan';
|
||||
import {
|
||||
batchDisassociateCase,
|
||||
disassociateCase,
|
||||
getPlanDetailFeatureCaseList,
|
||||
} from '@/api/modules/test-plan/testPlan';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import useTableStore from '@/hooks/useTableStore';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
@ -106,7 +122,7 @@
|
|||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'init', params: PlanDetailFeatureCaseListQueryParams): void;
|
||||
(e: 'getModuleCount', params: PlanDetailFeatureCaseListQueryParams): void;
|
||||
}>();
|
||||
|
||||
const { t } = useI18n();
|
||||
|
@ -114,8 +130,13 @@
|
|||
const router = useRouter();
|
||||
const appStore = useAppStore();
|
||||
const tableStore = useTableStore();
|
||||
const { openModal } = useModal();
|
||||
|
||||
const keyword = ref('');
|
||||
const tableParams = ref<PlanDetailFeatureCaseListQueryParams>({
|
||||
testPlanId: props.planId,
|
||||
projectId: appStore.currentProjectId,
|
||||
});
|
||||
|
||||
// TODO: 复制的Permission
|
||||
const hasOperationPermission = computed(() =>
|
||||
|
@ -235,10 +256,6 @@
|
|||
eventTag: 'execute',
|
||||
permission: ['PROJECT_TEST_PLAN:READ+EXECUTE'],
|
||||
},
|
||||
{
|
||||
label: 'testPlan.featureCase.sort',
|
||||
eventTag: 'sort',
|
||||
},
|
||||
{
|
||||
label: 'testPlan.featureCase.changeExecutor',
|
||||
eventTag: 'changeExecutor',
|
||||
|
@ -261,25 +278,6 @@
|
|||
],
|
||||
};
|
||||
|
||||
const tableSelected = ref<(string | number)[]>([]); // 表格选中的
|
||||
const batchParams = ref<BatchActionQueryParams>({
|
||||
selectedIds: [],
|
||||
selectAll: false,
|
||||
excludeIds: [],
|
||||
currentSelectCount: 0,
|
||||
});
|
||||
// 处理表格选中后批量操作
|
||||
function handleTableBatch(event: BatchActionParams, params: BatchActionQueryParams) {
|
||||
tableSelected.value = params?.selectedIds || [];
|
||||
batchParams.value = params;
|
||||
switch (event.eventTag) {
|
||||
case 'execute':
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
async function getModuleIds() {
|
||||
let moduleIds: string[] = [];
|
||||
if (props.activeModule !== 'all') {
|
||||
|
@ -293,16 +291,16 @@
|
|||
}
|
||||
async function loadCaseList() {
|
||||
const selectModules = await getModuleIds();
|
||||
const params: PlanDetailFeatureCaseListQueryParams = {
|
||||
tableParams.value = {
|
||||
testPlanId: props.planId,
|
||||
projectId: appStore.currentProjectId,
|
||||
moduleIds: selectModules,
|
||||
keyword: keyword.value,
|
||||
};
|
||||
setLoadListParams(params);
|
||||
setLoadListParams(tableParams.value);
|
||||
loadList();
|
||||
emit('init', {
|
||||
...params,
|
||||
emit('getModuleCount', {
|
||||
...tableParams.value,
|
||||
current: propsRes.value.msPagination?.current,
|
||||
pageSize: propsRes.value.msPagination?.pageSize,
|
||||
});
|
||||
|
@ -310,6 +308,90 @@
|
|||
onBeforeMount(() => {
|
||||
loadCaseList();
|
||||
});
|
||||
watch(
|
||||
() => props.activeModule,
|
||||
() => {
|
||||
loadCaseList();
|
||||
}
|
||||
);
|
||||
|
||||
const tableSelected = ref<(string | number)[]>([]); // 表格选中的
|
||||
const batchParams = ref<BatchActionQueryParams>({
|
||||
selectIds: [],
|
||||
selectAll: false,
|
||||
excludeIds: [],
|
||||
condition: {},
|
||||
currentSelectCount: 0,
|
||||
});
|
||||
|
||||
function resetCaseList() {
|
||||
resetSelector();
|
||||
emit('getModuleCount', {
|
||||
...tableParams.value,
|
||||
current: propsRes.value.msPagination?.current,
|
||||
pageSize: propsRes.value.msPagination?.pageSize,
|
||||
});
|
||||
loadList();
|
||||
}
|
||||
|
||||
// 批量取消关联用例
|
||||
function handleBatchDisassociateCase() {
|
||||
openModal({
|
||||
type: 'warning',
|
||||
title: t('caseManagement.caseReview.disassociateConfirmTitle', { count: batchParams.value.currentSelectCount }),
|
||||
content: t('testPlan.featureCase.batchDisassociateTipContent'),
|
||||
okText: t('common.cancelLink'),
|
||||
cancelText: t('common.cancel'),
|
||||
onBeforeOk: async () => {
|
||||
try {
|
||||
await batchDisassociateCase({
|
||||
...batchParams.value,
|
||||
...tableParams.value,
|
||||
});
|
||||
Message.success(t('common.updateSuccess'));
|
||||
resetCaseList();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
hideCancel: false,
|
||||
});
|
||||
}
|
||||
|
||||
// 处理表格选中后批量操作
|
||||
function handleTableBatch(event: BatchActionParams, params: BatchActionQueryParams) {
|
||||
tableSelected.value = params?.selectedIds || [];
|
||||
batchParams.value = params;
|
||||
switch (event.eventTag) {
|
||||
case 'execute':
|
||||
break;
|
||||
case 'disassociate':
|
||||
handleBatchDisassociateCase();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 取消关联
|
||||
const disassociateLoading = ref(false);
|
||||
async function handleDisassociateCase(record: PlanDetailFeatureCaseItem, done?: () => void) {
|
||||
try {
|
||||
disassociateLoading.value = true;
|
||||
await disassociateCase({ testPlanId: props.planId, id: record.id });
|
||||
if (done) {
|
||||
done();
|
||||
}
|
||||
Message.success(t('common.unLinkSuccess'));
|
||||
resetCaseList();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
} finally {
|
||||
disassociateLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 去用例详情页面
|
||||
function toCaseDetail(record: PlanDetailFeatureCaseItem) {
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
:active-module="activeFolderId"
|
||||
:offspring-ids="offspringIds"
|
||||
:module-tree="moduleTree"
|
||||
@init="getModuleCount"
|
||||
@get-module-count="getModuleCount"
|
||||
></CaseTable>
|
||||
</template>
|
||||
</MsSplitBox>
|
||||
|
|
|
@ -89,4 +89,9 @@ export default {
|
|||
'testPlan.featureCase.executor': 'Executor',
|
||||
'testPlan.featureCase.changeExecutor': 'Change executor',
|
||||
'testPlan.featureCase.sort': 'sort',
|
||||
'testPlan.featureCase.disassociateTip': 'Are you sure to cancel the association {name}? ',
|
||||
'testPlan.featureCase.disassociateTipContent':
|
||||
'After cancellation, it will affect the statistics related to the test plan',
|
||||
'testPlan.featureCase.batchDisassociateTipContent':
|
||||
' After cancellation, associate again, and the execution result is unexecuted',
|
||||
};
|
||||
|
|
|
@ -87,4 +87,7 @@ export default {
|
|||
'testPlan.featureCase.executor': '执行人',
|
||||
'testPlan.featureCase.changeExecutor': '修改执行人',
|
||||
'testPlan.featureCase.sort': '排序',
|
||||
'testPlan.featureCase.disassociateTip': '确认取消关联 { name } 吗?',
|
||||
'testPlan.featureCase.disassociateTipContent': '取消后,影响测试计划相关统计',
|
||||
'testPlan.featureCase.batchDisassociateTipContent': '取消后,再次关联,执行结果为:未执行',
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue