feat(1.4.0-beta1): 1. 调整重试任务和重试管理包路径
This commit is contained in:
parent
27546ed6bb
commit
820501785e
@ -344,8 +344,8 @@ const local: App.I18n.Schema = {
|
||||
notify_config: 'Notify Config',
|
||||
retry: 'Retry Task',
|
||||
retry_task: 'Retry Task',
|
||||
retry_info: "'Retry Task Management",
|
||||
retry_scene: 'Retry Scene',
|
||||
retry_log: 'Retry Log',
|
||||
'retry_dead-letter': 'Retry Dead Letter',
|
||||
user: 'User',
|
||||
user_manager: 'User Info',
|
||||
|
@ -344,12 +344,12 @@ const local: App.I18n.Schema = {
|
||||
notify_recipient: '通知人',
|
||||
notify_config: '通知配置',
|
||||
retry: '重试任务',
|
||||
retry_task: '任务管理',
|
||||
retry_task: '重试任务',
|
||||
retry_info: '任务管理',
|
||||
'retry_dead-letter': '死信任务',
|
||||
user: '用户管理',
|
||||
user_manager: '用户信息',
|
||||
retry_scene: '重试场景',
|
||||
retry_log: '重试日志',
|
||||
workflow: '工作流',
|
||||
workflow_task: '任务管理',
|
||||
workflow_batch: '执行批次',
|
||||
|
@ -31,7 +31,7 @@ export const views: Record<LastLevelRouteKey, RouteComponent | (() => Promise<Ro
|
||||
notify_recipient: () => import("@/views/notify/recipient/index.vue"),
|
||||
pods: () => import("@/views/pods/index.vue"),
|
||||
"retry_dead-letter": () => import("@/views/retry/dead-letter/index.vue"),
|
||||
retry_log: () => import("@/views/retry/log/index.vue"),
|
||||
retry_info: () => import("@/views/retry/info/index.vue"),
|
||||
retry_scene: () => import("@/views/retry/scene/index.vue"),
|
||||
retry_task: () => import("@/views/retry/task/index.vue"),
|
||||
user_manager: () => import("@/views/user/manager/index.vue"),
|
||||
|
@ -234,15 +234,13 @@ export const generatedRoutes: GeneratedRoute[] = [
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'retry_log',
|
||||
path: '/retry/log',
|
||||
component: 'view.retry_log',
|
||||
name: 'retry_info',
|
||||
path: '/retry/info',
|
||||
component: 'view.retry_info',
|
||||
meta: {
|
||||
title: 'retry_log',
|
||||
i18nKey: 'route.retry_log',
|
||||
icon: 'tabler:logs',
|
||||
order: 20,
|
||||
keepAlive: false
|
||||
title: 'retry_info',
|
||||
i18nKey: 'route.retry_info',
|
||||
icon: 'octicon:tasklist'
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -264,8 +262,7 @@ export const generatedRoutes: GeneratedRoute[] = [
|
||||
meta: {
|
||||
title: 'retry_task',
|
||||
i18nKey: 'route.retry_task',
|
||||
icon: 'octicon:tasklist',
|
||||
order: 10,
|
||||
icon: 'carbon:batch-job',
|
||||
keepAlive: false
|
||||
}
|
||||
}
|
||||
|
@ -143,22 +143,22 @@ const cardData = computed<CardData[]>(() => [
|
||||
{
|
||||
label: $t('common.success'),
|
||||
value: props.modelValue?.retryTask.finishNum ?? 0,
|
||||
click: () => routerPushByKey('retry_log', { state: { retryStatus: 1 } })
|
||||
click: () => routerPushByKey('retry_info', { state: { retryStatus: 1 } })
|
||||
},
|
||||
{
|
||||
label: $t('common.running'),
|
||||
value: props.modelValue?.retryTask.runningNum ?? 0,
|
||||
click: () => routerPushByKey('retry_log', { state: { retryStatus: 0 } })
|
||||
click: () => routerPushByKey('retry_info', { state: { retryStatus: 0 } })
|
||||
},
|
||||
{
|
||||
label: $t('page.home.retryTask.status.maxRetryTimes'),
|
||||
value: props.modelValue?.retryTask.maxCountNum ?? 0,
|
||||
click: () => routerPushByKey('retry_log', { state: { retryStatus: 2 } })
|
||||
click: () => routerPushByKey('retry_info', { state: { retryStatus: 2 } })
|
||||
},
|
||||
{
|
||||
label: $t('page.home.retryTask.status.pauseRetry'),
|
||||
value: props.modelValue?.retryTask.suspendNum ?? 0,
|
||||
click: () => routerPushByKey('retry_log', { state: { retryStatus: 3 } })
|
||||
click: () => routerPushByKey('retry_info', { state: { retryStatus: 3 } })
|
||||
}
|
||||
]
|
||||
},
|
||||
|
364
src/views/retry/info/index.vue
Normal file
364
src/views/retry/info/index.vue
Normal file
@ -0,0 +1,364 @@
|
||||
<script setup lang="tsx">
|
||||
import { NButton, NPopconfirm, NTag } from 'naive-ui';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { useBoolean } from '~/packages/hooks';
|
||||
import {
|
||||
fetchBatchDeleteRetryTask,
|
||||
fetchExecuteCallbackTask,
|
||||
fetchExecuteRetryTask,
|
||||
fetchGetAllGroupNameList,
|
||||
fetchGetRetryTaskById,
|
||||
fetchGetRetryTaskList,
|
||||
fetchUpdateRetryTaskStatus
|
||||
} from '@/service/api';
|
||||
import { $t } from '@/locales';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { useTable, useTableOperate } from '@/hooks/common/table';
|
||||
import { retryStatusTypeRecord, retryTaskTypeRecord } from '@/constants/business';
|
||||
import { tagColor } from '@/utils/common';
|
||||
import RetryTaskOperateDrawer from './modules/retry-operate-drawer.vue';
|
||||
import RetryTaskBatchAddDrawer from './modules/retr-batch-add-drawer.vue';
|
||||
import RetryTaskSearch from './modules/retry-search.vue';
|
||||
import RetryTaskDetailDrawerVue from './modules/retry-detail-drawer.vue';
|
||||
|
||||
/** 详情页属性数据 */
|
||||
const detailData = ref<Api.Retry.Retry | null>();
|
||||
/** 详情页可见状态 */
|
||||
const { bool: detailVisible, setTrue: openDetail } = useBoolean(false);
|
||||
|
||||
const appStore = useAppStore();
|
||||
|
||||
const { columns, columnChecks, data, getData, loading, mobilePagination, searchParams, resetSearchParams } = useTable({
|
||||
apiFn: fetchGetRetryTaskList,
|
||||
apiParams: {
|
||||
page: 1,
|
||||
size: 10,
|
||||
groupName: null,
|
||||
sceneName: null,
|
||||
idempotentId: null,
|
||||
bizNo: null,
|
||||
retryStatus: null
|
||||
},
|
||||
columns: () => [
|
||||
{
|
||||
type: 'selection',
|
||||
align: 'center',
|
||||
width: 48,
|
||||
disabled: row => row.retryStatus === 0
|
||||
},
|
||||
{
|
||||
key: 'id',
|
||||
title: $t('common.index'),
|
||||
align: 'center',
|
||||
width: 128,
|
||||
render: row => {
|
||||
async function showDetailDrawer() {
|
||||
await loadRetryInfo(row);
|
||||
openDetail();
|
||||
}
|
||||
|
||||
return (
|
||||
<n-button text tag="a" type="primary" onClick={showDetailDrawer} class="ws-normal">
|
||||
{row.id}
|
||||
</n-button>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'groupName',
|
||||
title: $t('page.retryTask.groupName'),
|
||||
align: 'left',
|
||||
resizable: true,
|
||||
minWidth: 120,
|
||||
maxWidth: 250
|
||||
},
|
||||
{
|
||||
key: 'sceneName',
|
||||
title: $t('page.retryTask.sceneName'),
|
||||
align: 'left',
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
key: 'nextTriggerAt',
|
||||
title: $t('page.retryTask.nextTriggerAt'),
|
||||
align: 'left',
|
||||
resizable: true,
|
||||
minWidth: 120,
|
||||
maxWidth: 150
|
||||
},
|
||||
{
|
||||
key: 'retryCount',
|
||||
title: $t('page.retryTask.retryCount'),
|
||||
align: 'center',
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
key: 'retryStatus',
|
||||
title: $t('page.retryTask.retryStatus'),
|
||||
align: 'left',
|
||||
width: 120,
|
||||
render: row => {
|
||||
if (row.retryStatus === null) {
|
||||
return null;
|
||||
}
|
||||
const label = $t(retryStatusTypeRecord[row.retryStatus!]);
|
||||
|
||||
return <NTag type={tagColor(row.retryStatus!)}>{label}</NTag>;
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'taskType',
|
||||
title: $t('page.retryTask.taskType'),
|
||||
align: 'left',
|
||||
width: 100,
|
||||
render: row => {
|
||||
if (row.taskType === null) {
|
||||
return null;
|
||||
}
|
||||
const tagMap: Record<Api.Retry.TaskType, NaiveUI.ThemeColor> = {
|
||||
1: 'warning',
|
||||
2: 'error'
|
||||
};
|
||||
const label = $t(retryTaskTypeRecord[row.taskType!]);
|
||||
|
||||
return <NTag type={tagMap[row.taskType!]}>{label}</NTag>;
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'idempotentId',
|
||||
title: $t('page.retryTask.idempotentId'),
|
||||
align: 'left',
|
||||
resizable: true,
|
||||
minWidth: 150,
|
||||
maxWidth: 300
|
||||
},
|
||||
{
|
||||
key: 'bizNo',
|
||||
title: $t('page.retryTask.bizNo'),
|
||||
align: 'left',
|
||||
resizable: true,
|
||||
minWidth: 150,
|
||||
maxWidth: 300
|
||||
},
|
||||
{
|
||||
key: 'operate',
|
||||
title: $t('common.operate'),
|
||||
align: 'center',
|
||||
width: 260,
|
||||
fixed: 'right',
|
||||
render: row => (
|
||||
<div class="flex-center gap-8px">
|
||||
{/* 非[完成,最大次数], 显示[执行]按钮 */}
|
||||
{row.retryStatus !== 1 && row.retryStatus !== 2 ? (
|
||||
<>
|
||||
<NPopconfirm onPositiveClick={() => handleExecute(row.groupName!, row.id! as any, row.taskType!)}>
|
||||
{{
|
||||
default: () => $t('common.confirmExecute'),
|
||||
trigger: () => (
|
||||
<NButton type="info" text ghost size="small">
|
||||
{$t('common.execute')}
|
||||
</NButton>
|
||||
)
|
||||
}}
|
||||
</NPopconfirm>
|
||||
<n-divider vertical />
|
||||
</>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{/* 非[完成,最大次数], 显示[完成]按钮 */}
|
||||
{row.retryStatus !== 1 && row.retryStatus !== 2 ? (
|
||||
<>
|
||||
<NPopconfirm onPositiveClick={() => handleFinish(Number(row.id!), row.groupName!)}>
|
||||
{{
|
||||
default: () => $t('common.confirmFinish'),
|
||||
trigger: () => (
|
||||
<NButton type="warning" text ghost size="small">
|
||||
{$t('common.finish')}
|
||||
</NButton>
|
||||
)
|
||||
}}
|
||||
</NPopconfirm>
|
||||
<n-divider vertical />
|
||||
</>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{/* 重试中, 显示[停止]按钮 */}
|
||||
{row.retryStatus === 0 ? (
|
||||
<>
|
||||
<NPopconfirm onPositiveClick={() => handlePause(Number(row.id!), row.groupName!)}>
|
||||
{{
|
||||
default: () => $t('common.confirmPause'),
|
||||
trigger: () => (
|
||||
<NButton type="success" text ghost size="small">
|
||||
{$t('common.pause')}
|
||||
</NButton>
|
||||
)
|
||||
}}
|
||||
</NPopconfirm>
|
||||
<n-divider vertical />
|
||||
</>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{/* 暂停, 显示[开始]按钮 */}
|
||||
{row.retryStatus === 3 ? (
|
||||
<>
|
||||
<NPopconfirm onPositiveClick={() => handleResume(Number(row.id!), row.groupName!)}>
|
||||
{{
|
||||
default: () => $t('common.confirmResume'),
|
||||
trigger: () => (
|
||||
<NButton type="info" text ghost size="small">
|
||||
{$t('common.resume')}
|
||||
</NButton>
|
||||
)
|
||||
}}
|
||||
</NPopconfirm>
|
||||
<n-divider vertical />
|
||||
</>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{
|
||||
<NPopconfirm onPositiveClick={() => handleDelete(row.groupName!, row.id!)}>
|
||||
{{
|
||||
default: () => $t('common.confirmDelete'),
|
||||
trigger: () => (
|
||||
<NButton type="error" text ghost size="small">
|
||||
{$t('common.delete')}
|
||||
</NButton>
|
||||
)
|
||||
}}
|
||||
</NPopconfirm>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
const {
|
||||
drawerVisible,
|
||||
operateType,
|
||||
handleAdd,
|
||||
checkedRowKeys,
|
||||
onBatchDeleted,
|
||||
onDeleted
|
||||
// closeDrawer
|
||||
} = useTableOperate(data, getData);
|
||||
|
||||
const { bool: batchAddDrawerVisible, setTrue: openBatchAddDrawer } = useBoolean();
|
||||
|
||||
async function handleDelete(groupName: string, id: string) {
|
||||
const { error } = await fetchBatchDeleteRetryTask({ groupName, ids: [id] });
|
||||
if (error) return;
|
||||
onDeleted();
|
||||
}
|
||||
|
||||
async function loadRetryInfo(row: Api.Retry.Retry) {
|
||||
const res = await fetchGetRetryTaskById(row.id!, row.groupName!);
|
||||
detailData.value = (res.data as Api.Retry.Retry) || null;
|
||||
}
|
||||
|
||||
async function handleBatchDelete() {
|
||||
const ids: string[] = checkedRowKeys.value as string[];
|
||||
if (ids.length === 0) return;
|
||||
const groupName = data.value[0].groupName;
|
||||
const { error } = await fetchBatchDeleteRetryTask({ groupName, ids });
|
||||
if (error) return;
|
||||
onBatchDeleted();
|
||||
}
|
||||
|
||||
function handleBatchAdd() {
|
||||
openBatchAddDrawer();
|
||||
}
|
||||
|
||||
function handleExecute(groupName: string, retryId: number, type: Api.Retry.TaskType) {
|
||||
if (type === 1) {
|
||||
fetchExecuteRetryTask({ groupName, retryIds: [retryId] });
|
||||
return;
|
||||
}
|
||||
|
||||
if (type === 2) {
|
||||
fetchExecuteCallbackTask({ groupName, retryIds: [retryId] });
|
||||
}
|
||||
}
|
||||
|
||||
function handleResume(id: number, groupName: string) {
|
||||
updateRetryTaskStatus(id, groupName, 0);
|
||||
}
|
||||
|
||||
function handlePause(id: number, groupName: string) {
|
||||
updateRetryTaskStatus(id, groupName, 3);
|
||||
}
|
||||
|
||||
function handleFinish(id: number, groupName: string) {
|
||||
updateRetryTaskStatus(id, groupName, 1);
|
||||
}
|
||||
|
||||
async function updateRetryTaskStatus(id: number, groupName: string, retryStatus: Api.Retry.RetryStatusType) {
|
||||
const { error } = await fetchUpdateRetryTaskStatus({ id, groupName, retryStatus });
|
||||
if (error) return;
|
||||
window.$message?.success($t('common.updateSuccess'));
|
||||
getData();
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
const { error, data: groupList } = await fetchGetAllGroupNameList();
|
||||
if (!error && groupList.length > 0) {
|
||||
searchParams.groupName = groupList[0];
|
||||
getData();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
||||
<RetryTaskSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getData" />
|
||||
<NCard
|
||||
:title="$t('page.retryTask.title')"
|
||||
:bordered="false"
|
||||
size="small"
|
||||
class="sm:flex-1-hidden card-wrapper"
|
||||
header-class="view-card-header"
|
||||
>
|
||||
<template #header-extra>
|
||||
<TableHeaderOperation
|
||||
v-model:columns="columnChecks"
|
||||
:disabled-delete="checkedRowKeys.length === 0"
|
||||
:loading="loading"
|
||||
@add="handleAdd"
|
||||
@delete="handleBatchDelete"
|
||||
@refresh="getData"
|
||||
>
|
||||
<template #addAfter>
|
||||
<NButton size="small" ghost type="primary" @click="handleBatchAdd">
|
||||
<template #icon>
|
||||
<icon-ic-round-plus class="text-icon" />
|
||||
</template>
|
||||
{{ $t('common.batchAdd') }}
|
||||
</NButton>
|
||||
</template>
|
||||
</TableHeaderOperation>
|
||||
</template>
|
||||
<NDataTable
|
||||
v-model:checked-row-keys="checkedRowKeys"
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
:flex-height="!appStore.isMobile"
|
||||
:scroll-x="2000"
|
||||
:loading="loading"
|
||||
remote
|
||||
:row-key="row => row.id"
|
||||
:pagination="mobilePagination"
|
||||
class="sm:h-full"
|
||||
/>
|
||||
<RetryTaskOperateDrawer v-model:visible="drawerVisible" :operate-type="operateType" @submitted="getData" />
|
||||
<RetryTaskBatchAddDrawer v-model:visible="batchAddDrawerVisible" @submitted="getData" />
|
||||
<RetryTaskDetailDrawerVue v-model:visible="detailVisible" :row-data="detailData" />
|
||||
</NCard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
@ -1,201 +0,0 @@
|
||||
<script setup lang="tsx">
|
||||
import { NButton, NPopconfirm, NTag } from 'naive-ui';
|
||||
import { ref } from 'vue';
|
||||
import { useBoolean } from '@sa/hooks';
|
||||
import { fetchBatchDeleteRetryLog, fetchDeleteRetryLog, fetchRetryLogById, fetchRetryLogPageList } from '@/service/api';
|
||||
import { $t } from '@/locales';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { useTable, useTableOperate } from '@/hooks/common/table';
|
||||
import { retryTaskStatusTypeRecord, retryTaskTypeRecord } from '@/constants/business';
|
||||
import { monthRangeISO8601, tagColor } from '@/utils/common';
|
||||
import RetryLogSearch from './modules/retry-log-search.vue';
|
||||
import RetryLogDetailDrawer from './modules/retry-log-detail-drawer.vue';
|
||||
|
||||
const appStore = useAppStore();
|
||||
|
||||
/** 详情页属性数据 */
|
||||
const detailData = ref<Api.RetryTask.RetryTask | null>();
|
||||
/** 详情页可见状态 */
|
||||
const { bool: detailVisible, setTrue: openDetail } = useBoolean(false);
|
||||
const taskStatus = history.state.taskStatus;
|
||||
|
||||
const { columns, columnChecks, data, getData, loading, mobilePagination, searchParams, resetSearchParams } = useTable({
|
||||
apiFn: fetchRetryLogPageList,
|
||||
apiParams: {
|
||||
page: 1,
|
||||
size: 10,
|
||||
// if you want to use the searchParams in Form, you need to define the following properties, and the value is null
|
||||
// the value can not be undefined, otherwise the property in Form will not be reactive
|
||||
groupName: null,
|
||||
sceneName: null,
|
||||
taskStatus: null,
|
||||
datetimeRange: monthRangeISO8601()
|
||||
},
|
||||
searchParams: {
|
||||
taskStatus
|
||||
},
|
||||
columns: () => [
|
||||
{
|
||||
type: 'selection',
|
||||
align: 'center',
|
||||
width: 48,
|
||||
disabled: row => row.taskStatus === 1
|
||||
},
|
||||
{
|
||||
key: 'id',
|
||||
title: $t('common.index'),
|
||||
align: 'center',
|
||||
width: 64,
|
||||
render: row => {
|
||||
async function showDetailDrawer() {
|
||||
await loadRetryInfo(row);
|
||||
openDetail();
|
||||
}
|
||||
|
||||
return (
|
||||
<n-button text tag="a" type="primary" onClick={showDetailDrawer} class="ws-normal">
|
||||
{row.id}
|
||||
</n-button>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'groupName',
|
||||
title: $t('page.retryLog.groupName'),
|
||||
align: 'left',
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
key: 'sceneName',
|
||||
title: $t('page.retryLog.sceneName'),
|
||||
align: 'left',
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
key: 'taskStatus',
|
||||
title: $t('page.retryLog.retryStatus'),
|
||||
align: 'left',
|
||||
minWidth: 120,
|
||||
render: row => {
|
||||
if (row.taskStatus === null) {
|
||||
return null;
|
||||
}
|
||||
const tagMap: Record<number, NaiveUI.ThemeColor> = {
|
||||
1: 'info',
|
||||
2: 'info',
|
||||
3: 'info',
|
||||
4: 'error',
|
||||
5: 'error',
|
||||
6: 'error'
|
||||
};
|
||||
|
||||
const label = $t(retryTaskStatusTypeRecord[row.taskStatus!]);
|
||||
|
||||
return <NTag type={tagMap[row.taskStatus!]}>{label}</NTag>;
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'taskType',
|
||||
title: $t('page.retryLog.taskType'),
|
||||
align: 'left',
|
||||
minWidth: 120,
|
||||
render: row => {
|
||||
if (row.taskType === null) {
|
||||
return null;
|
||||
}
|
||||
const label = $t(retryTaskTypeRecord[row.taskType!]);
|
||||
|
||||
return <NTag type={tagColor(row.taskType!)}>{label}</NTag>;
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'createDt',
|
||||
title: $t('page.retryLog.createDt'),
|
||||
align: 'left',
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
key: 'operate',
|
||||
title: $t('common.operate'),
|
||||
align: 'center',
|
||||
width: 80,
|
||||
render: row => (
|
||||
<div class="flex-center gap-8px">
|
||||
{row.taskStatus === 1 || row.taskStatus === 2 ? (
|
||||
<NPopconfirm onPositiveClick={() => handleDelete(row.id)}>
|
||||
{{
|
||||
default: () => $t('common.confirmDelete'),
|
||||
trigger: () => (
|
||||
<NButton type="error" text ghost size="small">
|
||||
{$t('common.delete')}
|
||||
</NButton>
|
||||
)
|
||||
}}
|
||||
</NPopconfirm>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
const { checkedRowKeys, onDeleted, onBatchDeleted } = useTableOperate(data, getData);
|
||||
|
||||
async function handleBatchDelete() {
|
||||
const { error } = await fetchBatchDeleteRetryLog(checkedRowKeys.value as any[]);
|
||||
if (error) return;
|
||||
onBatchDeleted();
|
||||
}
|
||||
|
||||
async function handleDelete(id: any) {
|
||||
const { error } = await fetchDeleteRetryLog(id);
|
||||
if (error) return;
|
||||
onDeleted();
|
||||
}
|
||||
|
||||
async function loadRetryInfo(row: Api.RetryTask.RetryTask) {
|
||||
const res = await fetchRetryLogById(row.id!);
|
||||
detailData.value = (res.data as Api.RetryTask.RetryTask) || null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
||||
<RetryLogSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getData" />
|
||||
<NCard
|
||||
:title="$t('page.retryLog.title')"
|
||||
:bordered="false"
|
||||
size="small"
|
||||
class="sm:flex-1-hidden card-wrapper"
|
||||
header-class="view-card-header"
|
||||
>
|
||||
<template #header-extra>
|
||||
<TableHeaderOperation
|
||||
v-model:columns="columnChecks"
|
||||
:disabled-delete="checkedRowKeys.length === 0"
|
||||
:loading="loading"
|
||||
:show-add="false"
|
||||
@delete="handleBatchDelete"
|
||||
@refresh="getData"
|
||||
/>
|
||||
</template>
|
||||
<NDataTable
|
||||
v-model:checked-row-keys="checkedRowKeys"
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
:flex-height="!appStore.isMobile"
|
||||
:scroll-x="962"
|
||||
:loading="loading"
|
||||
remote
|
||||
:row-key="row => row.id"
|
||||
:pagination="mobilePagination"
|
||||
class="sm:h-full"
|
||||
/>
|
||||
</NCard>
|
||||
<RetryLogDetailDrawer v-model:visible="detailVisible" :row-data="detailData" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
@ -1,56 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { $t } from '@/locales';
|
||||
import { tagColor } from '@/utils/common';
|
||||
import { retryTaskStatusTypeRecord, retryTaskTypeRecord } from '@/constants/business';
|
||||
|
||||
defineOptions({
|
||||
name: 'SceneDetailDrawer'
|
||||
});
|
||||
|
||||
interface Props {
|
||||
/** row data */
|
||||
rowData?: Api.RetryTask.RetryTask | null;
|
||||
}
|
||||
|
||||
defineProps<Props>();
|
||||
|
||||
const visible = defineModel<boolean>('visible', {
|
||||
default: false
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DetailDrawer v-model="visible" :title="$t('page.retryLog.detail')" :width="['50%', '90%']">
|
||||
<NTabs type="segment" animated>
|
||||
<NTabPane :name="0" :tab="$t('page.log.info')">
|
||||
<NDescriptions label-placement="top" bordered :column="2">
|
||||
<NDescriptionsItem :label="$t('page.retryLog.groupName')" :span="2">
|
||||
{{ rowData?.groupName }}
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem :label="$t('page.retryLog.sceneName')" :span="2">
|
||||
{{ rowData?.sceneName }}
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem :label="$t('page.retryLog.retryStatus')" :span="1">
|
||||
<NTag :type="tagColor(rowData?.taskStatus!)">
|
||||
{{ $t(retryTaskStatusTypeRecord[rowData?.taskStatus!]) }}
|
||||
</NTag>
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem :label="$t('page.retryLog.taskType')" :span="1">
|
||||
<NTag :type="tagColor(rowData?.taskType!)">{{ $t(retryTaskTypeRecord[rowData?.taskType!]) }}</NTag>
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem :label="$t('common.createDt')">{{ rowData?.createDt }}</NDescriptionsItem>
|
||||
</NDescriptions>
|
||||
</NTabPane>
|
||||
<NTabPane :name="1" :tab="$t('page.log.title')" display-directive="if">
|
||||
<LogDrawer :drawer="false" type="retry" :task-data="rowData!" />
|
||||
</NTabPane>
|
||||
</NTabs>
|
||||
</DetailDrawer>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(.virtual-list) {
|
||||
height: calc(100vh - 166px) !important;
|
||||
max-height: calc(100vh - 166px) !important;
|
||||
}
|
||||
</style>
|
@ -1,67 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { $t } from '@/locales';
|
||||
import { translateOptions } from '@/utils/common';
|
||||
import { retryStatusTypeOptions } from '@/constants/business';
|
||||
import SelectGroup from '@/components/common/select-group.vue';
|
||||
import SelectScene from '@/components/common/select-scene.vue';
|
||||
import DatetimeRange from '@/components/common/datetime-range.vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'RetryLogSearch'
|
||||
});
|
||||
|
||||
interface Emits {
|
||||
(e: 'reset'): void;
|
||||
(e: 'search'): void;
|
||||
}
|
||||
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
const model = defineModel<Api.RetryTask.RetryTaskSearchParams>('model', { required: true });
|
||||
|
||||
function reset() {
|
||||
emit('reset');
|
||||
}
|
||||
|
||||
function search() {
|
||||
emit('search');
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<SearchForm btn-span="24 xl:3" :model="model" @search="search" @reset="reset">
|
||||
<NFormItemGi span="24 s:12 m:6" :label="$t('page.retryLog.groupName')" path="groupName" class="pr-24px">
|
||||
<SelectGroup v-model:value="model.groupName" clearable />
|
||||
</NFormItemGi>
|
||||
<NFormItemGi span="24 s:12 m:6" :label="$t('page.retryLog.sceneName')" path="sceneName" class="pr-24px">
|
||||
<SelectScene v-model:value="model.sceneName" :group-name="model.groupName as string" clearable />
|
||||
</NFormItemGi>
|
||||
<!-- <NFormItemGi span="24 s:12 m:6" :label="$t('page.retryLog.UniqueId')" path="UniqueId" class="pr-24px">-->
|
||||
<!-- <NInput v-model:value="model.uniqueId" :placeholder="$t('page.retryLog.form.UniqueId')" clearable />-->
|
||||
<!-- </NFormItemGi>-->
|
||||
<!-- <NFormItemGi span="24 s:12 m:6" :label="$t('page.retryLog.idempotentId')" path="idempotentId" class="pr-24px">-->
|
||||
<!-- <NInput v-model:value="model.idempotentId" :placeholder="$t('page.retryLog.form.idempotentId')" clearable />-->
|
||||
<!-- </NFormItemGi>-->
|
||||
<!-- <NFormItemGi span="24 s:12 m:6" :label="$t('page.retryLog.bizNo')" path="bizNo" class="pr-24px">-->
|
||||
<!-- <NInput v-model:value="model.bizNo" :placeholder="$t('page.retryLog.form.bizNo')" clearable />-->
|
||||
<!-- </NFormItemGi>-->
|
||||
<NFormItemGi span="24 s:12 m:6" :label="$t('page.retryLog.retryStatus')" path="taskBatchStatus" class="pr-24px">
|
||||
<NSelect
|
||||
v-model:value="model.taskStatus"
|
||||
:placeholder="$t('page.retryTask.form.retryStatus')"
|
||||
:options="translateOptions(retryStatusTypeOptions)"
|
||||
clearable
|
||||
/>
|
||||
</NFormItemGi>
|
||||
<NFormItemGi
|
||||
span="24 s:24 m:15 l:12 xl:9"
|
||||
:label="$t('page.common.createTime')"
|
||||
path="datetimeRange"
|
||||
class="pr-24px"
|
||||
>
|
||||
<DatetimeRange v-model:value="model.datetimeRange!" />
|
||||
</NFormItemGi>
|
||||
</SearchForm>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
@ -1,56 +1,51 @@
|
||||
<script setup lang="tsx">
|
||||
import { NButton, NPopconfirm, NTag } from 'naive-ui';
|
||||
import { useBoolean } from '@sa/hooks';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import {
|
||||
fetchBatchDeleteRetryTask,
|
||||
fetchExecuteCallbackTask,
|
||||
fetchExecuteRetryTask,
|
||||
fetchGetAllGroupNameList,
|
||||
fetchGetRetryTaskById,
|
||||
fetchGetRetryTaskList,
|
||||
fetchUpdateRetryTaskStatus
|
||||
} from '@/service/api';
|
||||
import { ref } from 'vue';
|
||||
import { useBoolean } from '~/packages/hooks';
|
||||
import { fetchBatchDeleteRetryLog, fetchDeleteRetryLog, fetchRetryLogById, fetchRetryLogPageList } from '@/service/api';
|
||||
import { $t } from '@/locales';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { useTable, useTableOperate } from '@/hooks/common/table';
|
||||
import { retryStatusTypeRecord, retryTaskTypeRecord } from '@/constants/business';
|
||||
import { tagColor } from '@/utils/common';
|
||||
import RetryTaskOperateDrawer from './modules/retry-task-operate-drawer.vue';
|
||||
import RetryTaskBatchAddDrawer from './modules/retry-task-batch-add-drawer.vue';
|
||||
import RetryTaskSearch from './modules/retry-task-search.vue';
|
||||
import RetryTaskDetailDrawerVue from './modules/retry-task-detail-drawer.vue';
|
||||
|
||||
/** 详情页属性数据 */
|
||||
const detailData = ref<Api.Retry.Retry | null>();
|
||||
/** 详情页可见状态 */
|
||||
const { bool: detailVisible, setTrue: openDetail } = useBoolean(false);
|
||||
import { retryTaskStatusTypeRecord, retryTaskTypeRecord } from '@/constants/business';
|
||||
import { monthRangeISO8601, tagColor } from '@/utils/common';
|
||||
import RetryLogSearch from './modules/retry-task-search.vue';
|
||||
import RetryLogDetailDrawer from './modules/retry-task-detail-drawer.vue';
|
||||
|
||||
const appStore = useAppStore();
|
||||
|
||||
/** 详情页属性数据 */
|
||||
const detailData = ref<Api.RetryTask.RetryTask | null>();
|
||||
/** 详情页可见状态 */
|
||||
const { bool: detailVisible, setTrue: openDetail } = useBoolean(false);
|
||||
const taskStatus = history.state.taskStatus;
|
||||
|
||||
const { columns, columnChecks, data, getData, loading, mobilePagination, searchParams, resetSearchParams } = useTable({
|
||||
apiFn: fetchGetRetryTaskList,
|
||||
apiFn: fetchRetryLogPageList,
|
||||
apiParams: {
|
||||
page: 1,
|
||||
size: 10,
|
||||
// if you want to use the searchParams in Form, you need to define the following properties, and the value is null
|
||||
// the value can not be undefined, otherwise the property in Form will not be reactive
|
||||
groupName: null,
|
||||
sceneName: null,
|
||||
idempotentId: null,
|
||||
bizNo: null,
|
||||
retryStatus: null
|
||||
taskStatus: null,
|
||||
datetimeRange: monthRangeISO8601()
|
||||
},
|
||||
searchParams: {
|
||||
taskStatus
|
||||
},
|
||||
columns: () => [
|
||||
{
|
||||
type: 'selection',
|
||||
align: 'center',
|
||||
width: 48,
|
||||
disabled: row => row.retryStatus === 0
|
||||
disabled: row => row.taskStatus === 1
|
||||
},
|
||||
{
|
||||
key: 'id',
|
||||
title: $t('common.index'),
|
||||
align: 'center',
|
||||
width: 128,
|
||||
width: 64,
|
||||
render: row => {
|
||||
async function showDetailDrawer() {
|
||||
await loadRetryInfo(row);
|
||||
@ -66,162 +61,68 @@ const { columns, columnChecks, data, getData, loading, mobilePagination, searchP
|
||||
},
|
||||
{
|
||||
key: 'groupName',
|
||||
title: $t('page.retryTask.groupName'),
|
||||
align: 'left',
|
||||
resizable: true,
|
||||
minWidth: 120,
|
||||
maxWidth: 250
|
||||
},
|
||||
{
|
||||
key: 'sceneName',
|
||||
title: $t('page.retryTask.sceneName'),
|
||||
title: $t('page.retryLog.groupName'),
|
||||
align: 'left',
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
key: 'nextTriggerAt',
|
||||
title: $t('page.retryTask.nextTriggerAt'),
|
||||
key: 'sceneName',
|
||||
title: $t('page.retryLog.sceneName'),
|
||||
align: 'left',
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
key: 'taskStatus',
|
||||
title: $t('page.retryLog.retryStatus'),
|
||||
align: 'left',
|
||||
resizable: true,
|
||||
minWidth: 120,
|
||||
maxWidth: 150
|
||||
},
|
||||
{
|
||||
key: 'retryCount',
|
||||
title: $t('page.retryTask.retryCount'),
|
||||
align: 'center',
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
key: 'retryStatus',
|
||||
title: $t('page.retryTask.retryStatus'),
|
||||
align: 'left',
|
||||
width: 120,
|
||||
render: row => {
|
||||
if (row.retryStatus === null) {
|
||||
if (row.taskStatus === null) {
|
||||
return null;
|
||||
}
|
||||
const label = $t(retryStatusTypeRecord[row.retryStatus!]);
|
||||
const tagMap: Record<number, NaiveUI.ThemeColor> = {
|
||||
1: 'info',
|
||||
2: 'info',
|
||||
3: 'info',
|
||||
4: 'error',
|
||||
5: 'error',
|
||||
6: 'error'
|
||||
};
|
||||
|
||||
return <NTag type={tagColor(row.retryStatus!)}>{label}</NTag>;
|
||||
const label = $t(retryTaskStatusTypeRecord[row.taskStatus!]);
|
||||
|
||||
return <NTag type={tagMap[row.taskStatus!]}>{label}</NTag>;
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'taskType',
|
||||
title: $t('page.retryTask.taskType'),
|
||||
title: $t('page.retryLog.taskType'),
|
||||
align: 'left',
|
||||
width: 100,
|
||||
minWidth: 120,
|
||||
render: row => {
|
||||
if (row.taskType === null) {
|
||||
return null;
|
||||
}
|
||||
const tagMap: Record<Api.Retry.TaskType, NaiveUI.ThemeColor> = {
|
||||
1: 'warning',
|
||||
2: 'error'
|
||||
};
|
||||
const label = $t(retryTaskTypeRecord[row.taskType!]);
|
||||
|
||||
return <NTag type={tagMap[row.taskType!]}>{label}</NTag>;
|
||||
return <NTag type={tagColor(row.taskType!)}>{label}</NTag>;
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'idempotentId',
|
||||
title: $t('page.retryTask.idempotentId'),
|
||||
key: 'createDt',
|
||||
title: $t('page.retryLog.createDt'),
|
||||
align: 'left',
|
||||
resizable: true,
|
||||
minWidth: 150,
|
||||
maxWidth: 300
|
||||
},
|
||||
{
|
||||
key: 'bizNo',
|
||||
title: $t('page.retryTask.bizNo'),
|
||||
align: 'left',
|
||||
resizable: true,
|
||||
minWidth: 150,
|
||||
maxWidth: 300
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
key: 'operate',
|
||||
title: $t('common.operate'),
|
||||
align: 'center',
|
||||
width: 260,
|
||||
fixed: 'right',
|
||||
width: 80,
|
||||
render: row => (
|
||||
<div class="flex-center gap-8px">
|
||||
{/* 非[完成,最大次数], 显示[执行]按钮 */}
|
||||
{row.retryStatus !== 1 && row.retryStatus !== 2 ? (
|
||||
<>
|
||||
<NPopconfirm onPositiveClick={() => handleExecute(row.groupName!, row.id! as any, row.taskType!)}>
|
||||
{{
|
||||
default: () => $t('common.confirmExecute'),
|
||||
trigger: () => (
|
||||
<NButton type="info" text ghost size="small">
|
||||
{$t('common.execute')}
|
||||
</NButton>
|
||||
)
|
||||
}}
|
||||
</NPopconfirm>
|
||||
<n-divider vertical />
|
||||
</>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{/* 非[完成,最大次数], 显示[完成]按钮 */}
|
||||
{row.retryStatus !== 1 && row.retryStatus !== 2 ? (
|
||||
<>
|
||||
<NPopconfirm onPositiveClick={() => handleFinish(Number(row.id!), row.groupName!)}>
|
||||
{{
|
||||
default: () => $t('common.confirmFinish'),
|
||||
trigger: () => (
|
||||
<NButton type="warning" text ghost size="small">
|
||||
{$t('common.finish')}
|
||||
</NButton>
|
||||
)
|
||||
}}
|
||||
</NPopconfirm>
|
||||
<n-divider vertical />
|
||||
</>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{/* 重试中, 显示[停止]按钮 */}
|
||||
{row.retryStatus === 0 ? (
|
||||
<>
|
||||
<NPopconfirm onPositiveClick={() => handlePause(Number(row.id!), row.groupName!)}>
|
||||
{{
|
||||
default: () => $t('common.confirmPause'),
|
||||
trigger: () => (
|
||||
<NButton type="success" text ghost size="small">
|
||||
{$t('common.pause')}
|
||||
</NButton>
|
||||
)
|
||||
}}
|
||||
</NPopconfirm>
|
||||
<n-divider vertical />
|
||||
</>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{/* 暂停, 显示[开始]按钮 */}
|
||||
{row.retryStatus === 3 ? (
|
||||
<>
|
||||
<NPopconfirm onPositiveClick={() => handleResume(Number(row.id!), row.groupName!)}>
|
||||
{{
|
||||
default: () => $t('common.confirmResume'),
|
||||
trigger: () => (
|
||||
<NButton type="info" text ghost size="small">
|
||||
{$t('common.resume')}
|
||||
</NButton>
|
||||
)
|
||||
}}
|
||||
</NPopconfirm>
|
||||
<n-divider vertical />
|
||||
</>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{
|
||||
<NPopconfirm onPositiveClick={() => handleDelete(row.groupName!, row.id!)}>
|
||||
{row.taskStatus === 1 || row.taskStatus === 2 ? (
|
||||
<NPopconfirm onPositiveClick={() => handleDelete(row.id)}>
|
||||
{{
|
||||
default: () => $t('common.confirmDelete'),
|
||||
trigger: () => (
|
||||
@ -231,93 +132,40 @@ const { columns, columnChecks, data, getData, loading, mobilePagination, searchP
|
||||
)
|
||||
}}
|
||||
</NPopconfirm>
|
||||
}
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
const {
|
||||
drawerVisible,
|
||||
operateType,
|
||||
handleAdd,
|
||||
checkedRowKeys,
|
||||
onBatchDeleted,
|
||||
onDeleted
|
||||
// closeDrawer
|
||||
} = useTableOperate(data, getData);
|
||||
|
||||
const { bool: batchAddDrawerVisible, setTrue: openBatchAddDrawer } = useBoolean();
|
||||
|
||||
async function handleDelete(groupName: string, id: string) {
|
||||
const { error } = await fetchBatchDeleteRetryTask({ groupName, ids: [id] });
|
||||
if (error) return;
|
||||
onDeleted();
|
||||
}
|
||||
|
||||
async function loadRetryInfo(row: Api.Retry.Retry) {
|
||||
const res = await fetchGetRetryTaskById(row.id!, row.groupName!);
|
||||
detailData.value = (res.data as Api.Retry.Retry) || null;
|
||||
}
|
||||
const { checkedRowKeys, onDeleted, onBatchDeleted } = useTableOperate(data, getData);
|
||||
|
||||
async function handleBatchDelete() {
|
||||
const ids: string[] = checkedRowKeys.value as string[];
|
||||
if (ids.length === 0) return;
|
||||
const groupName = data.value[0].groupName;
|
||||
const { error } = await fetchBatchDeleteRetryTask({ groupName, ids });
|
||||
const { error } = await fetchBatchDeleteRetryLog(checkedRowKeys.value as any[]);
|
||||
if (error) return;
|
||||
onBatchDeleted();
|
||||
}
|
||||
|
||||
function handleBatchAdd() {
|
||||
openBatchAddDrawer();
|
||||
}
|
||||
|
||||
function handleExecute(groupName: string, retryId: number, type: Api.Retry.TaskType) {
|
||||
if (type === 1) {
|
||||
fetchExecuteRetryTask({ groupName, retryIds: [retryId] });
|
||||
return;
|
||||
}
|
||||
|
||||
if (type === 2) {
|
||||
fetchExecuteCallbackTask({ groupName, retryIds: [retryId] });
|
||||
}
|
||||
}
|
||||
|
||||
function handleResume(id: number, groupName: string) {
|
||||
updateRetryTaskStatus(id, groupName, 0);
|
||||
}
|
||||
|
||||
function handlePause(id: number, groupName: string) {
|
||||
updateRetryTaskStatus(id, groupName, 3);
|
||||
}
|
||||
|
||||
function handleFinish(id: number, groupName: string) {
|
||||
updateRetryTaskStatus(id, groupName, 1);
|
||||
}
|
||||
|
||||
async function updateRetryTaskStatus(id: number, groupName: string, retryStatus: Api.Retry.RetryStatusType) {
|
||||
const { error } = await fetchUpdateRetryTaskStatus({ id, groupName, retryStatus });
|
||||
async function handleDelete(id: any) {
|
||||
const { error } = await fetchDeleteRetryLog(id);
|
||||
if (error) return;
|
||||
window.$message?.success($t('common.updateSuccess'));
|
||||
getData();
|
||||
onDeleted();
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
const { error, data: groupList } = await fetchGetAllGroupNameList();
|
||||
if (!error && groupList.length > 0) {
|
||||
searchParams.groupName = groupList[0];
|
||||
getData();
|
||||
}
|
||||
});
|
||||
async function loadRetryInfo(row: Api.RetryTask.RetryTask) {
|
||||
const res = await fetchRetryLogById(row.id!);
|
||||
detailData.value = (res.data as Api.RetryTask.RetryTask) || null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
||||
<RetryTaskSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getData" />
|
||||
<RetryLogSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getData" />
|
||||
<NCard
|
||||
:title="$t('page.retryTask.title')"
|
||||
:title="$t('page.retryLog.title')"
|
||||
:bordered="false"
|
||||
size="small"
|
||||
class="sm:flex-1-hidden card-wrapper"
|
||||
@ -328,36 +176,25 @@ onMounted(async () => {
|
||||
v-model:columns="columnChecks"
|
||||
:disabled-delete="checkedRowKeys.length === 0"
|
||||
:loading="loading"
|
||||
@add="handleAdd"
|
||||
:show-add="false"
|
||||
@delete="handleBatchDelete"
|
||||
@refresh="getData"
|
||||
>
|
||||
<template #addAfter>
|
||||
<NButton size="small" ghost type="primary" @click="handleBatchAdd">
|
||||
<template #icon>
|
||||
<icon-ic-round-plus class="text-icon" />
|
||||
</template>
|
||||
{{ $t('common.batchAdd') }}
|
||||
</NButton>
|
||||
</template>
|
||||
</TableHeaderOperation>
|
||||
/>
|
||||
</template>
|
||||
<NDataTable
|
||||
v-model:checked-row-keys="checkedRowKeys"
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
:flex-height="!appStore.isMobile"
|
||||
:scroll-x="2000"
|
||||
:scroll-x="962"
|
||||
:loading="loading"
|
||||
remote
|
||||
:row-key="row => row.id"
|
||||
:pagination="mobilePagination"
|
||||
class="sm:h-full"
|
||||
/>
|
||||
<RetryTaskOperateDrawer v-model:visible="drawerVisible" :operate-type="operateType" @submitted="getData" />
|
||||
<RetryTaskBatchAddDrawer v-model:visible="batchAddDrawerVisible" @submitted="getData" />
|
||||
<RetryTaskDetailDrawerVue v-model:visible="detailVisible" :row-data="detailData" />
|
||||
</NCard>
|
||||
<RetryLogDetailDrawer v-model:visible="detailVisible" :row-data="detailData" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -1,9 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { onBeforeUnmount, ref } from 'vue';
|
||||
import { $t } from '@/locales';
|
||||
import { tagColor } from '@/utils/common';
|
||||
import { retryStatusTypeRecord, retryTaskTypeRecord } from '@/constants/business';
|
||||
import { fetchRetryLogList } from '@/service/api/log';
|
||||
import { retryTaskStatusTypeRecord, retryTaskTypeRecord } from '@/constants/business';
|
||||
|
||||
defineOptions({
|
||||
name: 'SceneDetailDrawer'
|
||||
@ -11,102 +9,43 @@ defineOptions({
|
||||
|
||||
interface Props {
|
||||
/** row data */
|
||||
rowData?: Api.Retry.Retry | null;
|
||||
rowData?: Api.RetryTask.RetryTask | null;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
defineProps<Props>();
|
||||
|
||||
const visible = defineModel<boolean>('visible', {
|
||||
default: false
|
||||
});
|
||||
|
||||
const logList = ref<Api.JobLog.JobMessage[]>([]);
|
||||
const interval = ref<NodeJS.Timeout>();
|
||||
const controller = new AbortController();
|
||||
const finished = ref<boolean>(false);
|
||||
let startId = '0';
|
||||
let fromIndex: number = 0;
|
||||
|
||||
async function getLogList() {
|
||||
const { data: logData, error } = await fetchRetryLogList({
|
||||
groupName: props.rowData!.groupName,
|
||||
retryTaskId: props.rowData!.id! as any,
|
||||
startId,
|
||||
fromIndex,
|
||||
size: 50
|
||||
});
|
||||
if (!error) {
|
||||
finished.value = logData.finished;
|
||||
startId = logData.nextStartId;
|
||||
fromIndex = logData.fromIndex;
|
||||
if (logData.message) {
|
||||
logList.value.push(...logData.message);
|
||||
logList.value.sort((a, b) => Number.parseInt(a.time_stamp, 10) - Number.parseInt(b.time_stamp, 10));
|
||||
}
|
||||
if (!finished.value) {
|
||||
clearTimeout(interval.value);
|
||||
interval.value = setTimeout(getLogList, 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const handleUpdateTab = async (value: number) => {
|
||||
if (value === 1 && logList.value.length === 0) {
|
||||
await getLogList();
|
||||
}
|
||||
};
|
||||
|
||||
const stopLog = () => {
|
||||
finished.value = true;
|
||||
controller.abort();
|
||||
clearTimeout(interval.value);
|
||||
interval.value = undefined;
|
||||
};
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
stopLog();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<OperateDrawer v-model="visible" :title="$t('page.retryTask.detail')">
|
||||
<NTabs type="segment" animated @update:value="handleUpdateTab">
|
||||
<DetailDrawer v-model="visible" :title="$t('page.retryLog.detail')" :width="['50%', '90%']">
|
||||
<NTabs type="segment" animated>
|
||||
<NTabPane :name="0" :tab="$t('page.log.info')">
|
||||
<NDescriptions label-placement="top" bordered :column="2">
|
||||
<NDescriptionsItem :label="$t('page.retryTask.groupName')" :span="2">
|
||||
<NDescriptionsItem :label="$t('page.retryLog.groupName')" :span="2">
|
||||
{{ rowData?.groupName }}
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem :label="$t('page.retryTask.sceneName')" :span="2">
|
||||
<NDescriptionsItem :label="$t('page.retryLog.sceneName')" :span="2">
|
||||
{{ rowData?.sceneName }}
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem :label="$t('page.retryTask.nextTriggerAt')" :span="1">
|
||||
{{ rowData?.nextTriggerAt }}
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem :label="$t('page.retryTask.retryCount')" :span="1">
|
||||
{{ rowData?.retryCount }}
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem :label="$t('page.retryTask.retryStatus')" :span="1">
|
||||
<NTag :type="tagColor(rowData?.retryStatus!)">
|
||||
{{ $t(retryStatusTypeRecord[rowData?.retryStatus!]) }}
|
||||
<NDescriptionsItem :label="$t('page.retryLog.retryStatus')" :span="1">
|
||||
<NTag :type="tagColor(rowData?.taskStatus!)">
|
||||
{{ $t(retryTaskStatusTypeRecord[rowData?.taskStatus!]) }}
|
||||
</NTag>
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem :label="$t('page.retryTask.taskType')" :span="1">
|
||||
<NDescriptionsItem :label="$t('page.retryLog.taskType')" :span="1">
|
||||
<NTag :type="tagColor(rowData?.taskType!)">{{ $t(retryTaskTypeRecord[rowData?.taskType!]) }}</NTag>
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem :label="$t('page.retryTask.bizNo')" :span="2">{{ rowData?.bizNo }}</NDescriptionsItem>
|
||||
<NDescriptionsItem :label="$t('page.retryTask.idempotentId')" :span="2">
|
||||
{{ rowData?.idempotentId }}
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem :label="$t('page.retryTask.executorName')" :span="2">
|
||||
{{ rowData?.executorName }}
|
||||
</NDescriptionsItem>
|
||||
<NDescriptionsItem :label="$t('page.retryTask.argsStr')" :span="2">{{ rowData?.argsStr }}</NDescriptionsItem>
|
||||
<NDescriptionsItem :label="$t('common.createDt')" :span="1">{{ rowData?.createDt }}</NDescriptionsItem>
|
||||
<NDescriptionsItem :label="$t('common.updateDt')" :span="1">{{ rowData?.updateDt }}</NDescriptionsItem>
|
||||
<NDescriptionsItem :label="$t('common.createDt')">{{ rowData?.createDt }}</NDescriptionsItem>
|
||||
</NDescriptions>
|
||||
</NTabPane>
|
||||
<NTabPane :name="1" :tab="$t('page.log.title')" display-directive="if">
|
||||
<LogDrawer :drawer="false" type="retry" :task-data="rowData!" />
|
||||
</NTabPane>
|
||||
</NTabs>
|
||||
</OperateDrawer>
|
||||
</DetailDrawer>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
@ -4,9 +4,10 @@ import { translateOptions } from '@/utils/common';
|
||||
import { retryStatusTypeOptions } from '@/constants/business';
|
||||
import SelectGroup from '@/components/common/select-group.vue';
|
||||
import SelectScene from '@/components/common/select-scene.vue';
|
||||
import DatetimeRange from '@/components/common/datetime-range.vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'RetryTaskSearch'
|
||||
name: 'RetryLogSearch'
|
||||
});
|
||||
|
||||
interface Emits {
|
||||
@ -16,7 +17,7 @@ interface Emits {
|
||||
|
||||
const emit = defineEmits<Emits>();
|
||||
|
||||
const model = defineModel<Api.Retry.RetrySearchParams>('model', { required: true });
|
||||
const model = defineModel<Api.RetryTask.RetryTaskSearchParams>('model', { required: true });
|
||||
|
||||
function reset() {
|
||||
emit('reset');
|
||||
@ -28,30 +29,38 @@ function search() {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<SearchForm :model="model" @search="search" @reset="reset">
|
||||
<NFormItemGi span="24 s:12 m:6" :label="$t('page.retryTask.groupName')" path="groupName" class="pr-24px">
|
||||
<SearchForm btn-span="24 xl:3" :model="model" @search="search" @reset="reset">
|
||||
<NFormItemGi span="24 s:12 m:6" :label="$t('page.retryLog.groupName')" path="groupName" class="pr-24px">
|
||||
<SelectGroup v-model:value="model.groupName" clearable />
|
||||
</NFormItemGi>
|
||||
<NFormItemGi span="24 s:12 m:6" :label="$t('page.retryTask.sceneName')" path="sceneName" class="pr-24px">
|
||||
<NFormItemGi span="24 s:12 m:6" :label="$t('page.retryLog.sceneName')" path="sceneName" class="pr-24px">
|
||||
<SelectScene v-model:value="model.sceneName" :group-name="model.groupName as string" clearable />
|
||||
</NFormItemGi>
|
||||
<!-- <NFormItemGi span="24 s:12 m:6" :label="$t('page.retryTask.uniqueId')" path="uniqueId" class="pr-24px">-->
|
||||
<!-- <NInput v-model:value="model.uniqueId" :placeholder="$t('page.retryTask.form.uniqueId')" clearable />-->
|
||||
<!-- <NFormItemGi span="24 s:12 m:6" :label="$t('page.retryLog.UniqueId')" path="UniqueId" class="pr-24px">-->
|
||||
<!-- <NInput v-model:value="model.uniqueId" :placeholder="$t('page.retryLog.form.UniqueId')" clearable />-->
|
||||
<!-- </NFormItemGi>-->
|
||||
<NFormItemGi span="24 s:12 m:6" :label="$t('page.retryTask.idempotentId')" path="idempotentId" class="pr-24px">
|
||||
<NInput v-model:value="model.idempotentId" :placeholder="$t('page.retryTask.form.idempotentId')" clearable />
|
||||
</NFormItemGi>
|
||||
<NFormItemGi span="24 s:12 m:6" :label="$t('page.retryTask.bizNo')" path="bizNo" class="pr-24px">
|
||||
<NInput v-model:value="model.bizNo" :placeholder="$t('page.retryTask.form.bizNo')" clearable />
|
||||
</NFormItemGi>
|
||||
<NFormItemGi span="24 s:12 m:6" :label="$t('page.retryTask.retryStatus')" path="retryStatus" class="pr-24px">
|
||||
<!-- <NFormItemGi span="24 s:12 m:6" :label="$t('page.retryLog.idempotentId')" path="idempotentId" class="pr-24px">-->
|
||||
<!-- <NInput v-model:value="model.idempotentId" :placeholder="$t('page.retryLog.form.idempotentId')" clearable />-->
|
||||
<!-- </NFormItemGi>-->
|
||||
<!-- <NFormItemGi span="24 s:12 m:6" :label="$t('page.retryLog.bizNo')" path="bizNo" class="pr-24px">-->
|
||||
<!-- <NInput v-model:value="model.bizNo" :placeholder="$t('page.retryLog.form.bizNo')" clearable />-->
|
||||
<!-- </NFormItemGi>-->
|
||||
<NFormItemGi span="24 s:12 m:6" :label="$t('page.retryLog.retryStatus')" path="taskBatchStatus" class="pr-24px">
|
||||
<NSelect
|
||||
v-model:value="model.retryStatus"
|
||||
v-model:value="model.taskStatus"
|
||||
:placeholder="$t('page.retryTask.form.retryStatus')"
|
||||
:options="translateOptions(retryStatusTypeOptions)"
|
||||
clearable
|
||||
/>
|
||||
</NFormItemGi>
|
||||
<NFormItemGi
|
||||
span="24 s:24 m:15 l:12 xl:9"
|
||||
:label="$t('page.common.createTime')"
|
||||
path="datetimeRange"
|
||||
class="pr-24px"
|
||||
>
|
||||
<DatetimeRange v-model:value="model.datetimeRange!" />
|
||||
</NFormItemGi>
|
||||
</SearchForm>
|
||||
</template>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user