feat(任务中心): 任务中心接口Done

This commit is contained in:
baiqi 2024-10-22 18:27:51 +08:00 committed by 刘瑞斌
parent e913074e2b
commit eed331d1a4
9 changed files with 147 additions and 41 deletions

View File

@ -1,7 +1,13 @@
import MSR from '@/api/http';
import * as reportUrl from '@/api/requrls/api-test/report';
import type { GetShareId, ReportDetail, ReportStepDetail, ReportStepDetailItem } from '@/models/apiTest/report';
import type {
GetShareId,
ReportDetail,
ReportStepDetail,
ReportStepDetailItem,
TaskReportDetail,
} from '@/models/apiTest/report';
import type { TableQueryParams } from '@/models/common';
import { ReportEnum } from '@/enums/reportEnum';
@ -113,7 +119,7 @@ export function downloadFile(data: string | undefined) {
// 获取用例任务报告
export function getCaseTaskReport(taskId: string) {
return MSR.get<ReportStepDetailItem[]>({ url: `${reportUrl.caseTaskReportUrl}/${taskId}` });
return MSR.get<TaskReportDetail>({ url: `${reportUrl.caseTaskReportUrl}/${taskId}` });
}
// 获取场景任务报告

View File

@ -167,8 +167,8 @@
</li>
</ul>
</div>
<TaskCenterDrawer v-model:visible="taskCenterVisible" />
<MessageCenterDrawer v-model:visible="messageCenterVisible" />
<TaskCenterDrawer v-if="taskCenterVisible" v-model:visible="taskCenterVisible" />
<MessageCenterDrawer v-if="messageCenterVisible" v-model:visible="messageCenterVisible" />
<AddProjectModal :visible="projectVisible" @cancel="projectVisible = false" />
</template>
@ -179,8 +179,6 @@
import { Message } from '@arco-design/web-vue';
import MessageBox from '@/components/pure/message-box/index.vue';
import MessageCenterDrawer from '@/components/business/ms-message/MessageCenterDrawer.vue';
import TaskCenterDrawer from '@/components/business/ms-task-center-drawer/index.vue';
import TopMenu from '@/components/business/ms-top-menu/index.vue';
import AddProjectModal from '@/views/setting/organization/project/components/addProjectModal.vue';
@ -202,6 +200,11 @@
import { IconInfoCircle } from '@arco-design/web-vue/es/icon';
import type { LocaleType } from '#/global';
const TaskCenterDrawer = defineAsyncComponent(() => import('@/components/business/ms-task-center-drawer/index.vue'));
const MessageCenterDrawer = defineAsyncComponent(
() => import('@/components/business/ms-message/MessageCenterDrawer.vue')
);
const props = defineProps<{
isPreview?: boolean;
logo?: string;

View File

@ -1,6 +1,6 @@
import { RequestResult } from '@/models/apiTest/common';
import type { RequestMethods } from '@/enums/apiEnum';
import type { ExecuteStatusEnum } from '@/enums/taskCenter';
import type { ExecuteResultEnum, ExecuteStatusEnum } from '@/enums/taskCenter';
export interface LegendData {
label: string;
@ -118,6 +118,7 @@ export interface ReportDetail {
name: string; // 报告名称
testPlanId: string;
createUser: string;
createTime?: number;
deleteTime: number;
deleteUser: string;
deleted: boolean;
@ -151,6 +152,11 @@ export interface ReportDetail {
children: ScenarioItemType[]; // 步骤列表
stepTotal: number; // 步骤总数
console: string; // 控制台
taskOrigin?: string; // 任务来源
taskOriginName?: string; // 任务来源名称
result?: ExecuteResultEnum;
resourcePoolNode?: string; // 资源池节点
threadId?: string; // 线程ID
[key: string]: any;
}
@ -161,3 +167,24 @@ export interface GetShareId {
reportId: string;
projectId: string;
}
// 用例任务报告详情
export interface TaskReportDetail {
id: string;
name: string; // 报告名称
createUser: string;
createTime: number;
startTime: number; // 开始时间/同创建时间一致
endTime: number; // 结束时间/报告执行完成
status: ExecuteStatusEnum; // 报告状态
poolId: string; // 资源池
resourcePoolName: string; // 资源池名称
integrated: boolean; // 是否是集成报告
environmentId: string; // 环境id
environmentName: string; // 环境名称
taskOrigin: string; // 任务来源
taskOriginName: string; // 任务来源名称
result: ExecuteResultEnum;
resourcePoolNode: string; // 资源池节点
threadId: string; // 线程ID
apiReportDetailDTOList: ReportStepDetailItem[];
}

View File

@ -104,15 +104,21 @@
import { FormInstance, Message } from '@arco-design/web-vue';
import { BatchActionQueryParams } from '@/components/pure/ms-table/type';
import MsRichMessage from '@/components/business/ms-rich-message/index.vue';
import { getEnvList } from '@/api/modules/api-test/common';
import { getPoolId, getPoolOption } from '@/api/modules/api-test/management';
import { useI18n } from '@/hooks/useI18n';
import useAppStore from '@/store/modules/app';
import useGlobalStore from '@/store/modules/global';
import { getGenerateId } from '@/utils';
import { Environment } from '@/models/apiTest/management';
import { ResourcePoolItem } from '@/models/setting/resourcePool';
import { GlobalEventNameEnum } from '@/enums/commonEnum';
import { TaskCenterEnum } from '@/enums/taskCenter';
const globalStore = useGlobalStore();
const { t } = useI18n();
const batchExecuteFormRef = ref<FormInstance>();
const batchExecuteForm = ref({
@ -213,7 +219,35 @@
versionId: '',
refId: '',
});
Message.success(t('case.detail.execute.success'));
Message.success({
content: () =>
h(
'div',
{
style: {
display: 'flex',
alignItems: 'center',
gap: '4px',
},
},
[
h(MsRichMessage, {
content: t('case.detail.execute.success'),
onGoDetail() {
globalStore.dispatchGlobalEvent({
id: getGenerateId(),
name: GlobalEventNameEnum.OPEN_TASK_CENTER,
params: {
tab: TaskCenterEnum.DETAIL,
},
});
},
}),
]
),
duration: 5000,
closable: true,
});
cancelBatchExecute();
resetBatchExecuteForm();
emit('finished');

View File

@ -495,7 +495,6 @@
import type { MsTreeNodeData } from '@/components/business/ms-tree/types';
import apiStatus from '@/views/api-test/components/apiStatus.vue';
import caseAndScenarioReportDrawer from '@/views/api-test/components/caseAndScenarioReportDrawer.vue';
import ApiExportModal from '@/views/api-test/management/components/management/api/apiExportModal.vue';
import ExecutionStatus from '@/views/api-test/report/component/reportStatus.vue';
import BatchRunModal from '@/views/api-test/scenario/components/batchRunModal.vue';
import ScenarioExportModal from '@/views/api-test/scenario/components/common/exportScenario/scenarioExportModal.vue';

View File

@ -14,7 +14,7 @@
</MsButton>
</div>
</template>
<a-spin :loading="loading" class="block">
<a-spin :loading="loading" class="block min-h-[200px]">
<MsDescription :descriptions="detail.description" :column="3" :line-gap="8" one-line-value>
<template #value="{ item }">
<execStatus v-if="item.key === 'status'" :status="props.record.status" size="small" />
@ -77,43 +77,44 @@
try {
loading.value = true;
const res = await getCaseTaskReport(props.record.id);
const [caseDetail] = res;
const { apiReportDetailDTOList } = res;
const [caseDetail] = apiReportDetailDTOList;
detail.value = {
name: caseDetail.requestName,
description: [
{
label: t('ms.taskCenter.executeStatus'),
key: 'status',
value: t(executeStatusMap[props.record.status].label),
value: t(executeStatusMap[res.status].label),
},
{
label: t('ms.taskCenter.operationUser'),
value: props.record.executor,
value: props.record.userName,
},
{
label: t('ms.taskCenter.taskCreateTime'),
value: dayjs(props.record.startTime).format('YYYY-MM-DD HH:mm:ss'),
value: res.createTime ? dayjs(res.createTime).format('YYYY-MM-DD HH:mm:ss') : '-',
},
{
label: t('ms.taskCenter.taskResource'),
value: props.record.resourceName,
value: res.taskOriginName || caseDetail.requestName,
},
{
label: t('ms.taskCenter.threadID'),
value: props.record.threadId,
value: res.threadId,
},
{
label: t('ms.taskCenter.taskStartTime'),
value: dayjs(props.record.startTime).format('YYYY-MM-DD HH:mm:ss'),
value: res.startTime ? dayjs(res.startTime).format('YYYY-MM-DD HH:mm:ss') : '-',
},
{
label: t('ms.taskCenter.executeEnvInfo'),
value: 'DEV 资源池1 10.11.1.1',
value: `${res.environmentName} ${res.resourcePoolName} ${res.resourcePoolNode}`,
class: '!w-[calc(100%/3*2)]',
},
{
label: t('ms.taskCenter.taskEndTime'),
value: dayjs(props.record.endTime).format('YYYY-MM-DD HH:mm:ss'),
value: res.endTime ? dayjs(res.endTime).format('YYYY-MM-DD HH:mm:ss') : '-',
},
] as Description[],
...caseDetail,

View File

@ -52,9 +52,11 @@
{{ t(executeMethodMap[record.triggerMode]) }}
</template>
<template #resourcePoolNode="{ record }">
<div>{{ record.resourcePoolNode }}</div>
<a-tooltip :content="record.resourcePoolNode">
<div class="one-line-text">{{ record.resourcePoolNode }}</div>
</a-tooltip>
<a-tooltip v-if="record.resourcePoolNodeStatus === false" :content="t('ms.taskCenter.nodeErrorTip')">
<icon-exclamation-circle-fill class="ml-[4px] !text-[rgb(var(--warning-6))]" :size="18" />
<icon-exclamation-circle-fill class="min-w-[18px] !text-[rgb(var(--warning-6))]" :size="18" />
</a-tooltip>
</template>
<template #action="{ record }">
@ -77,8 +79,16 @@
</MsButton>
</template>
</ms-base-table>
<caseExecuteResultDrawer v-model:visible="caseExecuteResultDrawerVisible" :record="activeRecord" />
<scenarioExecuteResultDrawer v-model:visible="scenarioExecuteResultDrawerVisible" :record="activeRecord" />
<caseExecuteResultDrawer
v-if="caseExecuteResultDrawerVisible"
v-model:visible="caseExecuteResultDrawerVisible"
:record="activeRecord"
/>
<scenarioExecuteResultDrawer
v-if="scenarioExecuteResultDrawerVisible"
v-model:visible="scenarioExecuteResultDrawerVisible"
:record="activeRecord"
/>
</template>
<script setup lang="ts">
@ -92,10 +102,8 @@
import useTable from '@/components/pure/ms-table/useTable';
import MsTag from '@/components/pure/ms-tag/ms-tag.vue';
import MsCascader from '@/components/business/ms-cascader/index.vue';
import caseExecuteResultDrawer from './caseExecuteResultDrawer.vue';
import execStatus from './execStatus.vue';
import executionStatus from './executionStatus.vue';
import scenarioExecuteResultDrawer from './scenarioExecuteResultDrawer.vue';
import {
getOrganizationExecuteTaskDetailList,
@ -132,6 +140,9 @@
import { executeMethodMap, executeResultMap, executeStatusMap } from './config';
const scenarioExecuteResultDrawer = defineAsyncComponent(() => import('./scenarioExecuteResultDrawer.vue'));
const caseExecuteResultDrawer = defineAsyncComponent(() => import('./caseExecuteResultDrawer.vue'));
const props = defineProps<{
type: 'system' | 'project' | 'org';
id?: string;
@ -168,7 +179,7 @@
title: 'ms.taskCenter.executeStatus',
dataIndex: 'status',
slotName: 'status',
width: 100,
width: 120,
filterConfig: {
options: Object.keys(executeStatusMap).map((key) => ({
label: t(executeStatusMap[key as ExecuteStatusEnum].label),
@ -176,12 +187,16 @@
})),
filterSlotName: FilterSlotNameEnum.GLOBAL_TASK_CENTER_EXEC_STATUS,
},
sortable: {
sortDirections: ['ascend', 'descend'],
sorter: true,
},
},
{
title: 'ms.taskCenter.executeMethod',
dataIndex: 'triggerMode',
slotName: 'triggerMode',
width: 100,
width: 120,
filterConfig: {
options: Object.keys(executeMethodMap).map((key) => ({
label: t(executeMethodMap[key]),
@ -189,12 +204,16 @@
})),
filterSlotName: FilterSlotNameEnum.GLOBAL_TASK_CENTER_EXEC_METHOD,
},
sortable: {
sortDirections: ['ascend', 'descend'],
sorter: true,
},
},
{
title: 'ms.taskCenter.executeResult',
dataIndex: 'result',
slotName: 'result',
width: 100,
width: 120,
filterConfig: {
options: Object.keys(executeResultMap).map((key) => ({
label: t(executeResultMap[key].label),
@ -203,6 +222,10 @@
})),
filterSlotName: FilterSlotNameEnum.GLOBAL_TASK_CENTER_EXEC_RESULT,
},
sortable: {
sortDirections: ['ascend', 'descend'],
sorter: true,
},
},
{
title: 'ms.taskCenter.resourcePool',
@ -534,6 +557,8 @@
const queue = res[item.id];
if (queue) {
item.lineNum = queue;
} else if ([ExecuteStatusEnum.COMPLETED, ExecuteStatusEnum.STOPPED].includes(item.status)) {
item.lineNum = '-';
} else {
item.lineNum = t('ms.taskCenter.waitQueue');
}

View File

@ -259,7 +259,7 @@
title: 'ms.taskCenter.executeStatus',
dataIndex: 'status',
slotName: 'status',
width: 100,
width: 120,
filterConfig: {
options: Object.keys(executeStatusMap).map((key) => ({
label: t(executeStatusMap[key as ExecuteStatusEnum].label),
@ -267,12 +267,16 @@
})),
filterSlotName: FilterSlotNameEnum.GLOBAL_TASK_CENTER_EXEC_STATUS,
},
sortable: {
sortDirections: ['ascend', 'descend'],
sorter: true,
},
},
{
title: 'ms.taskCenter.executeMethod',
dataIndex: 'triggerMode',
slotName: 'triggerMode',
width: 100,
width: 120,
filterConfig: {
options: Object.keys(executeMethodMap).map((key) => ({
label: t(executeMethodMap[key]),
@ -280,12 +284,16 @@
})),
filterSlotName: FilterSlotNameEnum.GLOBAL_TASK_CENTER_EXEC_METHOD,
},
sortable: {
sortDirections: ['ascend', 'descend'],
sorter: true,
},
},
{
title: 'ms.taskCenter.executeResult',
dataIndex: 'result',
slotName: 'result',
width: 100,
width: 120,
filterConfig: {
options: Object.keys(executeResultMap).map((key) => ({
label: t(executeResultMap[key].label),
@ -294,6 +302,10 @@
})),
filterSlotName: FilterSlotNameEnum.GLOBAL_TASK_CENTER_EXEC_RESULT,
},
sortable: {
sortDirections: ['ascend', 'descend'],
sorter: true,
},
},
{
title: 'ms.taskCenter.caseCount',

View File

@ -1,5 +1,5 @@
<template>
<MsDrawer v-model:visible="visible" :width="800" :footer="false">
<MsDrawer v-model:visible="visible" :width="960" :footer="false">
<template #title>
<div class="flex items-center gap-[8px]">
<a-tag :color="executeResultMap[props.record.result]?.color">
@ -14,10 +14,10 @@
</MsButton>
</div>
</template>
<a-spin :loading="loading" class="block">
<a-spin :loading="loading" class="block min-h-[200px]">
<MsDescription :descriptions="detail.description" :column="3" :line-gap="8" one-line-value>
<template #value="{ item }">
<execStatus v-if="item.key === 'status'" :status="item.value as ReportExecStatus" size="small" />
<execStatus v-if="item.key === 'status'" :status="props.record.status" size="small" />
<a-tooltip
v-else
:content="`${item.value}`"
@ -69,7 +69,6 @@
import { useI18n } from '@/hooks/useI18n';
import { TaskCenterTaskDetailItem } from '@/models/taskCenter';
import { ReportExecStatus } from '@/enums/apiEnum';
import { executeResultMap, executeStatusMap } from './config';
@ -96,27 +95,27 @@
},
{
label: t('ms.taskCenter.operationUser'),
value: res.creatUserName,
value: props.record.userName,
},
{
label: t('ms.taskCenter.taskCreateTime'),
value: dayjs(res.startTime).format('YYYY-MM-DD HH:mm:ss'),
value: res.createTime ? dayjs(res.createTime).format('YYYY-MM-DD HH:mm:ss') : '-',
},
{
label: t('ms.taskCenter.taskResource'),
value: props.record.resourceName,
value: res.taskOriginName || res.requestName,
},
{
label: t('ms.taskCenter.threadID'),
value: props.record.threadId,
value: res.threadId,
},
{
label: t('ms.taskCenter.taskStartTime'),
value: dayjs(res.startTime).format('YYYY-MM-DD HH:mm:ss'),
value: res.startTime ? dayjs(res.startTime).format('YYYY-MM-DD HH:mm:ss') : '-',
},
{
label: t('ms.taskCenter.executeEnvInfo'),
value: 'DEV 资源池1 10.11.1.1',
value: `${res.environmentName} ${res.poolName} ${res.resourcePoolNode}`,
class: '!w-[calc(100%/3*2)]',
},
{