Commit 92bcaa04d1b1d603ac7410c9a8f827fadcbb931a
1 parent
562282b2
refactor: job vxe
Showing
6 changed files
with
358 additions
and
402 deletions
yudao-ui-admin-vue3/src/api/infra/job/index.ts
| 1 | 1 | import request from '@/config/axios' |
| 2 | -import type { JobVO } from './types' | |
| 2 | + | |
| 3 | +export type JobVO = { | |
| 4 | + id: number | |
| 5 | + name: string | |
| 6 | + status: number | |
| 7 | + handlerName: string | |
| 8 | + handlerParam: string | |
| 9 | + cronExpression: string | |
| 10 | + retryCount: number | |
| 11 | + retryInterval: number | |
| 12 | + monitorTimeout: number | |
| 13 | +} | |
| 3 | 14 | |
| 4 | 15 | // 任务列表 |
| 5 | 16 | export const getJobPageApi = (params) => { | ... | ... |
yudao-ui-admin-vue3/src/api/infra/jobLog/index.ts
| 1 | 1 | import request from '@/config/axios' |
| 2 | 2 | |
| 3 | +export type JobLogVO = { | |
| 4 | + id: number | |
| 5 | + jobId: number | |
| 6 | + handlerName: string | |
| 7 | + handlerParam: string | |
| 8 | + cronExpression: string | |
| 9 | + executeIndex: string | |
| 10 | + beginTime: string | |
| 11 | + endTime: string | |
| 12 | + duration: string | |
| 13 | + status: number | |
| 14 | + createTime: string | |
| 15 | +} | |
| 16 | + | |
| 3 | 17 | // 任务日志列表 |
| 4 | 18 | export const getJobLogPageApi = (params) => { |
| 5 | 19 | return request.get({ url: '/infra/job-log/page', params }) | ... | ... |
yudao-ui-admin-vue3/src/views/infra/job/JobLog.vue
| 1 | -<script setup lang="ts"> | |
| 2 | -import { onMounted, ref } from 'vue' | |
| 3 | -import dayjs from 'dayjs' | |
| 4 | -import * as JobLogApi from '@/api/infra/jobLog' | |
| 5 | -import { JobLogVO } from '@/api/infra/jobLog/types' | |
| 6 | -import { DICT_TYPE } from '@/utils/dict' | |
| 7 | -import { useTable } from '@/hooks/web/useTable' | |
| 8 | -import { useI18n } from '@/hooks/web/useI18n' | |
| 9 | -import { useRoute } from 'vue-router' | |
| 10 | -import { allSchemas } from './jobLog.data' | |
| 11 | -const { t } = useI18n() // 国际化 | |
| 12 | -const { query } = useRoute() | |
| 13 | -// ========== 列表相关 ========== | |
| 14 | -const { register, tableObject, methods } = useTable<JobLogVO>({ | |
| 15 | - getListApi: JobLogApi.getJobLogPageApi, | |
| 16 | - exportListApi: JobLogApi.exportJobLogApi | |
| 17 | -}) | |
| 18 | -const { getList, setSearchParams, exportList } = methods | |
| 19 | -const getTableList = async () => { | |
| 20 | - const id = (query.id as unknown as number) && (query.jobId as unknown as number) | |
| 21 | - tableObject.params = { | |
| 22 | - jobId: id | |
| 23 | - } | |
| 24 | - await getList() | |
| 25 | -} | |
| 26 | - | |
| 27 | -// ========== CRUD 相关 ========== | |
| 28 | -const dialogVisible = ref(false) // 是否显示弹出层 | |
| 29 | -const dialogTitle = ref('') // 弹出层标题 | |
| 30 | - | |
| 31 | -// ========== 详情相关 ========== | |
| 32 | -const detailRef = ref() // 详情 Ref | |
| 33 | - | |
| 34 | -// 详情操作 | |
| 35 | -const handleDetail = async (row: JobLogVO) => { | |
| 36 | - // 设置数据 | |
| 37 | - const res = JobLogApi.getJobLogApi(row.id) | |
| 38 | - detailRef.value = res | |
| 39 | - dialogTitle.value = t('action.detail') | |
| 40 | - dialogVisible.value = true | |
| 41 | -} | |
| 42 | - | |
| 43 | -// ========== 初始化 ========== | |
| 44 | -onMounted(() => { | |
| 45 | - getTableList() | |
| 46 | -}) | |
| 47 | -</script> | |
| 48 | 1 | <template> |
| 49 | - <!-- 搜索工作区 --> | |
| 50 | - <ContentWrap> | |
| 51 | - <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" /> | |
| 52 | - </ContentWrap> | |
| 53 | 2 | <ContentWrap> |
| 54 | - <!-- 操作工具栏 --> | |
| 55 | - <div class="mb-10px"> | |
| 56 | - <el-button | |
| 57 | - type="warning" | |
| 58 | - v-hasPermi="['infra:job:export']" | |
| 59 | - :loading="tableObject.exportLoading" | |
| 60 | - @click="exportList('定时任务日志.xls')" | |
| 61 | - > | |
| 62 | - <Icon icon="ep:download" class="mr-5px" /> {{ t('action.export') }} | |
| 63 | - </el-button> | |
| 64 | - </div> | |
| 65 | 3 | <!-- 列表 --> |
| 66 | - <Table | |
| 67 | - :columns="allSchemas.tableColumns" | |
| 68 | - :selection="false" | |
| 69 | - :data="tableObject.tableList" | |
| 70 | - :loading="tableObject.loading" | |
| 71 | - :pagination="{ | |
| 72 | - total: tableObject.total | |
| 73 | - }" | |
| 74 | - v-model:pageSize="tableObject.pageSize" | |
| 75 | - v-model:currentPage="tableObject.currentPage" | |
| 76 | - @register="register" | |
| 77 | - > | |
| 78 | - <template #beginTime="{ row }"> | |
| 4 | + <vxe-grid ref="xGrid" v-bind="gridOptions" class="xtable-scrollbar"> | |
| 5 | + <template #toolbar_buttons> | |
| 6 | + <XButton | |
| 7 | + type="warning" | |
| 8 | + preIcon="ep:download" | |
| 9 | + :title="t('action.export')" | |
| 10 | + v-hasPermi="['infra:job:export']" | |
| 11 | + @click="handleExport()" | |
| 12 | + /> | |
| 13 | + </template> | |
| 14 | + <template #beginTime_default="{ row }"> | |
| 79 | 15 | <span>{{ |
| 80 | 16 | dayjs(row.beginTime).format('YYYY-MM-DD HH:mm:ss') + |
| 81 | 17 | ' ~ ' + |
| 82 | 18 | dayjs(row.endTime).format('YYYY-MM-DD HH:mm:ss') |
| 83 | 19 | }}</span> |
| 84 | 20 | </template> |
| 85 | - <template #duration="{ row }"> | |
| 21 | + <template #duration_default="{ row }"> | |
| 86 | 22 | <span>{{ row.duration + ' 毫秒' }}</span> |
| 87 | 23 | </template> |
| 88 | - <template #status="{ row }"> | |
| 89 | - <DictTag :type="DICT_TYPE.INFRA_JOB_LOG_STATUS" :value="row.status" /> | |
| 90 | - </template> | |
| 91 | - <template #action="{ row }"> | |
| 92 | - <el-button link type="primary" v-hasPermi="['infra:job:query']" @click="handleDetail(row)"> | |
| 93 | - <Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }} | |
| 94 | - </el-button> | |
| 24 | + <template #actionbtns_default="{ row }"> | |
| 25 | + <XTextButton | |
| 26 | + preIcon="ep:view" | |
| 27 | + :title="t('action.detail')" | |
| 28 | + v-hasPermi="['infra:job:query']" | |
| 29 | + @click="handleDetail(row)" | |
| 30 | + /> | |
| 95 | 31 | </template> |
| 96 | - </Table> | |
| 32 | + </vxe-grid> | |
| 97 | 33 | </ContentWrap> |
| 98 | 34 | <XModal v-model="dialogVisible" :title="dialogTitle"> |
| 99 | 35 | <!-- 对话框(详情) --> |
| ... | ... | @@ -111,3 +47,42 @@ onMounted(() => { |
| 111 | 47 | </template> |
| 112 | 48 | </XModal> |
| 113 | 49 | </template> |
| 50 | + | |
| 51 | +<script setup lang="ts"> | |
| 52 | +import { ref } from 'vue' | |
| 53 | +import dayjs from 'dayjs' | |
| 54 | +import { useI18n } from '@/hooks/web/useI18n' | |
| 55 | +import { useVxeGrid } from '@/hooks/web/useVxeGrid' | |
| 56 | +import { VxeGridInstance } from 'vxe-table' | |
| 57 | +import * as JobLogApi from '@/api/infra/jobLog' | |
| 58 | +import { JobLogVO } from '@/api/infra/jobLog/types' | |
| 59 | +import { allSchemas } from './jobLog.data' | |
| 60 | + | |
| 61 | +const { t } = useI18n() // 国际化 | |
| 62 | +// 列表相关的变量 | |
| 63 | +const xGrid = ref<VxeGridInstance>() // 列表 Grid Ref | |
| 64 | +const { gridOptions, exportList } = useVxeGrid<JobLogApi.JobLogVO>({ | |
| 65 | + allSchemas: allSchemas, | |
| 66 | + getListApi: JobLogApi.getJobLogPageApi, | |
| 67 | + exportListApi: JobLogApi.exportJobLogApi | |
| 68 | +}) | |
| 69 | +// ========== CRUD 相关 ========== | |
| 70 | +const dialogVisible = ref(false) // 是否显示弹出层 | |
| 71 | +const dialogTitle = ref('') // 弹出层标题 | |
| 72 | + | |
| 73 | +// ========== 详情相关 ========== | |
| 74 | +const detailRef = ref() // 详情 Ref | |
| 75 | + | |
| 76 | +// 详情操作 | |
| 77 | +const handleDetail = async (row: JobLogVO) => { | |
| 78 | + // 设置数据 | |
| 79 | + const res = JobLogApi.getJobLogApi(row.id) | |
| 80 | + detailRef.value = res | |
| 81 | + dialogTitle.value = t('action.detail') | |
| 82 | + dialogVisible.value = true | |
| 83 | +} | |
| 84 | +// 导出操作 | |
| 85 | +const handleExport = async () => { | |
| 86 | + await exportList(xGrid, '定时任务详情.xls') | |
| 87 | +} | |
| 88 | +</script> | ... | ... |
yudao-ui-admin-vue3/src/views/infra/job/index.vue
| 1 | +<template> | |
| 2 | + <ContentWrap> | |
| 3 | + <!-- 列表 --> | |
| 4 | + <vxe-grid ref="xGrid" v-bind="gridOptions" class="xtable-scrollbar"> | |
| 5 | + <template #toolbar_buttons> | |
| 6 | + <!-- 操作:新增 --> | |
| 7 | + <XButton | |
| 8 | + type="primary" | |
| 9 | + preIcon="ep:zoom-in" | |
| 10 | + :title="t('action.add')" | |
| 11 | + v-hasPermi="['infra:job:create']" | |
| 12 | + @click="handleCreate()" | |
| 13 | + /> | |
| 14 | + <!-- 操作:导出 --> | |
| 15 | + <XButton | |
| 16 | + type="warning" | |
| 17 | + preIcon="ep:download" | |
| 18 | + :title="t('action.export')" | |
| 19 | + v-hasPermi="['infra:job:export']" | |
| 20 | + @click="handleExport()" | |
| 21 | + /> | |
| 22 | + <XButton | |
| 23 | + type="info" | |
| 24 | + preIcon="ep:zoom-in" | |
| 25 | + title="执行日志" | |
| 26 | + v-hasPermi="['infra:job:query']" | |
| 27 | + @click="handleJobLog" | |
| 28 | + /> | |
| 29 | + </template> | |
| 30 | + <template #actionbtns_default="{ row }"> | |
| 31 | + <!-- 操作:修改 --> | |
| 32 | + <XTextButton | |
| 33 | + preIcon="ep:edit" | |
| 34 | + :title="t('action.edit')" | |
| 35 | + v-hasPermi="['infra:job:update']" | |
| 36 | + @click="handleUpdate(row.id)" | |
| 37 | + /> | |
| 38 | + <el-button | |
| 39 | + link | |
| 40 | + type="primary" | |
| 41 | + v-hasPermi="['infra:job:update']" | |
| 42 | + @click="handleChangeStatus(row)" | |
| 43 | + > | |
| 44 | + <Icon icon="ep:edit" class="mr-1px" /> | |
| 45 | + {{ row.status === InfraJobStatusEnum.STOP ? '开启' : '暂停' }} | |
| 46 | + </el-button> | |
| 47 | + <!-- 操作:详情 --> | |
| 48 | + <XTextButton | |
| 49 | + preIcon="ep:view" | |
| 50 | + :title="t('action.detail')" | |
| 51 | + v-hasPermi="['infra:job:query']" | |
| 52 | + @click="handleDetail(row.id)" | |
| 53 | + /> | |
| 54 | + <!-- 操作:删除 --> | |
| 55 | + <XTextButton | |
| 56 | + preIcon="ep:delete" | |
| 57 | + :title="t('action.del')" | |
| 58 | + v-hasPermi="['infra:job:delete']" | |
| 59 | + @click="handleDelete(row.id)" | |
| 60 | + /> | |
| 61 | + <XTextButton | |
| 62 | + preIcon="ep:view" | |
| 63 | + title="执行一次" | |
| 64 | + v-hasPermi="['infra:job:trigger']" | |
| 65 | + @click="handleRun(row)" | |
| 66 | + /> | |
| 67 | + <XTextButton | |
| 68 | + preIcon="ep:view" | |
| 69 | + title="调度日志" | |
| 70 | + v-hasPermi="['infra:job:query']" | |
| 71 | + @click="handleJobLog(row.id)" | |
| 72 | + /> | |
| 73 | + </template> | |
| 74 | + </vxe-grid> | |
| 75 | + </ContentWrap> | |
| 76 | + <XModal v-model="dialogVisible" :title="dialogTitle"> | |
| 77 | + <!-- 对话框(添加 / 修改) --> | |
| 78 | + <Form | |
| 79 | + v-if="['create', 'update'].includes(actionType)" | |
| 80 | + :schema="allSchemas.formSchema" | |
| 81 | + :rules="rules" | |
| 82 | + ref="formRef" | |
| 83 | + > | |
| 84 | + <template #cronExpression> | |
| 85 | + <Crontab v-model="cronExpression" :shortcuts="shortcuts" /> | |
| 86 | + </template> | |
| 87 | + </Form> | |
| 88 | + <!-- 对话框(详情) --> | |
| 89 | + <Descriptions | |
| 90 | + v-if="actionType === 'detail'" | |
| 91 | + :schema="allSchemas.detailSchema" | |
| 92 | + :data="detailRef" | |
| 93 | + > | |
| 94 | + <template #retryInterval="{ row }"> | |
| 95 | + <span>{{ row.retryInterval + '毫秒' }} </span> | |
| 96 | + </template> | |
| 97 | + <template #monitorTimeout="{ row }"> | |
| 98 | + <span>{{ row.monitorTimeout > 0 ? row.monitorTimeout + ' 毫秒' : '未开启' }}</span> | |
| 99 | + </template> | |
| 100 | + </Descriptions> | |
| 101 | + <!-- 操作按钮 --> | |
| 102 | + <template #footer> | |
| 103 | + <!-- 按钮:保存 --> | |
| 104 | + <XButton | |
| 105 | + v-if="['create', 'update'].includes(actionType)" | |
| 106 | + type="primary" | |
| 107 | + :title="t('action.save')" | |
| 108 | + :loading="actionLoading" | |
| 109 | + @click="submitForm()" | |
| 110 | + /> | |
| 111 | + <!-- 按钮:关闭 --> | |
| 112 | + <XButton :loading="actionLoading" :title="t('dialog.close')" @click="dialogVisible = false" /> | |
| 113 | + </template> | |
| 114 | + </XModal> | |
| 115 | +</template> | |
| 116 | + | |
| 1 | 117 | <script setup lang="ts"> |
| 2 | -import { Crontab } from '@/components/Crontab' | |
| 3 | 118 | import { ref, unref } from 'vue' |
| 4 | -import * as JobApi from '@/api/infra/job' | |
| 5 | -import { JobVO } from '@/api/infra/job/types' | |
| 6 | -import { DICT_TYPE } from '@/utils/dict' | |
| 7 | -import { useTable } from '@/hooks/web/useTable' | |
| 119 | +import { useRouter } from 'vue-router' | |
| 8 | 120 | import { useI18n } from '@/hooks/web/useI18n' |
| 121 | +import { useMessage } from '@/hooks/web/useMessage' | |
| 122 | +import { useVxeGrid } from '@/hooks/web/useVxeGrid' | |
| 123 | +import { VxeGridInstance } from 'vxe-table' | |
| 9 | 124 | import { FormExpose } from '@/components/Form' |
| 125 | +import { Crontab } from '@/components/Crontab' | |
| 126 | +import * as JobApi from '@/api/infra/job' | |
| 10 | 127 | import { rules, allSchemas } from './job.data' |
| 11 | -import { useRouter } from 'vue-router' | |
| 12 | -import { useMessage } from '@/hooks/web/useMessage' | |
| 13 | 128 | import { InfraJobStatusEnum } from '@/utils/constants' |
| 14 | -const message = useMessage() | |
| 129 | + | |
| 15 | 130 | const { t } = useI18n() // 国际化 |
| 131 | +const message = useMessage() // 消息弹窗 | |
| 16 | 132 | const { push } = useRouter() |
| 17 | -// ========== 列表相关 ========== | |
| 18 | -const { register, tableObject, methods } = useTable<JobVO>({ | |
| 133 | + | |
| 134 | +// 列表相关的变量 | |
| 135 | +const xGrid = ref<VxeGridInstance>() // 列表 Grid Ref | |
| 136 | +const { gridOptions, getList, deleteData, exportList } = useVxeGrid<JobApi.JobVO>({ | |
| 137 | + allSchemas: allSchemas, | |
| 19 | 138 | getListApi: JobApi.getJobPageApi, |
| 20 | - delListApi: JobApi.deleteJobApi, | |
| 139 | + deleteApi: JobApi.deleteJobApi, | |
| 21 | 140 | exportListApi: JobApi.exportJobApi |
| 22 | 141 | }) |
| 23 | -const { getList, setSearchParams, delList, exportList } = methods | |
| 24 | 142 | |
| 25 | 143 | // ========== CRUD 相关 ========== |
| 26 | 144 | const actionLoading = ref(false) // 遮罩层 |
| ... | ... | @@ -28,6 +146,7 @@ const actionType = ref('') // 操作按钮的类型 |
| 28 | 146 | const dialogVisible = ref(false) // 是否显示弹出层 |
| 29 | 147 | const dialogTitle = ref('edit') // 弹出层标题 |
| 30 | 148 | const formRef = ref<FormExpose>() // 表单 Ref |
| 149 | +const detailRef = ref() // 详情 Ref | |
| 31 | 150 | const cronExpression = ref('') |
| 32 | 151 | const shortcuts = ref([ |
| 33 | 152 | { |
| ... | ... | @@ -47,16 +166,31 @@ const handleCreate = () => { |
| 47 | 166 | cronExpression.value = '' |
| 48 | 167 | setDialogTile('create') |
| 49 | 168 | } |
| 50 | - | |
| 169 | +// 导出操作 | |
| 170 | +const handleExport = async () => { | |
| 171 | + await exportList(xGrid, '定时任务.xls') | |
| 172 | +} | |
| 51 | 173 | // 修改操作 |
| 52 | -const handleUpdate = async (row: JobVO) => { | |
| 174 | +const handleUpdate = async (rowId: number) => { | |
| 53 | 175 | setDialogTile('update') |
| 54 | 176 | // 设置数据 |
| 55 | - const res = await JobApi.getJobApi(row.id) | |
| 177 | + const res = await JobApi.getJobApi(rowId) | |
| 56 | 178 | cronExpression.value = res.cronExpression |
| 57 | 179 | unref(formRef)?.setValues(res) |
| 58 | 180 | } |
| 59 | -const handleChangeStatus = async (row: JobVO) => { | |
| 181 | + | |
| 182 | +// 详情操作 | |
| 183 | +const handleDetail = async (rowId: number) => { | |
| 184 | + // 设置数据 | |
| 185 | + const res = await JobApi.getJobApi(rowId) | |
| 186 | + detailRef.value = res | |
| 187 | + setDialogTile('detail') | |
| 188 | +} | |
| 189 | +// 删除操作 | |
| 190 | +const handleDelete = async (rowId: number) => { | |
| 191 | + await deleteData(xGrid, rowId) | |
| 192 | +} | |
| 193 | +const handleChangeStatus = async (row: JobApi.JobVO) => { | |
| 60 | 194 | const text = row.status === InfraJobStatusEnum.STOP ? '开启' : '关闭' |
| 61 | 195 | const status = |
| 62 | 196 | row.status === InfraJobStatusEnum.STOP ? InfraJobStatusEnum.NORMAL : InfraJobStatusEnum.STOP |
| ... | ... | @@ -69,7 +203,7 @@ const handleChangeStatus = async (row: JobVO) => { |
| 69 | 203 | : InfraJobStatusEnum.STOP |
| 70 | 204 | await JobApi.updateJobStatusApi(row.id, status) |
| 71 | 205 | message.success(text + '成功') |
| 72 | - await getList() | |
| 206 | + await getList(xGrid) | |
| 73 | 207 | }) |
| 74 | 208 | .catch(() => { |
| 75 | 209 | row.status = |
| ... | ... | @@ -79,19 +213,19 @@ const handleChangeStatus = async (row: JobVO) => { |
| 79 | 213 | }) |
| 80 | 214 | } |
| 81 | 215 | // 执行日志 |
| 82 | -const handleJobLog = (row: JobVO) => { | |
| 83 | - if (row.id) { | |
| 84 | - push('/job/job-log?id=' + row.id) | |
| 216 | +const handleJobLog = (rowId: number) => { | |
| 217 | + if (rowId) { | |
| 218 | + push('/job/job-log?id=' + rowId) | |
| 85 | 219 | } else { |
| 86 | 220 | push('/job/job-log') |
| 87 | 221 | } |
| 88 | 222 | } |
| 89 | 223 | // 执行一次 |
| 90 | -const handleRun = (row: JobVO) => { | |
| 224 | +const handleRun = (row: JobApi.JobVO) => { | |
| 91 | 225 | message.confirm('确认要立即执行一次' + row.name + '?', t('common.reminder')).then(async () => { |
| 92 | 226 | await JobApi.runJobApi(row.id) |
| 93 | 227 | message.success('执行成功') |
| 94 | - getList() | |
| 228 | + await getList(xGrid) | |
| 95 | 229 | }) |
| 96 | 230 | } |
| 97 | 231 | // 提交按钮 |
| ... | ... | @@ -103,7 +237,7 @@ const submitForm = async () => { |
| 103 | 237 | actionLoading.value = true |
| 104 | 238 | // 提交请求 |
| 105 | 239 | try { |
| 106 | - const data = unref(formRef)?.formModel as JobVO | |
| 240 | + const data = unref(formRef)?.formModel as JobApi.JobVO | |
| 107 | 241 | data.cronExpression = cronExpression.value |
| 108 | 242 | if (actionType.value === 'create') { |
| 109 | 243 | await JobApi.createJobApi(data) |
| ... | ... | @@ -112,139 +246,12 @@ const submitForm = async () => { |
| 112 | 246 | await JobApi.updateJobApi(data) |
| 113 | 247 | message.success(t('common.updateSuccess')) |
| 114 | 248 | } |
| 115 | - // 操作成功,重新加载列表 | |
| 116 | 249 | dialogVisible.value = false |
| 117 | - await getList() | |
| 118 | 250 | } finally { |
| 119 | 251 | actionLoading.value = false |
| 252 | + await getList(xGrid) | |
| 120 | 253 | } |
| 121 | 254 | } |
| 122 | 255 | }) |
| 123 | 256 | } |
| 124 | - | |
| 125 | -// ========== 详情相关 ========== | |
| 126 | -const detailRef = ref() // 详情 Ref | |
| 127 | - | |
| 128 | -// 详情操作 | |
| 129 | -const handleDetail = async (row: JobVO) => { | |
| 130 | - // 设置数据 | |
| 131 | - const res = JobApi.getJobApi(row.id) | |
| 132 | - detailRef.value = res | |
| 133 | - setDialogTile('detail') | |
| 134 | -} | |
| 135 | - | |
| 136 | -// ========== 初始化 ========== | |
| 137 | -getList() | |
| 138 | 257 | </script> |
| 139 | -<template> | |
| 140 | - <!-- 搜索工作区 --> | |
| 141 | - <ContentWrap> | |
| 142 | - <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" /> | |
| 143 | - </ContentWrap> | |
| 144 | - <ContentWrap> | |
| 145 | - <!-- 操作工具栏 --> | |
| 146 | - <div class="mb-10px"> | |
| 147 | - <el-button type="primary" v-hasPermi="['infra:job:create']" @click="handleCreate"> | |
| 148 | - <Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }} | |
| 149 | - </el-button> | |
| 150 | - <el-button | |
| 151 | - type="warning" | |
| 152 | - v-hasPermi="['infra:job:export']" | |
| 153 | - :loading="tableObject.exportLoading" | |
| 154 | - @click="exportList('定时任务.xls')" | |
| 155 | - > | |
| 156 | - <Icon icon="ep:download" class="mr-5px" /> {{ t('action.export') }} | |
| 157 | - </el-button> | |
| 158 | - <el-button type="info" v-hasPermi="['infra:job:query']" @click="handleJobLog"> | |
| 159 | - <Icon icon="ep:zoom-in" class="mr-5px" /> 执行日志 | |
| 160 | - </el-button> | |
| 161 | - </div> | |
| 162 | - <!-- 列表 --> | |
| 163 | - <Table | |
| 164 | - :columns="allSchemas.tableColumns" | |
| 165 | - :selection="false" | |
| 166 | - :data="tableObject.tableList" | |
| 167 | - :loading="tableObject.loading" | |
| 168 | - :pagination="{ | |
| 169 | - total: tableObject.total | |
| 170 | - }" | |
| 171 | - v-model:pageSize="tableObject.pageSize" | |
| 172 | - v-model:currentPage="tableObject.currentPage" | |
| 173 | - @register="register" | |
| 174 | - > | |
| 175 | - <template #status="{ row }"> | |
| 176 | - <DictTag :type="DICT_TYPE.INFRA_JOB_STATUS" :value="row.status" /> | |
| 177 | - </template> | |
| 178 | - <template #action="{ row }"> | |
| 179 | - <el-button link type="primary" v-hasPermi="['infra:job:update']" @click="handleUpdate(row)"> | |
| 180 | - <Icon icon="ep:edit" class="mr-1px" /> {{ t('action.edit') }} | |
| 181 | - </el-button> | |
| 182 | - <el-button | |
| 183 | - link | |
| 184 | - type="primary" | |
| 185 | - v-hasPermi="['infra:job:update']" | |
| 186 | - @click="handleChangeStatus(row)" | |
| 187 | - > | |
| 188 | - <Icon icon="ep:edit" class="mr-1px" /> | |
| 189 | - {{ row.status === InfraJobStatusEnum.STOP ? '开启' : '暂停' }} | |
| 190 | - </el-button> | |
| 191 | - <el-button link type="primary" v-hasPermi="['infra:job:query']" @click="handleDetail(row)"> | |
| 192 | - <Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }} | |
| 193 | - </el-button> | |
| 194 | - <el-button | |
| 195 | - link | |
| 196 | - type="primary" | |
| 197 | - v-hasPermi="['infra:job:delete']" | |
| 198 | - @click="delList(row.id, false)" | |
| 199 | - > | |
| 200 | - <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }} | |
| 201 | - </el-button> | |
| 202 | - <el-button link type="primary" v-hasPermi="['infra:job:trigger']" @click="handleRun(row)"> | |
| 203 | - <Icon icon="ep:view" class="mr-1px" /> 执行一次 | |
| 204 | - </el-button> | |
| 205 | - <el-button link type="primary" v-hasPermi="['infra:job:query']" @click="handleJobLog(row)"> | |
| 206 | - <Icon icon="ep:view" class="mr-1px" /> 调度日志 | |
| 207 | - </el-button> | |
| 208 | - </template> | |
| 209 | - </Table> | |
| 210 | - </ContentWrap> | |
| 211 | - <XModal v-model="dialogVisible" :title="dialogTitle"> | |
| 212 | - <!-- 对话框(添加 / 修改) --> | |
| 213 | - <Form | |
| 214 | - v-if="['create', 'update'].includes(actionType)" | |
| 215 | - :schema="allSchemas.formSchema" | |
| 216 | - :rules="rules" | |
| 217 | - ref="formRef" | |
| 218 | - > | |
| 219 | - <template #cronExpression> | |
| 220 | - <Crontab v-model="cronExpression" :shortcuts="shortcuts" /> | |
| 221 | - </template> | |
| 222 | - </Form> | |
| 223 | - <!-- 对话框(详情) --> | |
| 224 | - <Descriptions | |
| 225 | - v-if="actionType === 'detail'" | |
| 226 | - :schema="allSchemas.detailSchema" | |
| 227 | - :data="detailRef" | |
| 228 | - > | |
| 229 | - <template #retryInterval="{ row }"> | |
| 230 | - <span>{{ row.retryInterval + '毫秒' }} </span> | |
| 231 | - </template> | |
| 232 | - <template #monitorTimeout="{ row }"> | |
| 233 | - <span>{{ row.monitorTimeout > 0 ? row.monitorTimeout + ' 毫秒' : '未开启' }}</span> | |
| 234 | - </template> | |
| 235 | - </Descriptions> | |
| 236 | - <!-- 操作按钮 --> | |
| 237 | - <template #footer> | |
| 238 | - <!-- 按钮:保存 --> | |
| 239 | - <XButton | |
| 240 | - v-if="['create', 'update'].includes(actionType)" | |
| 241 | - type="primary" | |
| 242 | - :title="t('action.save')" | |
| 243 | - :loading="actionLoading" | |
| 244 | - @click="submitForm()" | |
| 245 | - /> | |
| 246 | - <!-- 按钮:关闭 --> | |
| 247 | - <XButton :loading="actionLoading" :title="t('dialog.close')" @click="dialogVisible = false" /> | |
| 248 | - </template> | |
| 249 | - </XModal> | |
| 250 | -</template> | ... | ... |
yudao-ui-admin-vue3/src/views/infra/job/job.data.ts
| ... | ... | @@ -2,9 +2,8 @@ import { reactive } from 'vue' |
| 2 | 2 | import { DICT_TYPE } from '@/utils/dict' |
| 3 | 3 | import { required } from '@/utils/formRules' |
| 4 | 4 | import { useI18n } from '@/hooks/web/useI18n' |
| 5 | -import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas' | |
| 6 | -// 国际化 | |
| 7 | -const { t } = useI18n() | |
| 5 | +import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas' | |
| 6 | +const { t } = useI18n() // 国际化 | |
| 8 | 7 | // 表单校验 |
| 9 | 8 | export const rules = reactive({ |
| 10 | 9 | name: [required], |
| ... | ... | @@ -14,87 +13,55 @@ export const rules = reactive({ |
| 14 | 13 | retryInterval: [required] |
| 15 | 14 | }) |
| 16 | 15 | // CrudSchema |
| 17 | -const crudSchemas = reactive<CrudSchema[]>([ | |
| 18 | - { | |
| 19 | - label: t('common.index'), | |
| 20 | - field: 'id', | |
| 21 | - type: 'index', | |
| 22 | - form: { | |
| 23 | - show: false | |
| 16 | +const crudSchemas = reactive<VxeCrudSchema>({ | |
| 17 | + primaryKey: 'id', | |
| 18 | + primaryType: 'seq', | |
| 19 | + action: true, | |
| 20 | + actionWidth: '500px', | |
| 21 | + columns: [ | |
| 22 | + { | |
| 23 | + title: '任务名称', | |
| 24 | + field: 'name', | |
| 25 | + search: { | |
| 26 | + show: true | |
| 27 | + } | |
| 24 | 28 | }, |
| 25 | - detail: { | |
| 26 | - show: false | |
| 27 | - } | |
| 28 | - }, | |
| 29 | - { | |
| 30 | - label: '任务名称', | |
| 31 | - field: 'name', | |
| 32 | - search: { | |
| 33 | - show: true | |
| 34 | - } | |
| 35 | - }, | |
| 36 | - { | |
| 37 | - label: t('common.status'), | |
| 38 | - field: 'status', | |
| 39 | - dictType: DICT_TYPE.INFRA_JOB_STATUS, | |
| 40 | - dictClass: 'number', | |
| 41 | - form: { | |
| 42 | - show: false | |
| 29 | + { | |
| 30 | + title: t('common.status'), | |
| 31 | + field: 'status', | |
| 32 | + dictType: DICT_TYPE.INFRA_JOB_STATUS, | |
| 33 | + dictClass: 'number', | |
| 34 | + isForm: false | |
| 43 | 35 | }, |
| 44 | - detail: { | |
| 45 | - show: false | |
| 46 | - } | |
| 47 | - }, | |
| 48 | - { | |
| 49 | - label: '处理器的名字', | |
| 50 | - field: 'handlerName', | |
| 51 | - search: { | |
| 52 | - show: true | |
| 53 | - } | |
| 54 | - }, | |
| 55 | - { | |
| 56 | - label: '处理器的参数', | |
| 57 | - field: 'handlerParam', | |
| 58 | - table: { | |
| 59 | - show: false | |
| 60 | - } | |
| 61 | - }, | |
| 62 | - { | |
| 63 | - label: 'CRON 表达式', | |
| 64 | - field: 'cronExpression' | |
| 65 | - }, | |
| 66 | - { | |
| 67 | - label: '重试次数', | |
| 68 | - field: 'retryCount', | |
| 69 | - table: { | |
| 70 | - show: false | |
| 71 | - } | |
| 72 | - }, | |
| 73 | - { | |
| 74 | - label: '重试间隔', | |
| 75 | - field: 'retryInterval', | |
| 76 | - table: { | |
| 77 | - show: false | |
| 78 | - } | |
| 79 | - }, | |
| 80 | - { | |
| 81 | - label: '监控超时时间', | |
| 82 | - field: 'monitorTimeout', | |
| 83 | - table: { | |
| 84 | - show: false | |
| 85 | - } | |
| 86 | - }, | |
| 87 | - { | |
| 88 | - field: 'action', | |
| 89 | - width: '500px', | |
| 90 | - label: t('table.action'), | |
| 91 | - form: { | |
| 92 | - show: false | |
| 36 | + { | |
| 37 | + title: '处理器的名字', | |
| 38 | + field: 'handlerName', | |
| 39 | + isSearch: true | |
| 40 | + }, | |
| 41 | + { | |
| 42 | + title: '处理器的参数', | |
| 43 | + field: 'handlerParam', | |
| 44 | + isTable: false | |
| 45 | + }, | |
| 46 | + { | |
| 47 | + title: 'CRON 表达式', | |
| 48 | + field: 'cronExpression' | |
| 93 | 49 | }, |
| 94 | - detail: { | |
| 95 | - show: false | |
| 50 | + { | |
| 51 | + title: '重试次数', | |
| 52 | + field: 'retryCount', | |
| 53 | + isTable: false | |
| 54 | + }, | |
| 55 | + { | |
| 56 | + title: '重试间隔', | |
| 57 | + field: 'retryInterval', | |
| 58 | + isTable: false | |
| 59 | + }, | |
| 60 | + { | |
| 61 | + title: '监控超时时间', | |
| 62 | + field: 'monitorTimeout', | |
| 63 | + isTable: false | |
| 96 | 64 | } |
| 97 | - } | |
| 98 | -]) | |
| 99 | - | |
| 100 | -export const { allSchemas } = useCrudSchemas(crudSchemas) | |
| 65 | + ] | |
| 66 | +}) | |
| 67 | +export const { allSchemas } = useVxeCrudSchemas(crudSchemas) | ... | ... |
yudao-ui-admin-vue3/src/views/infra/job/jobLog.data.ts
| 1 | 1 | import { reactive } from 'vue' |
| 2 | 2 | import { DICT_TYPE } from '@/utils/dict' |
| 3 | 3 | import { useI18n } from '@/hooks/web/useI18n' |
| 4 | -import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas' | |
| 4 | +import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas' | |
| 5 | 5 | // 国际化 |
| 6 | 6 | const { t } = useI18n() |
| 7 | 7 | // CrudSchema |
| 8 | -const crudSchemas = reactive<CrudSchema[]>([ | |
| 9 | - { | |
| 10 | - label: t('common.index'), | |
| 11 | - field: 'id', | |
| 12 | - type: 'index', | |
| 13 | - form: { | |
| 14 | - show: false | |
| 8 | +const crudSchemas = reactive<VxeCrudSchema>({ | |
| 9 | + primaryKey: 'id', | |
| 10 | + primaryType: 'seq', | |
| 11 | + action: true, | |
| 12 | + columns: [ | |
| 13 | + { | |
| 14 | + title: '任务编号', | |
| 15 | + field: 'jobId', | |
| 16 | + isSearch: true | |
| 15 | 17 | }, |
| 16 | - detail: { | |
| 17 | - show: false | |
| 18 | - } | |
| 19 | - }, | |
| 20 | - { | |
| 21 | - label: '任务编号', | |
| 22 | - field: 'jobId', | |
| 23 | - search: { | |
| 24 | - show: true | |
| 25 | - } | |
| 26 | - }, | |
| 27 | - { | |
| 28 | - label: '处理器的名字', | |
| 29 | - field: 'handlerName', | |
| 30 | - search: { | |
| 31 | - show: true | |
| 32 | - } | |
| 33 | - }, | |
| 34 | - { | |
| 35 | - label: '处理器的参数', | |
| 36 | - field: 'handlerParam' | |
| 37 | - }, | |
| 38 | - { | |
| 39 | - label: '第几次执行', | |
| 40 | - field: 'executeIndex' | |
| 41 | - }, | |
| 42 | - { | |
| 43 | - label: '开始执行时间', | |
| 44 | - field: 'beginTime', | |
| 45 | - search: { | |
| 46 | - show: true, | |
| 47 | - component: 'DatePicker', | |
| 48 | - componentProps: { | |
| 49 | - type: 'date', | |
| 50 | - valueFormat: 'YYYY-MM-DD HH:mm:ss' | |
| 18 | + { | |
| 19 | + title: '处理器的名字', | |
| 20 | + field: 'handlerName', | |
| 21 | + isSearch: true | |
| 22 | + }, | |
| 23 | + { | |
| 24 | + title: '处理器的参数', | |
| 25 | + field: 'handlerParam' | |
| 26 | + }, | |
| 27 | + { | |
| 28 | + title: '第几次执行', | |
| 29 | + field: 'executeIndex' | |
| 30 | + }, | |
| 31 | + { | |
| 32 | + title: '开始执行时间', | |
| 33 | + field: 'beginTime', | |
| 34 | + formatter: 'formatDate', | |
| 35 | + table: { | |
| 36 | + slots: { | |
| 37 | + default: 'beginTime_default' | |
| 38 | + } | |
| 39 | + }, | |
| 40 | + search: { | |
| 41 | + show: true, | |
| 42 | + itemRender: { | |
| 43 | + name: 'XDataTimePicker' | |
| 44 | + } | |
| 51 | 45 | } |
| 52 | - } | |
| 53 | - }, | |
| 54 | - { | |
| 55 | - label: '结束执行时间', | |
| 56 | - field: 'endTime', | |
| 57 | - search: { | |
| 58 | - show: true, | |
| 59 | - component: 'DatePicker', | |
| 60 | - componentProps: { | |
| 61 | - type: 'date', | |
| 62 | - valueFormat: 'YYYY-MM-DD HH:mm:ss' | |
| 46 | + }, | |
| 47 | + { | |
| 48 | + title: '结束执行时间', | |
| 49 | + field: 'endTime', | |
| 50 | + formatter: 'formatDate', | |
| 51 | + isTable: false, | |
| 52 | + search: { | |
| 53 | + show: true, | |
| 54 | + itemRender: { | |
| 55 | + name: 'XDataTimePicker' | |
| 56 | + } | |
| 63 | 57 | } |
| 64 | 58 | }, |
| 65 | - table: { | |
| 66 | - show: false | |
| 67 | - } | |
| 68 | - }, | |
| 69 | - { | |
| 70 | - label: '执行时长', | |
| 71 | - field: 'duration' | |
| 72 | - }, | |
| 73 | - { | |
| 74 | - label: t('common.status'), | |
| 75 | - field: 'status', | |
| 76 | - dictType: DICT_TYPE.INFRA_JOB_LOG_STATUS, | |
| 77 | - dictClass: 'number', | |
| 78 | - search: { | |
| 79 | - show: true | |
| 80 | - } | |
| 81 | - }, | |
| 82 | - { | |
| 83 | - field: 'action', | |
| 84 | - width: '100px', | |
| 85 | - label: t('table.action'), | |
| 86 | - form: { | |
| 87 | - show: false | |
| 59 | + { | |
| 60 | + title: '执行时长', | |
| 61 | + field: 'duration', | |
| 62 | + table: { | |
| 63 | + slots: { | |
| 64 | + default: 'duration_default' | |
| 65 | + } | |
| 66 | + } | |
| 88 | 67 | }, |
| 89 | - detail: { | |
| 90 | - show: false | |
| 68 | + { | |
| 69 | + title: t('common.status'), | |
| 70 | + field: 'status', | |
| 71 | + dictType: DICT_TYPE.INFRA_JOB_LOG_STATUS, | |
| 72 | + dictClass: 'number', | |
| 73 | + isSearch: true | |
| 91 | 74 | } |
| 92 | - } | |
| 93 | -]) | |
| 94 | - | |
| 95 | -export const { allSchemas } = useCrudSchemas(crudSchemas) | |
| 75 | + ] | |
| 76 | +}) | |
| 77 | +export const { allSchemas } = useVxeCrudSchemas(crudSchemas) | ... | ... |