mirror of
https://gitee.com/fit2cloud-feizhiyun/MeterSphere.git
synced 2024-12-01 03:28:59 +08:00
feat(测试计划): 测试计划详情-接口场景-点id新开场景详情页面&点击执行结果显示报告抽屉
This commit is contained in:
parent
3ee5bd00a8
commit
353b95ffad
@ -57,6 +57,8 @@ import type {
|
||||
ExecuteHistoryType,
|
||||
FollowPlanParams,
|
||||
PassRateCountDetail,
|
||||
PlanDetailApiCaseItem,
|
||||
PlanDetailApiScenarioItem,
|
||||
PlanDetailBugItem,
|
||||
PlanDetailFeatureCaseItem,
|
||||
PlanDetailFeatureCaseListQueryParams,
|
||||
@ -238,3 +240,11 @@ export function testPlanCancelBug(id: string) {
|
||||
export function executeHistory(data: ExecuteHistoryType) {
|
||||
return MSR.post<ExecuteHistoryItem[]>({ url: ExecuteHistoryUrl, data });
|
||||
}
|
||||
// 计划详情-接口用例列表 TODO 联调
|
||||
export function getPlanDetailApiCaseList(data: PlanDetailFeatureCaseListQueryParams) {
|
||||
return MSR.post<CommonList<PlanDetailApiCaseItem>>({ url: GetPlanDetailFeatureCaseListUrl, data });
|
||||
}
|
||||
// 计划详情-接口场景列表 TODO 联调
|
||||
export function getPlanDetailApiScenarioList(data: PlanDetailFeatureCaseListQueryParams) {
|
||||
return MSR.post<CommonList<PlanDetailApiScenarioItem>>({ url: GetPlanDetailFeatureCaseListUrl, data });
|
||||
}
|
||||
|
@ -98,6 +98,7 @@
|
||||
specialHeight: number; // 特殊高度,例如某些页面有面包屑,autoHeight 时无效
|
||||
hideBack: boolean; // 隐藏返回按钮
|
||||
autoHeight: boolean; // 内容区域高度是否自适应
|
||||
autoWidth: boolean; // 内容区域宽度是否自适应
|
||||
otherWidth: number; // 该宽度为卡片外部同级容器的宽度
|
||||
headerMinWidth: number; // 卡片头部最小宽度
|
||||
minWidth: number; // 卡片内容最小宽度
|
||||
@ -121,6 +122,7 @@
|
||||
specialHeight: 0,
|
||||
hideBack: false,
|
||||
autoHeight: false,
|
||||
autoWidth: false,
|
||||
hasBreadcrumb: false,
|
||||
noContentPadding: false,
|
||||
noBottomRadius: false,
|
||||
@ -180,11 +182,12 @@
|
||||
height: props.autoHeight ? 'auto' : `calc(100vh - ${cardOverHeight.value}px)`,
|
||||
};
|
||||
}
|
||||
const width = props.otherWidth
|
||||
? `calc(100vw - ${menuWidth.value}px - ${props.otherWidth}px)`
|
||||
: `calc(100vw - ${menuWidth.value}px - 58px)`;
|
||||
return {
|
||||
overflow: 'auto',
|
||||
width: props.otherWidth
|
||||
? `calc(100vw - ${menuWidth.value}px - ${props.otherWidth}px)`
|
||||
: `calc(100vw - ${menuWidth.value}px - 58px)`,
|
||||
width: props.autoWidth ? 'auto' : width,
|
||||
height: props.autoHeight ? 'auto' : `calc(100vh - ${cardOverHeight.value}px)`,
|
||||
};
|
||||
});
|
||||
|
@ -22,7 +22,7 @@
|
||||
<div class="flex flex-1 items-center justify-between">
|
||||
<div class="flex items-center">
|
||||
<a-tooltip :disabled="!props.title" :content="props.title">
|
||||
<span> {{ characterLimit(props.title) }}</span>
|
||||
<span class="one-line-text max-w-[300px]"> {{ props.title }}</span>
|
||||
</a-tooltip>
|
||||
|
||||
<slot name="headerLeft"></slot>
|
||||
|
@ -236,4 +236,43 @@ export interface ExecuteHistoryItem {
|
||||
deleted: boolean;
|
||||
}
|
||||
|
||||
// TODO: 联调
|
||||
export interface PlanDetailApiCaseItem {
|
||||
id: string;
|
||||
num: string;
|
||||
name: string;
|
||||
moduleId: string;
|
||||
versionName: string;
|
||||
createUser: string;
|
||||
createUserName: string;
|
||||
lastExecResult: LastExecuteResults;
|
||||
lastExecTime: number;
|
||||
executeUser: string;
|
||||
executeUserName: string;
|
||||
bugCount: number;
|
||||
customFields: customFieldsItem[]; // 自定义字段集合
|
||||
caseId: string;
|
||||
testPlanId: string;
|
||||
lastExecResultReportId: string;
|
||||
}
|
||||
|
||||
// TODO: 联调
|
||||
export interface PlanDetailApiScenarioItem {
|
||||
id: string;
|
||||
num: string;
|
||||
name: string;
|
||||
moduleId: string;
|
||||
versionName: string;
|
||||
createUser: string;
|
||||
createUserName: string;
|
||||
lastExecResult: LastExecuteResults;
|
||||
lastExecTime: number;
|
||||
executeUser: string;
|
||||
executeUserName: string;
|
||||
bugCount: number;
|
||||
customFields: customFieldsItem[]; // 自定义字段集合
|
||||
caseId: string;
|
||||
testPlanId: string;
|
||||
lastExecResultReportId: string;
|
||||
}
|
||||
export default {};
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<MsCard class="mb-[16px]" hide-back hide-footer auto-height no-content-padding hide-divider>
|
||||
<MsCard v-if="!props.isDrawer" class="mb-[16px]" hide-back hide-footer auto-height no-content-padding hide-divider>
|
||||
<template #headerLeft>
|
||||
<div class="flex items-center font-medium">
|
||||
<a-tooltip :content="detail.name" :mouse-enter-delay="300"
|
||||
@ -8,33 +8,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<template #headerRight>
|
||||
<a-popover position="bottom" content-class="response-popover-content">
|
||||
<div>
|
||||
<span class="text-[var(--color-text-4)]">{{ t('report.detail.api.executionTime') }}</span>
|
||||
{{ detail.executeTime ? dayjs(detail.executeTime).format('YYYY-MM-DD HH:mm:ss') : '-' }}
|
||||
<span class="text-[var(--color-text-4)]">{{ t('report.detail.api.executionTimeTo') }}</span>
|
||||
{{ detail.endTime ? dayjs(detail.endTime).format('YYYY-MM-DD HH:mm:ss') : '-' }}
|
||||
</div>
|
||||
<template #content>
|
||||
<div class="max-w-[400px] items-center gap-[8px] text-[14px]">
|
||||
<div class="flex-shrink-0 text-[var(--color-text-4)]">{{ t('report.detail.api.executionTime') }}</div>
|
||||
<div class="mt-2">
|
||||
{{ dayjs(detail.executeTime).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</a-popover>
|
||||
<MsButton
|
||||
v-if="hasAnyPermission(['PROJECT_TEST_PLAN_REPORT:READ+SHARE']) && !shareId"
|
||||
type="icon"
|
||||
status="secondary"
|
||||
class="ml-4 !rounded-[var(--border-radius-small)]"
|
||||
:loading="shareLoading"
|
||||
@click="shareHandler"
|
||||
>
|
||||
<MsIcon type="icon-icon_share1" class="mr-2 font-[16px]" />
|
||||
{{ t('common.share') }}
|
||||
</MsButton>
|
||||
<PlanDetailHeaderRight :share-id="shareId" :detail="detail" />
|
||||
</template>
|
||||
</MsCard>
|
||||
<div class="analysis-wrapper">
|
||||
@ -123,7 +97,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<MsCard class="mb-[16px]" simple auto-height>
|
||||
<MsCard class="mb-[16px]" simple auto-height auto-width>
|
||||
<div class="font-medium">{{ t('report.detail.reportSummary') }}</div>
|
||||
<div
|
||||
:class="`${hasAnyPermission(['PROJECT_TEST_PLAN_REPORT:READ+UPDATE']) && !shareId ? '' : 'cursor-not-allowed'}`"
|
||||
@ -145,7 +119,7 @@
|
||||
<a-button type="secondary" @click="handleCancel">{{ t('common.cancel') }}</a-button>
|
||||
</div>
|
||||
</MsCard>
|
||||
<MsCard simple auto-height>
|
||||
<MsCard simple auto-height auto-width>
|
||||
<MsTab
|
||||
v-model:active-key="activeTab"
|
||||
:show-badge="false"
|
||||
@ -164,38 +138,35 @@
|
||||
import { useEventListener } from '@vueuse/core';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
import MsChart from '@/components/pure/chart/index.vue';
|
||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||
import MsCard from '@/components/pure/ms-card/index.vue';
|
||||
import MsRichText from '@/components/pure/ms-rich-text/MsRichText.vue';
|
||||
import MsTab from '@/components/pure/ms-tab/index.vue';
|
||||
import PlanDetailHeaderRight from './planDetailHeaderRight.vue';
|
||||
import SetReportChart from '@/views/api-test/report/component/case/setReportChart.vue';
|
||||
import SingleStatusProgress from '@/views/test-plan/report/component/singleStatusProgress.vue';
|
||||
import BugTable from '@/views/test-plan/report/detail/component/bugTable.vue';
|
||||
import FeatureCaseTable from '@/views/test-plan/report/detail/component/featureCaseTable.vue';
|
||||
|
||||
import { editorUploadFile, planReportShare, updateReportDetail } from '@/api/modules/test-plan/report';
|
||||
import { editorUploadFile, updateReportDetail } from '@/api/modules/test-plan/report';
|
||||
import { PreviewEditorImageUrl } from '@/api/requrls/case-management/featureCase';
|
||||
import { defaultReportDetail, statusConfig } from '@/config/testPlan';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import { addCommasToNumber } from '@/utils';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import type { LegendData } from '@/models/apiTest/report';
|
||||
import type { PlanReportDetail, StatusListType } from '@/models/testPlan/testPlanReport';
|
||||
import { RouteEnum } from '@/enums/routeEnum';
|
||||
|
||||
import { getIndicators } from '@/views/api-test/report/utils';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const route = useRoute();
|
||||
const appStore = useAppStore();
|
||||
const props = defineProps<{
|
||||
detailInfo: PlanReportDetail;
|
||||
isDrawer?: boolean;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
@ -211,39 +182,7 @@
|
||||
/**
|
||||
* 分享share
|
||||
*/
|
||||
const shareLink = ref<string>('');
|
||||
const shareId = ref<string>(route.query.shareId as string);
|
||||
const shareLoading = ref<boolean>(false);
|
||||
async function shareHandler() {
|
||||
try {
|
||||
const res = await planReportShare({
|
||||
reportId: detail.value.id,
|
||||
projectId: appStore.currentProjectId,
|
||||
});
|
||||
const { origin } = window.location;
|
||||
shareLink.value = `${origin}/#/${RouteEnum.SHARE}/${RouteEnum.SHARE_REPORT_TEST_PLAN}${res.shareUrl}`;
|
||||
if (navigator.clipboard) {
|
||||
navigator.clipboard.writeText(shareLink.value).then(
|
||||
() => {
|
||||
Message.info(t('bugManagement.detail.shareTip'));
|
||||
},
|
||||
(e) => {
|
||||
Message.error(e);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
const input = document.createElement('input');
|
||||
input.value = shareLink.value;
|
||||
document.body.appendChild(input);
|
||||
input.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(input);
|
||||
Message.info(t('bugManagement.detail.shareTip'));
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
const legendData = ref<LegendData[]>([]);
|
||||
|
||||
|
@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<div class="flex items-center">
|
||||
<a-popover position="bottom" content-class="response-popover-content">
|
||||
<div>
|
||||
<span class="text-[var(--color-text-4)]">{{ t('report.detail.api.executionTime') }}</span>
|
||||
{{ props.detail.executeTime ? dayjs(props.detail.executeTime).format('YYYY-MM-DD HH:mm:ss') : '-' }}
|
||||
<span class="text-[var(--color-text-4)]">{{ t('report.detail.api.executionTimeTo') }}</span>
|
||||
{{ props.detail.endTime ? dayjs(props.detail.endTime).format('YYYY-MM-DD HH:mm:ss') : '-' }}
|
||||
</div>
|
||||
<template #content>
|
||||
<div class="max-w-[400px] items-center gap-[8px] text-[14px]">
|
||||
<div class="flex-shrink-0 text-[var(--color-text-4)]">{{ t('report.detail.api.executionTime') }}</div>
|
||||
<div class="mt-2">
|
||||
{{ dayjs(props.detail.executeTime).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</a-popover>
|
||||
<MsButton
|
||||
v-if="hasAnyPermission(['PROJECT_TEST_PLAN_REPORT:READ+SHARE']) && !props.shareId"
|
||||
type="icon"
|
||||
status="secondary"
|
||||
class="ml-4 !rounded-[var(--border-radius-small)]"
|
||||
:loading="shareLoading"
|
||||
@click="shareHandler"
|
||||
>
|
||||
<MsIcon type="icon-icon_share1" class="mr-2 font-[16px]" />
|
||||
{{ t('common.share') }}
|
||||
</MsButton>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||
|
||||
import { planReportShare } from '@/api/modules/test-plan/report';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import type { PlanReportDetail } from '@/models/testPlan/testPlanReport';
|
||||
import { RouteEnum } from '@/enums/routeEnum';
|
||||
|
||||
const props = defineProps<{
|
||||
detail: PlanReportDetail;
|
||||
shareId?: string;
|
||||
}>();
|
||||
|
||||
const appStore = useAppStore();
|
||||
const { t } = useI18n();
|
||||
|
||||
const shareLink = ref<string>('');
|
||||
const shareLoading = ref<boolean>(false);
|
||||
async function shareHandler() {
|
||||
try {
|
||||
const res = await planReportShare({
|
||||
reportId: props.detail.id,
|
||||
projectId: appStore.currentProjectId,
|
||||
});
|
||||
const { origin } = window.location;
|
||||
shareLink.value = `${origin}/#/${RouteEnum.SHARE}/${RouteEnum.SHARE_REPORT_TEST_PLAN}${res.shareUrl}`;
|
||||
if (navigator.clipboard) {
|
||||
navigator.clipboard.writeText(shareLink.value).then(
|
||||
() => {
|
||||
Message.info(t('bugManagement.detail.shareTip'));
|
||||
},
|
||||
(e) => {
|
||||
Message.error(e);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
const input = document.createElement('input');
|
||||
input.value = shareLink.value;
|
||||
document.body.appendChild(input);
|
||||
input.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(input);
|
||||
Message.info(t('bugManagement.detail.shareTip'));
|
||||
}
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
</script>
|
@ -39,6 +39,7 @@
|
||||
type="icon-icon_take-action_outlined"
|
||||
class="ml-[8px] cursor-pointer text-[rgb(var(--primary-5))]"
|
||||
size="16"
|
||||
@click="showReport(record)"
|
||||
/>
|
||||
</template>
|
||||
<template #status="{ record }">
|
||||
@ -78,6 +79,7 @@
|
||||
</MsButton>
|
||||
</template>
|
||||
</MsBaseTable>
|
||||
<ReportDrawer v-model:visible="reportVisible" :report-id="reportId" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -99,12 +101,13 @@
|
||||
import CaseLevel from '@/components/business/ms-case-associate/caseLevel.vue';
|
||||
import ExecuteResult from '@/components/business/ms-case-associate/executeResult.vue';
|
||||
import apiStatus from '@/views/api-test/components/apiStatus.vue';
|
||||
import ReportDrawer from '@/views/test-plan/testPlan/detail/reportDrawer.vue';
|
||||
|
||||
import {
|
||||
associationCaseToPlan,
|
||||
batchDisassociateCase,
|
||||
disassociateCase,
|
||||
getPlanDetailFeatureCaseList,
|
||||
getPlanDetailApiCaseList,
|
||||
sortFeatureCase,
|
||||
} from '@/api/modules/test-plan/testPlan';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
@ -115,7 +118,7 @@
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import { DragSortParams, ModuleTreeNode } from '@/models/common';
|
||||
import type { PlanDetailFeatureCaseItem, PlanDetailFeatureCaseListQueryParams } from '@/models/testPlan/testPlan';
|
||||
import type { PlanDetailApiCaseItem, PlanDetailFeatureCaseListQueryParams } from '@/models/testPlan/testPlan';
|
||||
import { LastExecuteResults } from '@/enums/caseEnum';
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
import { FilterSlotNameEnum } from '@/enums/tableFilterEnum';
|
||||
@ -266,7 +269,7 @@
|
||||
},
|
||||
]);
|
||||
|
||||
const tableProps = ref<Partial<MsTableProps<PlanDetailFeatureCaseItem>>>({
|
||||
const tableProps = ref<Partial<MsTableProps<PlanDetailApiCaseItem>>>({
|
||||
scroll: { x: '100%' },
|
||||
tableKey: TableKeyEnum.TEST_PLAN_DETAIL_API_CASE,
|
||||
showSetting: true,
|
||||
@ -278,8 +281,7 @@
|
||||
});
|
||||
|
||||
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable(
|
||||
// TODO 联调
|
||||
getPlanDetailFeatureCaseList,
|
||||
getPlanDetailApiCaseList,
|
||||
tableProps.value,
|
||||
(record) => {
|
||||
return {
|
||||
@ -393,6 +395,14 @@
|
||||
});
|
||||
}
|
||||
|
||||
// 显示执行报告
|
||||
const reportVisible = ref(false);
|
||||
const reportId = ref('');
|
||||
function showReport(record: PlanDetailApiCaseItem) {
|
||||
reportVisible.value = true;
|
||||
reportId.value = record.lastExecResultReportId; // TODO 联调
|
||||
}
|
||||
|
||||
const tableSelected = ref<(string | number)[]>([]); // 表格选中的
|
||||
const batchParams = ref<BatchActionQueryParams>({
|
||||
selectIds: [],
|
||||
@ -425,7 +435,7 @@
|
||||
}
|
||||
|
||||
// 复制用例
|
||||
async function handleCopyCase(record: PlanDetailFeatureCaseItem) {
|
||||
async function handleCopyCase(record: PlanDetailApiCaseItem) {
|
||||
try {
|
||||
// TODO 联调
|
||||
await associationCaseToPlan({
|
||||
@ -443,7 +453,7 @@
|
||||
|
||||
// 取消关联
|
||||
const disassociateLoading = ref(false);
|
||||
async function handleDisassociateCase(record: PlanDetailFeatureCaseItem, done?: () => void) {
|
||||
async function handleDisassociateCase(record: PlanDetailApiCaseItem, done?: () => void) {
|
||||
try {
|
||||
disassociateLoading.value = true;
|
||||
// TODO 联调
|
||||
|
@ -23,6 +23,9 @@
|
||||
@selected-change="handleTableSelect"
|
||||
@filter-change="getModuleCount"
|
||||
>
|
||||
<template #num="{ record }">
|
||||
<MsButton type="text" @click="toDetail(record)">{{ record.num }}</MsButton>
|
||||
</template>
|
||||
<template #[FilterSlotNameEnum.CASE_MANAGEMENT_CASE_LEVEL]="{ filterContent }">
|
||||
<CaseLevel :case-level="filterContent.value" />
|
||||
</template>
|
||||
@ -39,6 +42,7 @@
|
||||
type="icon-icon_take-action_outlined"
|
||||
class="ml-[8px] cursor-pointer text-[rgb(var(--primary-5))]"
|
||||
size="16"
|
||||
@click="showReport(record)"
|
||||
/>
|
||||
</template>
|
||||
<template #status="{ record }">
|
||||
@ -78,6 +82,7 @@
|
||||
</MsButton>
|
||||
</template>
|
||||
</MsBaseTable>
|
||||
<ReportDrawer v-model:visible="reportVisible" :report-id="reportId" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -99,24 +104,27 @@
|
||||
import CaseLevel from '@/components/business/ms-case-associate/caseLevel.vue';
|
||||
import ExecuteResult from '@/components/business/ms-case-associate/executeResult.vue';
|
||||
import apiStatus from '@/views/api-test/components/apiStatus.vue';
|
||||
import ReportDrawer from '@/views/test-plan/testPlan/detail/reportDrawer.vue';
|
||||
|
||||
import {
|
||||
associationCaseToPlan,
|
||||
batchDisassociateCase,
|
||||
disassociateCase,
|
||||
getPlanDetailFeatureCaseList,
|
||||
getPlanDetailApiScenarioList,
|
||||
sortFeatureCase,
|
||||
} from '@/api/modules/test-plan/testPlan';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import useOpenNewPage from '@/hooks/useOpenNewPage';
|
||||
import useTableStore from '@/hooks/useTableStore';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import { characterLimit } from '@/utils';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import { DragSortParams, ModuleTreeNode } from '@/models/common';
|
||||
import type { PlanDetailFeatureCaseItem, PlanDetailFeatureCaseListQueryParams } from '@/models/testPlan/testPlan';
|
||||
import type { PlanDetailApiScenarioItem, PlanDetailFeatureCaseListQueryParams } from '@/models/testPlan/testPlan';
|
||||
import { LastExecuteResults } from '@/enums/caseEnum';
|
||||
import { ApiTestRouteEnum } from '@/enums/routeEnum';
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
import { FilterSlotNameEnum } from '@/enums/tableFilterEnum';
|
||||
|
||||
@ -148,6 +156,7 @@
|
||||
const appStore = useAppStore();
|
||||
const tableStore = useTableStore();
|
||||
const { openModal } = useModal();
|
||||
const { openNewPage } = useOpenNewPage();
|
||||
|
||||
const keyword = ref('');
|
||||
const moduleNamePath = computed(() => {
|
||||
@ -160,6 +169,7 @@
|
||||
const columns = computed<MsTableColumn>(() => [
|
||||
{
|
||||
title: 'ID',
|
||||
slotName: 'num',
|
||||
dataIndex: 'num',
|
||||
sortIndex: 1,
|
||||
sortable: {
|
||||
@ -259,7 +269,7 @@
|
||||
},
|
||||
]);
|
||||
|
||||
const tableProps = ref<Partial<MsTableProps<PlanDetailFeatureCaseItem>>>({
|
||||
const tableProps = ref<Partial<MsTableProps<PlanDetailApiScenarioItem>>>({
|
||||
scroll: { x: '100%' },
|
||||
tableKey: TableKeyEnum.TEST_PLAN_DETAIL_API_CASE,
|
||||
showSetting: true,
|
||||
@ -271,8 +281,7 @@
|
||||
});
|
||||
|
||||
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable(
|
||||
// TODO 联调
|
||||
getPlanDetailFeatureCaseList,
|
||||
getPlanDetailApiScenarioList,
|
||||
tableProps.value,
|
||||
(record) => {
|
||||
return {
|
||||
@ -386,6 +395,14 @@
|
||||
});
|
||||
}
|
||||
|
||||
// 显示执行报告
|
||||
const reportVisible = ref(false);
|
||||
const reportId = ref('');
|
||||
function showReport(record: PlanDetailApiScenarioItem) {
|
||||
reportVisible.value = true;
|
||||
reportId.value = record.lastExecResultReportId; // TODO 联调
|
||||
}
|
||||
|
||||
const tableSelected = ref<(string | number)[]>([]); // 表格选中的
|
||||
const batchParams = ref<BatchActionQueryParams>({
|
||||
selectIds: [],
|
||||
@ -418,7 +435,7 @@
|
||||
}
|
||||
|
||||
// 复制用例
|
||||
async function handleCopyCase(record: PlanDetailFeatureCaseItem) {
|
||||
async function handleCopyCase(record: PlanDetailApiScenarioItem) {
|
||||
try {
|
||||
// TODO 联调
|
||||
await associationCaseToPlan({
|
||||
@ -436,7 +453,7 @@
|
||||
|
||||
// 取消关联
|
||||
const disassociateLoading = ref(false);
|
||||
async function handleDisassociateCase(record: PlanDetailFeatureCaseItem, done?: () => void) {
|
||||
async function handleDisassociateCase(record: PlanDetailApiScenarioItem, done?: () => void) {
|
||||
try {
|
||||
disassociateLoading.value = true;
|
||||
// TODO 联调
|
||||
@ -508,6 +525,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 去接口场景详情页面
|
||||
function toDetail(record: PlanDetailApiScenarioItem) {
|
||||
openNewPage(ApiTestRouteEnum.API_TEST_SCENARIO, {
|
||||
id: record.id,
|
||||
});
|
||||
}
|
||||
|
||||
onBeforeMount(() => {
|
||||
loadCaseList();
|
||||
});
|
||||
|
@ -16,14 +16,12 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
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';
|
||||
import useTable from '@/components/pure/ms-table/useTable';
|
||||
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import useOpenNewPage from '@/hooks/useOpenNewPage';
|
||||
|
||||
import type { PlanDetailBugItem } from '@/models/testPlan/testPlan';
|
||||
import { CaseManagementRouteEnum } from '@/enums/routeEnum';
|
||||
@ -33,8 +31,7 @@
|
||||
bugItem: PlanDetailBugItem;
|
||||
}>();
|
||||
|
||||
const router = useRouter();
|
||||
const appStore = useAppStore();
|
||||
const { openNewPage } = useOpenNewPage();
|
||||
|
||||
const columns: MsTableColumn = [
|
||||
{
|
||||
@ -68,11 +65,9 @@
|
||||
}
|
||||
|
||||
function goCaseDetail(id: string) {
|
||||
window.open(
|
||||
`${window.location.origin}#${
|
||||
router.resolve({ name: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE }).fullPath
|
||||
}?id=${id}&orgId=${appStore.currentOrgId}&pId=${appStore.currentProjectId}`
|
||||
);
|
||||
openNewPage(CaseManagementRouteEnum.CASE_MANAGEMENT_CASE, {
|
||||
id,
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -221,7 +221,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
@ -251,6 +251,7 @@
|
||||
} from '@/api/modules/test-plan/testPlan';
|
||||
import { testPlanDefaultDetail } from '@/config/testPlan';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useOpenNewPage from '@/hooks/useOpenNewPage';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
@ -267,8 +268,8 @@
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const appStore = useAppStore();
|
||||
const { openNewPage } = useOpenNewPage();
|
||||
|
||||
const planDetail = ref<TestPlanDetail>({
|
||||
...testPlanDefaultDetail,
|
||||
@ -334,11 +335,9 @@
|
||||
}
|
||||
|
||||
function goCaseDetail() {
|
||||
window.open(
|
||||
`${window.location.origin}#${
|
||||
router.resolve({ name: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE }).fullPath
|
||||
}?id=${activeCaseId.value}&orgId=${appStore.currentOrgId}&pId=${appStore.currentProjectId}`
|
||||
);
|
||||
openNewPage(CaseManagementRouteEnum.CASE_MANAGEMENT_CASE, {
|
||||
id: activeCaseId.value,
|
||||
});
|
||||
}
|
||||
|
||||
const caseDetail = ref<any>({});
|
||||
|
@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<MsDrawer
|
||||
v-model:visible="innerVisible"
|
||||
:title="detail.name"
|
||||
:width="1200"
|
||||
:footer="false"
|
||||
class="report-drawer"
|
||||
unmount-on-close
|
||||
no-content-padding
|
||||
show-full-screen
|
||||
>
|
||||
<template #tbutton>
|
||||
<PlanDetailHeaderRight share-id="" :detail="detail" />
|
||||
</template>
|
||||
<PlanDetail is-drawer :detail-info="detail" @update-success="getDetail()" />
|
||||
</MsDrawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
|
||||
import MsDrawer from '@/components/pure/ms-drawer/index.vue';
|
||||
import PlanDetail from '@/views/test-plan/report/detail/component/planDetail.vue';
|
||||
import PlanDetailHeaderRight from '@/views/test-plan/report/detail/component/planDetailHeaderRight.vue';
|
||||
|
||||
import { getReportDetail } from '@/api/modules/test-plan/report';
|
||||
import { defaultReportDetail } from '@/config/testPlan';
|
||||
|
||||
import type { PlanReportDetail } from '@/models/testPlan/testPlanReport';
|
||||
|
||||
const props = defineProps<{
|
||||
reportId: string;
|
||||
}>();
|
||||
|
||||
const innerVisible = defineModel<boolean>('visible', {
|
||||
required: true,
|
||||
});
|
||||
|
||||
const detail = ref<PlanReportDetail>(cloneDeep(defaultReportDetail));
|
||||
async function getDetail() {
|
||||
try {
|
||||
detail.value = await getReportDetail(props.reportId);
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => innerVisible.value,
|
||||
async (val) => {
|
||||
if (val) {
|
||||
await getDetail();
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.report-drawer {
|
||||
.ms-drawer-body {
|
||||
padding: 16px;
|
||||
background: var(--color-text-n9);
|
||||
}
|
||||
.right-operation-button-icon {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue
Block a user