2025-05-14 20:01:29 +08:00

455 lines
17 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch">
<el-form-item label="任务名称" prop="jobName">
<el-input v-model="queryParams.jobName" placeholder="请输入任务名称" clearable style="width: 200px"
@keyup.enter="handleQuery" />
</el-form-item>
<!-- <el-form-item label="任务组名" prop="jobGroup">
<el-select v-model="queryParams.jobGroup" placeholder="请选择任务组名" clearable style="width: 200px">
<el-option v-for="dict in sys_job_group" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item> -->
<el-form-item label="任务状态" prop="jobStatus">
<el-select v-model="queryParams.jobStatus" placeholder="请选择任务状态" clearable style="width: 200px">
<el-option v-for="dict in jobStatusList" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd">新增定时任务</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate"
v-hasPermi="['monitor:job:edit']">修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete"
v-hasPermi="['monitor:job:remove']">删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExport"
v-hasPermi="['monitor:job:export']">导出</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="info" plain icon="Operation" @click="handleJobLog"
v-hasPermi="['monitor:job:query']">日志</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="jobList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="任务ID" width="100" align="center" prop="id" />
<el-table-column label="任务名称" align="center" prop="jobName" :show-overflow-tooltip="true" />
<!-- <el-table-column label="调用目标字符串" align="center" prop="invokeTarget" :show-overflow-tooltip="true" /> -->
<el-table-column label="cron执行表达式" align="center" prop="cronExpression" :show-overflow-tooltip="true" />
<el-table-column label="任务状态" align="center">
<template #default="scope">
<el-switch v-model="scope.row.jobStatus" :active-value="0" :inactive-value="1"
@change="handleStatusChange(scope.row)"></el-switch>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" :show-overflow-tooltip="true">
<template #default="scope">
{{ scope.row.createTime.replace("T", " ") }}
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="200" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="修改任务" placement="top">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"></el-button>
</el-tooltip>
<el-tooltip content="删除任务" placement="top">
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"></el-button>
</el-tooltip>
<el-tooltip content="立即运行" placement="top">
<el-button link type="primary" icon="CaretRight" @click="handleRun(scope.row)"></el-button>
</el-tooltip>
<!-- <el-tooltip content="任务详细" placement="top">
<el-button link type="primary" icon="View" @click="handleView(scope.row)"></el-button>
</el-tooltip>
<el-tooltip content="调度日志" placement="top">
<el-button link type="primary" icon="Operation" @click="handleJobLog(scope.row)"></el-button>
</el-tooltip> -->
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize" @pagination="getList" />
<!-- 添加或修改定时任务对话框 -->
<el-dialog :title="title" v-model="open" width="820px" append-to-body>
<el-form ref="jobRef" :model="form" :rules="rules" label-width="120px">
<el-row>
<el-col :span="12">
<el-form-item label="任务名称" prop="jobName">
<el-input v-model="form.jobName" placeholder="请输入任务名称" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item prop="jobClazz">
<template #label>
<span>
任务全类名
<!-- <el-tooltip placement="top">
<template #content>
<div>
Bean调用示例ryTask.ryParams('ry')
<br />Class类调用示例com.ruoyi.quartz.task.RyTask.ryParams('ry')
<br />参数说明:支持字符串,布尔类型,长整型,浮点型,整型
</div>
</template>
<el-icon><question-filled /></el-icon>
</el-tooltip> -->
</span>
</template>
<el-input v-model="form.jobClazz" placeholder="请输入任务全类名" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="cron表达式" prop="cronExpression">
<el-input v-model="form.cronExpression" placeholder="请输入cron执行表达式">
<template #append>
<el-button type="primary" @click="handleShowCron">
生成表达式
<i class="el-icon-time el-icon--right"></i>
</el-button>
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="24" v-if="form.jobId !== undefined">
<el-form-item label="状态">
<el-radio-group v-model="form.status">
<el-radio v-for="dict in sys_job_status" :key="dict.value" :value="dict.value">{{ dict.label
}}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="备注" prop="remark">
<el-input type="textarea" v-model="form.remark" placeholder="请输入备注" :rows="3" />
</el-form-item>
</el-col>
<!-- <el-col :span="12">
<el-form-item label="是否并发" prop="concurrent">
<el-radio-group v-model="form.concurrent">
<el-radio-button value="0">允许</el-radio-button>
<el-radio-button value="1">禁止</el-radio-button>
</el-radio-group>
</el-form-item>
</el-col> -->
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</template>
</el-dialog>
<el-dialog title="Cron表达式生成器" v-model="openCron" append-to-body destroy-on-close>
<crontab ref="crontabRef" @hide="openCron = false" @fill="crontabFill" :expression="expression"></crontab>
</el-dialog>
<!-- 任务日志详细 -->
<el-dialog title="任务详细" v-model="openView" width="700px" append-to-body>
<el-form :model="form" label-width="120px">
<el-row>
<el-col :span="12">
<el-form-item label="任务编号:">{{ form.jobId }}</el-form-item>
<el-form-item label="任务名称:">{{ form.jobName }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="任务分组:">{{ jobGroupFormat(form) }}</el-form-item>
<el-form-item label="创建时间:">{{ form.createTime }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="cron表达式">{{ form.cronExpression }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="下次执行时间:">{{ parseTime(form.nextValidTime) }}</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="调用目标方法:">{{ form.jobClazz }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="任务状态:">
<div v-if="form.status == 0">正常</div>
<div v-else-if="form.status == 1">暂停</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="是否并发:">
<div v-if="form.concurrent == 0">允许</div>
<div v-else-if="form.concurrent == 1">禁止</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="执行策略:">
<div v-if="form.misfirePolicy == 0">默认策略</div>
<div v-else-if="form.misfirePolicy == 1">立即执行</div>
<div v-else-if="form.misfirePolicy == 2">执行一次</div>
<div v-else-if="form.misfirePolicy == 3">放弃执行</div>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="openView = false"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="Job">
import { listJob, getJob, delJob, addJob, updateJob, runJob, changeJobStatus } from "@/api/monitor/job";
import Crontab from '@/components/Crontab'
const router = useRouter();
const { proxy } = getCurrentInstance();
// const { sys_job_group, sys_job_status } = proxy.useDict("sys_job_group", "sys_job_status");
const jobList = ref([]);
const open = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const openView = ref(false);
const openCron = ref(false);
const expression = ref("");
const jobStatusList = ref([
{ label: '正常', value: 0 },
{ label: '暂停', value: 1 }
])
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
jobName: undefined,
jobStatus: undefined
},
rules: {
jobName: [{ required: true, message: "任务名称不能为空", trigger: "blur" }],
jobClazz: [{ required: true, message: "任务全类名不能为空", trigger: "blur" }],
cronExpression: [{ required: true, message: "cron执行表达式不能为空", trigger: "change" }]
}
});
const { queryParams, form, rules } = toRefs(data);
/** 查询定时任务列表 */
function getList() {
loading.value = true;
listJob(queryParams.value).then(response => {
console.log("定时任务列表", response)
jobList.value = response.data.records.map(item => {
item._isInit = true;
return item;
});
// 数据加载完成后延迟将_isInit设为false
setTimeout(() => {
jobList.value.forEach(item => {
item._isInit = false;
});
}, 0);
total.value = response.data.total;
loading.value = false;
});
}
/** 任务组名字典翻译 */
function jobGroupFormat(row, column) {
return proxy.selectDictLabel(sys_job_group.value, row.jobGroup);
}
/** 取消按钮 */
function cancel() {
open.value = false;
reset();
}
/** 表单重置 */
function reset() {
form.value = {
id: undefined,
jobName: undefined,
jobGroup: undefined,
jobClazz: undefined,
cronExpression: undefined,
remark: undefined,
};
proxy.resetForm("jobRef");
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm("queryRef");
handleQuery();
}
// 多选框选中数据
function handleSelectionChange(selection) {
ids.value = selection.map(item => item.jobId);
single.value = selection.length != 1;
multiple.value = !selection.length;
}
// 更多操作触发
function handleCommand(command, row) {
switch (command) {
case "handleRun":
handleRun(row);
break;
case "handleView":
handleView(row);
break;
case "handleJobLog":
handleJobLog(row);
break;
default:
break;
}
}
// 任务状态修改
function handleStatusChange(row) {
if (row._isInit) return;
const params = {
jobId: row.id,
targetStatus: row.jobStatus
};
let text = row.jobStatus === 0 ? "启用" : "停用";
proxy.$modal.confirm('确认要"' + text + '""' + row.jobName + '"任务吗?').then(function () {
return changeJobStatus(params);
}).then(() => {
proxy.$modal.msgSuccess(text + "成功");
}).catch(function () {
row.jobStatus = row.jobStatus === 0 ? 1 : 0;
});
}
/* 立即运行任务 */
function handleRun(row) {
const params = {
jobId: row.id
};
proxy.$modal.confirm('确认要立即运行"' + row.jobName + '"任务吗?').then(function () {
return runJob(params);
}).then(() => {
proxy.$modal.msgSuccess("执行成功");
})
.catch(() => { });
}
/** 任务详细信息 */
function handleView(row) {
getJob(row.jobId).then(response => {
form.value = response.data;
openView.value = true;
});
}
/** cron表达式按钮操作 */
function handleShowCron() {
expression.value = form.value.cronExpression;
openCron.value = true;
}
/** 确定后回传值 */
function crontabFill(value) {
form.value.cronExpression = value;
}
/** 任务日志列表查询 */
function handleJobLog(row) {
const jobId = row.jobId || 0;
router.push('/monitor/job-log/index/' + jobId)
}
/** 新增按钮操作 */
function handleAdd() {
reset();
form.value.id = undefined;
open.value = true;
title.value = "添加任务";
}
/** 修改按钮操作 */
function handleUpdate(row) {
reset();
form.value.id = row.id;
form.value.jobName = row.jobName;
form.value.jobClazz = row.jobClazz;
form.value.jobStatus = row.jobStatus;
form.value.cronExpression = row.cronExpression;
form.value.remark = row.remark;
open.value = true;
title.value = "修改任务";
}
const currentJobId = ref(null);
/** 提交按钮 */
function submitForm() {
proxy.$refs["jobRef"].validate(valid => {
if (valid) {
if (form.value.id != undefined) {
updateJob(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
} else {
addJob(form.value).then(response => {
proxy.$modal.msgSuccess("新增成功");
open.value = false;
getList();
});
}
}
});
}
/** 删除按钮操作 */
function handleDelete(row) {
const jobIds = row.id || ids.value;
proxy.$modal.confirm('是否确认删除定时任务编号为"' + jobIds + '"的数据项?').then(function () {
return delJob(jobIds);
}).then(() => {
getList();
proxy.$modal.msgSuccess("删除成功");
}).catch(() => { });
}
/** 导出按钮操作 */
function handleExport() {
proxy.download("monitor/job/export", {
...queryParams.value,
}, `job_${new Date().getTime()}.xlsx`);
}
getList();
</script>