refactor(测试计划): 优化测试计划报告分享页面获取报告详情

This commit is contained in:
wxg0103 2024-06-19 16:28:12 +08:00 committed by Craftsman
parent 8fd70d8479
commit a37d09f3ed
9 changed files with 211 additions and 13 deletions

View File

@ -60,5 +60,7 @@ public interface ExtTestPlanReportMapper {
List<ReportDTO> getScenarioReports(@Param("ids") List<String> ids); List<ReportDTO> getScenarioReports(@Param("ids") List<String> ids);
void batchUpdateExecuteTimeAndStatus(@Param("startTime") long startTime,@Param("ids")List<String> ids); void batchUpdateExecuteTimeAndStatus(@Param("startTime") long startTime, @Param("ids") List<String> ids);
List<ReportDTO> getReportsByIds(@Param("ids") List<String> ids);
} }

View File

@ -217,6 +217,18 @@
</foreach> </foreach>
</select> </select>
<select id="getReportsByIds" resultType="io.metersphere.api.dto.report.ReportDTO">
select
test_plan_report.id,
test_plan_report.name,
test_plan_report.project_id
from test_plan_report where test_plan_report.deleted = false
and test_plan_report.id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
<update id="batchUpdateExecuteTimeAndStatus" parameterType="java.lang.String"> <update id="batchUpdateExecuteTimeAndStatus" parameterType="java.lang.String">
update test_plan_report update test_plan_report
set start_time = #{startTime}, exec_status = 'RUNNING' set start_time = #{startTime}, exec_status = 'RUNNING'

View File

@ -291,6 +291,7 @@ public class TestPlanTaskCenterService {
detailReport(request, apiReports, userId, module, ApiExecuteResourceType.TEST_PLAN_API_CASE.name()); detailReport(request, apiReports, userId, module, ApiExecuteResourceType.TEST_PLAN_API_CASE.name());
List<ReportDTO> scenarioReports = extTestPlanReportMapper.getScenarioReports(subList); List<ReportDTO> scenarioReports = extTestPlanReportMapper.getScenarioReports(subList);
detailReport(request, scenarioReports, userId, module, ApiExecuteResourceType.TEST_PLAN_API_SCENARIO.name()); detailReport(request, scenarioReports, userId, module, ApiExecuteResourceType.TEST_PLAN_API_SCENARIO.name());
saveLog(subList, userId, StringUtils.join(module, "_REAL_TIME_TEST_PLAN"));
}); });
} }
@ -331,20 +332,13 @@ public class TestPlanTaskCenterService {
MsHttpClient.stopApi(endpoint, subList); MsHttpClient.stopApi(endpoint, subList);
} catch (Exception e) { } catch (Exception e) {
LogUtils.error(e); LogUtils.error(e);
} finally {
saveLog(subList, userId, StringUtils.join(module, "_REAL_TIME_TEST_PLAN"), resourceType);
} }
}); });
}); });
} }
private void saveLog(List<String> ids, String userId, String module, String type) { private void saveLog(List<String> ids, String userId, String module) {
List<ReportDTO> reports = new ArrayList<>(); List<ReportDTO> reports = extTestPlanReportMapper.getReportsByIds(ids);
if (StringUtils.equals(type, ApiExecuteResourceType.TEST_PLAN_API_CASE.name())) {
reports = extApiReportMapper.selectByIds(ids);
} else if (StringUtils.equals(type, ApiExecuteResourceType.TEST_PLAN_API_SCENARIO.name())) {
reports = extApiScenarioReportMapper.selectByIds(ids);
}
//取出所有的项目id //取出所有的项目id
List<String> projectIds = reports.stream().map(ReportDTO::getProjectId).distinct().toList(); List<String> projectIds = reports.stream().map(ReportDTO::getProjectId).distinct().toList();
//根据项目id取出组织id //根据项目id取出组织id

View File

@ -2,6 +2,7 @@ import MSR from '@/api/http';
import * as reportUrl from '@/api/requrls/test-plan/report'; import * as reportUrl from '@/api/requrls/test-plan/report';
import type { GetShareId } from '@/models/apiTest/report'; import type { GetShareId } from '@/models/apiTest/report';
import { ReportDetail, ReportStepDetail } from "@/models/apiTest/report";
import { CommonList, TableQueryParams } from '@/models/common'; import { CommonList, TableQueryParams } from '@/models/common';
import { import {
ApiOrScenarioCaseItem, ApiOrScenarioCaseItem,
@ -116,4 +117,37 @@ export function getReportDetailSharePage(data: TableQueryParams) {
return MSR.post<CommonList<PlanReportDetail>>({ url: reportUrl.ReportDetailSharePageUrl, data }); return MSR.post<CommonList<PlanReportDetail>>({ url: reportUrl.ReportDetailSharePageUrl, data });
} }
export function reportScenarioDetail(reportId: string, shareId?: string | undefined) {
if (shareId) {
return MSR.get<ReportDetail>({ url: `${reportUrl.ReportShareScenarioUrlGet}/${shareId}/${reportId}` });
}
return MSR.get<ReportDetail>({ url: `${reportUrl.ReportScenarioUrl}/${reportId}` });
}
// 报告步骤详情
export function reportStepDetail(reportId?: string, stepId?: string, shareId?: string | undefined) {
if (shareId) {
return MSR.get<ReportStepDetail>({
url: `${reportUrl.ReportShareScenarioUrlGetDetail}/${shareId}/${reportId}/${stepId}`,
});
}
return MSR.get<ReportStepDetail>({ url: `${reportUrl.ReportDetailScenarioUrl}/${reportId}/${stepId}` });
}
// 用例报告详情
export function reportCaseDetail(reportId: string, shareId?: string | undefined) {
if (shareId) {
return MSR.get<ReportDetail>({ url: `${reportUrl.ReportShareApiUrlGet}/${shareId}/${reportId}` });
}
return MSR.get<ReportDetail>({ url: `${reportUrl.ReportApiUrl}/${reportId}` });
}
// 报告步骤详情
export function reportCaseStepDetail(reportId: string, stepId: string, shareId?: string | undefined) {
if (shareId) {
return MSR.get<ReportStepDetail[]>({
url: `${reportUrl.ReportShareApiUrlGetDetail}/${shareId}/${reportId}/${stepId}`,
});
}
return MSR.get<ReportStepDetail[]>({ url: `${reportUrl.ReportDetailApiUrl}/${reportId}/${stepId}` });
}
export default {}; export default {};

View File

@ -40,3 +40,20 @@ export const ReportShareScenarioUrl = '/test-plan/report/share/detail/scenario/c
export const ReportDetailPageUrl = '/test-plan/report/detail/plan/report/page'; export const ReportDetailPageUrl = '/test-plan/report/detail/plan/report/page';
// 测试计划-聚合报告-报告明细-分享 // 测试计划-聚合报告-报告明细-分享
export const ReportDetailSharePageUrl = '/test-plan/report/share/detail/plan/report/page'; export const ReportDetailSharePageUrl = '/test-plan/report/share/detail/plan/report/page';
// 测试计划-报告明细-接口报告-分享
export const ReportShareApiUrlGet = '/test-plan/report/share/detail/api-report';
export const ReportShareApiUrlGetDetail = '/test-plan/report/share/detail/api-report/get';
// 测试计划-报告明细-接口报告
export const ReportApiUrl = '/test-plan/api/case/report/get';
export const ReportDetailApiUrl = '/test-plan/api/case/report/get/detail';
// 测试计划-报告明细-场景报告-分享
export const ReportShareScenarioUrlGet = '/test-plan/report/share/detail/scenario-report';
export const ReportShareScenarioUrlGetDetail = '/test-plan/report/share/detail/scenario-report/get';
// 测试计划-报告明细-场景报告
export const ReportScenarioUrl = '/test-plan/api/scenario/report/get';
export const ReportDetailScenarioUrl = '/test-plan/api/scenario/report/get/detail';

View File

@ -4,6 +4,7 @@
v-model:model-value="numberValue" v-model:model-value="numberValue"
class="w-[120px]" class="w-[120px]"
:min="1" :min="1"
:max="1000"
hide-button hide-button
size="small" size="small"
:disabled="props.disabled" :disabled="props.disabled"

View File

@ -904,6 +904,18 @@ export const pathMap: PathMapItem[] = [
type: TaskCenterEnum.API_SCENARIO, type: TaskCenterEnum.API_SCENARIO,
}, },
}, },
{
key: 'PROJECT_MANAGEMENT_TASK_CENTER_REAL_TIME_TEST_PLAN', // 项目管理-任务中心-实时任务-接口场景
locale: 'project.taskCenter.testPlan',
route: '',
permission: [],
level: MENU_LEVEL[2],
routeQuery: {
task: true,
tab: 'real',
type: TaskCenterEnum.TEST_PLAN,
},
},
], ],
}, },
{ {
@ -937,6 +949,18 @@ export const pathMap: PathMapItem[] = [
type: TaskCenterEnum.API_IMPORT, type: TaskCenterEnum.API_IMPORT,
}, },
}, },
{
key: 'PROJECT_MANAGEMENT_TASK_CENTER_TIME_TEST_PLAN', // 项目管理-任务中心-定时任务-测试计划
locale: 'project.taskCenter.testPlan',
route: '',
permission: [],
level: MENU_LEVEL[2],
routeQuery: {
task: true,
tab: 'timing',
type: TaskCenterEnum.TEST_PLAN,
},
},
], ],
}, },
], ],

View File

@ -21,7 +21,7 @@
v-model:visible="reportVisible" v-model:visible="reportVisible"
:is-scenario="props.activeTab === 'scenarioCase'" :is-scenario="props.activeTab === 'scenarioCase'"
:report-id="apiReportId" :report-id="apiReportId"
do-not-show-share :share-id="props.shareId"
/> />
</template> </template>
@ -31,8 +31,8 @@
import type { MsTableColumn } from '@/components/pure/ms-table/type'; import type { MsTableColumn } from '@/components/pure/ms-table/type';
import useTable from '@/components/pure/ms-table/useTable'; import useTable from '@/components/pure/ms-table/useTable';
import caseLevel from '@/components/business/ms-case-associate/caseLevel.vue'; import caseLevel from '@/components/business/ms-case-associate/caseLevel.vue';
import CaseAndScenarioReportDrawer from '@/views/api-test/components/caseAndScenarioReportDrawer.vue';
import ExecutionStatus from '@/views/api-test/report/component/reportStatus.vue'; import ExecutionStatus from '@/views/api-test/report/component/reportStatus.vue';
import CaseAndScenarioReportDrawer from '@/views/test-plan/report/detail/component/caseAndScenarioReportDrawer.vue';
import { getApiPage, getScenarioPage } from '@/api/modules/test-plan/report'; import { getApiPage, getScenarioPage } from '@/api/modules/test-plan/report';
@ -41,7 +41,6 @@
import { FilterSlotNameEnum } from '@/enums/tableFilterEnum'; import { FilterSlotNameEnum } from '@/enums/tableFilterEnum';
import { casePriorityOptions, lastReportStatusListOptions } from '@/views/api-test/components/config'; import { casePriorityOptions, lastReportStatusListOptions } from '@/views/api-test/components/config';
import { executionResultMap } from '@/views/case-management/caseManagementFeature/components/utils';
const props = defineProps<{ const props = defineProps<{
reportId: string; reportId: string;

View File

@ -0,0 +1,115 @@
<template>
<MsDrawer
v-model:visible="innerVisible"
:title="reportStepDetail.name"
:width="1200"
:footer="false"
unmount-on-close
no-content-padding
show-full-screen
>
<CaseReportCom
v-if="!props.isScenario"
:detail-info="reportStepDetail"
:get-report-step-detail="props.getReportStepDetail"
/>
<ScenarioCom v-else :detail-info="reportStepDetail" :get-report-step-detail="props.getReportStepDetail" />
</MsDrawer>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { useClipboard } from '@vueuse/core';
import MsDrawer from '@/components/pure/ms-drawer/index.vue';
import CaseReportCom from '@/views/api-test/report/component/caseReportCom.vue';
import ScenarioCom from '@/views/api-test/report/component/scenarioCom.vue';
import { reportCaseDetail,reportScenarioDetail } from '@/api/modules/test-plan/report';
import type { ReportDetail } from '@/models/apiTest/report';
const props = defineProps<{
reportId: string;
isScenario?: boolean;
reportDetail?: (...args: any) => Promise<any>; //
getReportStepDetail?: (...args: any) => Promise<any>; //
shareId?: string;
}>();
const { copy, isSupported } = useClipboard({ legacy: true });
const innerVisible = defineModel<boolean>('visible', {
required: true,
});
const initReportStepDetail = {
id: '',
name: '', //
testPlanId: '',
createUser: '',
deleteTime: 0,
deleteUser: '',
deleted: false,
updateUser: '',
updateTime: 0,
startTime: 0, // /
endTime: 0, // /
requestDuration: 0, //
status: '', // /SUCCESS/ERROR
triggerMode: '', //
runMode: '', //
poolId: '', //
poolName: '', //
versionId: '',
integrated: false, //
projectId: '',
environmentId: '', // id
environmentName: '', //
errorCount: 0, //
fakeErrorCount: 0, //
pendingCount: 0, //
successCount: 0, //
assertionCount: 0, //
assertionSuccessCount: 0, //
requestErrorRate: '', //
requestPendingRate: '', //
requestFakeErrorRate: '', //
requestPassRate: '', //
assertionPassRate: '', //
scriptIdentifier: '', //
children: [], //
stepTotal: 0, //
console: '',
};
const reportStepDetail = ref<ReportDetail>({
...initReportStepDetail,
});
async function getReportDetail() {
try {
if (props.reportDetail) {
reportStepDetail.value = await props.reportDetail(props.reportId);
return;
}
if (props.isScenario) {
reportStepDetail.value = await reportScenarioDetail(props.reportId, props.shareId);
} else {
reportStepDetail.value = await reportCaseDetail(props.reportId, props.shareId);
}
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
}
}
watch(
() => innerVisible.value,
async (val) => {
if (val) {
reportStepDetail.value = { ...initReportStepDetail };
await getReportDetail();
}
}
);
</script>