feat(测试计划): 测试计划报告优化测试集接口联调
This commit is contained in:
parent
2217d40ce1
commit
4436083f8c
|
@ -11,7 +11,7 @@ import {
|
|||
UpdateReportDetailParams,
|
||||
} from '@/models/testPlan/report';
|
||||
import type { ExecuteHistoryItem } from '@/models/testPlan/testPlan';
|
||||
import { manualReportGenParams, PlanReportDetail } from '@/models/testPlan/testPlanReport';
|
||||
import { manualReportGenParams, PlanReportDetail, testPlanSetItem } from '@/models/testPlan/testPlanReport';
|
||||
|
||||
// 报告列表
|
||||
export function reportList(data: TableQueryParams) {
|
||||
|
@ -187,3 +187,26 @@ export function logTestPlanReportBatchExport(data: BatchApiParams) {
|
|||
export function testPlanBatchReportExportGetIds(data: BatchApiParams) {
|
||||
return MSR.post<string[]>({ url: reportUrl.TestPlanBatchReportExportGetIdsUrl, data });
|
||||
}
|
||||
// 报告-详情-用例明细测试点
|
||||
export function getCollectFunctionalPage(data: TableQueryParams) {
|
||||
if (data.shareId) {
|
||||
return MSR.post<CommonList<testPlanSetItem>>({ url: `${reportUrl.getShareCollectFunctionalUrl}`, data });
|
||||
}
|
||||
return MSR.post<CommonList<testPlanSetItem>>({ url: `${reportUrl.getCollectFunctionalUrl}`, data });
|
||||
}
|
||||
// 报告-详情-接口明细测试点
|
||||
export function getCollectApiPage(data: TableQueryParams) {
|
||||
if (data.shareId) {
|
||||
return MSR.post<CommonList<testPlanSetItem>>({ url: `${reportUrl.getShareCollectionApiUrl}`, data });
|
||||
}
|
||||
return MSR.post<CommonList<testPlanSetItem>>({ url: `${reportUrl.getCollectApiUrl}`, data });
|
||||
}
|
||||
// 报告-详情-场景明细测试点
|
||||
export function getCollectScenarioPage(data: TableQueryParams) {
|
||||
if (data.shareId) {
|
||||
return MSR.post<CommonList<testPlanSetItem>>({ url: `${reportUrl.getShareCollectScenarioUrl}`, data });
|
||||
}
|
||||
return MSR.post<CommonList<testPlanSetItem>>({ url: `${reportUrl.getCollectScenarioUrl}`, data });
|
||||
}
|
||||
|
||||
export default {};
|
||||
|
|
|
@ -74,3 +74,15 @@ export const TestPlanReportExportUrl = '/test-plan/report/export';
|
|||
export const TestPlanBatchReportExportUrl = '/test-plan/report/batch-export';
|
||||
// 测试计划-报告-批量导出获取报告 ID 集合
|
||||
export const TestPlanBatchReportExportGetIdsUrl = '/test-plan/report/batch-param';
|
||||
// 测试计划-报告-详情-报告-用例明细-测试点
|
||||
export const getCollectFunctionalUrl = '/test-plan/report/detail/functional/collection/page';
|
||||
// 测试计划-报告-详情-报告-接口明细-测试点
|
||||
export const getCollectApiUrl = '/test-plan/report/detail/api/collection/page';
|
||||
// 测试计划-报告-详情-报告-场景明细-测试点
|
||||
export const getCollectScenarioUrl = '/test-plan/report/detail/scenario/collection/page';
|
||||
// 测试计划-报告-详情-分享-报告-用例明细-测试点
|
||||
export const getShareCollectFunctionalUrl = '/test-plan/report/share/detail/functional/collection/page';
|
||||
// 测试计划-报告-详情-分享-报告-接口明细-测试点
|
||||
export const getShareCollectionApiUrl = '/test-plan/report/share/detail/api/collection/page';
|
||||
// 测试计划-报告-详情-分享-报告-场景明细-测试点
|
||||
export const getShareCollectScenarioUrl = '/test-plan/report/share/detail/scenario/collection/page';
|
||||
|
|
|
@ -98,3 +98,11 @@ export type SelectedReportCardTypes =
|
|||
| ReportCardTypeEnum.FUNCTIONAL_DETAIL
|
||||
| ReportCardTypeEnum.API_CASE_DETAIL
|
||||
| ReportCardTypeEnum.SCENARIO_CASE_DETAIL;
|
||||
|
||||
// 测试集列表
|
||||
export interface testPlanSetItem {
|
||||
id: string;
|
||||
name: string; // 测试集名称
|
||||
count: number;
|
||||
planName: string; // 计划名称
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
import { defineStore } from 'pinia';
|
||||
|
||||
import { ReportCardTypeEnum } from '@/enums/testPlanReportEnum';
|
||||
|
||||
export interface testSetConfigType {
|
||||
TEST_PLAN: Record<keyof typeof ReportCardTypeEnum, boolean>;
|
||||
GROUP: Record<keyof typeof ReportCardTypeEnum, boolean>;
|
||||
}
|
||||
|
||||
const useTestPlanReportStore = defineStore('testPlanReport', {
|
||||
persist: true,
|
||||
state: (): {
|
||||
testSetConfig: Record<string, Record<string, boolean>>;
|
||||
} => ({
|
||||
testSetConfig: {
|
||||
TEST_PLAN: {
|
||||
[ReportCardTypeEnum.FUNCTIONAL_DETAIL]: false,
|
||||
[ReportCardTypeEnum.API_CASE_DETAIL]: false,
|
||||
[ReportCardTypeEnum.SCENARIO_CASE_DETAIL]: false,
|
||||
},
|
||||
GROUP: {
|
||||
[ReportCardTypeEnum.FUNCTIONAL_DETAIL]: false,
|
||||
[ReportCardTypeEnum.API_CASE_DETAIL]: false,
|
||||
[ReportCardTypeEnum.SCENARIO_CASE_DETAIL]: false,
|
||||
},
|
||||
},
|
||||
}),
|
||||
actions: {
|
||||
setTestStatus(isGroup: boolean, enable: boolean, cardType: ReportCardTypeEnum) {
|
||||
const testSetKey: 'TEST_PLAN' | 'GROUP' = isGroup ? 'GROUP' : 'TEST_PLAN';
|
||||
this.testSetConfig[testSetKey][cardType as keyof typeof ReportCardTypeEnum] = enable;
|
||||
},
|
||||
getTestStatus(isGroup: boolean, cardType: ReportCardTypeEnum) {
|
||||
const testSetKey: 'TEST_PLAN' | 'GROUP' = isGroup ? 'GROUP' : 'TEST_PLAN';
|
||||
return this.testSetConfig[testSetKey][cardType as keyof typeof ReportCardTypeEnum];
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export default useTestPlanReportStore;
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div :class="`${props.enabledTestSet ? 'test-set-wrapper test-set-cell' : ''}`">
|
||||
<div :class="`${props.enabledTestSet ? 'test-set-wrapper' : ''}`">
|
||||
<MsBaseTable v-bind="currentCaseTable.propsRes.value" v-on="currentCaseTable.propsEvent.value">
|
||||
<template #num="{ record }">
|
||||
<MsButton type="text" @click="toDetail(record)">{{ record.num }}</MsButton>
|
||||
|
@ -38,7 +38,7 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" async>
|
||||
<script setup lang="ts">
|
||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
||||
import type { MsTableColumn } from '@/components/pure/ms-table/type';
|
||||
|
@ -76,15 +76,16 @@
|
|||
const props = defineProps<{
|
||||
reportId: string;
|
||||
enabledTestSet: boolean;
|
||||
testSetId?: string; // 测试集id
|
||||
shareId?: string;
|
||||
activeType: ReportCardTypeEnum;
|
||||
isPreview?: boolean;
|
||||
isGroup?: boolean;
|
||||
}>();
|
||||
|
||||
const innerKeyword = defineModel<string>('keyword', {
|
||||
required: true,
|
||||
});
|
||||
const isGroup = inject<Ref<boolean>>('isPlanGroup', ref(false));
|
||||
|
||||
const staticColumns: MsTableColumn = [
|
||||
{
|
||||
|
@ -137,7 +138,8 @@
|
|||
showTooltip: true,
|
||||
width: 200,
|
||||
showInTable: true,
|
||||
showDrag: true,
|
||||
showDrag: false,
|
||||
columnSelectorDisabled: true,
|
||||
},
|
||||
];
|
||||
const lastStaticColumns: MsTableColumn = [
|
||||
|
@ -174,7 +176,7 @@
|
|||
];
|
||||
|
||||
const columns = computed(() => {
|
||||
if (props.isGroup) {
|
||||
if (isGroup.value) {
|
||||
return [...staticColumns, ...testPlanNameColumns, ...lastStaticColumns];
|
||||
}
|
||||
return [...staticColumns, ...lastStaticColumns];
|
||||
|
@ -192,7 +194,7 @@
|
|||
};
|
||||
|
||||
const tableKey = computed(() => {
|
||||
if (props.isGroup) {
|
||||
if (isGroup.value) {
|
||||
return keyMap.GROUP[props.activeType];
|
||||
}
|
||||
return keyMap.TEST_PLAN[props.activeType];
|
||||
|
@ -229,6 +231,7 @@
|
|||
reportId: props.reportId,
|
||||
shareId: props.shareId ?? undefined,
|
||||
keyword: innerKeyword.value,
|
||||
collectionId: props.testSetId,
|
||||
});
|
||||
currentCaseTable.value.loadList();
|
||||
}
|
||||
|
@ -259,13 +262,27 @@
|
|||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (props.reportId) {
|
||||
currentCaseTable.value.resetPagination();
|
||||
loadCaseList();
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
[() => props.reportId, () => props.isPreview],
|
||||
() => {
|
||||
if (props.reportId && props.isPreview) {
|
||||
() => props.reportId,
|
||||
(val) => {
|
||||
if (val) {
|
||||
currentCaseTable.value.resetPagination();
|
||||
loadCaseList();
|
||||
} else {
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.isPreview,
|
||||
(val) => {
|
||||
if (!val) {
|
||||
currentCaseTable.value.propsRes.value.data = detailTableExample[props.activeType];
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,4 +1,18 @@
|
|||
<template>
|
||||
<div class="mb-[8px] flex items-center justify-between">
|
||||
<div class="font-medium"> {{ props.label }} </div>
|
||||
<div v-if="props.isPreview" class="flex items-center">
|
||||
<a-input-search
|
||||
v-model:model-value="keyword"
|
||||
:placeholder="t('common.searchByIdName')"
|
||||
allow-clear
|
||||
class="w-[240px]"
|
||||
@search="loadCaseList"
|
||||
@press-enter="loadCaseList"
|
||||
@clear="loadCaseList"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<MsBaseTable v-bind="propsRes" v-on="propsEvent">
|
||||
<template #num="{ record }">
|
||||
<MsButton :disabled="!props.isPreview" type="text" @click="toDetail(record)">{{ record.num }}</MsButton>
|
||||
|
@ -16,6 +30,7 @@
|
|||
import useTable from '@/components/pure/ms-table/useTable';
|
||||
|
||||
import { getReportBugList, getReportShareBugList } from '@/api/modules/test-plan/report';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useOpenNewPage from '@/hooks/useOpenNewPage';
|
||||
|
||||
import { ReportBugItem } from '@/models/testPlan/report';
|
||||
|
@ -24,14 +39,19 @@
|
|||
|
||||
import { detailTableExample } from '@/views/test-plan/report/detail/component/reportConfig';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const { openNewPage } = useOpenNewPage();
|
||||
|
||||
const props = defineProps<{
|
||||
reportId: string;
|
||||
shareId?: string;
|
||||
isPreview?: boolean;
|
||||
label: string;
|
||||
}>();
|
||||
|
||||
const keyword = ref<string>('');
|
||||
|
||||
const sortableConfig = computed<TableSortable | undefined>(() => {
|
||||
return props.isPreview
|
||||
? {
|
||||
|
@ -86,8 +106,8 @@
|
|||
showSelectorAll: false,
|
||||
});
|
||||
|
||||
async function loadCaseList() {
|
||||
setLoadListParams({ reportId: props.reportId, shareId: props.shareId ?? undefined });
|
||||
function loadCaseList() {
|
||||
setLoadListParams({ reportId: props.reportId, shareId: props.shareId ?? undefined, keyword: keyword.value });
|
||||
loadList();
|
||||
}
|
||||
|
||||
|
@ -98,12 +118,25 @@
|
|||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (props.reportId) {
|
||||
loadCaseList();
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
[() => props.reportId, () => props.isPreview],
|
||||
() => {
|
||||
if (props.reportId && props.isPreview) {
|
||||
() => props.reportId,
|
||||
(val) => {
|
||||
if (val) {
|
||||
loadCaseList();
|
||||
} else {
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.isPreview,
|
||||
(val) => {
|
||||
if (!val) {
|
||||
propsRes.value.data = detailTableExample[ReportCardTypeEnum.BUG_DETAIL];
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div :class="`${props.enabledTestSet ? 'test-set-wrapper test-set-cell' : ''}`">
|
||||
<div :class="`${props.enabledTestSet ? 'test-set-wrapper' : ''}`">
|
||||
<MsBaseTable v-bind="propsRes" v-on="propsEvent">
|
||||
<template #num="{ record }">
|
||||
<MsButton :disabled="!props.isPreview" type="text" @click="toDetail(record)">{{ record.num }}</MsButton>
|
||||
|
@ -17,7 +17,6 @@
|
|||
</MsButton>
|
||||
</template>
|
||||
<template #expand-icon="{ record, expanded }">
|
||||
<!-- TODO 待联调 -->
|
||||
<div
|
||||
class="flex items-end gap-[2px] text-[var(--color-text-4)]"
|
||||
:class="[
|
||||
|
@ -84,9 +83,9 @@
|
|||
const props = defineProps<{
|
||||
enabledTestSet: boolean; // 开启测试集
|
||||
reportId: string;
|
||||
testSetId?: string; // 测试集id
|
||||
shareId?: string;
|
||||
isPreview?: boolean;
|
||||
isGroup?: boolean;
|
||||
}>();
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@ -102,6 +101,7 @@
|
|||
}
|
||||
: undefined;
|
||||
});
|
||||
const isGroup = inject<Ref<boolean>>('isPlanGroup', ref(false));
|
||||
|
||||
const staticColumns: MsTableColumn = [
|
||||
{
|
||||
|
@ -186,13 +186,14 @@
|
|||
dataIndex: 'planName',
|
||||
showTooltip: true,
|
||||
showInTable: true,
|
||||
showDrag: true,
|
||||
showDrag: false,
|
||||
columnSelectorDisabled: true,
|
||||
width: 200,
|
||||
},
|
||||
];
|
||||
|
||||
const columns = computed(() => {
|
||||
if (props.isGroup) {
|
||||
if (isGroup.value) {
|
||||
return [...staticColumns, ...testPlanNameColumns, ...lastStaticColumns];
|
||||
}
|
||||
return [...staticColumns, ...lastStaticColumns];
|
||||
|
@ -203,7 +204,7 @@
|
|||
};
|
||||
|
||||
const tableKey = computed(() =>
|
||||
props.isGroup
|
||||
isGroup.value
|
||||
? TableKeyEnum.TEST_PLAN_REPORT_FUNCTIONAL_TABLE_GROUP
|
||||
: TableKeyEnum.TEST_PLAN_REPORT_FUNCTIONAL_TABLE
|
||||
);
|
||||
|
@ -219,7 +220,12 @@
|
|||
});
|
||||
|
||||
async function loadCaseList() {
|
||||
setLoadListParams({ reportId: props.reportId, keyword: innerKeyword.value, shareId: props.shareId ?? undefined });
|
||||
setLoadListParams({
|
||||
reportId: props.reportId,
|
||||
keyword: innerKeyword.value,
|
||||
shareId: props.shareId ?? undefined,
|
||||
collectionId: props.testSetId,
|
||||
});
|
||||
loadList();
|
||||
}
|
||||
// 跳转用例详情
|
||||
|
@ -231,19 +237,20 @@
|
|||
}
|
||||
|
||||
watch(
|
||||
[() => props.reportId, () => props.isPreview],
|
||||
() => {
|
||||
if (props.reportId && props.isPreview) {
|
||||
() => props.reportId,
|
||||
(val) => {
|
||||
if (val) {
|
||||
loadCaseList();
|
||||
} else {
|
||||
propsRes.value.data = detailTableExample[ReportCardTypeEnum.FUNCTIONAL_DETAIL];
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
if (props.isPreview && props.reportId) {
|
||||
loadCaseList();
|
||||
}
|
||||
});
|
||||
|
||||
const showDetailVisible = ref<boolean>(false);
|
||||
|
||||
const executeReportId = ref<string>('');
|
||||
|
@ -272,6 +279,18 @@
|
|||
getExecuteStep();
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.isPreview,
|
||||
(val) => {
|
||||
if (!val) {
|
||||
propsRes.value.data = detailTableExample[ReportCardTypeEnum.FUNCTIONAL_DETAIL];
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
|
||||
defineExpose({
|
||||
loadCaseList,
|
||||
});
|
||||
|
|
|
@ -1,4 +1,38 @@
|
|||
<template>
|
||||
<div class="mb-[8px] flex items-center justify-between">
|
||||
<div class="font-medium"> {{ props.label }} </div>
|
||||
<div v-if="props.isPreview" class="flex items-center">
|
||||
<a-input-search
|
||||
v-model:model-value="keyword"
|
||||
:placeholder="t('common.searchByIdName')"
|
||||
allow-clear
|
||||
class="mr-[8px] w-[240px]"
|
||||
@search="loadReportDetailList"
|
||||
@press-enter="loadReportDetailList"
|
||||
@clear="loadReportDetailList"
|
||||
/>
|
||||
<a-radio-group
|
||||
v-if="props.isPreview"
|
||||
v-model:model-value="currentMode"
|
||||
type="button"
|
||||
size="medium"
|
||||
@change="handleModeChange"
|
||||
>
|
||||
<a-radio value="drawer">
|
||||
<div class="mode-button">
|
||||
<MsIcon :class="{ 'active-color': currentMode === 'drawer' }" type="icon-icon_drawer" />
|
||||
<span class="mode-button-title">{{ t('msTable.columnSetting.drawer') }}</span>
|
||||
</div>
|
||||
</a-radio>
|
||||
<a-radio value="new_window">
|
||||
<div class="mode-button">
|
||||
<MsIcon :class="{ 'active-color': currentMode === 'new_window' }" type="icon-icon_into-item_outlined" />
|
||||
<span class="mode-button-title">{{ t('msTable.columnSetting.newWindow') }}</span>
|
||||
</div>
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
<MsBaseTable v-bind="propsRes" no-disable filter-icon-align-left v-on="propsEvent">
|
||||
<template #passRateTitle="{ columnConfig }">
|
||||
<div class="flex items-center text-[var(--color-text-3)]">
|
||||
|
@ -66,11 +100,10 @@
|
|||
reportId: string;
|
||||
shareId?: string;
|
||||
isPreview?: boolean;
|
||||
label?: string;
|
||||
}>();
|
||||
|
||||
const innerCurrentMode = defineModel<string>('currentMode', {
|
||||
default: 'drawer',
|
||||
});
|
||||
const keyword = ref<string>('');
|
||||
|
||||
const statusResultOptions = computed(() => {
|
||||
return Object.keys(PlanReportStatus).map((key) => {
|
||||
|
@ -149,16 +182,14 @@
|
|||
);
|
||||
|
||||
function loadReportDetailList() {
|
||||
setLoadListParams({ reportId: props.reportId, shareId: props.shareId ?? undefined });
|
||||
setLoadListParams({ reportId: props.reportId, shareId: props.shareId ?? undefined, keyword: keyword.value });
|
||||
loadList();
|
||||
}
|
||||
|
||||
watch(
|
||||
[() => props.reportId, () => props.isPreview],
|
||||
() => {
|
||||
if (props.reportId && props.isPreview) {
|
||||
loadReportDetailList();
|
||||
} else {
|
||||
() => props.isPreview,
|
||||
(val) => {
|
||||
if (!val) {
|
||||
propsRes.value.data = detailTableExample[ReportCardTypeEnum.SUB_PLAN_DETAIL];
|
||||
}
|
||||
},
|
||||
|
@ -167,13 +198,29 @@
|
|||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
if (props.reportId) {
|
||||
loadReportDetailList();
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.reportId,
|
||||
(val) => {
|
||||
if (val) {
|
||||
loadReportDetailList();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const reportVisible = ref(false);
|
||||
|
||||
const independentReportId = ref<string>('');
|
||||
const currentMode = ref<string>('drawer');
|
||||
|
||||
function openReport(record: PlanReportDetail) {
|
||||
independentReportId.value = record.id;
|
||||
if (innerCurrentMode.value === 'drawer') {
|
||||
if (currentMode.value === 'drawer') {
|
||||
reportVisible.value = true;
|
||||
} else {
|
||||
openNewPage(RouteEnum.TEST_PLAN_REPORT_DETAIL, {
|
||||
|
@ -181,6 +228,10 @@
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
function handleModeChange(value: string | number | boolean, ev: Event) {
|
||||
currentMode.value = value as string;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
|
@ -4,21 +4,25 @@
|
|||
v-bind="propsRes"
|
||||
:expanded-keys="expandedKeys"
|
||||
:expandable="expandable"
|
||||
row-class="test-set-expand-tr"
|
||||
v-on="propsEvent"
|
||||
@expand="(record) => handleExpand(record.id as string)"
|
||||
>
|
||||
<template #expand-icon="{ record, expanded }">
|
||||
<div
|
||||
class="flex items-end gap-[2px] text-[var(--color-text-4)]"
|
||||
:class="[
|
||||
expanded ? '!text-[rgb(var(--primary-5))]' : '',
|
||||
record.testSetCount === 0 ? 'cursor-not-allowed' : '',
|
||||
]"
|
||||
:class="[expanded ? '!text-[rgb(var(--primary-5))]' : '', record.count === 0 ? 'cursor-not-allowed' : '']"
|
||||
>
|
||||
<MsIcon type="icon-icon_split_turn-down_arrow" />
|
||||
<div v-if="record.testSetCount" class="break-keep">{{ record.testSetCount }}</div>
|
||||
<div v-if="record.count" class="break-keep">{{ record.count }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #other>
|
||||
<span></span>
|
||||
</template>
|
||||
<template #empty>
|
||||
<span></span>
|
||||
</template>
|
||||
</MsBaseTable>
|
||||
</template>
|
||||
|
||||
|
@ -29,12 +33,11 @@
|
|||
import ApiAndScenarioTable from '@/views/test-plan/report/detail/component/system-card/apiAndScenarioTable.vue';
|
||||
import FeatureCaseTable from '@/views/test-plan/report/detail/component/system-card/featureCaseTable.vue';
|
||||
|
||||
import { getReportFeatureCaseList, getReportShareFeatureCaseList } from '@/api/modules/test-plan/report';
|
||||
import { getCollectApiPage, getCollectFunctionalPage, getCollectScenarioPage } from '@/api/modules/test-plan/report';
|
||||
|
||||
import type { SelectedReportCardTypes } from '@/models/testPlan/testPlanReport';
|
||||
import { ReportCardTypeEnum } from '@/enums/testPlanReportEnum';
|
||||
|
||||
import { detailTableExample } from '@/views/test-plan/report/detail/component/reportConfig';
|
||||
|
||||
const props = defineProps<{
|
||||
enabledTestSet: boolean;
|
||||
activeType: ReportCardTypeEnum; // 卡片类型
|
||||
|
@ -42,24 +45,25 @@
|
|||
reportId: string;
|
||||
shareId?: string;
|
||||
isPreview?: boolean;
|
||||
isGroup?: boolean;
|
||||
}>();
|
||||
|
||||
const expandedKeys = ref<string[]>([]);
|
||||
const isGroup = inject<Ref<boolean>>('isPlanGroup', ref(false));
|
||||
|
||||
const expandable = reactive({
|
||||
title: '',
|
||||
width: 30,
|
||||
expandedRowRender: (record: Record<string, any>) => {
|
||||
if (record.testSetCount) {
|
||||
if (record.count) {
|
||||
if (props.activeType === ReportCardTypeEnum.FUNCTIONAL_DETAIL) {
|
||||
return h(FeatureCaseTable, {
|
||||
keyword: props.keyword,
|
||||
reportId: props.reportId,
|
||||
shareId: props.shareId,
|
||||
isPreview: props.isPreview,
|
||||
isGroup: props.isGroup,
|
||||
isGroup: isGroup.value,
|
||||
enabledTestSet: props.enabledTestSet,
|
||||
testSetId: record.id,
|
||||
});
|
||||
}
|
||||
if (
|
||||
|
@ -72,8 +76,9 @@
|
|||
reportId: props.reportId,
|
||||
shareId: props.shareId,
|
||||
isPreview: props.isPreview,
|
||||
isGroup: props.isGroup,
|
||||
isGroup: isGroup.value,
|
||||
enabledTestSet: props.enabledTestSet,
|
||||
testSetId: record.id,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -89,53 +94,98 @@
|
|||
}
|
||||
};
|
||||
|
||||
const testSetColumns: MsTableColumn = [
|
||||
{
|
||||
title: 'ms.case.associate.testSet',
|
||||
dataIndex: 'testSetName',
|
||||
showInTable: true,
|
||||
showDrag: true,
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: 'report.plan.name',
|
||||
dataIndex: 'planName',
|
||||
showInTable: true,
|
||||
showDrag: true,
|
||||
width: 300,
|
||||
},
|
||||
];
|
||||
const columns = computed<MsTableColumn>(() => {
|
||||
if (isGroup.value) {
|
||||
return [
|
||||
{
|
||||
title: 'ms.case.associate.testSet',
|
||||
dataIndex: 'name',
|
||||
showInTable: true,
|
||||
showDrag: true,
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: 'report.plan.name',
|
||||
dataIndex: 'planName',
|
||||
showInTable: true,
|
||||
showDrag: true,
|
||||
width: 300,
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
dataIndex: 'other',
|
||||
slotName: 'other',
|
||||
showInTable: true,
|
||||
showDrag: true,
|
||||
width: 300,
|
||||
},
|
||||
];
|
||||
}
|
||||
return [
|
||||
{
|
||||
title: 'ms.case.associate.testSet',
|
||||
dataIndex: 'name',
|
||||
showInTable: true,
|
||||
showDrag: true,
|
||||
width: 200,
|
||||
},
|
||||
// 字段很少第一级别靠左展示,填充表头
|
||||
{
|
||||
title: '',
|
||||
dataIndex: 'other',
|
||||
slotName: 'other',
|
||||
showInTable: true,
|
||||
showDrag: true,
|
||||
width: 300,
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
dataIndex: 'empty',
|
||||
slotName: 'empty',
|
||||
showInTable: true,
|
||||
showDrag: true,
|
||||
width: 300,
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
const reportFeatureCaseList = () => {
|
||||
return !props.shareId ? getReportFeatureCaseList : getReportShareFeatureCaseList;
|
||||
const apiMap: Record<SelectedReportCardTypes, any> = {
|
||||
[ReportCardTypeEnum.FUNCTIONAL_DETAIL]: getCollectFunctionalPage,
|
||||
[ReportCardTypeEnum.API_CASE_DETAIL]: getCollectApiPage,
|
||||
[ReportCardTypeEnum.SCENARIO_CASE_DETAIL]: getCollectScenarioPage,
|
||||
};
|
||||
const { propsRes, propsEvent, loadList, setLoadListParams } = useTable(reportFeatureCaseList(), {
|
||||
columns: testSetColumns,
|
||||
|
||||
const getReportTestSetList = () => {
|
||||
return apiMap[props.activeType as SelectedReportCardTypes];
|
||||
};
|
||||
|
||||
const { propsRes, propsEvent, loadList, setLoadListParams } = useTable(getReportTestSetList(), {
|
||||
columns: columns.value,
|
||||
scroll: { x: '100%' },
|
||||
heightUsed: 320,
|
||||
showSelectorAll: false,
|
||||
});
|
||||
// TODO 待联调等接口
|
||||
async function loadCaseList() {
|
||||
|
||||
function loadCaseList() {
|
||||
if (props.enabledTestSet) {
|
||||
expandedKeys.value = [];
|
||||
}
|
||||
// setLoadListParams({ reportId: props.reportId, keyword: props.keyword, shareId: props.shareId ?? undefined });
|
||||
// loadList();
|
||||
setLoadListParams({ reportId: props.reportId, keyword: props.keyword, shareId: props.shareId });
|
||||
loadList();
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (props.reportId) {
|
||||
loadCaseList();
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
[() => props.reportId, () => props.isPreview],
|
||||
() => {
|
||||
if (props.reportId && props.isPreview) {
|
||||
// TODO 待联调等接口
|
||||
// loadCaseList();
|
||||
} else {
|
||||
propsRes.value.data = detailTableExample[ReportCardTypeEnum.FUNCTIONAL_DETAIL];
|
||||
() => props.reportId,
|
||||
(val) => {
|
||||
if (val) {
|
||||
loadCaseList();
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -174,8 +224,18 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
:deep(.arco-table-tr-expand) {
|
||||
> .arco-table-td {
|
||||
> .arco-table-cell {
|
||||
padding: 8px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
:deep(.arco-table-tr-expand .arco-table-cell) {
|
||||
padding: 12px !important;
|
||||
padding: 8px 16px !important;
|
||||
}
|
||||
:deep(.arco-table-cell-with-sorter) {
|
||||
margin: 8px 0 !important;
|
||||
}
|
||||
:deep(.arco-table .arco-table-tr-expand .arco-table-td .arco-table) {
|
||||
margin: 0 !important;
|
||||
|
@ -196,4 +256,11 @@
|
|||
:deep(.arco-table-tr-expand .arco-table-td .arco-table .arco-table-td) {
|
||||
border-color: var(--color-text-n8) !important;
|
||||
}
|
||||
:deep(.arco-table-tr.test-set-expand-tr) {
|
||||
&:hover {
|
||||
> .arco-table-td {
|
||||
background: white !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
<div class="mb-[8px] flex items-center justify-between">
|
||||
<div class="font-medium"> {{ props.label }} </div>
|
||||
<div v-if="props.isPreview" class="flex items-center">
|
||||
<a-switch v-model:model-value="enabledTestSet" size="small" />
|
||||
<span class="mx-[8px]"> {{ t('ms.case.associate.testSet') }}</span>
|
||||
<a-switch v-model:model-value="enabledTestSet" size="small" @change="(val)=>changeHandler(val as boolean)" />
|
||||
<span class="mx-[16px]"> {{ t('ms.case.associate.testSet') }}</span>
|
||||
<a-input-search
|
||||
v-model:model-value="keyword"
|
||||
:placeholder="t('common.searchByIdName')"
|
||||
|
@ -17,41 +17,34 @@
|
|||
</div>
|
||||
<!-- 开启测试集 -->
|
||||
<TestSetTable
|
||||
v-if="enabledTestSet"
|
||||
v-if="showSetTable"
|
||||
ref="testSetTableRef"
|
||||
v-model:keyword="keyword"
|
||||
:active-type="props.activeType"
|
||||
:report-id="props.reportId"
|
||||
:share-id="props.shareId"
|
||||
:is-preview="props.isPreview"
|
||||
:is-group="props.isGroup"
|
||||
:enabled-test-set="enabledTestSet"
|
||||
/>
|
||||
<!-- 功能用例明细 -->
|
||||
<FeatureCaseTable
|
||||
v-else-if="props.activeType === ReportCardTypeEnum.FUNCTIONAL_DETAIL && !enabledTestSet"
|
||||
v-if="showFeatureTable"
|
||||
ref="featureCaseTableRef"
|
||||
v-model:keyword="keyword"
|
||||
:report-id="props.reportId"
|
||||
:share-id="props.shareId"
|
||||
:is-preview="props.isPreview"
|
||||
:is-group="props.isGroup"
|
||||
:enabled-test-set="enabledTestSet"
|
||||
/>
|
||||
<!-- 接口用例明细和场景用例明细 -->
|
||||
<ApiAndScenarioTable
|
||||
v-else-if="
|
||||
(props.activeType === ReportCardTypeEnum.API_CASE_DETAIL ||
|
||||
props.activeType === ReportCardTypeEnum.SCENARIO_CASE_DETAIL) &&
|
||||
!enabledTestSet
|
||||
"
|
||||
v-if="showApiAndScenario"
|
||||
ref="apiAndScenarioTableRef"
|
||||
v-model:keyword="keyword"
|
||||
:active-type="props.activeType"
|
||||
:report-id="props.reportId"
|
||||
:share-id="props.shareId"
|
||||
:is-preview="props.isPreview"
|
||||
:is-group="props.isGroup"
|
||||
:keyword="keyword"
|
||||
:enabled-test-set="enabledTestSet"
|
||||
/>
|
||||
</template>
|
||||
|
@ -62,6 +55,7 @@
|
|||
import FeatureCaseTable from '@/views/test-plan/report/detail/component/system-card/featureCaseTable.vue';
|
||||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useTestPlanReportStore from '@/store/modules/testPlan/testPlanReport';
|
||||
|
||||
import { ReportCardTypeEnum } from '@/enums/testPlanReportEnum';
|
||||
|
||||
|
@ -71,17 +65,25 @@
|
|||
label: string;
|
||||
shareId?: string;
|
||||
isPreview?: boolean;
|
||||
isGroup?: boolean;
|
||||
}>();
|
||||
const { t } = useI18n();
|
||||
|
||||
const enabledTestSet = ref<boolean>(false);
|
||||
const testPlanReportStore = useTestPlanReportStore();
|
||||
|
||||
const keyword = ref<string>('');
|
||||
|
||||
const testSetTableRef = ref<InstanceType<typeof TestSetTable>>();
|
||||
const featureCaseTableRef = ref<InstanceType<typeof TestSetTable>>();
|
||||
const apiAndScenarioTableRef = ref<InstanceType<typeof TestSetTable>>();
|
||||
const isGroup = inject<Ref<boolean>>('isPlanGroup', ref(false));
|
||||
|
||||
const enabledTestSet = computed({
|
||||
set: (val) => {
|
||||
testPlanReportStore.setTestStatus(isGroup.value, val, props.activeType);
|
||||
},
|
||||
get: () => {
|
||||
return testPlanReportStore.getTestStatus(isGroup.value, props.activeType);
|
||||
},
|
||||
});
|
||||
|
||||
function searchList() {
|
||||
if (enabledTestSet.value) {
|
||||
|
@ -96,6 +98,33 @@
|
|||
keyword.value = '';
|
||||
searchList();
|
||||
}
|
||||
|
||||
const showFeatureTable = computed(() => {
|
||||
if (props.isPreview) {
|
||||
return props.activeType === ReportCardTypeEnum.FUNCTIONAL_DETAIL && !enabledTestSet.value;
|
||||
}
|
||||
return props.activeType === ReportCardTypeEnum.FUNCTIONAL_DETAIL;
|
||||
});
|
||||
|
||||
const showApiAndScenario = computed(() => {
|
||||
if (props.isPreview) {
|
||||
return (
|
||||
(props.activeType === ReportCardTypeEnum.API_CASE_DETAIL ||
|
||||
props.activeType === ReportCardTypeEnum.SCENARIO_CASE_DETAIL) &&
|
||||
!enabledTestSet.value
|
||||
);
|
||||
}
|
||||
return (
|
||||
props.activeType === ReportCardTypeEnum.API_CASE_DETAIL ||
|
||||
props.activeType === ReportCardTypeEnum.SCENARIO_CASE_DETAIL
|
||||
);
|
||||
});
|
||||
|
||||
const showSetTable = computed(() => (props.isPreview ? enabledTestSet.value : false));
|
||||
|
||||
function changeHandler(value: boolean) {
|
||||
testPlanReportStore.setTestStatus(isGroup.value, value, props.activeType);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
@ -105,9 +134,4 @@
|
|||
@apply overflow-y-auto bg-white;
|
||||
.ms-scroll-bar();
|
||||
}
|
||||
.test-set-cell {
|
||||
:deep(.arco-table-cell) {
|
||||
padding: 8px 16px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -140,39 +140,16 @@
|
|||
</div>
|
||||
<div class="wrapper-preview-card">
|
||||
<div class="flex items-center justify-between">
|
||||
<div v-if="!notShowLabel.includes(item.value)" class="mb-[8px] font-medium">
|
||||
<div v-if="item.value === ReportCardTypeEnum.SUMMARY" class="mb-[8px] font-medium">
|
||||
{{ t(item.label) }}
|
||||
</div>
|
||||
<a-radio-group
|
||||
v-if="item.value === ReportCardTypeEnum.SUB_PLAN_DETAIL && props.isPreview"
|
||||
class="mb-2"
|
||||
:model-value="currentMode"
|
||||
type="button"
|
||||
@change="handleModeChange"
|
||||
>
|
||||
<a-radio value="drawer">
|
||||
<div class="mode-button">
|
||||
<MsIcon :class="{ 'active-color': currentMode === 'drawer' }" type="icon-icon_drawer" />
|
||||
<span class="mode-button-title">{{ t('msTable.columnSetting.drawer') }}</span>
|
||||
</div>
|
||||
</a-radio>
|
||||
<a-radio value="new_window">
|
||||
<div class="mode-button">
|
||||
<MsIcon
|
||||
:class="{ 'active-color': currentMode === 'new_window' }"
|
||||
type="icon-icon_into-item_outlined"
|
||||
/>
|
||||
<span class="mode-button-title">{{ t('msTable.columnSetting.newWindow') }}</span>
|
||||
</div>
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
</div>
|
||||
<ReportDetailTable
|
||||
v-if="item.value === ReportCardTypeEnum.SUB_PLAN_DETAIL"
|
||||
v-model:current-mode="currentMode"
|
||||
:report-id="detail.id"
|
||||
:share-id="shareId"
|
||||
:is-preview="props.isPreview"
|
||||
:label="t(item.label)"
|
||||
/>
|
||||
<Summary
|
||||
v-if="item.value === ReportCardTypeEnum.SUMMARY"
|
||||
|
@ -193,14 +170,14 @@
|
|||
:report-id="detail.id"
|
||||
:share-id="shareId"
|
||||
:is-preview="props.isPreview"
|
||||
:label="t(item.label)"
|
||||
/>
|
||||
<TestSetTable
|
||||
<TestSetTableIndex
|
||||
v-else-if="hasTestSet.includes(item.value)"
|
||||
:report-id="detail.id"
|
||||
:share-id="shareId"
|
||||
:active-type="item.value"
|
||||
:is-preview="props.isPreview"
|
||||
:is-group="props.isGroup"
|
||||
:label="t(item.label)"
|
||||
/>
|
||||
<CustomRichText
|
||||
|
@ -240,7 +217,7 @@
|
|||
import ReportMetricsItem from '@/views/test-plan/report/detail/component/system-card/ReportMetricsItem.vue';
|
||||
import Summary from '@/views/test-plan/report/detail/component/system-card/summary.vue';
|
||||
import SystemTrigger from '@/views/test-plan/report/detail/component/system-card/systemTrigger.vue';
|
||||
import TestSetTable from '@/views/test-plan/report/detail/component/system-card/testTableIndex.vue';
|
||||
import TestSetTableIndex from '@/views/test-plan/report/detail/component/system-card/testTableIndex.vue';
|
||||
|
||||
import { getReportLayout, updateReportDetail } from '@/api/modules/test-plan/report';
|
||||
import {
|
||||
|
@ -306,19 +283,13 @@
|
|||
|
||||
const getAnalysisHover = computed(() => (props.isPreview ? '' : 'hover-analysis cursor-not-allowed'));
|
||||
|
||||
const notShowLabel = [
|
||||
ReportCardTypeEnum.CUSTOM_CARD,
|
||||
ReportCardTypeEnum.FUNCTIONAL_DETAIL,
|
||||
ReportCardTypeEnum.API_CASE_DETAIL,
|
||||
ReportCardTypeEnum.SCENARIO_CASE_DETAIL,
|
||||
];
|
||||
|
||||
const isPlanGroup = ref(props.isGroup);
|
||||
provide('isPlanGroup', isPlanGroup);
|
||||
const hasTestSet = [
|
||||
ReportCardTypeEnum.FUNCTIONAL_DETAIL,
|
||||
ReportCardTypeEnum.API_CASE_DETAIL,
|
||||
ReportCardTypeEnum.SCENARIO_CASE_DETAIL,
|
||||
];
|
||||
|
||||
/**
|
||||
* 分享share
|
||||
*/
|
||||
|
@ -543,23 +514,27 @@
|
|||
|
||||
const isDefaultLayout = ref<boolean>(false);
|
||||
|
||||
watchEffect(() => {
|
||||
if (props.detailInfo) {
|
||||
detail.value = cloneDeep(props.detailInfo);
|
||||
const { defaultLayout, id, name, summary } = detail.value;
|
||||
isDefaultLayout.value = defaultLayout;
|
||||
richText.value.summary = summary;
|
||||
reportForm.value.reportName = name;
|
||||
initOptionsData();
|
||||
if (props.isPreview) {
|
||||
if (!defaultLayout && id) {
|
||||
getDefaultLayout();
|
||||
} else {
|
||||
innerCardList.value = props.isGroup ? cloneDeep(defaultGroupConfig) : cloneDeep(defaultSingleConfig);
|
||||
watch(
|
||||
() => props.detailInfo,
|
||||
(val) => {
|
||||
if (val) {
|
||||
detail.value = cloneDeep(props.detailInfo);
|
||||
const { defaultLayout, id, name, summary } = detail.value;
|
||||
isDefaultLayout.value = defaultLayout;
|
||||
richText.value.summary = summary;
|
||||
reportForm.value.reportName = name;
|
||||
initOptionsData();
|
||||
if (props.isPreview) {
|
||||
if (!defaultLayout && id) {
|
||||
getDefaultLayout();
|
||||
} else {
|
||||
innerCardList.value = props.isGroup ? cloneDeep(defaultGroupConfig) : cloneDeep(defaultSingleConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
// 获取内容详情
|
||||
function getContent(item: configItem): customValueForm {
|
||||
|
@ -601,12 +576,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
const currentMode = ref<string>('drawer');
|
||||
|
||||
function handleModeChange(value: string | number | boolean, ev: Event) {
|
||||
currentMode.value = value as string;
|
||||
}
|
||||
|
||||
function getColor(index: number, type: string) {
|
||||
if (type === 'top' && index === 0) {
|
||||
return ['text-[rgb(var(--primary-3))]'];
|
||||
|
|
Loading…
Reference in New Issue