mirror of
https://gitee.com/fit2cloud-feizhiyun/MeterSphere.git
synced 2024-12-05 05:29:29 +08:00
feat(任务中心): 执行交互&任务中心部分操作接口联调&跳转交互
This commit is contained in:
parent
3aa53ef5c4
commit
bdf9fe47ec
@ -1,23 +1,34 @@
|
||||
import MSR from '@/api/http/index';
|
||||
import {
|
||||
organizationDeleteTaskUrl,
|
||||
organizationExecuteTaskDetailListUrl,
|
||||
organizationExecuteTaskListUrl,
|
||||
organizationExecuteTaskStatisticsUrl,
|
||||
organizationScheduleListUrl,
|
||||
organizationStopTaskUrl,
|
||||
organizationTaskCenterResourcePoolsUrl,
|
||||
projectDeleteTaskUrl,
|
||||
projectExecuteTaskDetailListUrl,
|
||||
projectExecuteTaskListUrl,
|
||||
projectExecuteTaskStatisticsUrl,
|
||||
projectScheduleTaskListUrl,
|
||||
projectStopTaskUrl,
|
||||
projectTaskCenterResourcePoolsUrl,
|
||||
scheduleProCenterListUrl,
|
||||
systemDeleteTaskUrl,
|
||||
systemExecuteTaskDetailListUrl,
|
||||
systemExecuteTaskListUrl,
|
||||
systemExecuteTaskStatisticsUrl,
|
||||
systemResourcePoolStatusUrl,
|
||||
systemScheduleListUrl,
|
||||
systemStopTaskUrl,
|
||||
systemTaskCenterResourcePoolsUrl,
|
||||
} from '@/api/requrls/taskCenter';
|
||||
|
||||
import type { CommonList, TableQueryParams } from '@/models/common';
|
||||
import type { TimingTaskCenterApiCaseItem } from '@/models/projectManagement/taskCenter';
|
||||
import type {
|
||||
TaskCenterResourcePoolStatus,
|
||||
TaskCenterStatisticsItem,
|
||||
TaskCenterSystemTaskItem,
|
||||
TaskCenterTaskDetailItem,
|
||||
@ -45,6 +56,21 @@ export function getProjectExecuteTaskStatistics(data: string[]) {
|
||||
return MSR.post<TaskCenterStatisticsItem[]>({ url: projectExecuteTaskStatisticsUrl, data });
|
||||
}
|
||||
|
||||
// 项目任务-获取资源池列表
|
||||
export function getProjectTaskCenterResourcePools() {
|
||||
return MSR.get<string[]>({ url: projectTaskCenterResourcePoolsUrl });
|
||||
}
|
||||
|
||||
// 项目任务-停止任务
|
||||
export function projectStopTask(id: string) {
|
||||
return MSR.get({ url: `${projectStopTaskUrl}/${id}` });
|
||||
}
|
||||
|
||||
// 项目任务-删除任务
|
||||
export function projectDeleteTask(id: string) {
|
||||
return MSR.get({ url: `${projectDeleteTaskUrl}/${id}` });
|
||||
}
|
||||
|
||||
// 接口测试-定时任务列表
|
||||
export function getScheduleProApiCaseList(data: TableQueryParams) {
|
||||
return MSR.post<CommonList<TimingTaskCenterApiCaseItem>>({ url: scheduleProCenterListUrl, data });
|
||||
@ -70,6 +96,26 @@ export function getSystemExecuteTaskStatistics(data: string[]) {
|
||||
return MSR.post<TaskCenterStatisticsItem[]>({ url: systemExecuteTaskStatisticsUrl, data });
|
||||
}
|
||||
|
||||
// 系统任务-获取资源池列表
|
||||
export function getSystemTaskCenterResourcePools() {
|
||||
return MSR.get<string[]>({ url: systemTaskCenterResourcePoolsUrl });
|
||||
}
|
||||
|
||||
// 系统任务-停止任务
|
||||
export function systemStopTask(id: string) {
|
||||
return MSR.get({ url: `${systemStopTaskUrl}/${id}` });
|
||||
}
|
||||
|
||||
// 系统任务-删除任务
|
||||
export function systemDeleteTask(id: string) {
|
||||
return MSR.get({ url: `${systemDeleteTaskUrl}/${id}` });
|
||||
}
|
||||
|
||||
// 任务中心-资源池状态
|
||||
export function getResourcePoolsStatus(data: string[]) {
|
||||
return MSR.post<TaskCenterResourcePoolStatus[]>({ url: systemResourcePoolStatusUrl, data });
|
||||
}
|
||||
|
||||
// 组织任务-系统后台任务列表
|
||||
export function getOrganizationScheduleList(data: TableQueryParams) {
|
||||
return MSR.post<CommonList<TaskCenterSystemTaskItem>>({ url: organizationScheduleListUrl, data });
|
||||
@ -89,3 +135,18 @@ export function getOrganizationExecuteTaskList(data: TableQueryParams) {
|
||||
export function getOrganizationExecuteTaskStatistics(data: string[]) {
|
||||
return MSR.post<TaskCenterStatisticsItem[]>({ url: organizationExecuteTaskStatisticsUrl, data });
|
||||
}
|
||||
|
||||
// 组织任务-获取资源池列表
|
||||
export function getOrgTaskCenterResourcePools() {
|
||||
return MSR.get<string[]>({ url: organizationTaskCenterResourcePoolsUrl });
|
||||
}
|
||||
|
||||
// 组织任务-停止任务
|
||||
export function organizationStopTask(id: string) {
|
||||
return MSR.get({ url: `${organizationStopTaskUrl}/${id}` });
|
||||
}
|
||||
|
||||
// 组织任务-删除任务
|
||||
export function organizationDeleteTask(id: string) {
|
||||
return MSR.get({ url: `${organizationDeleteTaskUrl}/${id}` });
|
||||
}
|
||||
|
@ -2,15 +2,24 @@ export const projectScheduleTaskListUrl = '/project/task-center/schedule/page';
|
||||
export const projectExecuteTaskStatisticsUrl = '/project/task-center/exec-task/statistics'; // 项目任务-获取任务统计
|
||||
export const projectExecuteTaskListUrl = '/project/task-center/exec-task/page'; // 项目任务-任务列表
|
||||
export const projectExecuteTaskDetailListUrl = '/project/task-center/exec-task/item/page'; // 项目任务-任务详情列表
|
||||
// 项目-任务中心-定时任务列表
|
||||
export const scheduleProCenterListUrl = '/task/center/project/schedule/page';
|
||||
export const scheduleProCenterListUrl = '/task/center/project/schedule/page'; // 项目-任务中心-定时任务列表
|
||||
export const projectTaskCenterResourcePoolsUrl = '/project/task-center/resource-pool/options'; // 项目-任务中心-获取资源池列表
|
||||
export const projectStopTaskUrl = '/project/task-center/exec-task/stop'; // 项目-任务中心-停止任务
|
||||
export const projectDeleteTaskUrl = '/project/task-center/exec-task/delete'; // 项目-任务中心-删除任务
|
||||
|
||||
export const systemScheduleListUrl = '/system/task-center/schedule/page'; // 系统任务-系统后台任务列表
|
||||
export const systemExecuteTaskListUrl = '/system/task-center/exec-task/page'; // 系统任务-执行任务列表
|
||||
export const systemExecuteTaskDetailListUrl = '/system/task-center/exec-task/item/page'; // 系统任务-执行任务详情列表
|
||||
export const systemExecuteTaskStatisticsUrl = '/system/task-center/exec-task/statistics'; // 系统任务-获取任务统计
|
||||
export const systemTaskCenterResourcePoolsUrl = '/system/task-center/resource-pool/options'; // 系统任务-获取资源池列表
|
||||
export const systemStopTaskUrl = '/system/task-center/exec-task/stop'; // 系统任务-停止任务
|
||||
export const systemDeleteTaskUrl = '/system/task-center/exec-task/delete'; // 系统任务-删除任务
|
||||
export const systemResourcePoolStatusUrl = '/system/task-center/resource-pool/status'; // 系统任务-资源池状态
|
||||
|
||||
export const organizationScheduleListUrl = '/organization/task-center/schedule/page'; // 系统任务-系统后台任务列表
|
||||
export const organizationExecuteTaskListUrl = '/organization/task-center/exec-task/page'; // 系统任务-执行任务列表
|
||||
export const organizationExecuteTaskDetailListUrl = '/organization/task-center/exec-task/item/page'; // 系统任务-执行任务详情列表
|
||||
export const organizationExecuteTaskStatisticsUrl = '/organization/task-center/exec-task/statistics'; // 系统任务-获取任务统计
|
||||
export const organizationScheduleListUrl = '/organization/task-center/schedule/page'; // 组织任务-系统后台任务列表
|
||||
export const organizationExecuteTaskListUrl = '/organization/task-center/exec-task/page'; // 组织任务-执行任务列表
|
||||
export const organizationExecuteTaskDetailListUrl = '/organization/task-center/exec-task/item/page'; // 组织任务-执行任务详情列表
|
||||
export const organizationExecuteTaskStatisticsUrl = '/organization/task-center/exec-task/statistics'; // 组织任务-获取任务统计
|
||||
export const organizationTaskCenterResourcePoolsUrl = '/organization/task-center/resource-pool/options'; // 组织任务-获取资源池列表
|
||||
export const organizationStopTaskUrl = '/organization/task-center/exec-task/stop'; // 组织任务-停止任务
|
||||
export const organizationDeleteTaskUrl = '/organization/task-center/exec-task/delete'; // 组织任务-删除任务
|
||||
|
28
frontend/src/components/business/ms-rich-message/index.vue
Normal file
28
frontend/src/components/business/ms-rich-message/index.vue
Normal file
@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<div class="flex flex-wrap items-center">
|
||||
<div class="mr-[8px]">{{ props.content }}</div>
|
||||
<MsButton v-if="props.showDetail" @click="goDetail">{{ t('common.checkDetail') }}</MsButton>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
content: string;
|
||||
showDetail?: boolean;
|
||||
}>(),
|
||||
{
|
||||
showDetail: true,
|
||||
}
|
||||
);
|
||||
const emit = defineEmits(['goDetail']);
|
||||
const { t } = useI18n();
|
||||
|
||||
function goDetail() {
|
||||
emit('goDetail');
|
||||
}
|
||||
</script>
|
@ -193,9 +193,12 @@
|
||||
import { LOCALE_OPTIONS } from '@/locale';
|
||||
import useLocale from '@/locale/useLocale';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import useGlobalStore from '@/store/modules/global';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import { getFirstRouteNameByPermission, hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import { GlobalEventNameEnum } from '@/enums/commonEnum';
|
||||
|
||||
import { IconInfoCircle } from '@arco-design/web-vue/es/icon';
|
||||
import type { LocaleType } from '#/global';
|
||||
|
||||
@ -208,6 +211,7 @@
|
||||
|
||||
const appStore = useAppStore();
|
||||
const userStore = useUserStore();
|
||||
const globalStore = useGlobalStore();
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const { t } = useI18n();
|
||||
@ -291,6 +295,15 @@
|
||||
function goTaskCenter() {
|
||||
taskCenterVisible.value = true;
|
||||
}
|
||||
watch(
|
||||
() => globalStore.getGlobalEvent,
|
||||
(event) => {
|
||||
if (event && event.id && event.name === GlobalEventNameEnum.OPEN_TASK_CENTER) {
|
||||
goTaskCenter();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
function goMessageCenter() {
|
||||
messageCenterVisible.value = true;
|
||||
}
|
||||
|
@ -40,3 +40,7 @@ export enum TagUpdateTypeEnum {
|
||||
APPEND = 'APPEND',
|
||||
CLEAR = 'CLEAR',
|
||||
}
|
||||
|
||||
export enum GlobalEventNameEnum {
|
||||
OPEN_TASK_CENTER = 'openTaskCenter',
|
||||
}
|
||||
|
@ -33,3 +33,18 @@ export enum ExecuteResultEnum {
|
||||
ERROR = 'ERROR',
|
||||
FAKE_ERROR = 'FAKE_ERROR',
|
||||
}
|
||||
|
||||
export enum ExecuteTriggerMode {
|
||||
MANUAL = 'MANUAL',
|
||||
BATCH = 'BATCH',
|
||||
API = 'API',
|
||||
SCHEDULE = 'SCHEDULE',
|
||||
}
|
||||
|
||||
export enum ExecuteTaskType {
|
||||
API_IMPORT = 'API_IMPORT',
|
||||
API_SCENARIO = 'API_SCENARIO',
|
||||
BUG_SYNC = 'BUG_SYNC',
|
||||
DEMAND_SYNC = 'DEMAND_SYNC',
|
||||
TEST_PLAN = 'TEST_PLAN',
|
||||
}
|
||||
|
@ -216,4 +216,5 @@ export default {
|
||||
'common.currentUser': 'Current user',
|
||||
'common.type': 'Type',
|
||||
'common.batchUpdate': 'Updated to',
|
||||
'common.checkDetail': 'View details',
|
||||
};
|
||||
|
@ -216,4 +216,5 @@ export default {
|
||||
'common.currentUser': '当前用户',
|
||||
'common.type': '类型',
|
||||
'common.batchUpdate': '更新为',
|
||||
'common.checkDetail': '查看详情',
|
||||
};
|
||||
|
@ -1,3 +1,5 @@
|
||||
import type { ExecuteTriggerMode } from '@/enums/taskCenter';
|
||||
|
||||
import type { TableQueryParams } from './common';
|
||||
|
||||
export interface TaskCenterSystemTaskItem {
|
||||
@ -32,7 +34,7 @@ export interface TaskCenterTaskItem {
|
||||
result: string; // 执行结果
|
||||
taskType: string; // 任务类型
|
||||
resourceId: string;
|
||||
triggerMode: string; // 触发方式
|
||||
triggerMode: ExecuteTriggerMode; // 执行方式
|
||||
projectId: string;
|
||||
organizationId: string;
|
||||
createTime: number;
|
||||
@ -42,6 +44,7 @@ export interface TaskCenterTaskItem {
|
||||
organizationName: string; // 所属组织名称
|
||||
projectName: string; // 所属项目名称
|
||||
createUserName: string; // 创建人
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface TaskCenterTaskDetailItem {
|
||||
@ -77,3 +80,8 @@ export interface TaskCenterStatisticsItem {
|
||||
pendingCount: number; // 待执行数
|
||||
caseTotal: number; // 用例总数
|
||||
}
|
||||
|
||||
export interface TaskCenterResourcePoolStatus {
|
||||
id: string;
|
||||
status: boolean; // 状态, true: 正常, false: 异常
|
||||
}
|
||||
|
@ -5,11 +5,12 @@ import useTableStore from '@/hooks/useTableStore';
|
||||
import useAppStore from './modules/app';
|
||||
import useVisitStore from './modules/app/visit';
|
||||
import useMinderStore from './modules/components/minder-editor';
|
||||
import useGlobalStore from './modules/global';
|
||||
import useUserStore from './modules/user';
|
||||
import { debouncePlugin } from './plugins';
|
||||
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
|
||||
|
||||
const pinia = createPinia().use(debouncePlugin).use(piniaPluginPersistedstate);
|
||||
|
||||
export { useAppStore, useMinderStore, useTableStore, useUserStore, useVisitStore };
|
||||
export { useAppStore, useGlobalStore, useMinderStore, useTableStore, useUserStore, useVisitStore };
|
||||
export default pinia;
|
||||
|
@ -12,10 +12,10 @@ export interface AppState {
|
||||
navbar: boolean;
|
||||
menu: boolean;
|
||||
hideMenu: boolean;
|
||||
menuCollapse: boolean;
|
||||
menuCollapse: boolean; // 菜单是否折叠
|
||||
footer: boolean;
|
||||
menuWidth: number;
|
||||
collapsedWidth: number;
|
||||
collapsedWidth: number; // 菜单折叠宽度
|
||||
globalSettings: boolean;
|
||||
device: string;
|
||||
tabBar: boolean;
|
||||
@ -45,7 +45,7 @@ export interface AppState {
|
||||
ordList: { id: string; name: string }[];
|
||||
envList: EnvironmentItem[];
|
||||
currentEnvConfig?: EnvConfig; // 当前环境配置信息
|
||||
fileMaxSize: number;
|
||||
fileMaxSize: number; // 文件上传最大限制
|
||||
}
|
||||
|
||||
export interface UploadFileTaskState {
|
||||
|
20
frontend/src/store/modules/global/index.ts
Normal file
20
frontend/src/store/modules/global/index.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
import type { GlobalState, GlobalStateEvent } from './types';
|
||||
|
||||
const useGlobalStore = defineStore('global', {
|
||||
state: (): GlobalState => ({
|
||||
globalEvent: undefined,
|
||||
}),
|
||||
getters: {
|
||||
getGlobalEvent(state: GlobalState) {
|
||||
return state.globalEvent;
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
dispatchGlobalEvent(event: GlobalStateEvent) {
|
||||
this.globalEvent = event;
|
||||
},
|
||||
},
|
||||
});
|
||||
export default useGlobalStore;
|
11
frontend/src/store/modules/global/types.ts
Normal file
11
frontend/src/store/modules/global/types.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import type { GlobalEventNameEnum } from '@/enums/commonEnum';
|
||||
|
||||
export interface GlobalStateEvent {
|
||||
id: string;
|
||||
name: GlobalEventNameEnum;
|
||||
params?: Record<string, any>;
|
||||
}
|
||||
|
||||
export interface GlobalState {
|
||||
globalEvent?: GlobalStateEvent;
|
||||
}
|
@ -214,7 +214,7 @@
|
||||
:max-length="255"
|
||||
class="w-[550px]"
|
||||
></a-input>
|
||||
<MsButton type="text" @click="taskDrawerVisible = true">
|
||||
<MsButton type="text" @click="emit('openTaskDrawer')">
|
||||
{{ t('apiTestManagement.timeTaskList') }}
|
||||
</MsButton>
|
||||
</div>
|
||||
@ -328,52 +328,20 @@
|
||||
</template>
|
||||
</a-form>
|
||||
</MsDrawer>
|
||||
<MsDrawer v-model:visible="taskDrawerVisible" :width="960" :title="t('apiTestManagement.timeTask')" :footer="false">
|
||||
<div class="mb-[16px] flex items-center justify-end">
|
||||
<a-input-search
|
||||
v-model:model-value="keyword"
|
||||
:placeholder="t('apiTestManagement.searchTaskPlaceholder')"
|
||||
allow-clear
|
||||
class="mr-[8px] w-[240px]"
|
||||
@search="loadTaskList"
|
||||
@press-enter="loadTaskList"
|
||||
@clear="loadTaskList"
|
||||
/>
|
||||
</div>
|
||||
<ms-base-table v-bind="propsRes" no-disable v-on="propsEvent">
|
||||
<template #action="{ record }">
|
||||
<a-switch
|
||||
v-model:modelValue="record.enable"
|
||||
type="line"
|
||||
size="small"
|
||||
:before-change="() => handleBeforeEnableChange(record)"
|
||||
></a-switch>
|
||||
</template>
|
||||
</ms-base-table>
|
||||
</MsDrawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useVModel } from '@vueuse/core';
|
||||
import { FormInstance, Message } from '@arco-design/web-vue';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||
import MsCronSelect from '@/components/pure/ms-cron-select/index.vue';
|
||||
import MsDrawer from '@/components/pure/ms-drawer/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 MsUpload from '@/components/pure/ms-upload/index.vue';
|
||||
import type { MsFileItem } from '@/components/pure/ms-upload/types';
|
||||
|
||||
import {
|
||||
createDefinitionSchedule,
|
||||
importDefinition,
|
||||
switchDefinitionSchedule,
|
||||
} from '@/api/modules/api-test/management';
|
||||
import { getScheduleProApiCaseList } from '@/api/modules/taskCenter';
|
||||
import { createDefinitionSchedule, importDefinition } from '@/api/modules/api-test/management';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
@ -381,16 +349,14 @@
|
||||
|
||||
import type { ImportApiDefinitionParams, ImportApiDefinitionRequest } from '@/models/apiTest/management';
|
||||
import type { ModuleTreeNode } from '@/models/common';
|
||||
import { TimingTaskCenterApiCaseItem } from '@/models/projectManagement/taskCenter';
|
||||
import { RequestImportFormat, RequestImportType } from '@/enums/apiEnum';
|
||||
import { TaskCenterEnum } from '@/enums/taskCenter';
|
||||
|
||||
const props = defineProps<{
|
||||
visible: boolean;
|
||||
moduleTree: ModuleTreeNode[];
|
||||
activeModule: string;
|
||||
}>();
|
||||
const emit = defineEmits(['update:visible', 'done']);
|
||||
const emit = defineEmits(['update:visible', 'done', 'openTaskDrawer']);
|
||||
|
||||
const { t } = useI18n();
|
||||
const appStore = useAppStore();
|
||||
@ -481,7 +447,6 @@
|
||||
|
||||
const cronValue = ref('0 0 0/1 * * ?');
|
||||
const importLoading = ref(false);
|
||||
const taskDrawerVisible = ref(false);
|
||||
|
||||
function setActiveImportFormat(format: RequestImportFormat) {
|
||||
importForm.value.platform = format;
|
||||
@ -583,7 +548,7 @@
|
||||
importType.value = 'time';
|
||||
fileList.value = [];
|
||||
moreSettingActive.value = [];
|
||||
taskDrawerVisible.value = true;
|
||||
emit('openTaskDrawer');
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
@ -604,107 +569,6 @@
|
||||
});
|
||||
}
|
||||
|
||||
const keyword = ref('');
|
||||
const columns: MsTableColumn = [
|
||||
{
|
||||
title: 'project.taskCenter.resourceID',
|
||||
dataIndex: 'resourceNum',
|
||||
slotName: 'resourceNum',
|
||||
width: 140,
|
||||
showInTable: true,
|
||||
showTooltip: true,
|
||||
},
|
||||
{
|
||||
title: 'project.taskCenter.resourceName',
|
||||
slotName: 'resourceName',
|
||||
dataIndex: 'resourceName',
|
||||
width: 200,
|
||||
showDrag: true,
|
||||
showTooltip: true,
|
||||
},
|
||||
{
|
||||
title: 'project.taskCenter.swaggerUrl',
|
||||
slotName: 'swaggerUrl',
|
||||
dataIndex: 'swaggerUrl',
|
||||
width: 300,
|
||||
showDrag: false,
|
||||
showTooltip: true,
|
||||
columnSelectorDisabled: true,
|
||||
showInTable: true,
|
||||
},
|
||||
{
|
||||
title: 'apiTestManagement.taskRunRule',
|
||||
dataIndex: 'value',
|
||||
width: 140,
|
||||
},
|
||||
{
|
||||
title: 'apiTestManagement.taskNextRunTime',
|
||||
dataIndex: 'nextTime',
|
||||
showTooltip: true,
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: 'apiTestManagement.taskOperator',
|
||||
dataIndex: 'createUserName',
|
||||
showTooltip: true,
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: 'apiTestManagement.taskOperationTime',
|
||||
dataIndex: 'createTime',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: 'common.operation',
|
||||
slotName: 'action',
|
||||
dataIndex: 'operation',
|
||||
fixed: 'right',
|
||||
width: 80,
|
||||
},
|
||||
];
|
||||
const { propsRes, propsEvent, loadList, setLoadListParams } = useTable(
|
||||
getScheduleProApiCaseList,
|
||||
{
|
||||
columns,
|
||||
scroll: { x: '100%' },
|
||||
},
|
||||
(item) => ({
|
||||
...item,
|
||||
operationTime: dayjs(item.operationTime).format('YYYY-MM-DD HH:mm:ss'),
|
||||
nextTime: item.nextTime ? dayjs(item.nextTime).format('YYYY-MM-DD HH:mm:ss') : '-',
|
||||
})
|
||||
);
|
||||
function loadTaskList() {
|
||||
setLoadListParams({
|
||||
keyword: keyword.value,
|
||||
moduleType: TaskCenterEnum.API_IMPORT,
|
||||
});
|
||||
loadList();
|
||||
}
|
||||
|
||||
watch(
|
||||
() => taskDrawerVisible.value,
|
||||
(value) => {
|
||||
if (value) {
|
||||
loadTaskList();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
async function handleBeforeEnableChange(record: TimingTaskCenterApiCaseItem) {
|
||||
try {
|
||||
await switchDefinitionSchedule(record.id);
|
||||
Message.success(
|
||||
t(record.enable ? 'apiTestManagement.disableTaskSuccess' : 'apiTestManagement.enableTaskSuccess')
|
||||
);
|
||||
return true;
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function openLink() {
|
||||
window.open('https://converter.swagger.io/', '_blank');
|
||||
}
|
||||
|
@ -0,0 +1,165 @@
|
||||
<template>
|
||||
<MsDrawer v-model:visible="taskDrawerVisible" :width="960" :title="t('apiTestManagement.timeTask')" :footer="false">
|
||||
<div class="mb-[16px] flex items-center justify-end">
|
||||
<a-input-search
|
||||
v-model:model-value="keyword"
|
||||
:placeholder="t('apiTestManagement.searchTaskPlaceholder')"
|
||||
allow-clear
|
||||
class="mr-[8px] w-[240px]"
|
||||
@search="loadTaskList"
|
||||
@press-enter="loadTaskList"
|
||||
@clear="loadTaskList"
|
||||
/>
|
||||
</div>
|
||||
<ms-base-table v-bind="propsRes" no-disable v-on="propsEvent">
|
||||
<template #action="{ record }">
|
||||
<div class="flex items-center gap-[12px]">
|
||||
<a-switch
|
||||
v-model:modelValue="record.enable"
|
||||
type="line"
|
||||
size="small"
|
||||
:before-change="() => handleBeforeEnableChange(record)"
|
||||
></a-switch>
|
||||
<MsButton @click="deleteTask(record)">
|
||||
{{ t('common.delete') }}
|
||||
</MsButton>
|
||||
</div>
|
||||
</template>
|
||||
</ms-base-table>
|
||||
</MsDrawer>
|
||||
</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 MsDrawer from '@/components/pure/ms-drawer/index.vue';
|
||||
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
||||
import { MsTableColumn } from '@/components/pure/ms-table/type';
|
||||
import useTable from '@/components/pure/ms-table/useTable';
|
||||
|
||||
import { switchDefinitionSchedule } from '@/api/modules/api-test/management';
|
||||
import { getScheduleProApiCaseList } from '@/api/modules/taskCenter';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
|
||||
import { TimingTaskCenterApiCaseItem } from '@/models/projectManagement/taskCenter';
|
||||
import { TaskCenterEnum } from '@/enums/taskCenter';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const taskDrawerVisible = defineModel<boolean>('visible', { required: true });
|
||||
const keyword = ref('');
|
||||
const columns: MsTableColumn = [
|
||||
{
|
||||
title: 'apiTestManagement.resourceID',
|
||||
dataIndex: 'resourceNum',
|
||||
slotName: 'resourceNum',
|
||||
width: 140,
|
||||
showInTable: true,
|
||||
showTooltip: true,
|
||||
},
|
||||
{
|
||||
title: 'apiTestManagement.resourceName',
|
||||
slotName: 'resourceName',
|
||||
dataIndex: 'resourceName',
|
||||
width: 200,
|
||||
showDrag: true,
|
||||
showTooltip: true,
|
||||
},
|
||||
{
|
||||
title: 'apiTestManagement.swaggerUrl',
|
||||
slotName: 'swaggerUrl',
|
||||
dataIndex: 'swaggerUrl',
|
||||
width: 300,
|
||||
showDrag: false,
|
||||
showTooltip: true,
|
||||
columnSelectorDisabled: true,
|
||||
showInTable: true,
|
||||
},
|
||||
{
|
||||
title: 'apiTestManagement.taskRunRule',
|
||||
dataIndex: 'value',
|
||||
width: 140,
|
||||
},
|
||||
{
|
||||
title: 'apiTestManagement.taskNextRunTime',
|
||||
dataIndex: 'nextTime',
|
||||
showTooltip: true,
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: 'apiTestManagement.taskOperator',
|
||||
dataIndex: 'createUserName',
|
||||
showTooltip: true,
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: 'apiTestManagement.taskOperationTime',
|
||||
dataIndex: 'createTime',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: 'common.operation',
|
||||
slotName: 'action',
|
||||
dataIndex: 'operation',
|
||||
fixed: 'right',
|
||||
width: 110,
|
||||
},
|
||||
];
|
||||
const { propsRes, propsEvent, loadList, setLoadListParams } = useTable(
|
||||
getScheduleProApiCaseList,
|
||||
{
|
||||
columns,
|
||||
scroll: { x: '100%' },
|
||||
},
|
||||
(item) => ({
|
||||
...item,
|
||||
operationTime: dayjs(item.operationTime).format('YYYY-MM-DD HH:mm:ss'),
|
||||
nextTime: item.nextTime ? dayjs(item.nextTime).format('YYYY-MM-DD HH:mm:ss') : '-',
|
||||
})
|
||||
);
|
||||
function loadTaskList() {
|
||||
setLoadListParams({
|
||||
keyword: keyword.value,
|
||||
moduleType: TaskCenterEnum.API_IMPORT,
|
||||
});
|
||||
loadList();
|
||||
}
|
||||
|
||||
watch(
|
||||
() => taskDrawerVisible.value,
|
||||
(value) => {
|
||||
if (value) {
|
||||
loadTaskList();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
async function handleBeforeEnableChange(record: TimingTaskCenterApiCaseItem) {
|
||||
try {
|
||||
await switchDefinitionSchedule(record.id);
|
||||
Message.success(
|
||||
t(record.enable ? 'apiTestManagement.disableTaskSuccess' : 'apiTestManagement.enableTaskSuccess')
|
||||
);
|
||||
return true;
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteTask(record: TimingTaskCenterApiCaseItem) {
|
||||
try {
|
||||
// await switchDefinitionSchedule(record.id);
|
||||
Message.success(t('common.deleteSuccess'));
|
||||
loadTaskList();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
@ -47,6 +47,7 @@
|
||||
:active-module="activeModule"
|
||||
popup-container="#managementContainer"
|
||||
@done="handleImportDone"
|
||||
@open-task-drawer="taskDrawerVisible = true"
|
||||
/>
|
||||
</div>
|
||||
<management
|
||||
@ -116,6 +117,7 @@
|
||||
is-share
|
||||
/>
|
||||
</MsCard>
|
||||
<importTaskDrawer v-model:visible="taskDrawerVisible" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
@ -131,6 +133,7 @@
|
||||
import type { BatchActionQueryParams } from '@/components/pure/ms-table/type';
|
||||
import { RequestParam } from '../components/requestComposition/index.vue';
|
||||
import importApi from './components/import.vue';
|
||||
import importTaskDrawer from './components/importTaskDrawer.vue';
|
||||
import management from './components/management/index.vue';
|
||||
import moduleTree from './components/moduleTree.vue';
|
||||
import ApiExportModal from '@/views/api-test/management/components/management/api/apiExportModal.vue';
|
||||
@ -423,10 +426,14 @@
|
||||
});
|
||||
}
|
||||
|
||||
const taskDrawerVisible = ref(false);
|
||||
onBeforeMount(() => {
|
||||
if (docShareId.value) {
|
||||
getShareDetail();
|
||||
}
|
||||
if (route.query.taskDrawer) {
|
||||
taskDrawerVisible.value = true;
|
||||
}
|
||||
});
|
||||
|
||||
/** 向子孙组件提供方法和值 */
|
||||
|
@ -196,6 +196,8 @@ export default {
|
||||
'Delete, share a link can lead to user access is to access the link is unusual, please careful operation',
|
||||
'apiTestManagement.passwordView': 'Password',
|
||||
'apiTestManagement.publicityView': 'Public',
|
||||
'apiTestManagement.resourceID': 'Resource ID',
|
||||
'apiTestManagement.swaggerUrl': 'Swagger URL',
|
||||
'case.execute.selectEnv': 'Select Environment',
|
||||
'case.execute.defaultEnv': 'Default Environment',
|
||||
'case.execute.newEnv': 'New Environment',
|
||||
|
@ -188,6 +188,8 @@ export default {
|
||||
'apiTestManagement.deleteShareTip': '删除后,分享链接会导致正在访问该链接的用户访问异常,请谨慎操作!',
|
||||
'apiTestManagement.passwordView': '密码',
|
||||
'apiTestManagement.publicityView': '公开',
|
||||
'apiTestManagement.resourceID': '资源 ID',
|
||||
'apiTestManagement.swaggerUrl': 'Swagger URL',
|
||||
'case.execute.selectEnv': '环境选择',
|
||||
'case.execute.defaultEnv': '默认环境',
|
||||
'case.execute.newEnv': '新环境',
|
||||
|
@ -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');
|
||||
|
@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<MsDrawer v-model:visible="visible" :title="title" :width="800" :footer="false">
|
||||
<ms-base-table v-bind="propsRes" ref="tableRef" v-on="propsEvent" @filter-change="filterChange">
|
||||
<template #name="{ record, rowIndex }">
|
||||
<a-button type="text" class="max-w-full justify-start px-0" @click="showReportDetail(record.id, rowIndex)">
|
||||
<template #name="{ record }">
|
||||
<a-button type="text" class="max-w-full justify-start px-0" @click="showReportDetail(record)">
|
||||
<div class="one-line-text">
|
||||
{{ record.num }}
|
||||
</div>
|
||||
@ -43,6 +43,7 @@
|
||||
</template>
|
||||
</ms-base-table>
|
||||
</MsDrawer>
|
||||
<ReportDrawer v-model:visible="reportVisible" :report-id="independentReportId" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -55,6 +56,7 @@
|
||||
import MsTag from '@/components/pure/ms-tag/ms-tag.vue';
|
||||
import ExecutionStatus from '@/views/api-test/report/component/reportStatus.vue';
|
||||
import ExecStatus from '@/views/test-plan/report/component/execStatus.vue';
|
||||
import ReportDrawer from '@/views/test-plan/testPlan/detail/reportDrawer.vue';
|
||||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useTableStore from '@/hooks/useTableStore';
|
||||
@ -224,8 +226,12 @@
|
||||
initData(dataIndex, value);
|
||||
}
|
||||
|
||||
function showReportDetail(id: string, rowIndex: number) {
|
||||
console.log(id, rowIndex);
|
||||
const reportVisible = ref(false);
|
||||
const independentReportId = ref<string>('');
|
||||
|
||||
function showReportDetail(record: any) {
|
||||
independentReportId.value = record.id;
|
||||
reportVisible.value = true;
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -49,8 +49,8 @@
|
||||
</template>
|
||||
<template #resourcePoolNode="{ record }">
|
||||
<div>{{ record.resourcePoolNode }}</div>
|
||||
<a-tooltip :content="t('ms.taskCenter.nodeErrorTip')">
|
||||
<icon-exclamation-circle-fill class="!text-[rgb(var(--warning-6))]" :size="18" />
|
||||
<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" />
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template #action="{ record }">
|
||||
@ -85,7 +85,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { CascaderOption, Message } from '@arco-design/web-vue';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||
@ -102,8 +102,12 @@
|
||||
|
||||
import {
|
||||
getOrganizationExecuteTaskDetailList,
|
||||
getOrgTaskCenterResourcePools,
|
||||
getProjectExecuteTaskDetailList,
|
||||
getProjectTaskCenterResourcePools,
|
||||
getResourcePoolsStatus,
|
||||
getSystemExecuteTaskDetailList,
|
||||
getSystemTaskCenterResourcePools,
|
||||
} from '@/api/modules/taskCenter';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useModal from '@/hooks/useModal';
|
||||
@ -111,6 +115,7 @@
|
||||
import { characterLimit } from '@/utils';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import { TaskCenterTaskDetailItem } from '@/models/taskCenter';
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
import { FilterSlotNameEnum } from '@/enums/tableFilterEnum';
|
||||
import { ExecuteResultEnum, ExecuteStatusEnum } from '@/enums/taskCenter';
|
||||
@ -128,7 +133,7 @@
|
||||
|
||||
const keyword = ref('');
|
||||
const resourcePool = ref([]);
|
||||
const resourcePoolOptions = ref([]);
|
||||
const resourcePoolOptions = ref<CascaderOption[]>([]);
|
||||
const tableSelected = ref<string[]>([]);
|
||||
const batchModalParams = ref();
|
||||
|
||||
@ -164,6 +169,7 @@
|
||||
{
|
||||
title: 'ms.taskCenter.executeMethod',
|
||||
dataIndex: 'triggerMode',
|
||||
slotName: 'triggerMode',
|
||||
width: 100,
|
||||
filterConfig: {
|
||||
options: Object.keys(executeMethodMap).map((key) => ({
|
||||
@ -197,7 +203,7 @@
|
||||
title: 'ms.taskCenter.node',
|
||||
dataIndex: 'resourcePoolNode',
|
||||
slotName: 'resourcePoolNode',
|
||||
width: 100,
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: 'ms.taskCenter.queue',
|
||||
@ -207,7 +213,8 @@
|
||||
{
|
||||
title: 'ms.taskCenter.threadID',
|
||||
dataIndex: 'threadId',
|
||||
width: 100,
|
||||
showTooltip: true,
|
||||
width: 190,
|
||||
},
|
||||
{
|
||||
title: 'ms.taskCenter.startExecuteTime',
|
||||
@ -229,7 +236,7 @@
|
||||
},
|
||||
{
|
||||
title: 'ms.taskCenter.operationUser',
|
||||
dataIndex: 'executor',
|
||||
dataIndex: 'userName',
|
||||
width: 100,
|
||||
showTooltip: true,
|
||||
},
|
||||
@ -305,8 +312,8 @@
|
||||
return {
|
||||
...item,
|
||||
resourcePoolName: [item.resourcePoolName],
|
||||
startExecuteTime: dayjs(item.startExecuteTime).format('YYYY-MM-DD HH:mm:ss'),
|
||||
endExecuteTime: dayjs(item.endExecuteTime).format('YYYY-MM-DD HH:mm:ss'),
|
||||
startExecuteTime: item.startExecuteTime ? dayjs(item.startExecuteTime).format('YYYY-MM-DD HH:mm:ss') : '-',
|
||||
endExecuteTime: item.endExecuteTime ? dayjs(item.endExecuteTime).format('YYYY-MM-DD HH:mm:ss') : '-',
|
||||
};
|
||||
}
|
||||
);
|
||||
@ -319,7 +326,7 @@
|
||||
/**
|
||||
* 删除任务
|
||||
*/
|
||||
function deleteTask(record?: any, isBatch?: boolean, params?: BatchActionQueryParams) {
|
||||
function deleteTask(record?: TaskCenterTaskDetailItem, isBatch?: boolean, params?: BatchActionQueryParams) {
|
||||
let title = t('ms.taskCenter.deleteTaskTitle', { name: characterLimit(record?.taskName) });
|
||||
let selectIds = [record?.id || ''];
|
||||
if (isBatch) {
|
||||
@ -358,7 +365,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
function stopTask(record?: any, isBatch?: boolean, params?: BatchActionQueryParams) {
|
||||
function stopTask(record?: TaskCenterTaskDetailItem, isBatch?: boolean, params?: BatchActionQueryParams) {
|
||||
let title = t('ms.taskCenter.stopTaskTitle', { name: characterLimit(record?.taskName) });
|
||||
let selectIds = [record?.id || ''];
|
||||
if (isBatch) {
|
||||
@ -415,23 +422,67 @@
|
||||
}
|
||||
}
|
||||
|
||||
function rerunTask(record: any) {
|
||||
function rerunTask(record: TaskCenterTaskDetailItem) {
|
||||
console.log('rerunTask', record);
|
||||
}
|
||||
|
||||
const executeResultId = ref('');
|
||||
const caseExecuteResultDrawerVisible = ref(false);
|
||||
const scenarioExecuteResultDrawerVisible = ref(false);
|
||||
function checkExecuteResult(record: any) {
|
||||
function checkExecuteResult(record: TaskCenterTaskDetailItem) {
|
||||
executeResultId.value = record.id;
|
||||
scenarioExecuteResultDrawerVisible.value = true;
|
||||
if (record.resourceType === 'API_SCENARIO') {
|
||||
scenarioExecuteResultDrawerVisible.value = true;
|
||||
} else {
|
||||
caseExecuteResultDrawerVisible.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
const currentResourcePoolRequest = {
|
||||
system: getProjectTaskCenterResourcePools,
|
||||
project: getOrgTaskCenterResourcePools,
|
||||
org: getSystemTaskCenterResourcePools,
|
||||
}[props.type];
|
||||
|
||||
async function initResourcePools() {
|
||||
try {
|
||||
const res = await currentResourcePoolRequest();
|
||||
resourcePoolOptions.value = res.map((item) => ({
|
||||
key: item,
|
||||
value: item,
|
||||
}));
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
async function initCurrentPageResourcePoolsStatus() {
|
||||
const ids = propsRes.value.data.map((item) => item.id);
|
||||
if (ids.length === 0) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const res = await getResourcePoolsStatus(ids);
|
||||
res.forEach((item) => {
|
||||
const target = propsRes.value.data.find((task) => task.id === item.id);
|
||||
if (target) {
|
||||
target.resourcePoolNodeStatus = item.status;
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
if (props.id) {
|
||||
keyword.value = props.id;
|
||||
}
|
||||
searchTask();
|
||||
initResourcePools();
|
||||
await loadList();
|
||||
initCurrentPageResourcePoolsStatus();
|
||||
});
|
||||
|
||||
await tableStore.initColumn(TableKeyEnum.TASK_CENTER_CASE_TASK_DETAIL, columns, 'drawer');
|
||||
|
@ -44,10 +44,16 @@
|
||||
{{ t(executeMethodMap[record.triggerMode]) }}
|
||||
</template>
|
||||
<template #executeRate="{ record }">
|
||||
<a-popover trigger="hover" position="bottom">
|
||||
<div>{{ record.executeRate }}%</div>
|
||||
<a-popover
|
||||
v-model:popup-visible="record.executeRatePopVisible"
|
||||
trigger="hover"
|
||||
position="bottom"
|
||||
:disabled="record.caseTotal === 0 || record.status === ExecuteStatusEnum.PENDING"
|
||||
@popup-visible-change="($event) => handleExecuteRatePopVisibleChange($event, record)"
|
||||
>
|
||||
<div>{{ record.executeRate || '0.00' }}%</div>
|
||||
<template #content>
|
||||
<div class="flex w-[130px] flex-col gap-[8px]">
|
||||
<a-spin :loading="record.loading" class="flex w-[130px] flex-col gap-[8px]">
|
||||
<div class="ms-taskCenter-execute-rate-item">
|
||||
<div class="ms-taskCenter-execute-rate-item-label">
|
||||
{{ t('ms.taskCenter.executeFinishedRate') }}
|
||||
@ -92,7 +98,7 @@
|
||||
</div>
|
||||
<div class="ms-taskCenter-execute-rate-item-value">{{ record.errorCount }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-spin>
|
||||
</template>
|
||||
</a-popover>
|
||||
</template>
|
||||
@ -123,6 +129,7 @@
|
||||
</MsButton>
|
||||
</template>
|
||||
</ms-base-table>
|
||||
<batchTaskReportDrawer v-model:visible="taskReportDrawerVisible" type="case" :module-type="reportModuleType" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -135,6 +142,7 @@
|
||||
import type { BatchActionParams, BatchActionQueryParams, MsTableColumn } from '@/components/pure/ms-table/type';
|
||||
import useTable from '@/components/pure/ms-table/useTable';
|
||||
import MsTag from '@/components/pure/ms-tag/ms-tag.vue';
|
||||
import batchTaskReportDrawer from './batchTaskReportDrawer.vue';
|
||||
import execStatus from './execStatus.vue';
|
||||
import executionStatus from './executionStatus.vue';
|
||||
|
||||
@ -145,16 +153,26 @@
|
||||
getProjectExecuteTaskStatistics,
|
||||
getSystemExecuteTaskList,
|
||||
getSystemExecuteTaskStatistics,
|
||||
organizationDeleteTask,
|
||||
organizationStopTask,
|
||||
projectDeleteTask,
|
||||
projectStopTask,
|
||||
systemDeleteTask,
|
||||
systemStopTask,
|
||||
} from '@/api/modules/taskCenter';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import useOpenNewPage from '@/hooks/useOpenNewPage';
|
||||
import useTableStore from '@/hooks/useTableStore';
|
||||
import { characterLimit } from '@/utils';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import { TaskCenterTaskItem } from '@/models/taskCenter';
|
||||
import { ReportEnum } from '@/enums/reportEnum';
|
||||
import { ApiTestRouteEnum, TestPlanRouteEnum } from '@/enums/routeEnum';
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
import { FilterSlotNameEnum } from '@/enums/tableFilterEnum';
|
||||
import { ExecuteResultEnum, ExecuteStatusEnum } from '@/enums/taskCenter';
|
||||
import { ExecuteResultEnum, ExecuteStatusEnum, ExecuteTaskType, ExecuteTriggerMode } from '@/enums/taskCenter';
|
||||
|
||||
import { executeFinishedRateMap, executeMethodMap, executeResultMap, executeStatusMap } from './config';
|
||||
|
||||
@ -167,6 +185,7 @@
|
||||
|
||||
const { t } = useI18n();
|
||||
const { openModal } = useModal();
|
||||
const { openNewPage } = useOpenNewPage();
|
||||
const tableStore = useTableStore();
|
||||
|
||||
const keyword = ref('');
|
||||
@ -268,7 +287,7 @@
|
||||
},
|
||||
{
|
||||
title: 'ms.taskCenter.operationUser',
|
||||
dataIndex: 'createUser',
|
||||
dataIndex: 'createUserName',
|
||||
width: 100,
|
||||
showTooltip: true,
|
||||
},
|
||||
@ -319,6 +338,18 @@
|
||||
org: getOrganizationExecuteTaskStatistics,
|
||||
}[props.type];
|
||||
|
||||
const currentStopTask = {
|
||||
system: projectStopTask,
|
||||
project: organizationStopTask,
|
||||
org: systemStopTask,
|
||||
}[props.type];
|
||||
|
||||
const currentDeleteTask = {
|
||||
system: projectDeleteTask,
|
||||
project: organizationDeleteTask,
|
||||
org: systemDeleteTask,
|
||||
}[props.type];
|
||||
|
||||
const tableBatchActions = {
|
||||
baseAction: [
|
||||
{
|
||||
@ -347,9 +378,11 @@
|
||||
(item) => {
|
||||
return {
|
||||
...item,
|
||||
startTime: dayjs(item.startTime).format('YYYY-MM-DD HH:mm:ss'),
|
||||
createTime: dayjs(item.createTime).format('YYYY-MM-DD HH:mm:ss'),
|
||||
endTime: dayjs(item.endTime).format('YYYY-MM-DD HH:mm:ss'),
|
||||
loading: false,
|
||||
executeRatePopVisible: false,
|
||||
startTime: item.startTime ? dayjs(item.startTime).format('YYYY-MM-DD HH:mm:ss') : '-',
|
||||
createTime: item.createTime ? dayjs(item.createTime).format('YYYY-MM-DD HH:mm:ss') : '-',
|
||||
endTime: item.endTime ? dayjs(item.endTime).format('YYYY-MM-DD HH:mm:ss') : '-',
|
||||
};
|
||||
}
|
||||
);
|
||||
@ -359,115 +392,6 @@
|
||||
loadList();
|
||||
}
|
||||
|
||||
function showTaskDetail(id: string) {
|
||||
emit('goDetail', id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除任务
|
||||
*/
|
||||
function deleteTask(record?: any, isBatch?: boolean, params?: BatchActionQueryParams) {
|
||||
let title = t('ms.taskCenter.deleteTaskTitle', { name: characterLimit(record?.taskName) });
|
||||
let selectIds = [record?.id || ''];
|
||||
if (isBatch) {
|
||||
title = t('ms.taskCenter.deleteCaseTaskTitle', {
|
||||
count: params?.currentSelectCount || tableSelected.value.length,
|
||||
});
|
||||
selectIds = tableSelected.value as string[];
|
||||
}
|
||||
openModal({
|
||||
type: 'error',
|
||||
title,
|
||||
content: t('ms.taskCenter.deleteCaseTaskTip'),
|
||||
okText: t('common.confirmDelete'),
|
||||
cancelText: t('common.cancel'),
|
||||
okButtonProps: {
|
||||
status: 'danger',
|
||||
},
|
||||
maskClosable: false,
|
||||
onBeforeOk: async () => {
|
||||
try {
|
||||
// await deleteUserInfo({
|
||||
// selectIds,
|
||||
// selectAll: !!params?.selectAll,
|
||||
// excludeIds: params?.excludeIds || [],
|
||||
// condition: { keyword: keyword.value },
|
||||
// });
|
||||
Message.success(t('common.deleteSuccess'));
|
||||
resetSelector();
|
||||
loadList();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
hideCancel: false,
|
||||
});
|
||||
}
|
||||
|
||||
function stopTask(record?: any, isBatch?: boolean, params?: BatchActionQueryParams) {
|
||||
let title = t('ms.taskCenter.stopTaskTitle', { name: characterLimit(record?.taskName) });
|
||||
let selectIds = [record?.id || ''];
|
||||
if (isBatch) {
|
||||
title = t('ms.taskCenter.batchStopTaskTitle', {
|
||||
count: params?.currentSelectCount || tableSelected.value.length,
|
||||
});
|
||||
selectIds = tableSelected.value as string[];
|
||||
}
|
||||
openModal({
|
||||
type: 'warning',
|
||||
title,
|
||||
content: t('ms.taskCenter.stopTimeTaskTip'),
|
||||
okText: t('common.stopConfirm'),
|
||||
cancelText: t('common.cancel'),
|
||||
maskClosable: false,
|
||||
onBeforeOk: async () => {
|
||||
try {
|
||||
// await deleteUserInfo({
|
||||
// selectIds,
|
||||
// selectAll: !!params?.selectAll,
|
||||
// excludeIds: params?.excludeIds || [],
|
||||
// condition: { keyword: keyword.value },
|
||||
// });
|
||||
Message.success(t('common.stopped'));
|
||||
resetSelector();
|
||||
loadList();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
hideCancel: false,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理表格选中后批量操作
|
||||
* @param event 批量操作事件对象
|
||||
*/
|
||||
function handleTableBatch(event: BatchActionParams, params: BatchActionQueryParams) {
|
||||
tableSelected.value = params.selectedIds || [];
|
||||
batchModalParams.value = params;
|
||||
switch (event.eventTag) {
|
||||
case 'delete':
|
||||
deleteTask(undefined, true, params);
|
||||
break;
|
||||
case 'stop':
|
||||
stopTask(undefined, true, params);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function rerunTask(record: any) {
|
||||
console.log('rerunTask', record);
|
||||
}
|
||||
|
||||
function checkReport(record: any) {
|
||||
console.log('checkReport', record);
|
||||
}
|
||||
|
||||
async function initTaskStatistics() {
|
||||
try {
|
||||
const ids = propsRes.value.data.map((item) => item.id);
|
||||
@ -496,8 +420,156 @@
|
||||
initTaskStatistics();
|
||||
}
|
||||
|
||||
async function handleExecuteRatePopVisibleChange(visible: boolean, record: TaskCenterTaskItem) {
|
||||
if (visible) {
|
||||
try {
|
||||
record.loading = true;
|
||||
const res = await currentExecuteTaskStatistics([record.id]);
|
||||
record.executeRate = res[0].executeRate;
|
||||
record.pendingCount = res[0].pendingCount;
|
||||
record.successCount = res[0].successCount;
|
||||
record.fakeErrorCount = res[0].fakeErrorCount;
|
||||
record.errorCount = res[0].errorCount;
|
||||
record.caseTotal = res[0].caseTotal;
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
} finally {
|
||||
record.loading = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function showTaskDetail(id: string) {
|
||||
emit('goDetail', id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除任务
|
||||
*/
|
||||
function deleteTask(record?: TaskCenterTaskItem, isBatch?: boolean, params?: BatchActionQueryParams) {
|
||||
let title = t('ms.taskCenter.deleteTaskTitle', { name: characterLimit(record?.taskName) });
|
||||
let selectIds = [record?.id || ''];
|
||||
if (isBatch) {
|
||||
title = t('ms.taskCenter.deleteCaseTaskTitle', {
|
||||
count: params?.currentSelectCount || tableSelected.value.length,
|
||||
});
|
||||
selectIds = tableSelected.value as string[];
|
||||
}
|
||||
openModal({
|
||||
type: 'error',
|
||||
title,
|
||||
content: t('ms.taskCenter.deleteCaseTaskTip'),
|
||||
okText: t('common.confirmDelete'),
|
||||
cancelText: t('common.cancel'),
|
||||
okButtonProps: {
|
||||
status: 'danger',
|
||||
},
|
||||
maskClosable: false,
|
||||
onBeforeOk: async () => {
|
||||
try {
|
||||
if (isBatch) {
|
||||
// await deleteUserInfo({
|
||||
// selectIds,
|
||||
// selectAll: !!params?.selectAll,
|
||||
// excludeIds: params?.excludeIds || [],
|
||||
// condition: { keyword: keyword.value },
|
||||
// });
|
||||
} else {
|
||||
await currentDeleteTask(record?.id || '');
|
||||
}
|
||||
Message.success(t('common.deleteSuccess'));
|
||||
resetSelector();
|
||||
refresh();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
hideCancel: false,
|
||||
});
|
||||
}
|
||||
|
||||
function stopTask(record?: TaskCenterTaskItem, isBatch?: boolean, params?: BatchActionQueryParams) {
|
||||
let title = t('ms.taskCenter.stopTaskTitle', { name: characterLimit(record?.taskName) });
|
||||
let selectIds = [record?.id || ''];
|
||||
if (isBatch) {
|
||||
title = t('ms.taskCenter.batchStopTaskTitle', {
|
||||
count: params?.currentSelectCount || tableSelected.value.length,
|
||||
});
|
||||
selectIds = tableSelected.value as string[];
|
||||
}
|
||||
openModal({
|
||||
type: 'warning',
|
||||
title,
|
||||
content: t('ms.taskCenter.stopTimeTaskTip'),
|
||||
okText: t('common.stopConfirm'),
|
||||
cancelText: t('common.cancel'),
|
||||
maskClosable: false,
|
||||
onBeforeOk: async () => {
|
||||
try {
|
||||
if (isBatch) {
|
||||
// await deleteUserInfo({
|
||||
// selectIds,
|
||||
// selectAll: !!params?.selectAll,
|
||||
// excludeIds: params?.excludeIds || [],
|
||||
// condition: { keyword: keyword.value },
|
||||
// });
|
||||
} else {
|
||||
await currentStopTask(record?.id || '');
|
||||
}
|
||||
Message.success(t('common.stopped'));
|
||||
resetSelector();
|
||||
refresh();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
hideCancel: false,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理表格选中后批量操作
|
||||
* @param event 批量操作事件对象
|
||||
*/
|
||||
function handleTableBatch(event: BatchActionParams, params: BatchActionQueryParams) {
|
||||
tableSelected.value = params.selectedIds || [];
|
||||
batchModalParams.value = params;
|
||||
switch (event.eventTag) {
|
||||
case 'delete':
|
||||
deleteTask(undefined, true, params);
|
||||
break;
|
||||
case 'stop':
|
||||
stopTask(undefined, true, params);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function rerunTask(record: TaskCenterTaskItem) {
|
||||
console.log('rerunTask', record);
|
||||
}
|
||||
|
||||
const taskReportDrawerVisible = ref(false);
|
||||
const reportModuleType = ref();
|
||||
function checkReport(record: TaskCenterTaskItem) {
|
||||
if (record.taskType.includes('BATCH')) {
|
||||
reportModuleType.value = record.taskType.includes('CASE')
|
||||
? ReportEnum.API_REPORT
|
||||
: ReportEnum.API_SCENARIO_REPORT;
|
||||
taskReportDrawerVisible.value = true;
|
||||
} else if (record.taskType === ExecuteTaskType.API_SCENARIO) {
|
||||
openNewPage(ApiTestRouteEnum.API_TEST_REPORT);
|
||||
} else if (record.taskType === ExecuteTaskType.TEST_PLAN) {
|
||||
openNewPage(TestPlanRouteEnum.TEST_PLAN_REPORT);
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
loadList();
|
||||
searchTask();
|
||||
});
|
||||
|
||||
watch(
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="flex items-center justify-start">
|
||||
<MsIcon :type="getExecutionResult()?.icon" :class="`text-[${getExecutionResult()?.color}]`" size="14" />
|
||||
<span class="ml-1">{{ t(getExecutionResult()?.label) }}</span>
|
||||
<span class="ml-1">{{ t(getExecutionResult()?.label || '-') }}</span>
|
||||
<!-- <a-tooltip v-if="props.scriptIdentifier" :content="getMsg()">
|
||||
<MsTag
|
||||
class="ml-2"
|
||||
|
@ -30,15 +30,22 @@
|
||||
</a-button>
|
||||
</template>
|
||||
<template #status="{ record }">
|
||||
<a-switch v-model:model-value="record.enable" size="small"></a-switch>
|
||||
<a-switch
|
||||
v-model:model-value="record.enable"
|
||||
size="small"
|
||||
:before-change="() => handleBeforeEnableChange(record)"
|
||||
></a-switch>
|
||||
</template>
|
||||
<template #resourceType="{ record }">
|
||||
{{ t(scheduleTaskTypeMap[record.resourceType]) }}
|
||||
</template>
|
||||
<template #action="{ record }">
|
||||
<MsButton v-permission="['SYSTEM_USER:READ+DELETE']" @click="deleteTask(record)">
|
||||
<MsButton v-permission="['SYSTEM_USER:READ+DELETE']" class="!mr-[12px]" @click="deleteTask(record)">
|
||||
{{ t('common.delete') }}
|
||||
</MsButton>
|
||||
<MsButton v-permission="['SYSTEM_USER:READ+DELETE']" class="!mr-0" @click="checkDetail(record)">
|
||||
{{ t('common.detail') }}
|
||||
</MsButton>
|
||||
</template>
|
||||
</ms-base-table>
|
||||
</template>
|
||||
@ -57,10 +64,12 @@
|
||||
import { getOrganizationScheduleList, getProjectScheduleList, getSystemScheduleList } from '@/api/modules/taskCenter';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import useOpenNewPage from '@/hooks/useOpenNewPage';
|
||||
import useTableStore from '@/hooks/useTableStore';
|
||||
import { characterLimit } from '@/utils';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import { ApiTestRouteEnum } from '@/enums/routeEnum';
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
|
||||
import { scheduleTaskTypeMap } from './config';
|
||||
@ -71,6 +80,7 @@
|
||||
|
||||
const { t } = useI18n();
|
||||
const { openModal } = useModal();
|
||||
const { openNewPage } = useOpenNewPage();
|
||||
const tableStore = useTableStore();
|
||||
|
||||
const keyword = ref('');
|
||||
@ -146,7 +156,7 @@
|
||||
slotName: 'action',
|
||||
dataIndex: 'operation',
|
||||
fixed: 'right',
|
||||
width: 60,
|
||||
width: 110,
|
||||
},
|
||||
];
|
||||
if (props.type === 'system') {
|
||||
@ -209,9 +219,9 @@
|
||||
(item) => {
|
||||
return {
|
||||
...item,
|
||||
operationTime: dayjs(item.operationTime).format('YYYY-MM-DD HH:mm:ss'),
|
||||
lastFinishTime: dayjs(item.lastFinishTime).format('YYYY-MM-DD HH:mm:ss'),
|
||||
nextExecuteTime: dayjs(item.nextExecuteTime).format('YYYY-MM-DD HH:mm:ss'),
|
||||
operationTime: item.operationTime ? dayjs(item.operationTime).format('YYYY-MM-DD HH:mm:ss') : '-',
|
||||
lastFinishTime: item.lastFinishTime ? dayjs(item.lastFinishTime).format('YYYY-MM-DD HH:mm:ss') : '-',
|
||||
nextExecuteTime: item.nextExecuteTime ? dayjs(item.nextExecuteTime).format('YYYY-MM-DD HH:mm:ss') : '-',
|
||||
};
|
||||
}
|
||||
);
|
||||
@ -271,6 +281,23 @@
|
||||
console.log(record);
|
||||
}
|
||||
|
||||
function checkDetail(record: any) {
|
||||
openNewPage(ApiTestRouteEnum.API_TEST_MANAGEMENT, {
|
||||
taskDrawer: true,
|
||||
});
|
||||
}
|
||||
|
||||
async function handleBeforeEnableChange(record: any) {
|
||||
try {
|
||||
Message.success(t(record.enable ? 'ms.taskCenter.closeTaskSuccess' : 'ms.taskCenter.openTaskSuccess'));
|
||||
return true;
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理表格选中后批量操作
|
||||
* @param event 批量操作事件对象
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-tabs v-model:active-key="activeTab" class="no-content">
|
||||
<a-tabs v-model:active-key="activeTab" class="no-content" @change="handleTabChange">
|
||||
<a-tab-pane v-for="item of tabList" :key="item.value" :title="item.label" />
|
||||
</a-tabs>
|
||||
<a-divider margin="0"></a-divider>
|
||||
@ -22,7 +22,10 @@
|
||||
import systemTaskTable from './component/systemTaskTable.vue';
|
||||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useLocalForage from '@/hooks/useLocalForage';
|
||||
import useGlobalStore from '@/store/modules/global';
|
||||
|
||||
import { GlobalEventNameEnum } from '@/enums/commonEnum';
|
||||
import { TaskCenterEnum } from '@/enums/taskCenter';
|
||||
|
||||
const props = defineProps<{
|
||||
@ -32,6 +35,8 @@
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const globalStore = useGlobalStore();
|
||||
const { getItem, setItem } = useLocalForage();
|
||||
|
||||
const tabList = ref([
|
||||
{
|
||||
@ -55,6 +60,24 @@
|
||||
activeTaskId.value = id;
|
||||
activeTab.value = TaskCenterEnum.DETAIL;
|
||||
}
|
||||
|
||||
function handleTabChange(key: string | number) {
|
||||
setItem('taskCenterActiveTab', key);
|
||||
}
|
||||
|
||||
watch(
|
||||
() => globalStore.getGlobalEvent,
|
||||
(event) => {
|
||||
if (event && event.id && event.name === GlobalEventNameEnum.OPEN_TASK_CENTER) {
|
||||
activeTab.value = event.params?.tab;
|
||||
setItem('taskCenterActiveTab', event.params?.tab);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
onBeforeMount(async () => {
|
||||
activeTab.value = (await getItem('taskCenterActiveTab')) || TaskCenterEnum.CASE;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
@ -8,7 +8,7 @@ export default {
|
||||
'ms.taskCenter.taskName': 'Task Name',
|
||||
'ms.taskCenter.executeStatus': 'Execution Status',
|
||||
'ms.taskCenter.executeMethod': 'Execution Method',
|
||||
'ms.taskCenter.executeResult': 'Execution Result',
|
||||
'ms.taskCenter.executeResult': 'Result',
|
||||
'ms.taskCenter.caseCount': 'Case Count',
|
||||
'ms.taskCenter.executeFinishedRate': 'Execution Completion Rate',
|
||||
'ms.taskCenter.createTime': 'Initiation Time',
|
||||
@ -53,4 +53,6 @@ export default {
|
||||
'ms.taskCenter.apiImport': 'API Import',
|
||||
'ms.taskCenter.apiScenario': 'Api Scenario',
|
||||
'ms.taskCenter.thirdPartSync': 'Third-party sync',
|
||||
'ms.taskCenter.openTaskSuccess': 'Task started successfully',
|
||||
'ms.taskCenter.closeTaskSuccess': 'Task closed successfully',
|
||||
};
|
||||
|
@ -53,4 +53,6 @@ export default {
|
||||
'ms.taskCenter.apiImport': 'API导入',
|
||||
'ms.taskCenter.apiScenario': '接口场景',
|
||||
'ms.taskCenter.thirdPartSync': '第三方同步',
|
||||
'ms.taskCenter.openTaskSuccess': '任务开启成功',
|
||||
'ms.taskCenter.closeTaskSuccess': '任务关闭成功',
|
||||
};
|
||||
|
@ -362,7 +362,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { FormInstance, Message } from '@arco-design/web-vue';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
@ -381,6 +381,7 @@
|
||||
import MsTableMoreAction from '@/components/pure/ms-table-more-action/index.vue';
|
||||
import { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
||||
import MsTag from '@/components/pure/ms-tag/ms-tag.vue';
|
||||
import MsRichMessage from '@/components/business/ms-rich-message/index.vue';
|
||||
import MsStatusTag from '@/components/business/ms-status-tag/index.vue';
|
||||
import executeHistoryTable from '../detail/executeHistory/index.vue';
|
||||
import ActionModal from './actionModal.vue';
|
||||
@ -391,7 +392,7 @@
|
||||
import PlanExpandRow from '@/views/test-plan/testPlan/components/planExpandRow.vue';
|
||||
|
||||
import {
|
||||
addTestPlan,
|
||||
// addTestPlan,
|
||||
archivedPlan,
|
||||
batchArchivedPlan,
|
||||
batchCopyPlan,
|
||||
@ -414,12 +415,13 @@
|
||||
import useModal from '@/hooks/useModal';
|
||||
import { useAppStore, useTableStore } from '@/store';
|
||||
import useCacheStore from '@/store/modules/cache/cache';
|
||||
import { characterLimit } from '@/utils';
|
||||
import useGlobalStore from '@/store/modules/global';
|
||||
import { characterLimit, getGenerateId } from '@/utils';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import { DragSortParams, ModuleTreeNode, TableQueryParams } from '@/models/common';
|
||||
import type {
|
||||
AddTestPlanParams,
|
||||
// AddTestPlanParams,
|
||||
BatchExecutePlan,
|
||||
BatchMoveParams,
|
||||
CreateTask,
|
||||
@ -429,18 +431,20 @@
|
||||
TestPlanItem,
|
||||
} from '@/models/testPlan/testPlan';
|
||||
import { LastExecuteResults } from '@/enums/caseEnum';
|
||||
import { GlobalEventNameEnum } from '@/enums/commonEnum';
|
||||
import { RouteEnum, TestPlanRouteEnum } from '@/enums/routeEnum';
|
||||
import { ColumnEditTypeEnum, TableKeyEnum } from '@/enums/tableEnum';
|
||||
import { FilterSlotNameEnum } from '@/enums/tableFilterEnum';
|
||||
import { TaskCenterEnum } from '@/enums/taskCenter';
|
||||
import { testPlanTypeEnum } from '@/enums/testPlanEnum';
|
||||
|
||||
import { planStatusOptions } from '../config';
|
||||
import { getModules } from '@/views/case-management/caseManagementFeature/components/utils';
|
||||
|
||||
const cacheStore = useCacheStore();
|
||||
|
||||
const tableStore = useTableStore();
|
||||
const appStore = useAppStore();
|
||||
const globalStore = useGlobalStore();
|
||||
const router = useRouter();
|
||||
const { t } = useI18n();
|
||||
const { openModal } = useModal();
|
||||
@ -1001,7 +1005,35 @@
|
||||
try {
|
||||
await executePlanOrGroup(executeForm.value);
|
||||
cancelHandler();
|
||||
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.CASE,
|
||||
},
|
||||
});
|
||||
},
|
||||
}),
|
||||
]
|
||||
),
|
||||
duration: 5000,
|
||||
closable: true,
|
||||
});
|
||||
fetchData();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
@ -1022,7 +1054,35 @@
|
||||
executionSource: 'MANUAL',
|
||||
};
|
||||
await executeSinglePlan(params);
|
||||
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.CASE,
|
||||
},
|
||||
});
|
||||
},
|
||||
}),
|
||||
]
|
||||
),
|
||||
duration: 5000,
|
||||
closable: true,
|
||||
});
|
||||
fetchData();
|
||||
cancelHandler();
|
||||
} catch (error) {
|
||||
@ -1535,73 +1595,73 @@
|
||||
emitTableParams();
|
||||
}
|
||||
|
||||
const showQuickCreateForm = ref(false);
|
||||
const quickCreateFormRef = ref<FormInstance>();
|
||||
// const showQuickCreateForm = ref(false);
|
||||
// const quickCreateFormRef = ref<FormInstance>();
|
||||
|
||||
const initPlanGroupForm: AddTestPlanParams = {
|
||||
groupId: 'NONE',
|
||||
name: '',
|
||||
projectId: appStore.currentProjectId,
|
||||
moduleId: '',
|
||||
cycle: [],
|
||||
tags: [],
|
||||
description: '',
|
||||
testPlanning: false,
|
||||
automaticStatusUpdate: true,
|
||||
repeatCase: false,
|
||||
passThreshold: 100,
|
||||
type: testPlanTypeEnum.GROUP,
|
||||
baseAssociateCaseRequest: { selectIds: [], selectAll: false, condition: {} },
|
||||
};
|
||||
const quickCreateForm = ref<AddTestPlanParams>(cloneDeep(initPlanGroupForm));
|
||||
// const initPlanGroupForm: AddTestPlanParams = {
|
||||
// groupId: 'NONE',
|
||||
// name: '',
|
||||
// projectId: appStore.currentProjectId,
|
||||
// moduleId: '',
|
||||
// cycle: [],
|
||||
// tags: [],
|
||||
// description: '',
|
||||
// testPlanning: false,
|
||||
// automaticStatusUpdate: true,
|
||||
// repeatCase: false,
|
||||
// passThreshold: 100,
|
||||
// type: testPlanTypeEnum.GROUP,
|
||||
// baseAssociateCaseRequest: { selectIds: [], selectAll: false, condition: {} },
|
||||
// };
|
||||
// const quickCreateForm = ref<AddTestPlanParams>(cloneDeep(initPlanGroupForm));
|
||||
|
||||
const quickCreateLoading = ref(false);
|
||||
// const quickCreateLoading = ref(false);
|
||||
|
||||
function quickCreateCancel() {
|
||||
showQuickCreateForm.value = false;
|
||||
quickCreateForm.value = cloneDeep(initPlanGroupForm);
|
||||
quickCreateFormRef.value?.resetFields();
|
||||
}
|
||||
// function quickCreateCancel() {
|
||||
// showQuickCreateForm.value = false;
|
||||
// quickCreateForm.value = cloneDeep(initPlanGroupForm);
|
||||
// quickCreateFormRef.value?.resetFields();
|
||||
// }
|
||||
|
||||
/**
|
||||
* 快速创建测试计划或者测试计划组
|
||||
*/
|
||||
const createType = ref<keyof typeof testPlanTypeEnum>(showType.value);
|
||||
// const createType = ref<keyof typeof testPlanTypeEnum>(showType.value);
|
||||
// TODO: 快捷创建先不上
|
||||
function quickCreateConfirm() {
|
||||
quickCreateFormRef.value?.validate(async (errors) => {
|
||||
if (!errors) {
|
||||
try {
|
||||
quickCreateLoading.value = true;
|
||||
const params = {
|
||||
...cloneDeep(quickCreateForm.value),
|
||||
groupId: 'NONE',
|
||||
projectId: appStore.currentProjectId,
|
||||
moduleId: props.activeFolder === 'all' ? 'root' : props.activeFolder,
|
||||
testPlanning: false,
|
||||
automaticStatusUpdate: true,
|
||||
repeatCase: false,
|
||||
passThreshold: 100,
|
||||
type: showType.value === testPlanTypeEnum.ALL ? createType.value : showType.value,
|
||||
};
|
||||
await addTestPlan(params);
|
||||
Message.success(t('common.createSuccess'));
|
||||
quickCreateCancel();
|
||||
fetchData();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
} finally {
|
||||
quickCreateLoading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
// function quickCreateConfirm() {
|
||||
// quickCreateFormRef.value?.validate(async (errors) => {
|
||||
// if (!errors) {
|
||||
// try {
|
||||
// quickCreateLoading.value = true;
|
||||
// const params = {
|
||||
// ...cloneDeep(quickCreateForm.value),
|
||||
// groupId: 'NONE',
|
||||
// projectId: appStore.currentProjectId,
|
||||
// moduleId: props.activeFolder === 'all' ? 'root' : props.activeFolder,
|
||||
// testPlanning: false,
|
||||
// automaticStatusUpdate: true,
|
||||
// repeatCase: false,
|
||||
// passThreshold: 100,
|
||||
// type: showType.value === testPlanTypeEnum.ALL ? createType.value : showType.value,
|
||||
// };
|
||||
// await addTestPlan(params);
|
||||
// Message.success(t('common.createSuccess'));
|
||||
// quickCreateCancel();
|
||||
// fetchData();
|
||||
// } catch (error) {
|
||||
// // eslint-disable-next-line no-console
|
||||
// console.log(error);
|
||||
// } finally {
|
||||
// quickCreateLoading.value = false;
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// TODO: 快捷创建先不上
|
||||
function handleSelect(value: string | number | Record<string, any> | undefined) {
|
||||
showQuickCreateForm.value = true;
|
||||
createType.value = value as keyof typeof testPlanTypeEnum;
|
||||
}
|
||||
// function handleSelect(value: string | number | Record<string, any> | undefined) {
|
||||
// showQuickCreateForm.value = true;
|
||||
// createType.value = value as keyof typeof testPlanTypeEnum;
|
||||
// }
|
||||
|
||||
// 查看已归档测试计划以及计划组
|
||||
function archivedChangeHandler() {
|
||||
|
@ -150,6 +150,7 @@
|
||||
import useTable from '@/components/pure/ms-table/useTable';
|
||||
import MsBugOperation from '@/components/business/ms-bug-operation/index.vue';
|
||||
import CaseLevel from '@/components/business/ms-case-associate/caseLevel.vue';
|
||||
import MsRichMessage from '@/components/business/ms-rich-message/index.vue';
|
||||
import ApiMethodName from '@/views/api-test/components/apiMethodName.vue';
|
||||
import apiStatus from '@/views/api-test/components/apiStatus.vue';
|
||||
import CaseAndScenarioReportDrawer from '@/views/api-test/components/caseAndScenarioReportDrawer.vue';
|
||||
@ -178,7 +179,8 @@
|
||||
import useOpenNewPage from '@/hooks/useOpenNewPage';
|
||||
import useTableStore from '@/hooks/useTableStore';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import { characterLimit } from '@/utils';
|
||||
import useGlobalStore from '@/store/modules/global';
|
||||
import { characterLimit, getGenerateId } from '@/utils';
|
||||
import { hasAllPermission, hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import { DragSortParams, ModuleTreeNode, TableQueryParams } from '@/models/common';
|
||||
@ -187,10 +189,12 @@
|
||||
import { FilterType, ViewTypeEnum } from '@/enums/advancedFilterEnum';
|
||||
import { AssociatedBugApiTypeEnum } from '@/enums/associateBugEnum';
|
||||
import { CaseLinkEnum } from '@/enums/caseEnum';
|
||||
import { GlobalEventNameEnum } from '@/enums/commonEnum';
|
||||
import { ReportEnum } from '@/enums/reportEnum';
|
||||
import { ApiTestRouteEnum } from '@/enums/routeEnum';
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
import { FilterRemoteMethodsEnum, FilterSlotNameEnum } from '@/enums/tableFilterEnum';
|
||||
import { TaskCenterEnum } from '@/enums/taskCenter';
|
||||
|
||||
import {
|
||||
casePriorityOptions,
|
||||
@ -222,6 +226,7 @@
|
||||
const { openModal } = useModal();
|
||||
const { openNewPage } = useOpenNewPage();
|
||||
const appStore = useAppStore();
|
||||
const globalStore = useGlobalStore();
|
||||
|
||||
const keyword = ref('');
|
||||
|
||||
@ -823,7 +828,35 @@
|
||||
try {
|
||||
tableLoading.value = true;
|
||||
await runApiCase(record.id);
|
||||
Message.success(t('common.executionSuccess'));
|
||||
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,
|
||||
});
|
||||
resetSelectorAndCaseList();
|
||||
emit('refresh');
|
||||
} catch (error) {
|
||||
@ -845,7 +878,35 @@
|
||||
excludeIds: batchParams.value?.excludeIds || [],
|
||||
...tableParams,
|
||||
});
|
||||
Message.success(t('common.operationSuccess'));
|
||||
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,
|
||||
});
|
||||
resetSelectorAndCaseList();
|
||||
emit('refresh');
|
||||
} catch (error) {
|
||||
|
@ -150,6 +150,7 @@
|
||||
import useTable from '@/components/pure/ms-table/useTable';
|
||||
import MsBugOperation from '@/components/business/ms-bug-operation/index.vue';
|
||||
import CaseLevel from '@/components/business/ms-case-associate/caseLevel.vue';
|
||||
import MsRichMessage from '@/components/business/ms-rich-message/index.vue';
|
||||
import apiStatus from '@/views/api-test/components/apiStatus.vue';
|
||||
import CaseAndScenarioReportDrawer from '@/views/api-test/components/caseAndScenarioReportDrawer.vue';
|
||||
import ExecutionStatus from '@/views/api-test/report/component/reportStatus.vue';
|
||||
@ -177,7 +178,8 @@
|
||||
import useOpenNewPage from '@/hooks/useOpenNewPage';
|
||||
import useTableStore from '@/hooks/useTableStore';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import { characterLimit } from '@/utils';
|
||||
import useGlobalStore from '@/store/modules/global';
|
||||
import { characterLimit, getGenerateId } from '@/utils';
|
||||
import { hasAllPermission, hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import { DragSortParams, ModuleTreeNode, TableQueryParams } from '@/models/common';
|
||||
@ -186,10 +188,12 @@
|
||||
import { FilterType, ViewTypeEnum } from '@/enums/advancedFilterEnum';
|
||||
import { AssociatedBugApiTypeEnum } from '@/enums/associateBugEnum';
|
||||
import { CaseLinkEnum } from '@/enums/caseEnum';
|
||||
import { GlobalEventNameEnum } from '@/enums/commonEnum';
|
||||
import { ReportEnum } from '@/enums/reportEnum';
|
||||
import { ApiTestRouteEnum } from '@/enums/routeEnum';
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
import { FilterRemoteMethodsEnum, FilterSlotNameEnum } from '@/enums/tableFilterEnum';
|
||||
import { TaskCenterEnum } from '@/enums/taskCenter';
|
||||
|
||||
import { casePriorityOptions, lastReportStatusListOptions } from '@/views/api-test/components/config';
|
||||
import { scenarioStatusOptions } from '@/views/api-test/scenario/components/config';
|
||||
@ -216,6 +220,7 @@
|
||||
const { openModal } = useModal();
|
||||
const { openNewPage } = useOpenNewPage();
|
||||
const appStore = useAppStore();
|
||||
const globalStore = useGlobalStore();
|
||||
|
||||
const keyword = ref('');
|
||||
|
||||
@ -793,7 +798,35 @@
|
||||
try {
|
||||
tableLoading.value = true;
|
||||
await runApiScenario(record.id);
|
||||
Message.success(t('common.executionSuccess'));
|
||||
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,
|
||||
});
|
||||
resetSelectorAndCaseList();
|
||||
emit('refresh');
|
||||
} catch (error) {
|
||||
@ -815,7 +848,35 @@
|
||||
excludeIds: batchParams.value?.excludeIds || [],
|
||||
...tableParams,
|
||||
});
|
||||
Message.success(t('common.operationSuccess'));
|
||||
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,
|
||||
});
|
||||
resetSelectorAndCaseList();
|
||||
emit('refresh');
|
||||
} catch (error) {
|
||||
|
Loading…
Reference in New Issue
Block a user