feat(测试计划): 测试计划详情用例关联缺陷联调
This commit is contained in:
parent
11fe18e5d0
commit
e759d15c15
|
@ -7,7 +7,11 @@ import {
|
||||||
ApiScenarioReportDetailStepUrl,
|
ApiScenarioReportDetailStepUrl,
|
||||||
ApiScenarioReportDetailUrl,
|
ApiScenarioReportDetailUrl,
|
||||||
archivedPlanUrl,
|
archivedPlanUrl,
|
||||||
|
AssociatedBugToApiCaseUrl,
|
||||||
|
AssociatedBugToScenarioCaseUrl,
|
||||||
|
BatchAddBugToCaseUrl,
|
||||||
batchArchivedPlanUrl,
|
batchArchivedPlanUrl,
|
||||||
|
BatchAssociatedBugToCaseUrl,
|
||||||
batchCopyPlanUrl,
|
batchCopyPlanUrl,
|
||||||
batchDeletePlanUrl,
|
batchDeletePlanUrl,
|
||||||
BatchDisassociateApiCaseUrl,
|
BatchDisassociateApiCaseUrl,
|
||||||
|
@ -23,6 +27,8 @@ import {
|
||||||
BatchRunApiScenarioUrl,
|
BatchRunApiScenarioUrl,
|
||||||
BatchRunCaseUrl,
|
BatchRunCaseUrl,
|
||||||
BatchUpdateCaseExecutorUrl,
|
BatchUpdateCaseExecutorUrl,
|
||||||
|
CancelBugFromApiCaseUrl,
|
||||||
|
CancelBugFromScenarioCaseUrl,
|
||||||
ConfigScheduleUrl,
|
ConfigScheduleUrl,
|
||||||
copyTestPlanUrl,
|
copyTestPlanUrl,
|
||||||
deletePlanUrl,
|
deletePlanUrl,
|
||||||
|
@ -56,7 +62,9 @@ import {
|
||||||
GetTestPlanModuleCountUrl,
|
GetTestPlanModuleCountUrl,
|
||||||
GetTestPlanModuleUrl,
|
GetTestPlanModuleUrl,
|
||||||
GetTestPlanUsersUrl,
|
GetTestPlanUsersUrl,
|
||||||
|
GetUnAssociatedApiBugUrl,
|
||||||
GetUnAssociatedListUrl,
|
GetUnAssociatedListUrl,
|
||||||
|
GetUnAssociatedScenarioBugUrl,
|
||||||
MoveTestPlanModuleUrl,
|
MoveTestPlanModuleUrl,
|
||||||
planDetailBugPageUrl,
|
planDetailBugPageUrl,
|
||||||
PlanDetailExecuteHistoryUrl,
|
PlanDetailExecuteHistoryUrl,
|
||||||
|
@ -439,7 +447,39 @@ export function testPlanAssociateModuleCount(data: TableQueryParams) {
|
||||||
export function getExecuteUserOption(projectId: string, keyword?: string) {
|
export function getExecuteUserOption(projectId: string, keyword?: string) {
|
||||||
return MSR.get({ url: `${GetTestPlanExecutorOptionsUrl}/${projectId}`, params: { keyword } });
|
return MSR.get({ url: `${GetTestPlanExecutorOptionsUrl}/${projectId}`, params: { keyword } });
|
||||||
}
|
}
|
||||||
// 获取测试计划未关联抽屉缺陷列表
|
// 获取测试计划-功能用例-未关联抽屉缺陷列表
|
||||||
export function getTestPlanBugPage(data: TableQueryParams) {
|
export function getTestPlanBugPage(data: TableQueryParams) {
|
||||||
return MSR.post<CommonList<CaseManagementTable>>({ url: GetUnAssociatedListUrl, data });
|
return MSR.post<CommonList<CaseManagementTable>>({ url: GetUnAssociatedListUrl, data });
|
||||||
}
|
}
|
||||||
|
// 获取测试计划-接口用例-未关联抽屉缺陷列表
|
||||||
|
export function getTestPlanApiBugPage(data: TableQueryParams) {
|
||||||
|
return MSR.post<CommonList<CaseManagementTable>>({ url: GetUnAssociatedApiBugUrl, data });
|
||||||
|
}
|
||||||
|
// 获取测试计划-接口用例-未关联抽屉缺陷列表
|
||||||
|
export function getTestPlanScenarioBugPage(data: TableQueryParams) {
|
||||||
|
return MSR.post<CommonList<CaseManagementTable>>({ url: GetUnAssociatedScenarioBugUrl, data });
|
||||||
|
}
|
||||||
|
// 测试计划-用例详情-关联缺陷
|
||||||
|
export function associateBugToApiCase(data: TableQueryParams) {
|
||||||
|
return MSR.post({ url: AssociatedBugToApiCaseUrl, data });
|
||||||
|
}
|
||||||
|
// 测试计划-用例详情-关联缺陷
|
||||||
|
export function associateBugToScenarioCase(data: TableQueryParams) {
|
||||||
|
return MSR.post({ url: AssociatedBugToScenarioCaseUrl, data });
|
||||||
|
}
|
||||||
|
// 测试计划-接口用例-取消关联联缺陷
|
||||||
|
export function cancelBugFromApiCase(id: string) {
|
||||||
|
return MSR.get({ url: `${CancelBugFromApiCaseUrl}/${id}` });
|
||||||
|
}
|
||||||
|
// 测试计划-场景用例-取消关联联缺陷
|
||||||
|
export function cancelBugFromScenarioCase(id: string) {
|
||||||
|
return MSR.get({ url: `${CancelBugFromScenarioCaseUrl}/${id}` });
|
||||||
|
}
|
||||||
|
// 测试计划-详情-批量关联缺陷
|
||||||
|
export function batchAssociatedBugToCase(data: TableQueryParams) {
|
||||||
|
return MSR.post({ url: BatchAssociatedBugToCaseUrl, data });
|
||||||
|
}
|
||||||
|
// 测试计划-详情-批量新建缺陷
|
||||||
|
export function batchAddBugToCase(data: TableQueryParams) {
|
||||||
|
return MSR.post({ url: BatchAddBugToCaseUrl, data });
|
||||||
|
}
|
||||||
|
|
|
@ -157,3 +157,19 @@ export const TestPlanAssociationUrl = '/test-plan/association/api/case/module/co
|
||||||
export const GetTestPlanExecutorOptionsUrl = '/test-plan-execute/user-option';
|
export const GetTestPlanExecutorOptionsUrl = '/test-plan-execute/user-option';
|
||||||
// 获取测试计划未关联缺陷列表
|
// 获取测试计划未关联缺陷列表
|
||||||
export const GetUnAssociatedListUrl = '/test-plan/functional/case/associate/bug/page';
|
export const GetUnAssociatedListUrl = '/test-plan/functional/case/associate/bug/page';
|
||||||
|
// 获取测试计划未关联缺陷列表
|
||||||
|
export const GetUnAssociatedApiBugUrl = '/test-plan/api/case/associate/bug/page';
|
||||||
|
// 获取测试计划未关联缺陷列表
|
||||||
|
export const GetUnAssociatedScenarioBugUrl = '/test-plan/api/scenario/associate/bug/page';
|
||||||
|
// 测试计划-接口用例-单个用例关联缺陷
|
||||||
|
export const AssociatedBugToApiCaseUrl = '/test-plan/api/case/associate/bug';
|
||||||
|
// 测试计划-场景用例-单个用例关联缺陷
|
||||||
|
export const AssociatedBugToScenarioCaseUrl = '/test-plan/api/scenario/associate/bug';
|
||||||
|
// 测试计划-接口用例-取消关联联缺陷
|
||||||
|
export const CancelBugFromApiCaseUrl = '/test-plan/api/case/disassociate/bug';
|
||||||
|
// 测试计划-场景用例-取消关联联缺陷
|
||||||
|
export const CancelBugFromScenarioCaseUrl = '/test-plan/api/scenario/disassociate/bug';
|
||||||
|
// 测试计划-详情-用例列表-批量关联缺陷
|
||||||
|
export const BatchAssociatedBugToCaseUrl = '/test-plan/functional/case/batch/associate-bug';
|
||||||
|
// 测试计划-详情-用例列表-批量新建缺陷
|
||||||
|
export const BatchAddBugToCaseUrl = '/test-plan/functional/case/batch/add-bug';
|
||||||
|
|
|
@ -23,16 +23,18 @@
|
||||||
import type { MsTableColumn, MsTableProps } from '@/components/pure/ms-table/type';
|
import type { MsTableColumn, MsTableProps } from '@/components/pure/ms-table/type';
|
||||||
import useTable from '@/components/pure/ms-table/useTable';
|
import useTable from '@/components/pure/ms-table/useTable';
|
||||||
|
|
||||||
import { testPlanCancelBug } from '@/api/modules/test-plan/testPlan';
|
import { cancelBugFromApiCase, cancelBugFromScenarioCase, testPlanCancelBug } from '@/api/modules/test-plan/testPlan';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
|
||||||
import type { CaseBugItem } from '@/models/testPlan/testPlan';
|
import type { CaseBugItem } from '@/models/testPlan/testPlan';
|
||||||
|
import { CaseLinkEnum } from '@/enums/caseEnum';
|
||||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
bugList?: CaseBugItem[]; // 缺陷列表
|
bugList?: CaseBugItem[]; // 缺陷列表
|
||||||
canEdit: boolean;
|
canEdit: boolean;
|
||||||
bugCount: number;
|
bugCount: number;
|
||||||
|
caseType: CaseLinkEnum;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
|
@ -85,11 +87,17 @@
|
||||||
propsRes.value.data = props.bugList || [];
|
propsRes.value.data = props.bugList || [];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const cancelBugMap: Record<string, (id: string) => Promise<any>> = {
|
||||||
|
FUNCTIONAL: testPlanCancelBug,
|
||||||
|
API: cancelBugFromApiCase,
|
||||||
|
SCENARIO: cancelBugFromScenarioCase,
|
||||||
|
};
|
||||||
|
|
||||||
// 取消关联缺陷
|
// 取消关联缺陷
|
||||||
async function cancelLink(id: string) {
|
async function cancelLink(id: string) {
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
await testPlanCancelBug(id);
|
await cancelBugMap[props.caseType](id);
|
||||||
Message.success(t('common.unLinkSuccess'));
|
Message.success(t('common.unLinkSuccess'));
|
||||||
emit('loadList');
|
emit('loadList');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
@ -1,14 +1,21 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center" @click="selectedStyle">
|
||||||
<BugCountPopover :bug-list="bugList || []" :bug-count="bugCount" :can-edit="props.canEdit" @load-list="loadList" />
|
<BugCountPopover
|
||||||
|
:case-type="props.caseType"
|
||||||
|
:bug-list="bugList || []"
|
||||||
|
:bug-count="bugCount"
|
||||||
|
:can-edit="props.canEdit"
|
||||||
|
@load-list="loadList"
|
||||||
|
/>
|
||||||
<a-dropdown
|
<a-dropdown
|
||||||
v-if="hasAllPermission(['PROJECT_BUG:READ', ...(props.linkBugPermission || [])])"
|
v-if="hasAllPermission(['PROJECT_BUG:READ', ...(props.linkBugPermission || [])])"
|
||||||
position="bl"
|
position="bl"
|
||||||
@select="handleSelect"
|
@select="handleSelect"
|
||||||
|
@popup-visible-change="popupVisibleChange"
|
||||||
>
|
>
|
||||||
<a-button
|
<a-button
|
||||||
v-permission="['PROJECT_BUG:READ+ADD']"
|
v-permission="['PROJECT_BUG:READ+ADD']"
|
||||||
class="arco-btn-outline--secondary ml-[8px] !p-[4px]"
|
:class="`${isSelected ? 'selected-class' : 'operation-button'} arco-btn-outline--secondary ml-[8px] !p-[4px]`"
|
||||||
type="outline"
|
type="outline"
|
||||||
size="small"
|
size="small"
|
||||||
>
|
>
|
||||||
|
@ -34,6 +41,7 @@
|
||||||
import { hasAllPermission, hasAnyPermission } from '@/utils/permission';
|
import { hasAllPermission, hasAnyPermission } from '@/utils/permission';
|
||||||
|
|
||||||
import type { CaseBugItem } from '@/models/testPlan/testPlan';
|
import type { CaseBugItem } from '@/models/testPlan/testPlan';
|
||||||
|
import { CaseLinkEnum } from '@/enums/caseEnum';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
@ -41,6 +49,7 @@
|
||||||
resourceId: string; // 资源id: 功能用例id/接口用例id/场景用例id
|
resourceId: string; // 资源id: 功能用例id/接口用例id/场景用例id
|
||||||
bugCount: number; // 缺陷数
|
bugCount: number; // 缺陷数
|
||||||
existedDefect: number; // 已经存在缺陷数
|
existedDefect: number; // 已经存在缺陷数
|
||||||
|
caseType: CaseLinkEnum; // 用例类型
|
||||||
canEdit: boolean;
|
canEdit: boolean;
|
||||||
bugList?: CaseBugItem[];
|
bugList?: CaseBugItem[];
|
||||||
linkBugPermission?: string[];
|
linkBugPermission?: string[];
|
||||||
|
@ -63,6 +72,17 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isSelected = ref<boolean>(false);
|
||||||
|
function selectedStyle() {
|
||||||
|
isSelected.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function popupVisibleChange(val: boolean) {
|
||||||
|
if (!val) {
|
||||||
|
isSelected.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function loadList() {
|
function loadList() {
|
||||||
emit('loadList');
|
emit('loadList');
|
||||||
}
|
}
|
||||||
|
@ -70,7 +90,11 @@
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
:deep(.arco-btn-outline--secondary) {
|
:deep(.arco-btn-outline--secondary) {
|
||||||
&:hover {
|
border-color: var(--color-text-n8) !important;
|
||||||
|
}
|
||||||
|
.selected-class {
|
||||||
|
opacity: 1;
|
||||||
|
&.arco-btn-outline--secondary {
|
||||||
border-color: rgb(var(--primary-5)) !important;
|
border-color: rgb(var(--primary-5)) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -382,6 +382,13 @@ export default function useTableProps<T>(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props?.showSelectorAll,
|
||||||
|
(val) => {
|
||||||
|
propsRes.value.showSelectorAll = val;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// 事件触发组
|
// 事件触发组
|
||||||
const propsEvent = ref({
|
const propsEvent = ref({
|
||||||
// 排序触发
|
// 排序触发
|
||||||
|
|
|
@ -2,6 +2,8 @@ export enum AssociatedBugApiTypeEnum {
|
||||||
FUNCTIONAL_BUG_LIST = 'FUNCTIONAL_BUG_LIST', // 功能用例关联缺陷
|
FUNCTIONAL_BUG_LIST = 'FUNCTIONAL_BUG_LIST', // 功能用例关联缺陷
|
||||||
TEST_PLAN_BUG_LIST = 'TEST_PLAN_BUG_LIST', // 测试计划关联缺陷
|
TEST_PLAN_BUG_LIST = 'TEST_PLAN_BUG_LIST', // 测试计划关联缺陷
|
||||||
BUG_TOTAL_LIST = 'BUG_TOTAL_LIST', // 批量关联总缺陷列表
|
BUG_TOTAL_LIST = 'BUG_TOTAL_LIST', // 批量关联总缺陷列表
|
||||||
|
API_BUG_LIST = 'API_BUG_LIST', // 接口用例缺陷列表
|
||||||
|
SCENARIO_BUG_LIST = 'SCENARIO_BUG_LIST', // 场景用例缺陷列表
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {};
|
export default {};
|
||||||
|
|
|
@ -48,16 +48,21 @@
|
||||||
|
|
||||||
import MsDrawer from '@/components/pure/ms-drawer/index.vue';
|
import MsDrawer from '@/components/pure/ms-drawer/index.vue';
|
||||||
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
||||||
import type { MsTableColumn } from '@/components/pure/ms-table/type';
|
import type { MsTableColumn, MsTableProps } from '@/components/pure/ms-table/type';
|
||||||
import useTable from '@/components/pure/ms-table/useTable';
|
import useTable from '@/components/pure/ms-table/useTable';
|
||||||
import BugNamePopover from '@/views/case-management/caseManagementFeature/components/tabContent/tabBug/bugNamePopover.vue';
|
import BugNamePopover from '@/views/case-management/caseManagementFeature/components/tabContent/tabBug/bugNamePopover.vue';
|
||||||
|
|
||||||
import { getBugList } from '@/api/modules/bug-management';
|
import { getBugList } from '@/api/modules/bug-management';
|
||||||
import { getDrawerDebugPage } from '@/api/modules/case-management/featureCase';
|
import { getDrawerDebugPage } from '@/api/modules/case-management/featureCase';
|
||||||
import { getTestPlanBugPage } from '@/api/modules/test-plan/testPlan';
|
import {
|
||||||
|
getTestPlanApiBugPage,
|
||||||
|
getTestPlanBugPage,
|
||||||
|
getTestPlanScenarioBugPage,
|
||||||
|
} from '@/api/modules/test-plan/testPlan';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
import { useAppStore } from '@/store';
|
import { useAppStore } from '@/store';
|
||||||
|
|
||||||
|
import { BugListItem } from '@/models/bug-management';
|
||||||
import { AssociatedBugApiTypeEnum } from '@/enums/associateBugEnum';
|
import { AssociatedBugApiTypeEnum } from '@/enums/associateBugEnum';
|
||||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||||
|
|
||||||
|
@ -67,9 +72,11 @@
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
|
|
||||||
const getModuleTreeApiMap: Record<string, any> = {
|
const getModuleTreeApiMap: Record<string, any> = {
|
||||||
[AssociatedBugApiTypeEnum.FUNCTIONAL_BUG_LIST]: getDrawerDebugPage, // 功能用例-关联缺陷
|
[AssociatedBugApiTypeEnum.FUNCTIONAL_BUG_LIST]: getDrawerDebugPage, // 用例测试-功能用例-待关联缺陷列表
|
||||||
[AssociatedBugApiTypeEnum.TEST_PLAN_BUG_LIST]: getTestPlanBugPage, // 测试计划-关联缺陷
|
[AssociatedBugApiTypeEnum.TEST_PLAN_BUG_LIST]: getTestPlanBugPage, // 测试计划-功能用例-待关联缺陷列表
|
||||||
[AssociatedBugApiTypeEnum.BUG_TOTAL_LIST]: getBugList, // 总缺陷列表
|
[AssociatedBugApiTypeEnum.BUG_TOTAL_LIST]: getBugList, // 总缺陷列表
|
||||||
|
[AssociatedBugApiTypeEnum.API_BUG_LIST]: getTestPlanApiBugPage, // 接口用例-待关联缺陷列表
|
||||||
|
[AssociatedBugApiTypeEnum.SCENARIO_BUG_LIST]: getTestPlanScenarioBugPage, // 接口用例-待关联缺陷列表
|
||||||
};
|
};
|
||||||
|
|
||||||
const currentProjectId = computed(() => appStore.currentProjectId);
|
const currentProjectId = computed(() => appStore.currentProjectId);
|
||||||
|
@ -151,16 +158,18 @@
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const getTotalBugTable = useTable(
|
const totalCaseProps = ref<Partial<MsTableProps<BugListItem>>>({
|
||||||
getModuleTreeApiMap[AssociatedBugApiTypeEnum.BUG_TOTAL_LIST],
|
|
||||||
{
|
|
||||||
scroll: { x: '100%' },
|
scroll: { x: '100%' },
|
||||||
columns,
|
columns,
|
||||||
tableKey: TableKeyEnum.CASE_MANAGEMENT_TAB_DEFECT,
|
tableKey: TableKeyEnum.CASE_MANAGEMENT_TAB_DEFECT,
|
||||||
selectable: true,
|
selectable: true,
|
||||||
showSelectorAll: props.showSelectorAll,
|
showSelectorAll: props.showSelectorAll,
|
||||||
heightUsed: 340,
|
heightUsed: 340,
|
||||||
},
|
});
|
||||||
|
|
||||||
|
const getTotalBugTable = useTable(
|
||||||
|
getModuleTreeApiMap[AssociatedBugApiTypeEnum.BUG_TOTAL_LIST],
|
||||||
|
totalCaseProps.value,
|
||||||
(record) => {
|
(record) => {
|
||||||
return {
|
return {
|
||||||
...record,
|
...record,
|
||||||
|
@ -174,17 +183,7 @@
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const getSingleBugTable = useTable(
|
const getSingleBugTable = useTable(getModuleTreeApiMap[props.loadApi], totalCaseProps.value, (record) => {
|
||||||
getModuleTreeApiMap[props.loadApi],
|
|
||||||
{
|
|
||||||
scroll: { x: '100%' },
|
|
||||||
columns,
|
|
||||||
tableKey: TableKeyEnum.CASE_MANAGEMENT_TAB_DEFECT,
|
|
||||||
selectable: true,
|
|
||||||
showSelectorAll: props.showSelectorAll,
|
|
||||||
heightUsed: 340,
|
|
||||||
},
|
|
||||||
(record) => {
|
|
||||||
return {
|
return {
|
||||||
...record,
|
...record,
|
||||||
tags: (record.tags || []).map((item: string, i: number) => {
|
tags: (record.tags || []).map((item: string, i: number) => {
|
||||||
|
@ -194,6 +193,15 @@
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.showSelectorAll,
|
||||||
|
(val) => {
|
||||||
|
totalCaseProps.value.showSelectorAll = val;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
immediate: true,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -39,14 +39,15 @@
|
||||||
</template>
|
</template>
|
||||||
<template #bugCount="{ record }">
|
<template #bugCount="{ record }">
|
||||||
<MsBugOperation
|
<MsBugOperation
|
||||||
|
:case-type="CaseLinkEnum.API"
|
||||||
:can-edit="props.canEdit"
|
:can-edit="props.canEdit"
|
||||||
:bug-list="record.bugList"
|
:bug-list="record.bugList"
|
||||||
:resource-id="record.id"
|
:resource-id="record.id"
|
||||||
:bug-count="record.bugCount || 0"
|
:bug-count="record.bugCount || 0"
|
||||||
:existed-defect="existedDefect"
|
:existed-defect="existedDefect"
|
||||||
@load-list="loadList"
|
@load-list="refreshDetailAndList()"
|
||||||
@associated="associatedDefect(false, record.id)"
|
@associated="associateAndCreateDefect(true, false, record)"
|
||||||
@create="newDefect(record.id)"
|
@create="associateAndCreateDefect(false, false, record)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #[FilterSlotNameEnum.API_TEST_CASE_API_LAST_EXECUTE_STATUS]="{ filterContent }">
|
<template #[FilterSlotNameEnum.API_TEST_CASE_API_LAST_EXECUTE_STATUS]="{ filterContent }">
|
||||||
|
@ -109,14 +110,20 @@
|
||||||
@load-list="resetCaseList"
|
@load-list="resetCaseList"
|
||||||
/>
|
/>
|
||||||
<!-- TODO 等待联调 -->
|
<!-- TODO 等待联调 -->
|
||||||
<AddDefectDrawer v-model:visible="showCreateBugDrawer" :extra-params="{ caseId: associatedCaseId }" />
|
<AddDefectDrawer
|
||||||
|
v-model:visible="showCreateBugDrawer"
|
||||||
|
:extra-params="{ caseId: associatedCaseId, testPlanId: props.planId, testPlanCaseId }"
|
||||||
|
@success="refreshDetailAndList()"
|
||||||
|
/>
|
||||||
<!-- TODO 等待联调 -->
|
<!-- TODO 等待联调 -->
|
||||||
<LinkDefectDrawer
|
<LinkDefectDrawer
|
||||||
v-model:visible="showLinkBugDrawer"
|
v-model:visible="showLinkBugDrawer"
|
||||||
:case-id="associatedCaseId"
|
:case-id="testPlanCaseId"
|
||||||
:load-api="AssociatedBugApiTypeEnum.TEST_PLAN_BUG_LIST"
|
:load-api="AssociatedBugApiTypeEnum.API_BUG_LIST"
|
||||||
:is-batch="isBatchAssociate"
|
:is-batch="isBatchAssociate"
|
||||||
:drawer-loading="drawerLoading"
|
:drawer-loading="drawerLoading"
|
||||||
|
:show-selector-all="!isBatchAssociate"
|
||||||
|
@save="saveApiBugHandler"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -147,6 +154,8 @@
|
||||||
import BatchApiMoveModal from '@/views/test-plan/testPlan/components/batchApiMoveModal.vue';
|
import BatchApiMoveModal from '@/views/test-plan/testPlan/components/batchApiMoveModal.vue';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
associateBugToApiCase,
|
||||||
|
batchAssociatedBugToCase,
|
||||||
batchDisassociateApiCase,
|
batchDisassociateApiCase,
|
||||||
batchMoveApiCase,
|
batchMoveApiCase,
|
||||||
batchRunApiCase,
|
batchRunApiCase,
|
||||||
|
@ -165,9 +174,10 @@
|
||||||
import { characterLimit } from '@/utils';
|
import { characterLimit } from '@/utils';
|
||||||
import { hasAllPermission, hasAnyPermission } from '@/utils/permission';
|
import { hasAllPermission, hasAnyPermission } from '@/utils/permission';
|
||||||
|
|
||||||
import { DragSortParams, ModuleTreeNode } from '@/models/common';
|
import { DragSortParams, ModuleTreeNode, TableQueryParams } from '@/models/common';
|
||||||
import type { PlanDetailApiCaseItem, PlanDetailApiCaseQueryParams } from '@/models/testPlan/testPlan';
|
import type { PlanDetailApiCaseItem, PlanDetailApiCaseQueryParams } from '@/models/testPlan/testPlan';
|
||||||
import { AssociatedBugApiTypeEnum } from '@/enums/associateBugEnum';
|
import { AssociatedBugApiTypeEnum } from '@/enums/associateBugEnum';
|
||||||
|
import { CaseLinkEnum } from '@/enums/caseEnum';
|
||||||
import { ReportEnum } from '@/enums/reportEnum';
|
import { ReportEnum } from '@/enums/reportEnum';
|
||||||
import { ApiTestRouteEnum } from '@/enums/routeEnum';
|
import { ApiTestRouteEnum } from '@/enums/routeEnum';
|
||||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||||
|
@ -547,6 +557,11 @@
|
||||||
loadList();
|
loadList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function refreshDetailAndList() {
|
||||||
|
emit('refresh');
|
||||||
|
loadCaseList();
|
||||||
|
}
|
||||||
|
|
||||||
// 拖拽排序
|
// 拖拽排序
|
||||||
async function handleDragChange(params: DragSortParams) {
|
async function handleDragChange(params: DragSortParams) {
|
||||||
try {
|
try {
|
||||||
|
@ -654,24 +669,61 @@
|
||||||
|
|
||||||
const showLinkBugDrawer = ref(false);
|
const showLinkBugDrawer = ref(false);
|
||||||
const associatedCaseId = ref<string>();
|
const associatedCaseId = ref<string>();
|
||||||
|
const testPlanCaseId = ref<string>();
|
||||||
const existedDefect = inject<Ref<number>>('existedDefect', ref(0));
|
const existedDefect = inject<Ref<number>>('existedDefect', ref(0));
|
||||||
|
const showCreateBugDrawer = ref<boolean>(false);
|
||||||
const isBatchAssociate = ref(false);
|
const isBatchAssociate = ref(false);
|
||||||
// 关联缺陷
|
// 关联缺陷
|
||||||
function associatedDefect(isBatch: boolean, caseId?: string) {
|
function associateAndCreateDefect(isAssociate: boolean, isBatch: boolean, record?: PlanDetailApiCaseItem) {
|
||||||
isBatchAssociate.value = isBatch;
|
isBatchAssociate.value = isBatch;
|
||||||
associatedCaseId.value = caseId;
|
if (record) {
|
||||||
|
const { id, apiTestCaseId } = record;
|
||||||
|
associatedCaseId.value = apiTestCaseId;
|
||||||
|
testPlanCaseId.value = id;
|
||||||
|
}
|
||||||
|
if (isAssociate) {
|
||||||
showLinkBugDrawer.value = true;
|
showLinkBugDrawer.value = true;
|
||||||
|
} else {
|
||||||
|
showCreateBugDrawer.value = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const drawerLoading = ref(false);
|
const drawerLoading = ref(false);
|
||||||
|
|
||||||
const showCreateBugDrawer = ref<boolean>(false);
|
// 接口用例关联缺陷
|
||||||
|
async function saveApiBugHandler(params: TableQueryParams) {
|
||||||
|
try {
|
||||||
|
drawerLoading.value = true;
|
||||||
|
const tableParams = await getTableParams(true);
|
||||||
|
if (isBatchAssociate.value) {
|
||||||
|
await batchAssociatedBugToCase({
|
||||||
|
selectIds: tableSelected.value as string[],
|
||||||
|
selectAll: batchParams.value.selectAll,
|
||||||
|
excludeIds: batchParams.value?.excludeIds || [],
|
||||||
|
...tableParams,
|
||||||
|
bugIds: params.selectIds,
|
||||||
|
projectId: appStore.currentProjectId,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await associateBugToApiCase({
|
||||||
|
...params,
|
||||||
|
caseId: associatedCaseId.value,
|
||||||
|
testPlanId: props.planId,
|
||||||
|
testPlanCaseId: testPlanCaseId.value,
|
||||||
|
projectId: appStore.currentProjectId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 新建缺陷
|
Message.success(t('caseManagement.featureCase.associatedSuccess'));
|
||||||
function newDefect(caseId?: string) {
|
showLinkBugDrawer.value = false;
|
||||||
associatedCaseId.value = caseId;
|
resetSelectorAndCaseList();
|
||||||
showCreateBugDrawer.value = true;
|
emit('refresh');
|
||||||
|
} catch (error) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
drawerLoading.value = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 批量批量移动
|
// 批量批量移动
|
||||||
|
@ -700,10 +752,10 @@
|
||||||
batchMoveModalVisible.value = true;
|
batchMoveModalVisible.value = true;
|
||||||
break;
|
break;
|
||||||
case 'linkDefect':
|
case 'linkDefect':
|
||||||
associatedDefect(true);
|
associateAndCreateDefect(true, true);
|
||||||
break;
|
break;
|
||||||
case 'newBug':
|
case 'newBug':
|
||||||
newDefect();
|
associateAndCreateDefect(false, true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -51,14 +51,15 @@
|
||||||
</template>
|
</template>
|
||||||
<template #bugCount="{ record }">
|
<template #bugCount="{ record }">
|
||||||
<MsBugOperation
|
<MsBugOperation
|
||||||
|
:case-type="CaseLinkEnum.SCENARIO"
|
||||||
:can-edit="props.canEdit"
|
:can-edit="props.canEdit"
|
||||||
:bug-list="record.bugList"
|
:bug-list="record.bugList"
|
||||||
:resource-id="record.id"
|
:resource-id="record.id"
|
||||||
:bug-count="record.bugCount || 0"
|
:bug-count="record.bugCount || 0"
|
||||||
:existed-defect="existedDefect"
|
:existed-defect="existedDefect"
|
||||||
@load-list="loadList"
|
@load-list="refreshListAndDetail()"
|
||||||
@associated="associatedDefect(false, record.id)"
|
@associated="associateAndCreateDefect(true, false, record)"
|
||||||
@create="newDefect(record.id)"
|
@create="associateAndCreateDefect(false, false, record)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="props.canEdit" #operation="{ record }">
|
<template v-if="props.canEdit" #operation="{ record }">
|
||||||
|
@ -109,14 +110,20 @@
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- TODO 等待联调 -->
|
<!-- TODO 等待联调 -->
|
||||||
<AddDefectDrawer v-model:visible="showCreateBugDrawer" :extra-params="{ caseId: associatedCaseId }" />
|
<AddDefectDrawer
|
||||||
|
v-model:visible="showCreateBugDrawer"
|
||||||
|
:extra-params="{ caseId: associatedCaseId, testPlanId: props.planId, testPlanCaseId }"
|
||||||
|
@success="refreshListAndDetail()"
|
||||||
|
/>
|
||||||
<!-- TODO 等待联调 -->
|
<!-- TODO 等待联调 -->
|
||||||
<LinkDefectDrawer
|
<LinkDefectDrawer
|
||||||
v-model:visible="showLinkBugDrawer"
|
v-model:visible="showLinkBugDrawer"
|
||||||
:case-id="associatedCaseId"
|
:case-id="testPlanCaseId"
|
||||||
:load-api="AssociatedBugApiTypeEnum.TEST_PLAN_BUG_LIST"
|
:load-api="AssociatedBugApiTypeEnum.SCENARIO_BUG_LIST"
|
||||||
:is-batch="isBatchAssociate"
|
:is-batch="isBatchAssociate"
|
||||||
:drawer-loading="drawerLoading"
|
:drawer-loading="drawerLoading"
|
||||||
|
:show-selector-all="!isBatchAssociate"
|
||||||
|
@save="saveScenarioBugHandler"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -146,6 +153,8 @@
|
||||||
import BatchApiMoveModal from '@/views/test-plan/testPlan/components/batchApiMoveModal.vue';
|
import BatchApiMoveModal from '@/views/test-plan/testPlan/components/batchApiMoveModal.vue';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
associateBugToScenarioCase,
|
||||||
|
batchAssociatedBugToCase,
|
||||||
batchDisassociateApiScenario,
|
batchDisassociateApiScenario,
|
||||||
batchMoveApiScenario,
|
batchMoveApiScenario,
|
||||||
batchRunApiScenario,
|
batchRunApiScenario,
|
||||||
|
@ -164,9 +173,10 @@
|
||||||
import { characterLimit } from '@/utils';
|
import { characterLimit } from '@/utils';
|
||||||
import { hasAllPermission, hasAnyPermission } from '@/utils/permission';
|
import { hasAllPermission, hasAnyPermission } from '@/utils/permission';
|
||||||
|
|
||||||
import { DragSortParams, ModuleTreeNode } from '@/models/common';
|
import { DragSortParams, ModuleTreeNode, TableQueryParams } from '@/models/common';
|
||||||
import type { PlanDetailApiScenarioItem, PlanDetailApiScenarioQueryParams } from '@/models/testPlan/testPlan';
|
import type { PlanDetailApiScenarioItem, PlanDetailApiScenarioQueryParams } from '@/models/testPlan/testPlan';
|
||||||
import { AssociatedBugApiTypeEnum } from '@/enums/associateBugEnum';
|
import { AssociatedBugApiTypeEnum } from '@/enums/associateBugEnum';
|
||||||
|
import { CaseLinkEnum } from '@/enums/caseEnum';
|
||||||
import { ReportEnum } from '@/enums/reportEnum';
|
import { ReportEnum } from '@/enums/reportEnum';
|
||||||
import { ApiTestRouteEnum } from '@/enums/routeEnum';
|
import { ApiTestRouteEnum } from '@/enums/routeEnum';
|
||||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||||
|
@ -489,6 +499,11 @@
|
||||||
loadCaseList();
|
loadCaseList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function refreshListAndDetail() {
|
||||||
|
loadCaseList();
|
||||||
|
emit('refresh');
|
||||||
|
}
|
||||||
|
|
||||||
async function getModuleCount() {
|
async function getModuleCount() {
|
||||||
const tableParams = await getTableParams(false);
|
const tableParams = await getTableParams(false);
|
||||||
emit('getModuleCount', {
|
emit('getModuleCount', {
|
||||||
|
@ -645,19 +660,59 @@
|
||||||
const isBatchAssociate = ref(false);
|
const isBatchAssociate = ref(false);
|
||||||
const showLinkBugDrawer = ref<boolean>(false);
|
const showLinkBugDrawer = ref<boolean>(false);
|
||||||
const associatedCaseId = ref<string>();
|
const associatedCaseId = ref<string>();
|
||||||
|
const testPlanCaseId = ref<string>();
|
||||||
|
const showCreateBugDrawer = ref<boolean>(false);
|
||||||
|
|
||||||
const drawerLoading = ref<boolean>(false);
|
const drawerLoading = ref<boolean>(false);
|
||||||
// 关联缺陷
|
// 关联缺陷
|
||||||
function associatedDefect(isBatch: boolean, caseId?: string) {
|
function associateAndCreateDefect(isAssociate: boolean, isBatch: boolean, record?: PlanDetailApiScenarioItem) {
|
||||||
isBatchAssociate.value = isBatch;
|
isBatchAssociate.value = isBatch;
|
||||||
associatedCaseId.value = caseId;
|
if (record) {
|
||||||
|
const { id, apiScenarioId } = record;
|
||||||
|
associatedCaseId.value = apiScenarioId;
|
||||||
|
testPlanCaseId.value = id;
|
||||||
|
}
|
||||||
|
if (isAssociate) {
|
||||||
showLinkBugDrawer.value = true;
|
showLinkBugDrawer.value = true;
|
||||||
|
} else {
|
||||||
|
showCreateBugDrawer.value = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const showCreateBugDrawer = ref<boolean>(false);
|
// 场景关联缺陷
|
||||||
// 新建缺陷
|
async function saveScenarioBugHandler(params: TableQueryParams) {
|
||||||
function newDefect(caseId?: string) {
|
try {
|
||||||
associatedCaseId.value = caseId;
|
drawerLoading.value = true;
|
||||||
showCreateBugDrawer.value = true;
|
const tableParams = await getTableParams(true);
|
||||||
|
if (isBatchAssociate.value) {
|
||||||
|
await batchAssociatedBugToCase({
|
||||||
|
selectIds: tableSelected.value as string[],
|
||||||
|
selectAll: batchParams.value.selectAll,
|
||||||
|
excludeIds: batchParams.value?.excludeIds || [],
|
||||||
|
...tableParams,
|
||||||
|
bugIds: params.selectIds,
|
||||||
|
projectId: appStore.currentProjectId,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await associateBugToScenarioCase({
|
||||||
|
...params,
|
||||||
|
caseId: associatedCaseId.value,
|
||||||
|
testPlanId: props.planId,
|
||||||
|
testPlanCaseId: testPlanCaseId.value,
|
||||||
|
projectId: appStore.currentProjectId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Message.success(t('caseManagement.featureCase.associatedSuccess'));
|
||||||
|
showLinkBugDrawer.value = false;
|
||||||
|
resetSelectorAndCaseList();
|
||||||
|
emit('refresh');
|
||||||
|
} catch (error) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
drawerLoading.value = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理表格选中后批量操作
|
// 处理表格选中后批量操作
|
||||||
|
@ -682,10 +737,10 @@
|
||||||
batchMoveModalVisible.value = true;
|
batchMoveModalVisible.value = true;
|
||||||
break;
|
break;
|
||||||
case 'linkDefect':
|
case 'linkDefect':
|
||||||
associatedDefect(true);
|
associateAndCreateDefect(true, true);
|
||||||
break;
|
break;
|
||||||
case 'newBug':
|
case 'newBug':
|
||||||
newDefect();
|
associateAndCreateDefect(false, true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
<template>
|
<template>
|
||||||
<a-popover position="br" content-class="case-count-popover" @popup-visible-change="popupChange">
|
<a-popover position="br" content-class="case-count-popover" @popup-visible-change="popupChange">
|
||||||
<div class="one-line-text cursor-pointer px-0 text-[rgb(var(--primary-5))]">{{
|
<div class="one-line-text cursor-pointer px-0 text-[rgb(var(--primary-5))]">
|
||||||
props.bugItem.relateCases?.length ?? 0
|
{{ props.bugItem.relateCases?.length ?? 0 }}
|
||||||
}}</div>
|
</div>
|
||||||
<template #content>
|
<template #content>
|
||||||
<div class="w-[500px]">
|
<div class="w-[500px]">
|
||||||
<MsBaseTable v-bind="propsRes" v-on="propsEvent">
|
<MsBaseTable v-bind="propsRes" v-on="propsEvent">
|
||||||
<template #num="{ record }">
|
<template #num="{ record }">
|
||||||
<MsButton size="mini" type="text" @click="goCaseDetail(record.id)">{{ record.num }}</MsButton>
|
<MsButton size="mini" type="text" @click="goCaseDetail(record.id)">{{ record.num }}</MsButton>
|
||||||
</template>
|
</template>
|
||||||
|
<template #type="{ record }">
|
||||||
|
<span>{{ getCaseType(record.type) || '-' }}</span>
|
||||||
|
</template>
|
||||||
</MsBaseTable>
|
</MsBaseTable>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -21,9 +24,11 @@
|
||||||
import type { MsTableColumn } from '@/components/pure/ms-table/type';
|
import type { MsTableColumn } from '@/components/pure/ms-table/type';
|
||||||
import useTable from '@/components/pure/ms-table/useTable';
|
import useTable from '@/components/pure/ms-table/useTable';
|
||||||
|
|
||||||
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
import useOpenNewPage from '@/hooks/useOpenNewPage';
|
import useOpenNewPage from '@/hooks/useOpenNewPage';
|
||||||
|
|
||||||
import type { PlanDetailBugItem } from '@/models/testPlan/testPlan';
|
import type { PlanDetailBugItem } from '@/models/testPlan/testPlan';
|
||||||
|
import { CaseLinkEnum } from '@/enums/caseEnum';
|
||||||
import { CaseManagementRouteEnum } from '@/enums/routeEnum';
|
import { CaseManagementRouteEnum } from '@/enums/routeEnum';
|
||||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||||
|
|
||||||
|
@ -32,6 +37,7 @@
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { openNewPage } = useOpenNewPage();
|
const { openNewPage } = useOpenNewPage();
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
const columns: MsTableColumn = [
|
const columns: MsTableColumn = [
|
||||||
{
|
{
|
||||||
|
@ -50,11 +56,25 @@
|
||||||
{
|
{
|
||||||
title: 'testPlan.caseType',
|
title: 'testPlan.caseType',
|
||||||
dataIndex: 'type',
|
dataIndex: 'type',
|
||||||
|
slotName: 'type',
|
||||||
showTooltip: true,
|
showTooltip: true,
|
||||||
width: 200,
|
width: 200,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
function getCaseType(type: CaseLinkEnum) {
|
||||||
|
switch (type) {
|
||||||
|
case CaseLinkEnum.API:
|
||||||
|
return t('testPlan.testPlanIndex.apiCase');
|
||||||
|
case CaseLinkEnum.FUNCTIONAL:
|
||||||
|
return t('testPlan.testPlanIndex.functionalUseCase');
|
||||||
|
case CaseLinkEnum.SCENARIO:
|
||||||
|
return t('testPlan.testPlanIndex.apiScenarioCase');
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const { propsRes, propsEvent } = useTable(undefined, {
|
const { propsRes, propsEvent } = useTable(undefined, {
|
||||||
columns,
|
columns,
|
||||||
size: 'mini',
|
size: 'mini',
|
||||||
|
|
|
@ -80,14 +80,15 @@
|
||||||
</template>
|
</template>
|
||||||
<template #bugCount="{ record }">
|
<template #bugCount="{ record }">
|
||||||
<MsBugOperation
|
<MsBugOperation
|
||||||
|
:case-type="CaseLinkEnum.FUNCTIONAL"
|
||||||
:can-edit="props.canEdit"
|
:can-edit="props.canEdit"
|
||||||
:bug-list="record.bugList"
|
:bug-list="record.bugList"
|
||||||
:resource-id="record.id"
|
:resource-id="record.id"
|
||||||
:bug-count="record.bugCount || 0"
|
:bug-count="record.bugCount || 0"
|
||||||
:existed-defect="existedDefect"
|
:existed-defect="existedDefect"
|
||||||
@load-list="loadList"
|
@load-list="refreshList()"
|
||||||
@associated="associatedDefect(false, record.id)"
|
@associated="associateAndCreateDefect(true, false, record)"
|
||||||
@create="newDefect(record.id)"
|
@create="associateAndCreateDefect(false, false, record)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="props.canEdit" #operation="{ record }">
|
<template v-if="props.canEdit" #operation="{ record }">
|
||||||
|
@ -177,17 +178,18 @@
|
||||||
<!-- TODO 等待联调 -->
|
<!-- TODO 等待联调 -->
|
||||||
<AddDefectDrawer
|
<AddDefectDrawer
|
||||||
v-model:visible="showCreateBugDrawer"
|
v-model:visible="showCreateBugDrawer"
|
||||||
:extra-params="{ caseId: associatedCaseId }"
|
:extra-params="{ caseId: associatedCaseId, testPlanId: props.planId, testPlanCaseId }"
|
||||||
@success="refreshList"
|
@success="refreshList()"
|
||||||
/>
|
/>
|
||||||
<!-- TODO 等待联调 -->
|
<!-- TODO 等待联调 -->
|
||||||
<LinkDefectDrawer
|
<LinkDefectDrawer
|
||||||
v-model:visible="showLinkBugDrawer"
|
v-model:visible="showLinkBugDrawer"
|
||||||
:case-id="associatedCaseId"
|
:case-id="testPlanCaseId"
|
||||||
:drawer-loading="drawerLoading"
|
:drawer-loading="drawerLoading"
|
||||||
:load-api="AssociatedBugApiTypeEnum.TEST_PLAN_BUG_LIST"
|
:load-api="AssociatedBugApiTypeEnum.TEST_PLAN_BUG_LIST"
|
||||||
|
:show-selector-all="!isBatchAssociate"
|
||||||
:is-batch="isBatchAssociate"
|
:is-batch="isBatchAssociate"
|
||||||
@save="saveHandler"
|
@save="saveFunctionBugHandler"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -222,6 +224,8 @@
|
||||||
import ExecuteForm from '@/views/test-plan/testPlan/detail/featureCase/components/executeForm.vue';
|
import ExecuteForm from '@/views/test-plan/testPlan/detail/featureCase/components/executeForm.vue';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
associateBugToPlan,
|
||||||
|
batchAssociatedBugToCase,
|
||||||
batchDisassociateCase,
|
batchDisassociateCase,
|
||||||
batchExecuteCase,
|
batchExecuteCase,
|
||||||
batchMoveFeatureCase,
|
batchMoveFeatureCase,
|
||||||
|
@ -243,7 +247,7 @@
|
||||||
import { DragSortParams, ModuleTreeNode, TableQueryParams } from '@/models/common';
|
import { DragSortParams, ModuleTreeNode, TableQueryParams } from '@/models/common';
|
||||||
import type { ExecuteFeatureCaseFormParams, PlanDetailFeatureCaseItem } from '@/models/testPlan/testPlan';
|
import type { ExecuteFeatureCaseFormParams, PlanDetailFeatureCaseItem } from '@/models/testPlan/testPlan';
|
||||||
import { AssociatedBugApiTypeEnum } from '@/enums/associateBugEnum';
|
import { AssociatedBugApiTypeEnum } from '@/enums/associateBugEnum';
|
||||||
import { LastExecuteResults } from '@/enums/caseEnum';
|
import { CaseLinkEnum, LastExecuteResults } from '@/enums/caseEnum';
|
||||||
import { TestPlanRouteEnum } from '@/enums/routeEnum';
|
import { TestPlanRouteEnum } from '@/enums/routeEnum';
|
||||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||||
import { FilterRemoteMethodsEnum, FilterSlotNameEnum } from '@/enums/tableFilterEnum';
|
import { FilterRemoteMethodsEnum, FilterSlotNameEnum } from '@/enums/tableFilterEnum';
|
||||||
|
@ -801,17 +805,38 @@
|
||||||
|
|
||||||
const showLinkBugDrawer = ref<boolean>(false);
|
const showLinkBugDrawer = ref<boolean>(false);
|
||||||
const associatedCaseId = ref<string>();
|
const associatedCaseId = ref<string>();
|
||||||
|
const testPlanCaseId = ref<string>();
|
||||||
const drawerLoading = ref<boolean>(false);
|
const drawerLoading = ref<boolean>(false);
|
||||||
|
const isBatchAssociate = ref(false);
|
||||||
|
|
||||||
// TODO 等待联调
|
// 功能用例关联缺陷
|
||||||
function saveHandler(params: TableQueryParams) {
|
async function saveFunctionBugHandler(params: TableQueryParams) {
|
||||||
try {
|
try {
|
||||||
drawerLoading.value = true;
|
drawerLoading.value = true;
|
||||||
|
const tableParams = await getTableParams(true);
|
||||||
|
if (isBatchAssociate.value) {
|
||||||
|
await batchAssociatedBugToCase({
|
||||||
|
selectIds: tableSelected.value as string[],
|
||||||
|
selectAll: batchParams.value.selectAll,
|
||||||
|
excludeIds: batchParams.value?.excludeIds || [],
|
||||||
|
...tableParams,
|
||||||
|
projectId: appStore.currentProjectId,
|
||||||
|
bugIds: params.selectIds,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await associateBugToPlan({
|
||||||
|
...params,
|
||||||
|
projectId: appStore.currentProjectId,
|
||||||
|
caseId: associatedCaseId.value,
|
||||||
|
testPlanId: props.planId,
|
||||||
|
testPlanCaseId: testPlanCaseId.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Message.success(t('caseManagement.featureCase.associatedSuccess'));
|
Message.success(t('caseManagement.featureCase.associatedSuccess'));
|
||||||
resetCaseList();
|
|
||||||
initModules();
|
|
||||||
emit('refresh');
|
|
||||||
showLinkBugDrawer.value = false;
|
showLinkBugDrawer.value = false;
|
||||||
|
resetCaseList();
|
||||||
|
emit('refresh');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
@ -822,25 +847,25 @@
|
||||||
|
|
||||||
function refreshList() {
|
function refreshList() {
|
||||||
resetCaseList();
|
resetCaseList();
|
||||||
initModules();
|
|
||||||
emit('refresh');
|
emit('refresh');
|
||||||
}
|
}
|
||||||
|
|
||||||
const isBatchAssociate = ref(false);
|
|
||||||
|
|
||||||
// 关联缺陷
|
|
||||||
function associatedDefect(isBatch: boolean, caseId?: string) {
|
|
||||||
isBatchAssociate.value = isBatch;
|
|
||||||
associatedCaseId.value = caseId;
|
|
||||||
showLinkBugDrawer.value = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const showCreateBugDrawer = ref<boolean>(false);
|
const showCreateBugDrawer = ref<boolean>(false);
|
||||||
// 新建缺陷
|
|
||||||
function newDefect(caseId?: string) {
|
// 关联/关联缺陷
|
||||||
|
function associateAndCreateDefect(isAssociate: boolean, isBatch: boolean, record?: PlanDetailFeatureCaseItem) {
|
||||||
|
isBatchAssociate.value = isBatch;
|
||||||
|
if (record) {
|
||||||
|
const { id, caseId } = record;
|
||||||
associatedCaseId.value = caseId;
|
associatedCaseId.value = caseId;
|
||||||
|
testPlanCaseId.value = id;
|
||||||
|
}
|
||||||
|
if (isAssociate) {
|
||||||
|
showLinkBugDrawer.value = true;
|
||||||
|
} else {
|
||||||
showCreateBugDrawer.value = true;
|
showCreateBugDrawer.value = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 批量修改执行人 和 批量移动
|
// 批量修改执行人 和 批量移动
|
||||||
const batchUpdateExecutorModalVisible = ref(false);
|
const batchUpdateExecutorModalVisible = ref(false);
|
||||||
|
@ -861,10 +886,10 @@
|
||||||
batchMoveModalVisible.value = true;
|
batchMoveModalVisible.value = true;
|
||||||
break;
|
break;
|
||||||
case 'linkDefect':
|
case 'linkDefect':
|
||||||
associatedDefect(true);
|
associateAndCreateDefect(true, true);
|
||||||
break;
|
break;
|
||||||
case 'newBug':
|
case 'newBug':
|
||||||
newDefect();
|
associateAndCreateDefect(false, true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -597,4 +597,14 @@
|
||||||
:deep(.arco-tabs-content) {
|
:deep(.arco-tabs-content) {
|
||||||
@apply hidden;
|
@apply hidden;
|
||||||
}
|
}
|
||||||
|
:deep(.arco-table-tr) {
|
||||||
|
.operation-button {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
.operation-button {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
Loading…
Reference in New Issue