init
This commit is contained in:
211
src/views/tools/job-manage/form.vue
Normal file
211
src/views/tools/job-manage/form.vue
Normal file
@@ -0,0 +1,211 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" :close-on-click-modal="false" :title="form.jobId ? $t('common.editBtn') : $t('common.addBtn')" draggable>
|
||||
<el-form ref="dataFormRef" :model="form" :rules="dataRules" formDialogRef label-width="120px" v-loading="loading">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item :label="t('job.jobName')" prop="jobName">
|
||||
<el-input v-model="form.jobName" :placeholder="t('job.inputjobNameTip')" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item :label="t('job.jobGroup')" prop="jobGroup">
|
||||
<el-input v-model="form.jobGroup" :placeholder="t('job.inputjobGroupTip')" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item :label="t('job.jobType')" prop="jobType">
|
||||
<el-select v-model="form.jobType" :placeholder="t('job.jobType')">
|
||||
<el-option v-for="(item, index) in job_type" :key="index" :label="item.label" :value="item.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12" class="mb20" v-if="['1'].includes(form.jobType)">
|
||||
<el-form-item :label="t('job.jobType1ClassName')" prop="className">
|
||||
<el-input v-model="form.className" :placeholder="t('job.inputclassNameTip')" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20" v-if="['2'].includes(form.jobType)">
|
||||
<el-form-item :label="t('job.jobType2ClassName')" prop="className">
|
||||
<el-input v-model="form.className" :placeholder="t('job.inputBeanNameTip')" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20" v-if="['1', '2'].includes(form.jobType)">
|
||||
<el-form-item :label="t('job.jobType1MethodName')" prop="methodName">
|
||||
<el-input v-model="form.methodName" :placeholder="t('job.inputmethodNameTip')" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20" v-if="['3'].includes(form.jobType)">
|
||||
<el-form-item :label="t('job.jobType3ExecutePath')" prop="executePath">
|
||||
<el-input v-model="form.executePath" :placeholder="t('job.inputexecutePathTip')" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="mb20" v-if="['4'].includes(form.jobType)">
|
||||
<el-form-item :label="t('job.jobType4ExecutePath')" prop="executePath">
|
||||
<el-input v-model="form.executePath" :placeholder="t('job.inputexecutePathTip')" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item prop="methodParamsValue">
|
||||
<template #label> {{ t('job.methodParamsValue') }} <tip :content="t('job.singleParam')" /></template>
|
||||
<el-input v-model="form.methodParamsValue" :placeholder="t('job.inputmethodParamsValueTip')" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item :label="t('job.cronExpression')" prop="cronExpression">
|
||||
<crontab clearable @hide="popoverVis(false)" v-model="form.cronExpression"></crontab>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12" class="mb20">
|
||||
<el-form-item :label="t('job.misfirePolicy')" prop="misfirePolicy">
|
||||
<el-select v-model="form.misfirePolicy" :placeholder="t('job.inputmisfirePolicyTip')">
|
||||
<el-option v-for="(item, index) in misfire_policy" :key="index" :label="item.label" :value="item.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item :label="t('job.remark')" prop="remark">
|
||||
<el-input v-model="form.remark" :placeholder="t('job.inputremarkTip')" type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button formDialogRef @click="visible = false">{{ $t('common.cancelButtonText') }}</el-button>
|
||||
<el-button formDialogRef type="primary" @click="onSubmit" :disabled="loading">{{ $t('common.confirmButtonText') }}</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="SysJobDialog" setup>
|
||||
// 定义子组件向父组件传值/事件
|
||||
import { useDict } from '/@/hooks/dict';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { addObj, getObj, putObj, validateJob } from '/@/api/daemon/job';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
const emit = defineEmits(['refresh']);
|
||||
const Crontab = defineAsyncComponent(() => import('/@/components/Crontab/index.vue'));
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref();
|
||||
const visible = ref(false);
|
||||
const loading = ref(false);
|
||||
|
||||
// 定义字典
|
||||
const { misfire_policy, job_type } = useDict('job_status', 'job_execute_status', 'misfire_policy', 'job_type');
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
jobId: '',
|
||||
jobName: '',
|
||||
jobGroup: '',
|
||||
jobType: '',
|
||||
executePath: '',
|
||||
className: '',
|
||||
methodName: '',
|
||||
methodParamsValue: '',
|
||||
cronExpression: '',
|
||||
misfirePolicy: '',
|
||||
jobStatus: '',
|
||||
jobExecuteStatus: '',
|
||||
remark: '',
|
||||
});
|
||||
|
||||
const popoverVis = (bol: boolean) => {
|
||||
popoverVisible.value = bol;
|
||||
};
|
||||
|
||||
const popoverVisible = ref(false);
|
||||
// 定义校验规则
|
||||
const dataRules = reactive({
|
||||
jobName: [{ required: true, message: '任务名称不能为空', trigger: 'blur' }],
|
||||
jobGroup: [{ required: true, message: '任务组名不能为空', trigger: 'blur' }],
|
||||
jobType: [{ required: true, message: '任务类型不能为空', trigger: 'blur' }],
|
||||
cronExpression: [{ required: true, message: 'cron不能为空', trigger: 'blur' }],
|
||||
misfirePolicy: [{ required: true, message: '策略不能为空', trigger: 'blur' }],
|
||||
executePath: [{ required: true, message: '执行路径不能为空', trigger: 'blur' }],
|
||||
className: [
|
||||
{ required: true, message: '名称不能为空', trigger: 'blur' },
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
validateJob(rule, value, callback, form);
|
||||
},
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
methodName: [
|
||||
{ required: true, message: '方法不能为空', trigger: 'blur' },
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
validateJob(rule, value, callback, form);
|
||||
},
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
methodParamsValue: [
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
validateJob(rule, value, callback, form);
|
||||
},
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = (id: string) => {
|
||||
visible.value = true;
|
||||
form.jobId = '';
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields();
|
||||
});
|
||||
|
||||
// 获取sysJob信息
|
||||
if (id) {
|
||||
form.jobId = id;
|
||||
getsysJobData(id);
|
||||
}
|
||||
};
|
||||
|
||||
// 提交
|
||||
const onSubmit = async () => {
|
||||
const valid = await dataFormRef.value.validate().catch(() => {});
|
||||
if (!valid) return false;
|
||||
|
||||
try {
|
||||
loading.value = true;
|
||||
form.jobId ? await putObj(form) : await addObj(form);
|
||||
useMessage().success(t(form.jobId ? 'common.editSuccessText' : 'common.addSuccessText'));
|
||||
visible.value = false;
|
||||
emit('refresh');
|
||||
} catch (err: any) {
|
||||
useMessage().error('任务初始化异常');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化表单数据
|
||||
const getsysJobData = (id: string) => {
|
||||
// 获取数据
|
||||
getObj(id).then((res: any) => {
|
||||
Object.assign(form, res.data);
|
||||
});
|
||||
};
|
||||
|
||||
// 暴露变量
|
||||
defineExpose({
|
||||
openDialog,
|
||||
});
|
||||
</script>
|
||||
105
src/views/tools/job-manage/i18n/en.ts
Normal file
105
src/views/tools/job-manage/i18n/en.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
export default {
|
||||
job: {
|
||||
index: '#',
|
||||
jobLogBtn: 'log',
|
||||
jobStartBtn: 'start',
|
||||
jobRunBtn: 'execute',
|
||||
jobPauseBtn: 'pause',
|
||||
importsysJobTip: 'import SysJob',
|
||||
jobId: 'jobId',
|
||||
jobName: 'jobName',
|
||||
jobGroup: 'jobGroup',
|
||||
jobOrder: 'jobOrder',
|
||||
jobType: 'jobType',
|
||||
executePath: 'executePath',
|
||||
className: 'className',
|
||||
methodName: 'methodName',
|
||||
methodParamsValue: 'methodParamsValue',
|
||||
cronExpression: 'cronExpression',
|
||||
misfirePolicy: 'misfirePolicy',
|
||||
jobTenantType: 'jobTenantType',
|
||||
jobStatus: 'jobStatus',
|
||||
jobExecuteStatus: 'jobExecuteStatus',
|
||||
createBy: 'createBy',
|
||||
createTime: 'createTime',
|
||||
updateBy: 'updateBy',
|
||||
updateTime: 'updateTime',
|
||||
startTime: 'startTime',
|
||||
previousTime: 'previousTime',
|
||||
nextTime: 'nextTime',
|
||||
tenantId: 'tenantId',
|
||||
remark: 'remark',
|
||||
jobMessage: 'jobMessage',
|
||||
jobLogStatus: 'jobLogStatus',
|
||||
executeTime: 'executeTime',
|
||||
exceptionInfo: 'exceptionInfo',
|
||||
inputjobIdTip: 'input jobId',
|
||||
inputjobNameTip: 'input jobName',
|
||||
inputjobGroupTip: 'input jobGroup',
|
||||
inputjobOrderTip: 'input jobOrder',
|
||||
inputjobTypeTip: 'input jobType',
|
||||
inputexecutePathTip: 'Please enter the Request Address',
|
||||
inputclassNameTip: 'Please enter the Full Class Path',
|
||||
inputmethodNameTip: 'input methodName',
|
||||
inputmethodParamsValueTip: 'input methodParamsValue',
|
||||
inputcronExpressionTip: 'input cronExpression',
|
||||
inputmisfirePolicyTip: 'input misfirePolicy',
|
||||
inputjobTenantTypeTip: 'input jobTenantType',
|
||||
inputjobStatusTip: 'input jobStatus',
|
||||
inputjobExecuteStatusTip: 'input jobExecuteStatus',
|
||||
inputcreateByTip: 'input createBy',
|
||||
inputcreateTimeTip: 'input createTime',
|
||||
inputupdateByTip: 'input updateBy',
|
||||
inputupdateTimeTip: 'input updateTime',
|
||||
inputstartTimeTip: 'input startTime',
|
||||
inputpreviousTimeTip: 'input previousTime',
|
||||
inputnextTimeTip: 'input nextTime',
|
||||
inputtenantIdTip: 'input tenantId',
|
||||
inputremarkTip: 'input remark',
|
||||
jobType1ClassName: 'Full Class Path',
|
||||
jobType1MethodName: 'Method Name',
|
||||
jobType2ClassName: 'Bean Name',
|
||||
jobType2MethodName: 'Method Name',
|
||||
jobType3ExecutePath: 'Request Address',
|
||||
jobType4ExecutePath: 'Jar Path',
|
||||
singleParam: 'Only single parameter is supported',
|
||||
},
|
||||
log: {
|
||||
index: '#',
|
||||
importsysJobLogTip: 'import SysJobLog',
|
||||
jobLogId: 'jobLogId',
|
||||
jobId: 'jobId',
|
||||
jobName: 'jobName',
|
||||
jobGroup: 'jobGroup',
|
||||
jobOrder: 'jobOrder',
|
||||
jobType: 'jobType',
|
||||
executePath: 'executePath',
|
||||
className: 'className',
|
||||
methodName: 'methodName',
|
||||
methodParamsValue: 'methodParamsValue',
|
||||
cronExpression: 'cronExpression',
|
||||
jobMessage: 'jobMessage',
|
||||
jobLogStatus: 'jobLogStatus',
|
||||
executeTime: 'executeTime',
|
||||
exceptionInfo: 'exceptionInfo',
|
||||
createTime: 'createTime',
|
||||
tenantId: 'tenantId',
|
||||
inputJobLogIdTip: 'input jobLogId',
|
||||
inputJobIdTip: 'input jobId',
|
||||
inputJobNameTip: 'input jobName',
|
||||
inputJobGroupTip: 'input jobGroup',
|
||||
inputJobOrderTip: 'input jobOrder',
|
||||
inputJobTypeTip: 'input jobType',
|
||||
inputExecutePathTip: 'input executePath',
|
||||
inputClassNameTip: 'input className',
|
||||
inputMethodNameTip: 'input methodName',
|
||||
inputMethodParamsValueTip: 'input methodParamsValue',
|
||||
inputCronExpressionTip: 'input cronExpression',
|
||||
inputJobMessageTip: 'input jobMessage',
|
||||
inputJobLogStatusTip: 'input jobLogStatus',
|
||||
inputExecuteTimeTip: 'input executeTime',
|
||||
inputExceptionInfoTip: 'input exceptionInfo',
|
||||
inputCreateTimeTip: 'input createTime',
|
||||
inputTenantIdTip: 'input tenantId',
|
||||
},
|
||||
};
|
||||
95
src/views/tools/job-manage/i18n/zh-cn.ts
Normal file
95
src/views/tools/job-manage/i18n/zh-cn.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
export default {
|
||||
job: {
|
||||
index: '#',
|
||||
jobLogBtn: '日志',
|
||||
jobStartBtn: '启动',
|
||||
jobRunBtn: '执行',
|
||||
jobPauseBtn: '暂停',
|
||||
importsysJobTip: '导入定时任务调度表',
|
||||
jobId: '任务id',
|
||||
jobName: '任务名称',
|
||||
jobGroup: '任务组名',
|
||||
jobOrder: '组内执行顺利',
|
||||
jobType: '类型',
|
||||
executePath: '执行路径',
|
||||
className: '执行文件',
|
||||
methodName: '执行方法',
|
||||
methodParamsValue: '参数值',
|
||||
cronExpression: 'cron表达式',
|
||||
misfirePolicy: '错失执行策略',
|
||||
jobTenantType: '1、多租户任务;2、非多租户任务',
|
||||
jobStatus: '任务状态',
|
||||
jobExecuteStatus: '执行状态',
|
||||
createBy: '创建者',
|
||||
createTime: '创建时间',
|
||||
updateBy: '更新者',
|
||||
updateTime: '更新时间',
|
||||
startTime: '初次执行时间',
|
||||
previousTime: '上次执行时间',
|
||||
nextTime: '下次执行时间',
|
||||
tenantId: '租户',
|
||||
remark: '备注信息',
|
||||
jobMessage: '日志信息',
|
||||
jobLogStatus: '执行状态',
|
||||
executeTime: '执行时间',
|
||||
exceptionInfo: '异常信息',
|
||||
inputjobIdTip: '请输入任务id',
|
||||
inputjobNameTip: '请输入任务名称',
|
||||
inputjobGroupTip: '请输入任务组名',
|
||||
inputjobOrderTip: '请输入组内执行顺利',
|
||||
inputjobTypeTip: '请输入类型',
|
||||
inputexecutePathTip: '请输入请求地址',
|
||||
inputclassNameTip: '请输入类全路径',
|
||||
inputBeanNameTip: '请输入Bean名称',
|
||||
inputmethodNameTip: '请输入方法名称',
|
||||
inputmethodParamsValueTip: '请输入参数值',
|
||||
inputcronExpressionTip: '请输入cron表达式',
|
||||
inputmisfirePolicyTip: '请输入错失执行策略',
|
||||
inputjobTenantTypeTip: '请输入1、多租户任务;2、非多租户任务',
|
||||
inputjobStatusTip: '请输入任务状态',
|
||||
inputjobExecuteStatusTip: '请输入执行状态',
|
||||
inputcreateByTip: '请输入创建者',
|
||||
inputcreateTimeTip: '请输入创建时间',
|
||||
inputupdateByTip: '请输入更新者',
|
||||
inputupdateTimeTip: '请输入更新时间',
|
||||
inputstartTimeTip: '请输入初次执行时间',
|
||||
inputpreviousTimeTip: '请输入上次执行时间',
|
||||
inputnextTimeTip: '请输入下次执行时间',
|
||||
inputtenantIdTip: '请输入租户',
|
||||
inputremarkTip: '请输入备注信息',
|
||||
jobType1ClassName: '类全路径',
|
||||
jobType1MethodName: '方法名称',
|
||||
jobType2ClassName: 'Bean名称',
|
||||
jobType2MethodName: '方法名称',
|
||||
jobType3ExecutePath: '请求地址',
|
||||
jobType4ExecutePath: 'Jar包路径',
|
||||
singleParam: '只支持单个参数',
|
||||
},
|
||||
log: {
|
||||
index: '#',
|
||||
importsysJobLogTip: '导入定时任务执行日志表',
|
||||
jobLogId: '任务日志ID',
|
||||
jobId: '任务id',
|
||||
jobName: '任务名称',
|
||||
jobGroup: '任务组名',
|
||||
jobMessage: '日志信息',
|
||||
jobLogStatus: '执行状态',
|
||||
executeTime: '执行时间',
|
||||
exceptionInfo: '异常信息',
|
||||
createTime: '创建时间',
|
||||
tenantId: '租户id',
|
||||
inputJobLogIdTip: '请输入任务日志ID',
|
||||
inputJobIdTip: '请输入任务id',
|
||||
inputJobNameTip: '请输入任务名称',
|
||||
inputJobGroupTip: '请输入任务组名',
|
||||
inputMethodNameTip: '请输入任务方法',
|
||||
inputMethodParamsValueTip: '请输入参数值',
|
||||
inputCronExpressionTip: '请输入cron执行表达式',
|
||||
inputJobMessageTip: '请输入日志信息',
|
||||
inputJobLogStatusTip: '请输入执行状态',
|
||||
inputExecuteTimeTip: '请输入执行时间',
|
||||
inputExceptionInfoTip: '请输入异常信息',
|
||||
inputCreateTimeTip: '请输入创建时间',
|
||||
inputTenantIdTip: '请输入租户id',
|
||||
},
|
||||
};
|
||||
427
src/views/tools/job-manage/index.vue
Normal file
427
src/views/tools/job-manage/index.vue
Normal file
@@ -0,0 +1,427 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<el-row class="ml10" v-show="showSearch">
|
||||
<el-form :inline="true" :model="state.queryForm" ref="queryRef">
|
||||
<el-form-item :label="$t('job.jobName')" prop="jobName">
|
||||
<el-input :placeholder="$t('job.inputjobNameTip')" @keyup.enter="getDataList" clearable
|
||||
v-model="state.queryForm.jobName"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('job.jobStatus')" prop="jobStatus">
|
||||
<el-select :placeholder="t('job.inputjobStatusTip')" v-model="state.queryForm.jobStatus">
|
||||
<el-option :key="index" :label="item.label" :value="item.value"
|
||||
v-for="(item, index) in job_status"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('job.jobExecuteStatus')" prop="jobExecuteStatus">
|
||||
<el-select :placeholder="t('job.inputjobExecuteStatusTip')" v-model="state.queryForm.jobExecuteStatus">
|
||||
<el-option :key="index" :label="item.label" :value="item.value"
|
||||
v-for="(item, index) in job_execute_status"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button @click="getDataList" icon="Search" type="primary">{{ $t('common.queryBtn') }}</el-button>
|
||||
<el-button @click="resetQuery" icon="Refresh">{{ $t('common.resetBtn') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button v-auth="'job_sys_job_add'" @click="formDialogRef.openDialog()" class="ml10" icon="folder-add"
|
||||
type="primary">
|
||||
{{ $t('common.addBtn') }}
|
||||
</el-button>
|
||||
<el-button plain v-auth="'job_sys_job_del'" :disabled="multiple" @click="handleDelete(undefined)" class="ml10"
|
||||
icon="Delete" type="primary">
|
||||
{{ $t('common.delBtn') }}
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
:export="'job_sys_job_add'"
|
||||
@exportExcel="exportExcel"
|
||||
@queryTable="getDataList"
|
||||
class="ml10"
|
||||
style="float: right; margin-right: 20px"
|
||||
v-model:showSearch="showSearch"
|
||||
>
|
||||
<el-tooltip class="item" effect="dark" :content="$t('queryTree.view')" placement="top">
|
||||
<el-button circle icon="Grid" @click="tableViewRef = !tableViewRef"></el-button>
|
||||
</el-tooltip>
|
||||
</right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<!-- 表格视图 -->
|
||||
<el-table
|
||||
v-if="tableViewRef"
|
||||
:data="state.dataList"
|
||||
@selection-change="handleSelectionChange"
|
||||
style="width: 100%"
|
||||
row-key="jobId"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column align="center" type="selection" width="40"/>
|
||||
<el-table-column :label="t('job.index')" fixed="left" type="index" width="60"/>
|
||||
<el-table-column :label="t('job.jobName')" fixed="left" prop="jobName" show-overflow-tooltip width="120"/>
|
||||
<el-table-column :label="t('job.jobGroup')" prop="jobGroup" show-overflow-tooltip width="120"/>
|
||||
<el-table-column :label="t('job.jobStatus')" prop="jobStatus" show-overflow-tooltip width="120">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="job_status" :value="scope.row.jobStatus"></dict-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('job.jobExecuteStatus')" prop="jobExecuteStatus" show-overflow-tooltip width="120">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="job_execute_status" :value="scope.row.jobExecuteStatus"></dict-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column :label="t('job.startTime')" prop="startTime" show-overflow-tooltip width="120"/>
|
||||
|
||||
<el-table-column :label="t('job.previousTime')" prop="previousTime" show-overflow-tooltip width="120"/>
|
||||
<el-table-column :label="t('job.nextTime')" prop="nextTime" show-overflow-tooltip width="120"/>
|
||||
<el-table-column :label="t('job.jobType')" prop="jobType" show-overflow-tooltip width="120">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="job_type" :value="scope.row.jobType"></dict-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="t('job.executePath')" prop="executePath" show-overflow-tooltip width="120"/>
|
||||
<el-table-column :label="t('job.className')" prop="className" show-overflow-tooltip width="120"/>
|
||||
<el-table-column :label="t('job.methodName')" prop="methodName" show-overflow-tooltip width="120"/>
|
||||
<el-table-column :label="t('job.methodParamsValue')" prop="methodParamsValue" show-overflow-tooltip
|
||||
width="120"/>
|
||||
<el-table-column :label="t('job.cronExpression')" prop="cronExpression" show-overflow-tooltip width="120"/>
|
||||
<el-table-column :label="t('job.misfirePolicy')" prop="misfirePolicy" show-overflow-tooltip width="200">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="misfire_policy" :value="scope.row.misfirePolicy"></dict-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('common.action')" fixed="right" width="300">
|
||||
<template #default="scope">
|
||||
<el-button @click="handleJobLog(scope.row)" text type="primary">{{ $t('job.jobLogBtn') }}</el-button>
|
||||
|
||||
<el-button v-auth="'job_sys_job_start_job'" @click="handleStartJob(scope.row)" text type="primary"
|
||||
v-if="scope.row.jobStatus !== '2'"
|
||||
>
|
||||
{{ $t('job.jobStartBtn') }}
|
||||
</el-button>
|
||||
|
||||
<el-button
|
||||
v-auth="'job_sys_job_shutdown_job'"
|
||||
@click="handleShutDownJob(scope.row)"
|
||||
text
|
||||
type="primary"
|
||||
v-if="scope.row.jobStatus === '2'"
|
||||
>
|
||||
{{ $t('job.jobPauseBtn') }}
|
||||
</el-button>
|
||||
|
||||
<el-button v-auth="'job_sys_job_edit'" @click="handleEditJob(scope.row)" text type="primary">
|
||||
{{ $t('common.editBtn') }}
|
||||
</el-button>
|
||||
|
||||
<el-button v-auth="'job_sys_job_start_job'" @click="handleRunJob(scope.row)" text type="primary">
|
||||
{{ $t('job.jobRunBtn') }}
|
||||
</el-button>
|
||||
|
||||
<el-button v-auth="'job_sys_job_del'" @click="handleDelete(scope.row)" text type="primary"
|
||||
:disabled="scope.row.jobStatus === '2'">{{ $t('common.delBtn') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 卡片视图 -->
|
||||
<el-scrollbar v-if="!tableViewRef">
|
||||
<div class="p-4">
|
||||
<div class="mx-auto">
|
||||
<!-- Main -->
|
||||
<div class="grid grid-cols-4 gap-x-4 gap-y-6">
|
||||
<div
|
||||
v-for="job in state.dataList"
|
||||
:key="job.jobId"
|
||||
class="w-full max-w-sm mt-2 bg-gray-100 dark:bg-[#1d1e1f] rounded-lg border dark:border-[#303030]"
|
||||
>
|
||||
<div aria-label="header" class="flex items-center p-4 space-x-4">
|
||||
<div aria-label="avatar" class="flex items-center mr-auto space-x-4">
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<div class="text-lg font-bold text-gray-900 dark:text-gray-100">
|
||||
{{ job.jobName }}
|
||||
</div>
|
||||
<p class="text-base font-normal text-gray-500 truncate dark:text-gray-400">
|
||||
{{ job.jobGroup }} / {{ job_type.find((item: any) => item.value === job.jobType)?.label }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div aria-label="navigation" class="py-2">
|
||||
<nav class="grid gap-1">
|
||||
<div class="flex items-center w-full px-4 py-1 space-x-3 leading-6 text-gray-600 dark:text-gray-300 hover:bg-white dark:hover:bg-[#303030] rounded-md">
|
||||
<span class="font-medium">{{ $t('job.jobStatus') }}:</span>
|
||||
<span>{{ job_status.find((item: any) => item.value === job.jobStatus)?.label }}</span>
|
||||
</div>
|
||||
<div class="flex items-center w-full px-4 py-1 space-x-3 leading-6 text-gray-600 dark:text-gray-300 hover:bg-white dark:hover:bg-[#303030] rounded-md">
|
||||
<span class="font-medium">{{ $t('job.cronExpression') }}:</span>
|
||||
<span>{{ job.cronExpression }}</span>
|
||||
</div>
|
||||
<div class="flex items-center w-full px-4 py-1 space-x-3 leading-6 text-gray-600 dark:text-gray-300 hover:bg-white dark:hover:bg-[#303030] rounded-md">
|
||||
<span class="font-medium">{{ $t('job.previousTime') }}:</span>
|
||||
<span>{{ job.previousTime }}</span>
|
||||
</div>
|
||||
<div class="flex items-center w-full px-4 py-1 space-x-3 leading-6 text-gray-600 dark:text-gray-300 hover:bg-white dark:hover:bg-[#303030] rounded-md">
|
||||
<span class="font-medium">{{ $t('job.nextTime') }}:</span>
|
||||
<span>{{ job.nextTime }}</span>
|
||||
</div>
|
||||
<div class="flex items-center w-full px-4 py-1 space-x-3 leading-6 text-gray-600 dark:text-gray-300 hover:bg-white dark:hover:bg-[#303030] rounded-md">
|
||||
<span class="font-medium">{{ $t('job.jobExecuteStatus') }}:</span>
|
||||
<span>
|
||||
<el-icon v-if="job.jobExecuteStatus === '1'"><CircleCloseFilled/></el-icon>
|
||||
<el-icon v-if="job.jobExecuteStatus === '0'"><CircleCheckFilled/></el-icon>
|
||||
</span>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
<div aria-label="footer" class="pt-2 border-t dark:border-[#303030]">
|
||||
<div class="flex items-center justify-center min-w-full">
|
||||
<nav class="flex">
|
||||
<a
|
||||
@click="handleJobLog(job)"
|
||||
href="javascript:;"
|
||||
class="px-2 py-2 text-primary hover:text-primary-400 dark:text-primary-300"
|
||||
>
|
||||
<span>{{ $t('job.jobLogBtn') }}</span>
|
||||
</a>
|
||||
<a
|
||||
v-auth="'job_sys_job_start_job'"
|
||||
@click="handleStartJob(job)"
|
||||
v-if="job.jobStatus !== '2'"
|
||||
href="javascript:;"
|
||||
class="px-2 py-2 text-primary hover:text-primary-400 dark:text-primary-300"
|
||||
>
|
||||
<span>{{ $t('job.jobStartBtn') }}</span>
|
||||
</a>
|
||||
<a
|
||||
v-auth="'job_sys_job_shutdown_job'"
|
||||
@click="handleShutDownJob(job)"
|
||||
v-if="job.jobStatus === '2'"
|
||||
href="javascript:;"
|
||||
class="px-2 py-2 text-primary hover:text-primary-400 dark:text-primary-300"
|
||||
>
|
||||
<span>{{ $t('job.jobPauseBtn') }}</span>
|
||||
</a>
|
||||
<a
|
||||
v-auth="'job_sys_job_edit'" @click="handleEditJob(job)"
|
||||
href="javascript:;"
|
||||
class="px-2 py-2 text-primary hover:text-primary-400 dark:text-primary-300"
|
||||
>
|
||||
<span> {{ $t('common.editBtn') }}</span>
|
||||
</a>
|
||||
<a
|
||||
v-auth="'job_sys_job_start_job'" @click="handleRunJob(job)"
|
||||
href="javascript:;"
|
||||
class="px-2 py-2 text-primary hover:text-primary-400 dark:text-primary-300"
|
||||
>
|
||||
<span>{{ $t('job.jobRunBtn') }}</span>
|
||||
</a>
|
||||
|
||||
<a
|
||||
v-auth="'job_sys_job_del'" @click="handleDelete(job)" type="primary"
|
||||
v-if="job.jobStatus !== '2'"
|
||||
href="javascript:;"
|
||||
class="px-2 py-2 text-primary hover:text-primary-400 dark:text-primary-300"
|
||||
>
|
||||
<span>{{ $t('common.delBtn') }}</span>
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
|
||||
<pagination @current-change="currentChangeHandle" @size-change="sizeChangeHandle" v-bind="state.pagination"/>
|
||||
</div>
|
||||
|
||||
<!-- 编辑、新增 -->
|
||||
<form-dialog @refresh="getDataList()" ref="formDialogRef"/>
|
||||
<job-log ref="jobLogRef"></job-log>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="systemSysJob" setup>
|
||||
import {BasicTableProps, useTable} from '/@/hooks/table';
|
||||
import {delObj, fetchList, runJobRa, shutDownJobRa, startJobRa} from '/@/api/daemon/job';
|
||||
import {useMessage, useMessageBox} from '/@/hooks/message';
|
||||
import {useDict} from '/@/hooks/dict';
|
||||
import {useI18n} from 'vue-i18n';
|
||||
|
||||
// 引入组件
|
||||
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
||||
const JobLog = defineAsyncComponent(() => import('./job-log.vue'));
|
||||
|
||||
// 获取国际化方法
|
||||
const {t} = useI18n();
|
||||
|
||||
/** 表单弹窗引用 */
|
||||
const formDialogRef = ref();
|
||||
/** 作业日志引用 */
|
||||
const jobLogRef = ref();
|
||||
/** 表格视图 */
|
||||
const tableViewRef = ref(false)
|
||||
/** 搜索表单信息 */
|
||||
const queryForm = reactive({
|
||||
jobName: '',
|
||||
jobGroup: '',
|
||||
jobStatus: '',
|
||||
jobExecuteStatus: '',
|
||||
});
|
||||
/** 是否展示搜索表单 */
|
||||
const showSearch = ref(true);
|
||||
|
||||
// 多选变量
|
||||
/** 选中的行 */
|
||||
const selectedRows = ref([]);
|
||||
/** 是否可以多选 */
|
||||
const multiple = ref(true);
|
||||
|
||||
/** 查询字典 */
|
||||
const {
|
||||
job_status,
|
||||
job_execute_status,
|
||||
misfire_policy,
|
||||
job_type
|
||||
} = useDict('job_status', 'job_execute_status', 'misfire_policy', 'job_type');
|
||||
|
||||
/** 表格状态变量 */
|
||||
const state = reactive<BasicTableProps>({
|
||||
queryForm,
|
||||
pageList: fetchList,
|
||||
pagination: {
|
||||
size: 8,
|
||||
pageSizes: [4, 8, 12]
|
||||
}
|
||||
});
|
||||
|
||||
/** 获取表格数据方法 */
|
||||
const {getDataList, currentChangeHandle, sizeChangeHandle, downBlobFile, tableStyle} = useTable(state);
|
||||
|
||||
/** 重置查询表单 */
|
||||
const resetQuery = () => {
|
||||
Object.keys(queryForm).forEach((key) => (queryForm[key] = ''));
|
||||
getDataList();
|
||||
};
|
||||
|
||||
/** 行选中事件 */
|
||||
const handleSelectionChange = (rows: any) => {
|
||||
selectedRows.value = rows;
|
||||
multiple.value = !rows.length;
|
||||
};
|
||||
|
||||
/** 导出Excel */
|
||||
const exportExcel = () => {
|
||||
downBlobFile('/job/sys-job/export', Object.assign(state.queryForm, {ids: selectedRows}), 'job.xlsx');
|
||||
};
|
||||
|
||||
/** 查看作业日志 */
|
||||
const handleJobLog = (row) => {
|
||||
jobLogRef.value.openDialog(row.jobId);
|
||||
};
|
||||
|
||||
/** 编辑作业 */
|
||||
const handleEditJob = (row) => {
|
||||
const jobStatus = row.jobStatus;
|
||||
if (jobStatus === '1' || jobStatus === '3') {
|
||||
formDialogRef.value.openDialog(row.jobId);
|
||||
} else {
|
||||
useMessage().error('运行中定时任务不可修改,请先暂停后操作');
|
||||
}
|
||||
};
|
||||
|
||||
/** 启动作业 */
|
||||
const handleStartJob = async (row) => {
|
||||
const jobStatus = row.jobStatus;
|
||||
if (jobStatus === '1' || jobStatus === '3') {
|
||||
try {
|
||||
await useMessageBox().confirm(`即将发布或启动(任务名称: ${row.jobName}), 是否继续?`);
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await startJobRa(row.jobId);
|
||||
getDataList();
|
||||
useMessage().success(t('common.optSuccessText'));
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg);
|
||||
}
|
||||
} else {
|
||||
useMessage().error('定时任务已运行');
|
||||
}
|
||||
};
|
||||
|
||||
/** 暂停作业 */
|
||||
const handleShutDownJob = async (row) => {
|
||||
const jobStatus = row.jobStatus;
|
||||
if (jobStatus === '2') {
|
||||
try {
|
||||
await useMessageBox().confirm(`即将暂停(任务名称: ${row.jobName}), 是否继续?`);
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await shutDownJobRa(row.jobId);
|
||||
getDataList();
|
||||
useMessage().success(t('common.optSuccessText'));
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg);
|
||||
}
|
||||
} else {
|
||||
useMessage().error('已暂停,不要重复操作');
|
||||
}
|
||||
};
|
||||
|
||||
/** 运行作业 */
|
||||
const handleRunJob = async (row) => {
|
||||
try {
|
||||
await useMessageBox().confirm(`立刻执行一次任务(任务名称: ${row.jobName}), 是否继续?`);
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await runJobRa(row.jobId);
|
||||
getDataList();
|
||||
useMessage().success(t('common.optSuccessText'));
|
||||
} catch (err: any) {
|
||||
useMessage().error('运行失败');
|
||||
}
|
||||
};
|
||||
|
||||
/** 删除操作 */
|
||||
const handleDelete = async (row) => {
|
||||
if (!row) {
|
||||
selectedRows.value.forEach(handleDelete);
|
||||
return;
|
||||
}
|
||||
|
||||
const {jobId, jobName} = row;
|
||||
try {
|
||||
await useMessageBox().confirm(`${t('common.delConfirmText')}(任务名称:${jobName})`);
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await delObj(jobId);
|
||||
getDataList();
|
||||
useMessage().success(t('common.delSuccessText'));
|
||||
} catch (error: any) {
|
||||
useMessage().error('删除失败');
|
||||
}
|
||||
};
|
||||
</script>
|
||||
125
src/views/tools/job-manage/job-log.vue
Normal file
125
src/views/tools/job-manage/job-log.vue
Normal file
@@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" :close-on-click-modal="false" fullscreen title="运行日志" draggable>
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button
|
||||
formDialogRef
|
||||
:disabled="multiple"
|
||||
icon="Delete"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
v-auth="'sys_log_del'"
|
||||
@click="handleDelete(selectObjs)"
|
||||
>
|
||||
{{ $t('common.delBtn') }}
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
class="ml10"
|
||||
style="float: right; margin-right: 20px"
|
||||
@queryTable="getDataList"
|
||||
></right-toolbar>
|
||||
</div>
|
||||
</el-row>
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
style="width: 100%"
|
||||
@selection-change="handleSelectionChange"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<el-table-column type="selection" width="40" align="center" />
|
||||
<el-table-column type="index" :label="t('log.index')" width="80" />
|
||||
<el-table-column prop="jobName" :label="t('log.jobName')" show-overflow-tooltip />
|
||||
<el-table-column prop="jobMessage" :label="t('log.jobMessage')" show-overflow-tooltip />
|
||||
<el-table-column prop="jobLogStatus" :label="t('log.jobLogStatus')" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<dict-tag :options="job_execute_status" :value="scope.row.jobLogStatus"></dict-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="executeTime" :label="t('log.executeTime')" show-overflow-tooltip />
|
||||
<el-table-column prop="exceptionInfo" :label="t('log.exceptionInfo')" show-overflow-tooltip />
|
||||
<el-table-column prop="createTime" :label="t('log.createTime')" show-overflow-tooltip />
|
||||
<el-table-column :label="$t('common.action')" width="150">
|
||||
<template #default="scope">
|
||||
<el-button text type="primary" v-auth="'cloud_log_edit'" @click="formDialogRef.openDialog(scope.row.jobLogId)"
|
||||
>{{ $t('common.editBtn') }}
|
||||
</el-button>
|
||||
<el-button text type="primary" v-auth="'sys_log_del'" @click="handleDelete([scope.row.jobLogId])">{{ $t('common.delBtn') }} </el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle" v-bind="state.pagination" />
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="job-log">
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { fetchList, delObjs } from '/@/api/daemon/job-log';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useDict } from '/@/hooks/dict';
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||
|
||||
const { t } = useI18n();
|
||||
const visible = ref(false);
|
||||
|
||||
const { job_execute_status } = useDict('job_type', 'job_execute_status');
|
||||
|
||||
// 定义变量内容
|
||||
const formDialogRef = ref();
|
||||
// 搜索变量
|
||||
const showSearch = ref(true);
|
||||
// 多选变量
|
||||
const selectObjs = ref([]) as any;
|
||||
const multiple = ref(true);
|
||||
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: {
|
||||
jobId: '',
|
||||
},
|
||||
pageList: fetchList,
|
||||
createdIsNeed: false,
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
|
||||
const openDialog = (id: string) => {
|
||||
visible.value = true;
|
||||
state.queryForm.jobId = id;
|
||||
getDataList();
|
||||
};
|
||||
|
||||
// 多选事件
|
||||
const handleSelectionChange = (objs: { jobLogId: string }[]) => {
|
||||
selectObjs.value = objs.map(({ jobLogId }) => jobLogId);
|
||||
multiple.value = !objs.length;
|
||||
};
|
||||
|
||||
// 删除操作
|
||||
const handleDelete = async (ids: string[]) => {
|
||||
try {
|
||||
await useMessageBox().confirm(t('common.delConfirmText'));
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await delObjs(ids);
|
||||
getDataList();
|
||||
useMessage().success(t('common.delSuccessText'));
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg);
|
||||
}
|
||||
};
|
||||
|
||||
// 暴露变量
|
||||
defineExpose({
|
||||
openDialog,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
Reference in New Issue
Block a user