From 6736cc5f1796830bb98d9e41bb11fe5a50044b45 Mon Sep 17 00:00:00 2001 From: "xinxin.wu" Date: Sat, 23 Mar 2024 18:18:45 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=8E=A5=E5=8F=A3=E6=B5=8B=E8=AF=95):=20?= =?UTF-8?q?=E6=8A=A5=E5=91=8A=E8=AF=A6=E6=83=85=5F=E6=8A=A5=E5=91=8A?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E8=81=94=E8=B0=83100%?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/api/modules/api-test/report.ts | 58 ++- frontend/src/api/requrls/api-test/report.ts | 20 + frontend/src/enums/routeEnum.ts | 8 + frontend/src/layout/share-layout.vue | 25 ++ frontend/src/models/apiTest/common.ts | 1 + frontend/src/models/apiTest/report.ts | 16 +- frontend/src/router/constants.ts | 25 ++ frontend/src/router/routes/base.ts | 1 + frontend/src/router/routes/modules/share.ts | 42 ++ .../requestComposition/response/index.vue | 2 +- .../requestComposition/response/result.vue | 134 +----- .../response/result/assertionTable.vue | 64 +++ .../response/result/body.vue | 63 +++ .../response/result/console.vue | 27 ++ .../response/result/index.vue | 298 +++++++++++++ .../response/result/resValueScript.vue | 43 ++ .../response/result/tiledDisplay.vue | 146 +++++++ .../management/api/preview/detail.vue | 2 +- .../report/component/caseReportCom.vue | 388 +++++++++++++++++ .../report/component/caseReportDrawer.vue | 304 ++----------- .../report/component/conditionStatus.vue | 2 +- .../report/component/reportDetailDrawer.vue | 367 +++------------- .../report/component/reportStatus.vue | 6 +- .../report/component/responseContent.vue | 217 ---------- .../api-test/report/component/scenarioCom.vue | 407 ++++++++++++++++++ .../report/component/scenarioItem.vue | 288 ------------- .../report/component/step/assertTable.vue | 84 ---- .../report/component/step/resContent.vue | 36 -- .../report/component/step/stepDrawer.vue | 343 ++------------- .../report/component/step/stepTree.vue | 395 +++++++++++++++++ .../report/component/stepProgress.vue | 13 +- .../api-test/report/component/subRequest.vue | 18 - .../api-test/report/component/tiledList.vue | 67 +-- .../src/views/api-test/report/locale/en-US.ts | 2 + .../src/views/api-test/report/locale/zh-CN.ts | 4 +- .../views/api-test/report/shareCaseIndex.vue | 108 +++++ .../views/api-test/report/shareSceneIndex.vue | 35 ++ .../common/importApiDrawer/table.vue | 5 +- .../taskCenter/component/executionStatus.vue | 16 +- .../taskCenter/locale/en-US.ts | 2 +- .../taskCenter/locale/zh-CN.ts | 2 +- 41 files changed, 2373 insertions(+), 1711 deletions(-) create mode 100644 frontend/src/layout/share-layout.vue create mode 100644 frontend/src/router/routes/modules/share.ts create mode 100644 frontend/src/views/api-test/components/requestComposition/response/result/assertionTable.vue create mode 100644 frontend/src/views/api-test/components/requestComposition/response/result/body.vue create mode 100644 frontend/src/views/api-test/components/requestComposition/response/result/console.vue create mode 100644 frontend/src/views/api-test/components/requestComposition/response/result/index.vue create mode 100644 frontend/src/views/api-test/components/requestComposition/response/result/resValueScript.vue create mode 100644 frontend/src/views/api-test/components/requestComposition/response/result/tiledDisplay.vue create mode 100644 frontend/src/views/api-test/report/component/caseReportCom.vue delete mode 100644 frontend/src/views/api-test/report/component/responseContent.vue create mode 100644 frontend/src/views/api-test/report/component/scenarioCom.vue delete mode 100644 frontend/src/views/api-test/report/component/scenarioItem.vue delete mode 100644 frontend/src/views/api-test/report/component/step/assertTable.vue delete mode 100644 frontend/src/views/api-test/report/component/step/resContent.vue create mode 100644 frontend/src/views/api-test/report/component/step/stepTree.vue delete mode 100644 frontend/src/views/api-test/report/component/subRequest.vue create mode 100644 frontend/src/views/api-test/report/shareCaseIndex.vue create mode 100644 frontend/src/views/api-test/report/shareSceneIndex.vue diff --git a/frontend/src/api/modules/api-test/report.ts b/frontend/src/api/modules/api-test/report.ts index 20e0340982..e794435b90 100644 --- a/frontend/src/api/modules/api-test/report.ts +++ b/frontend/src/api/modules/api-test/report.ts @@ -1,7 +1,7 @@ import MSR from '@/api/http'; import * as reportUrl from '@/api/requrls/api-test/report'; -import type { ReportDetail, ReportStepDetail } from '@/models/apiTest/report'; +import type { GetShareId, ReportDetail, ReportStepDetail } from '@/models/apiTest/report'; import type { TableQueryParams } from '@/models/common'; import { ReportEnum } from '@/enums/reportEnum'; @@ -37,22 +37,68 @@ export function reportBathDelete(moduleType: string, data: TableQueryParams) { return MSR.post({ url: reportUrl.ApiBatchDeleteUrl, data }); } -// Api报告详情 -export function reportDetail(reportId: string) { +// 报告详情 +export function reportScenarioDetail(reportId: string, shareId?: string | undefined) { + if (shareId) { + return MSR.get({ url: `${reportUrl.ScenarioReportShareDetailUrl}/${shareId}/${reportId}` }); + } return MSR.get({ url: `${reportUrl.ScenarioReportDetailUrl}/${reportId}` }); } // 报告步骤详情 -export function reportStepDetail(reportId: string, stepId: string) { +export function reportStepDetail(reportId?: string, stepId?: string, shareId?: string | undefined) { + if (shareId) { + return MSR.get({ + url: `${reportUrl.ScenarioReportShareDetailStepUrl}/${shareId}/${reportId}/${stepId}`, + }); + } return MSR.get({ url: `${reportUrl.ScenarioReportDetailStepUrl}/${reportId}/${stepId}` }); } // 用例报告详情 -export function reportCaseDetail(reportId: string) { +export function reportCaseDetail(reportId: string, shareId?: string | undefined) { + if (shareId) { + return MSR.get({ url: `${reportUrl.CaseReportShareDetailUrl}/${shareId}/${reportId}` }); + } return MSR.get({ url: `${reportUrl.CaseReportDetailUrl}/${reportId}` }); } // 报告步骤详情 -export function reportCaseStepDetail(reportId: string, stepId: string) { +export function reportCaseStepDetail(reportId: string, stepId: string, shareId?: string | undefined) { + if (shareId) { + return MSR.get({ + url: `${reportUrl.CaseStepDetailShareStepUrl}/${shareId}/${reportId}/${stepId}`, + }); + } return MSR.get({ url: `${reportUrl.CaseStepDetailStepUrl}/${reportId}/${stepId}` }); } +// 生成分享id +export function getShareInfo(data: GetShareId) { + return MSR.post({ url: `${reportUrl.getShareIdUrl}`, data }); +} +// 获取场景分享详情 +export function getScenarioReportShareDetail(data: { shareId: string; reportId: string }) { + return MSR.get({ + url: `${reportUrl.ScenarioReportDetailUrl}/${data.shareId}/${data.reportId}`, + }); +} +// 获取用例分享详情 +export function getCaseReportShareDetail(data: { shareId: string; reportId: string }) { + return MSR.get({ + url: `${reportUrl.CaseReportDetailUrl}/${data.shareId}/${data.reportId}`, + }); +} + +// 报告分享(场景) +export function reportScenarioShare(shareId: string, stepId: string) { + return MSR.get({ url: `${reportUrl.reportScenarioShareUrl}/${shareId}/${stepId}` }); +} +// 报告分享(用例) +export function reportCaseShare(shareId: string, stepId: string) { + return MSR.get({ url: `${reportUrl.reportCaseShareUrl}/${shareId}/${stepId}` }); +} +// 获取分享报告id +export function getShareReportInfo(shareId: string) { + return MSR.get({ url: `${reportUrl.getShareReportInfoUrl}/${shareId}` }); +} + export default {}; diff --git a/frontend/src/api/requrls/api-test/report.ts b/frontend/src/api/requrls/api-test/report.ts index 7a86d0561a..212a15fe91 100644 --- a/frontend/src/api/requrls/api-test/report.ts +++ b/frontend/src/api/requrls/api-test/report.ts @@ -18,9 +18,29 @@ export const ApiBatchDeleteUrl = '/api/report/case/batch/delete'; // 场景报告详情(API) export const ScenarioReportDetailUrl = '/api/report/scenario/get'; +// 场景报告详情分享(API) +export const ScenarioReportShareDetailUrl = '/api/report/scenario/share'; + // 场景报告详情(用例) export const CaseReportDetailUrl = '/api/report/case/get'; +// 场景报告详情分享(用例) +export const CaseReportShareDetailUrl = '/api/report/case/share'; + // 报告详情步骤(API) export const ScenarioReportDetailStepUrl = '/api/report/scenario/get/detail'; +// 报告详情步骤分享(API) +export const ScenarioReportShareDetailStepUrl = '/api/report/scenario/share/detail'; + // 报告详情步骤(用例) export const CaseStepDetailStepUrl = '/api/report/case/get/detail'; +// 报告详情步骤分享(用例) +export const CaseStepDetailShareStepUrl = '/api/report/case/share/detail'; + +// 报告分享(API) +export const reportScenarioShareUrl = '/api/report/scenario/share'; +// 报告分享(CASE) +export const reportCaseShareUrl = '/api/report/case/share'; + +// 获取分享id +export const getShareIdUrl = '/api/report/share/gen'; +export const getShareReportInfoUrl = '/api/report/share/get'; diff --git a/frontend/src/enums/routeEnum.ts b/frontend/src/enums/routeEnum.ts index fb76959cb1..4ca22e372c 100644 --- a/frontend/src/enums/routeEnum.ts +++ b/frontend/src/enums/routeEnum.ts @@ -6,6 +6,7 @@ export enum ApiTestRouteEnum { API_TEST_SCENARIO = 'apiTestScenario', API_TEST_SCENARIO_RECYCLE = 'apiTestScenarioRecycle', API_TEST_REPORT = 'apiTestReport', + API_TEST_REPORT_SHARE = 'apiTestReportShare', } export enum BugManagementRouteEnum { @@ -99,6 +100,12 @@ export enum SettingRouteEnum { SETTING_ORGANIZATION_TASK_CENTER = 'settingOrganizationTaskCenter', } +export enum ShareEnum { + SHARE = 'share', + SHARE_REPORT_SCENARIO = 'shareReportScenario', + SHARE_REPORT_CASE = 'shareReportCase', +} + export const RouteEnum = { ...ApiTestRouteEnum, ...SettingRouteEnum, @@ -109,4 +116,5 @@ export const RouteEnum = { ...TestPlanRouteEnum, ...UITestRouteEnum, ...WorkbenchRouteEnum, + ...ShareEnum, }; diff --git a/frontend/src/layout/share-layout.vue b/frontend/src/layout/share-layout.vue new file mode 100644 index 0000000000..a818d4b9e6 --- /dev/null +++ b/frontend/src/layout/share-layout.vue @@ -0,0 +1,25 @@ + + + + + diff --git a/frontend/src/models/apiTest/common.ts b/frontend/src/models/apiTest/common.ts index d1d562c310..6d5ea17a6f 100644 --- a/frontend/src/models/apiTest/common.ts +++ b/frontend/src/models/apiTest/common.ts @@ -406,6 +406,7 @@ export interface RequestResult { url: string; method: string; responseResult: ResponseResult; + [key: string]: any; } export interface RequestTaskResult { requestResults: RequestResult[]; // 请求结果 diff --git a/frontend/src/models/apiTest/report.ts b/frontend/src/models/apiTest/report.ts index a983299258..5b02f8f292 100644 --- a/frontend/src/models/apiTest/report.ts +++ b/frontend/src/models/apiTest/report.ts @@ -1,3 +1,5 @@ +import { RequestResult } from '@/models/apiTest/common'; + export interface LegendData { label: string; value: string; @@ -36,6 +38,8 @@ export interface ResponseResult { assertions: AssertionItem[]; } +export type resultType = RequestResult & ResponseResult; + export interface StepContent { resourceId: string; projectId: string; @@ -54,7 +58,7 @@ export interface StepContent { method: string; assertionTotal: number; passAssertionsTotal: number; - subRequestResults: any; + subRequestResults: ResponseResult[]; responseResult: ResponseResult; isSuccessful: boolean; fakeErrorCode: string; @@ -62,6 +66,7 @@ export interface StepContent { [key: string]: any; } +export type StepContentType = StepContent & RequestResult; // 步骤详情 export interface ReportStepDetailItem { id: string; @@ -74,7 +79,7 @@ export interface ReportStepDetailItem { code: string; responseSize: number; scriptIdentifier: string; - content: StepContent; + content: StepContentType; [key: string]: any; } @@ -96,6 +101,7 @@ export interface ScenarioItemType { responseSize: number; // 响应内容大小 scriptIdentifier: string; // 脚本标识 fold: boolean; // 是否展示折叠 + expanded: boolean; // 是否展开折叠树节点 children: ScenarioItemType[]; level?: number; stepDetail: ReportStepDetailItem; @@ -145,3 +151,9 @@ export interface ReportDetail { } export type ReportDetailPartial = Partial; + +// 获取分享id +export interface GetShareId { + reportId: string; + projectId: string; +} diff --git a/frontend/src/router/constants.ts b/frontend/src/router/constants.ts index 1b16c9130c..d440700a17 100644 --- a/frontend/src/router/constants.ts +++ b/frontend/src/router/constants.ts @@ -3,6 +3,31 @@ export const WHITE_LIST = [ { name: 'notFound', path: '/notFound', children: [] }, { name: 'invite', path: '/invite', children: [] }, { name: 'index', path: '/index', children: [] }, + { + name: 'share', + path: '/share', + children: [ + { + name: 'shareReportScenario', + path: '/shareReportScenario', + }, + { + name: 'shareReportCase', + path: '/shareReportCase', + children: [], + }, + ], + }, + { + name: 'shareReportScenario', + path: '/shareReportScenario', + children: [], + }, + { + name: 'shareReportCase', + path: '/shareReportCase', + children: [], + }, ]; // 左侧菜单底部对齐的菜单数组,数组项为一级路由的name diff --git a/frontend/src/router/routes/base.ts b/frontend/src/router/routes/base.ts index f6ffbbcfb1..99a95d7264 100644 --- a/frontend/src/router/routes/base.ts +++ b/frontend/src/router/routes/base.ts @@ -5,6 +5,7 @@ import type { RouteRecordRaw } from 'vue-router'; export const DEFAULT_LAYOUT = () => import('@/layout/default-layout.vue'); export const PAGE_LAYOUT = () => import('@/layout/page-layout.vue'); export const NO_PERMISSION_LAYOUT = () => import('@/layout/no-permission-layout.vue'); +export const SHARE_LAYOUT = () => import('@/layout/share-layout.vue'); export const INDEX_ROUTE: RouteRecordRaw = { path: '/index', diff --git a/frontend/src/router/routes/modules/share.ts b/frontend/src/router/routes/modules/share.ts new file mode 100644 index 0000000000..c9b1f45127 --- /dev/null +++ b/frontend/src/router/routes/modules/share.ts @@ -0,0 +1,42 @@ +import { ShareEnum } from '@/enums/routeEnum'; + +import { SHARE_LAYOUT } from '../base'; +import type { AppRouteRecordRaw } from '../types'; + +const ShareRoute: AppRouteRecordRaw = { + path: '/share', + name: ShareEnum.SHARE, + component: SHARE_LAYOUT, + meta: { + locale: 'menu.testPlan', + icon: 'icon-icon_test-tracking_filled', + hideChildrenInMenu: true, + roles: ['*'], + hideInMenu: true, + }, + children: [ + // 测试计划 + { + path: 'shareReportScenario', + name: ShareEnum.SHARE_REPORT_SCENARIO, + component: () => import('@/views/api-test/report/shareSceneIndex.vue'), + meta: { + locale: '', + roles: ['*'], + isTopMenu: false, + }, + }, + { + path: 'shareReportCase', + name: ShareEnum.SHARE_REPORT_CASE, + component: () => import('@/views/api-test/report/shareCaseIndex.vue'), + meta: { + locale: '', + roles: ['*'], + isTopMenu: false, + }, + }, + ], +}; + +export default ShareRoute; diff --git a/frontend/src/views/api-test/components/requestComposition/response/index.vue b/frontend/src/views/api-test/components/requestComposition/response/index.vue index d517da5842..b462a87159 100644 --- a/frontend/src/views/api-test/components/requestComposition/response/index.vue +++ b/frontend/src/views/api-test/components/requestComposition/response/index.vue @@ -16,7 +16,7 @@ v-else type="icon" status="secondary" - class="!mr-0 !rounded-full" + class="!mr-0 !rounded-full bg-[rgb(var(--primary-1))]" size="small" @click="emit('changeExpand', true)" > diff --git a/frontend/src/views/api-test/components/requestComposition/response/result.vue b/frontend/src/views/api-test/components/requestComposition/response/result.vue index 72da3475b1..247732fb66 100644 --- a/frontend/src/views/api-test/components/requestComposition/response/result.vue +++ b/frontend/src/views/api-test/components/requestComposition/response/result.vue @@ -4,58 +4,18 @@
- - - - - -
+ + -
{{ getResponsePreContent(activeTab) }}
-
- - - + :active-tab="activeTab" + :request-result="props.requestResult" + /> +
{ - if (props.requestResult) { - const { contentType } = props.requestResult.responseResult; - if (contentType.includes('json')) { - return LanguageEnum.JSON; - } - if (contentType.includes('html')) { - return LanguageEnum.HTML; - } - if (contentType.includes('xml')) { - return LanguageEnum.XML; - } - } - return LanguageEnum.PLAINTEXT; - }); - const { copy, isSupported } = useClipboard(); async function copyScript() { @@ -174,58 +114,6 @@ Message.warning(t('apiTestDebug.copyNotSupport')); } } - - function getResponsePreContent(type: keyof typeof ResponseComposition) { - switch (type) { - case ResponseComposition.HEADER: - return props.requestResult?.responseResult?.headers.trim(); - case ResponseComposition.REAL_REQUEST: - return props.requestResult?.body - ? `${t('apiTestDebug.requestUrl')}:\n${props.requestResult.url}\n${t('apiTestDebug.header')}:\n${ - props.requestResult.headers - }\nBody:\n${props.requestResult.body.trim()}` - : ''; - case ResponseComposition.EXTRACT: - return props.requestResult?.responseResult?.vars?.trim(); - default: - return ''; - } - } - - const columns: MsTableColumn = [ - { - title: 'apiTestDebug.content', - dataIndex: 'content', - showTooltip: true, - }, - { - title: 'apiTestDebug.status', - dataIndex: 'pass', - slotName: 'status', - width: 80, - }, - { - title: 'apiTestDebug.reason', - dataIndex: 'message', - showTooltip: true, - }, - ]; - const { propsRes, propsEvent } = useTable(undefined, { - scroll: { x: '100%' }, - columns, - }); - - watch( - () => props.requestResult?.responseResult.assertions, - (val) => { - if (val) { - propsRes.value.data = props.requestResult?.responseResult.assertions || []; - } - }, - { - immediate: true, - } - ); diff --git a/frontend/src/views/api-test/components/requestComposition/response/result/body.vue b/frontend/src/views/api-test/components/requestComposition/response/result/body.vue new file mode 100644 index 0000000000..d74caae2c1 --- /dev/null +++ b/frontend/src/views/api-test/components/requestComposition/response/result/body.vue @@ -0,0 +1,63 @@ + + + + + diff --git a/frontend/src/views/api-test/components/requestComposition/response/result/console.vue b/frontend/src/views/api-test/components/requestComposition/response/result/console.vue new file mode 100644 index 0000000000..4d2f2ab3b8 --- /dev/null +++ b/frontend/src/views/api-test/components/requestComposition/response/result/console.vue @@ -0,0 +1,27 @@ + + + + + diff --git a/frontend/src/views/api-test/components/requestComposition/response/result/index.vue b/frontend/src/views/api-test/components/requestComposition/response/result/index.vue new file mode 100644 index 0000000000..1876d43838 --- /dev/null +++ b/frontend/src/views/api-test/components/requestComposition/response/result/index.vue @@ -0,0 +1,298 @@ + + + + + diff --git a/frontend/src/views/api-test/components/requestComposition/response/result/resValueScript.vue b/frontend/src/views/api-test/components/requestComposition/response/result/resValueScript.vue new file mode 100644 index 0000000000..adb0f96838 --- /dev/null +++ b/frontend/src/views/api-test/components/requestComposition/response/result/resValueScript.vue @@ -0,0 +1,43 @@ + + + + + diff --git a/frontend/src/views/api-test/components/requestComposition/response/result/tiledDisplay.vue b/frontend/src/views/api-test/components/requestComposition/response/result/tiledDisplay.vue new file mode 100644 index 0000000000..c905b7baab --- /dev/null +++ b/frontend/src/views/api-test/components/requestComposition/response/result/tiledDisplay.vue @@ -0,0 +1,146 @@ + + + + + diff --git a/frontend/src/views/api-test/management/components/management/api/preview/detail.vue b/frontend/src/views/api-test/management/components/management/api/preview/detail.vue index 7ead34a8c0..907cc1119b 100644 --- a/frontend/src/views/api-test/management/components/management/api/preview/detail.vue +++ b/frontend/src/views/api-test/management/components/management/api/preview/detail.vue @@ -357,7 +357,7 @@ import type { RequestParam } from '@/views/api-test/components/requestComposition/index.vue'; const props = defineProps<{ - isCase?: boolean; // case详情 + isCase?: boolean; // case 详情 detail: RequestParam; protocols: ProtocolItem[]; isPriorityLocalExec?: boolean; diff --git a/frontend/src/views/api-test/report/component/caseReportCom.vue b/frontend/src/views/api-test/report/component/caseReportCom.vue new file mode 100644 index 0000000000..6844fc0ee3 --- /dev/null +++ b/frontend/src/views/api-test/report/component/caseReportCom.vue @@ -0,0 +1,388 @@ + + + + + diff --git a/frontend/src/views/api-test/report/component/caseReportDrawer.vue b/frontend/src/views/api-test/report/component/caseReportDrawer.vue index db595b4489..e31e227565 100644 --- a/frontend/src/views/api-test/report/component/caseReportDrawer.vue +++ b/frontend/src/views/api-test/report/component/caseReportDrawer.vue @@ -28,7 +28,7 @@ {{ t('common.share') }} - {{ t('common.export') }} - + --> @@ -406,12 +191,11 @@ @apply mb-4 bg-white; } .analyze { - min-height: 196px; - max-height: 200px; + height: 196px; border-radius: 4px; - @apply mb-2 flex justify-between bg-white; + @apply mb-4 flex justify-between bg-white; .request-analyze { - @apply flex flex-1 flex-col p-4; + @apply flex h-full flex-1 flex-col p-4; .chart-legend { .chart-legend-item { @apply grid grid-cols-3 gap-2; @@ -425,7 +209,7 @@ } } .time-analyze { - @apply flex flex-1 flex-col p-4; + @apply flex h-full flex-1 flex-col p-4; .time-card { @apply flex items-center justify-between; .time-card-item { diff --git a/frontend/src/views/api-test/report/component/conditionStatus.vue b/frontend/src/views/api-test/report/component/conditionStatus.vue index cf32fc3ee1..55f585d4dd 100644 --- a/frontend/src/views/api-test/report/component/conditionStatus.vue +++ b/frontend/src/views/api-test/report/component/conditionStatus.vue @@ -26,9 +26,9 @@ [ScenarioStepType.IF_CONTROLLER]: { label: 'apiScenario.conditionControl', color: 'rgba(238, 80, 163, 1)' }, [ScenarioStepType.ONCE_ONLY_CONTROLLER]: { label: 'apiScenario.onlyOnceControl', color: 'rgba(211, 68, 0, 1)' }, [ScenarioStepType.SCRIPT_OPERATION]: { label: 'apiScenario.scriptOperation', color: 'rgba(20, 225, 198, 1)' }, - [ScenarioStepType.CUSTOM_API]: { label: 'apiScenario.customApi', color: 'rgb(var(--link-4))' }, [ScenarioStepType.API_CASE]: { label: 'report.detail.api.apiCase', color: 'rgb(var(--link-4))' }, [ScenarioStepType.CUSTOM_REQUEST]: { label: 'report.detail.api.apiCase', color: 'rgb(var(--link-4))' }, + [ScenarioStepType.API]: { label: 'report.detail.api', color: 'rgb(var(--link-4))' }, }; const getClass = computed(() => { diff --git a/frontend/src/views/api-test/report/component/reportDetailDrawer.vue b/frontend/src/views/api-test/report/component/reportDetailDrawer.vue index a6afe6a98b..ddb7775d59 100644 --- a/frontend/src/views/api-test/report/component/reportDetailDrawer.vue +++ b/frontend/src/views/api-test/report/component/reportDetailDrawer.vue @@ -4,10 +4,10 @@ v-model:visible="showDrawer" :width="1200" :footer="false" - :title="t('project.fileManagement.detail')" + :title="reportStepDetail.name" :detail-id="props.reportId" :detail-index="props.activeReportIndex" - :get-detail-func="reportDetail" + :get-detail-func="reportScenarioDetail" :pagination="props.pagination" :table-data="props.tableData" :page-change="props.pageChange" @@ -28,7 +28,8 @@ {{ t('common.share') }} - + diff --git a/frontend/src/views/api-test/report/component/scenarioCom.vue b/frontend/src/views/api-test/report/component/scenarioCom.vue new file mode 100644 index 0000000000..a99c99a41c --- /dev/null +++ b/frontend/src/views/api-test/report/component/scenarioCom.vue @@ -0,0 +1,407 @@ + + + + + diff --git a/frontend/src/views/api-test/report/component/scenarioItem.vue b/frontend/src/views/api-test/report/component/scenarioItem.vue deleted file mode 100644 index 701bd43daf..0000000000 --- a/frontend/src/views/api-test/report/component/scenarioItem.vue +++ /dev/null @@ -1,288 +0,0 @@ - - - - - diff --git a/frontend/src/views/api-test/report/component/step/assertTable.vue b/frontend/src/views/api-test/report/component/step/assertTable.vue deleted file mode 100644 index 5568ccc2f1..0000000000 --- a/frontend/src/views/api-test/report/component/step/assertTable.vue +++ /dev/null @@ -1,84 +0,0 @@ - - - - - diff --git a/frontend/src/views/api-test/report/component/step/resContent.vue b/frontend/src/views/api-test/report/component/step/resContent.vue deleted file mode 100644 index 056fbe8051..0000000000 --- a/frontend/src/views/api-test/report/component/step/resContent.vue +++ /dev/null @@ -1,36 +0,0 @@ - - - - - diff --git a/frontend/src/views/api-test/report/component/step/stepDrawer.vue b/frontend/src/views/api-test/report/component/step/stepDrawer.vue index 493f3b173b..c3df887de2 100644 --- a/frontend/src/views/api-test/report/component/step/stepDrawer.vue +++ b/frontend/src/views/api-test/report/component/step/stepDrawer.vue @@ -4,107 +4,48 @@ v-model:visible="showDrawer" :width="960" :footer="false" - :title="t('步骤名称')" + :title="props.scenarioDetail?.name" show-full-screen :unmount-on-close="true" >
-
-
- - - - - +
diff --git a/frontend/src/views/api-test/report/component/stepProgress.vue b/frontend/src/views/api-test/report/component/stepProgress.vue index 34a2326663..cbc564095f 100644 --- a/frontend/src/views/api-test/report/component/stepProgress.vue +++ b/frontend/src/views/api-test/report/component/stepProgress.vue @@ -64,6 +64,11 @@ }>(); const { t } = useI18n(); + const getCountTotal = computed(() => { + const { successCount, errorCount, fakeErrorCount, pendingCount } = props.reportDetail; + return successCount + errorCount + fakeErrorCount + pendingCount; + }); + const colorData = computed(() => { if ( props.reportDetail.status === 'ERROR' || @@ -81,19 +86,19 @@ } return [ { - percentage: (props.reportDetail.successCount / props.reportDetail.stepTotal) * 100, + percentage: (props.reportDetail.successCount / getCountTotal.value) * 100, color: 'rgb(var(--success-6))', }, { - percentage: (props.reportDetail.errorCount / props.reportDetail.stepTotal) * 100, + percentage: (props.reportDetail.errorCount / getCountTotal.value) * 100, color: 'rgb(var(--danger-6))', }, { - percentage: (props.reportDetail.fakeErrorCount / props.reportDetail.stepTotal) * 100, + percentage: (props.reportDetail.fakeErrorCount / getCountTotal.value) * 100, color: 'rgb(var(--warning-6))', }, { - percentage: (props.reportDetail.pendingCount / props.reportDetail.stepTotal) * 100, + percentage: (props.reportDetail.pendingCount / getCountTotal.value) * 100, color: 'var(--color-text-input-border)', }, ]; diff --git a/frontend/src/views/api-test/report/component/subRequest.vue b/frontend/src/views/api-test/report/component/subRequest.vue deleted file mode 100644 index f1bf7eaa6e..0000000000 --- a/frontend/src/views/api-test/report/component/subRequest.vue +++ /dev/null @@ -1,18 +0,0 @@ - - - - - diff --git a/frontend/src/views/api-test/report/component/tiledList.vue b/frontend/src/views/api-test/report/component/tiledList.vue index 36525f454c..b93400149b 100644 --- a/frontend/src/views/api-test/report/component/tiledList.vue +++ b/frontend/src/views/api-test/report/component/tiledList.vue @@ -1,29 +1,31 @@ @@ -40,37 +43,33 @@ import { ref } from 'vue'; import { cloneDeep } from 'lodash-es'; - import MsEmpty from '@/components/pure/ms-empty/index.vue'; - import ScenarioItem from './scenarioItem.vue'; import StepDrawer from './step/stepDrawer.vue'; + import StepTree from './step/stepTree.vue'; import { addLevelToTree } from '@/utils'; - import type { ReportDetail, ScenarioDetailItem, ScenarioItemType } from '@/models/apiTest/report'; + import type { ReportDetail, ScenarioItemType } from '@/models/apiTest/report'; import { addFoldField } from '../utils'; const props = defineProps<{ reportDetail: ReportDetail; - activeType: string; // 平铺模式|tab模式 + activeType: 'tiled' | 'tab'; // 平铺模式|tab模式 showType: 'API' | 'CASE'; // 接口场景|用例 }>(); const tiledList = ref([]); - watchEffect(() => { - if (props.reportDetail && props.reportDetail.children) { - tiledList.value = props.reportDetail.children || []; - tiledList.value = addLevelToTree(tiledList.value) as ScenarioItemType[]; - tiledList.value.forEach((item) => { - addFoldField(item); - }); - } - }); + + const isExpandAll = ref(false); // 是否展开全部 const showStepDrawer = ref(false); const activeDetailId = ref(''); const activeStepIndex = ref(0); - const scenarioDetail = ref({}); + const scenarioDetail = ref(); + + /** + * 步骤详情 + */ function showDetail(item: ScenarioItemType) { showStepDrawer.value = true; scenarioDetail.value = cloneDeep(item); @@ -81,6 +80,16 @@ onMounted(() => { tiledList.value = addLevelToTree(tiledList.value) as ScenarioItemType[]; }); + + watchEffect(() => { + if (props.reportDetail && props.reportDetail.children) { + tiledList.value = props.reportDetail.children || []; + tiledList.value = addLevelToTree(tiledList.value) as ScenarioItemType[]; + tiledList.value.forEach((item) => { + addFoldField(item); + }); + } + }); diff --git a/frontend/src/views/api-test/report/shareSceneIndex.vue b/frontend/src/views/api-test/report/shareSceneIndex.vue new file mode 100644 index 0000000000..c325e20d25 --- /dev/null +++ b/frontend/src/views/api-test/report/shareSceneIndex.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/frontend/src/views/api-test/scenario/components/common/importApiDrawer/table.vue b/frontend/src/views/api-test/scenario/components/common/importApiDrawer/table.vue index aac2de48a8..2cfbb2b02f 100644 --- a/frontend/src/views/api-test/scenario/components/common/importApiDrawer/table.vue +++ b/frontend/src/views/api-test/scenario/components/common/importApiDrawer/table.vue @@ -218,11 +218,12 @@ * 表格单行选中事件处理 */ function handleRowSelectChange(key: string) { - const selectedData = currentTable.value.propsRes.value.data.find((e) => e.id === key); + const selectedData = currentTable.value.propsRes.value.data.find((e: any) => e.id === key); if (tableSelectedKeys.value.includes(key)) { // 取消选中 tableSelectedData.value = tableSelectedData.value.filter((e) => e.id !== key); - } else if (selectedData) { + } + if (selectedData) { tableSelectedData.value.push(selectedData); } emit('select', tableSelectedData.value); diff --git a/frontend/src/views/project-management/taskCenter/component/executionStatus.vue b/frontend/src/views/project-management/taskCenter/component/executionStatus.vue index a7581667dc..781fc6edb1 100644 --- a/frontend/src/views/project-management/taskCenter/component/executionStatus.vue +++ b/frontend/src/views/project-management/taskCenter/component/executionStatus.vue @@ -54,9 +54,9 @@ color: '!text-[rgb(var(--link-6))]', }, PENDING: { - icon: 'icon-icon_wait', + icon: 'icon-icon_block_filled', label: 'project.taskCenter.queuing', - color: '!text-[rgb(var(--link-6))]', + color: '!text-[var(--color-text-input-border)]', }, }, [TaskCenterEnum.API_SCENARIO]: { @@ -88,9 +88,9 @@ color: '!text-[rgb(var(--link-6))]', }, PENDING: { - icon: 'icon-icon_wait', + icon: 'icon-icon_block_filled', label: 'project.taskCenter.queuing', - color: '!text-[rgb(var(--link-6))]', + color: '!text-[var(--color-text-input-border)]', }, }, [TaskCenterEnum.LOAD_TEST]: { @@ -124,9 +124,9 @@ }, [TaskCenterEnum.UI_TEST]: { PENDING: { - icon: 'icon-icon_wait', + icon: 'icon-icon_block_filled', label: 'project.taskCenter.queuing', - color: '!text-[rgb(var(--link-6))]', + color: '!text-[var(--color-text-input-border)]', }, RUNNING: { icon: 'icon-icon_testing', @@ -154,9 +154,9 @@ }, [TaskCenterEnum.TEST_PLAN]: { RUNNING: { - icon: 'icon-icon_testing', + icon: 'icon-icon_block_filled', label: 'project.taskCenter.queuing', - color: '!text-[rgb(var(--link-6))]', + color: '!text-[var(--color-text-input-border)]', }, SUCCESS: { icon: 'icon-icon_succeed_colorful', diff --git a/frontend/src/views/project-management/taskCenter/locale/en-US.ts b/frontend/src/views/project-management/taskCenter/locale/en-US.ts index 2b67c7de40..13a1453faa 100644 --- a/frontend/src/views/project-management/taskCenter/locale/en-US.ts +++ b/frontend/src/views/project-management/taskCenter/locale/en-US.ts @@ -31,7 +31,7 @@ export default { 'project.taskCenter.falseAlarm': 'False alarm', 'project.taskCenter.inExecution': 'In execution', 'project.taskCenter.rerun': 'Rerun', - 'project.taskCenter.queuing': 'Be queuing', + 'project.taskCenter.queuing': 'pending', 'project.taskCenter.starting': 'Be starting', 'project.taskCenter.complete': 'complete', 'project.taskCenter.scheduledTask': 'Scheduled task', diff --git a/frontend/src/views/project-management/taskCenter/locale/zh-CN.ts b/frontend/src/views/project-management/taskCenter/locale/zh-CN.ts index af3b235297..b448944493 100644 --- a/frontend/src/views/project-management/taskCenter/locale/zh-CN.ts +++ b/frontend/src/views/project-management/taskCenter/locale/zh-CN.ts @@ -31,7 +31,7 @@ export default { 'project.taskCenter.falseAlarm': '误报', 'project.taskCenter.inExecution': '执行中', 'project.taskCenter.rerun': '重跑中', - 'project.taskCenter.queuing': '排队中', + 'project.taskCenter.queuing': '未执行', 'project.taskCenter.starting': '启动中', 'project.taskCenter.complete': '完成', 'project.taskCenter.scheduledTask': '定时任务',