Files
intc-vue3/src/views/monitor/job/index.vue
2024-04-29 15:06:24 +08:00

449 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">
<div class="search-con" ref="searchHeightRef">
<div class="title">查询条件</div>
<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="status">
<el-select v-model="queryParams.status" placeholder="请选择任务状态" clearable style="width: 200px">
<el-option v-for="dict in sys_job_status" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
</el-form>
<div class="search-btn-con">
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button type="info" icon="Refresh" @click="resetQuery">重置</el-button>
</div>
</div>
<div class="main-con" :style="{ height: mainStyleHeight }">
<div class="title-con">
<div class="title">基本信息</div>
<div class="operate-btn-con">
<el-button icon="Plus" @click="handleAdd" v-hasPermi="['monitor:job:add']">新增</el-button>
<el-button icon="Edit" :disabled="single" @click="handleUpdate" v-hasPermi="['monitor:job:edit']">修改</el-button>
<el-button icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['monitor:job:remove']">删除</el-button>
<el-button icon="Download" @click="handleExport" v-hasPermi="['monitor:job:export']">导出</el-button>
<el-button icon="Operation" @click="handleJobLog" v-hasPermi="['monitor:job:query']">日志</el-button>
<!-- <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> -->
</div>
</div>
<div class="content-con" v-loading="loading">
<el-table v-loading="loading" :data="jobList" @selection-change="handleSelectionChange" stripe height="calc(100% - 0.62rem)">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="任务编号" width="100" align="center" prop="jobId" />
<el-table-column label="任务名称" align="center" prop="jobName" :show-overflow-tooltip="true" />
<el-table-column label="任务组名" align="center" prop="jobGroup">
<template #default="scope">
<dict-tag :options="sys_job_group" :value="scope.row.jobGroup" />
</template>
</el-table-column>
<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.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="240" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="修改" placement="top">
<el-button circle icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['monitor:job:edit']"></el-button>
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button circle icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['monitor:job:remove']"></el-button>
</el-tooltip>
<el-tooltip content="执行一次" placement="top">
<el-button circle icon="CaretRight" @click="handleRun(scope.row)" v-hasPermi="['monitor:job:changeStatus']"></el-button>
</el-tooltip>
<el-tooltip content="任务详细" placement="top">
<el-button circle icon="View" @click="handleView(scope.row)" v-hasPermi="['monitor:job:query']"></el-button>
</el-tooltip>
<el-tooltip content="调度日志" placement="top">
<el-button circle icon="Operation" @click="handleJobLog(scope.row)" v-hasPermi="['monitor:job:query']"></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<el-pagination
small
background
layout="total, prev, pager, next"
:total="total"
v-model:current-page="currentPage"
@current-change="handleCurrentChange"
/>
</div>
</div>
<!-- 添加或修改定时任务对话框 -->
<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="12">
<el-form-item label="任务分组" prop="jobGroup">
<el-select v-model="form.jobGroup" placeholder="请选择">
<el-option v-for="dict in sys_job_group" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item prop="invokeTarget">
<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.invokeTarget" 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" :label="dict.value">{{ dict.label }}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="执行策略" prop="misfirePolicy">
<el-radio-group v-model="form.misfirePolicy">
<el-radio-button label="1">立即执行</el-radio-button>
<el-radio-button label="2">执行一次</el-radio-button>
<el-radio-button label="3">放弃执行</el-radio-button>
</el-radio-group>
</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 label="0">允许</el-radio-button>
<el-radio-button label="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.invokeTarget }}</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 currentPage = ref(1)
const mainStyleHeight = ref(0)
const searchHeightRef = ref(null)
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
jobName: undefined,
jobGroup: undefined,
status: undefined
},
rules: {
jobName: [{ required: true, message: '任务名称不能为空', trigger: 'blur' }],
invokeTarget: [{ 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) => {
jobList.value = response.rows
total.value = response.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 = {
jobId: undefined,
jobName: undefined,
jobGroup: undefined,
invokeTarget: undefined,
cronExpression: undefined,
misfirePolicy: 1,
concurrent: 1,
status: '0'
}
proxy.resetForm('jobRef')
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1
getList()
}
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm('queryRef')
currentPage.value = 1
handleQuery()
}
// 多选框选中数据
function handleSelectionChange(selection) {
ids.value = selection.map((item) => item.jobId)
// eslint-disable-next-line
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) {
// eslint-disable-next-line
let text = row.status === '0' ? '启用' : '停用'
proxy.$modal
.confirm('确认要"' + text + '""' + row.jobName + '"任务吗?')
.then(function () {
return changeJobStatus(row.jobId, row.status)
})
.then(() => {
proxy.$modal.msgSuccess(text + '成功')
})
.catch(function () {
row.status = row.status === '0' ? '1' : '0'
})
}
/* 立即执行一次 */
function handleRun(row) {
proxy.$modal
.confirm('确认要立即执行一次"' + row.jobName + '"任务吗?')
.then(function () {
return runJob(row.jobId, row.jobGroup)
})
.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()
open.value = true
title.value = '添加任务'
}
/** 修改按钮操作 */
function handleUpdate(row) {
reset()
const jobId = row.jobId || ids.value
getJob(jobId).then((response) => {
form.value = response.data
open.value = true
title.value = '修改任务'
})
}
/** 提交按钮 */
function submitForm() {
// eslint-disable-next-line
proxy.$refs['jobRef'].validate((valid) => {
if (valid) {
// eslint-disable-next-line
if (form.value.jobId != 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.jobId || ids.value
proxy.$modal
.confirm('是否确认删除定时任务编号为"' + jobIds + '"的数据项?')
.then(function () {
return delJob(jobIds)
})
.then(() => {
getList()
proxy.$modal.msgSuccess('删除成功')
})
.catch(() => {})
}
/** 导出按钮操作 */
function handleExport() {
proxy.download(
'schedule/job/export',
{
...queryParams.value
},
`job_${new Date().getTime()}.xlsx`
)
}
// 分页
const handleCurrentChange = (val) => {
queryParams.value.pageNum = val
getList()
}
onMounted(() => {
mainStyleHeight.value = `calc(100% - ${(searchHeightRef.value.clientHeight + 10) / 100}rem)`
})
getList()
</script>