<!DOCTYPE html>
|
<html>
|
|
<head>
|
<meta charset="utf-8">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
<meta name="renderer" content="webkit">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<link rel="icon" href="favicon.ico">
|
<title>智慧水务-南京地铁智慧泵站监测系统</title>
|
|
<link rel="stylesheet" href="css/main.css" />
|
|
<link rel="stylesheet" href="js/lib/element-plus/index.css" />
|
<script src="js/lib/vue.global.js"></script>
|
<script src="js/lib/element-plus/element-plus.js"></script>
|
<script src="js/lib/element-plus/icons-vue.js"></script>
|
|
<script src="js/lib/axios.min.js"></script>
|
<script src="js/lib/httpVueLoader.js"></script>
|
</head>
|
<body>
|
<div id="app">
|
<div id="loader-wrapper" v-if="loading">
|
<div id="loader"></div>
|
<div class="loader-section section-left"></div>
|
<div class="loader-section section-right"></div>
|
<div class="load_title">正在加载系统资源,请耐心等待</div>
|
</div>
|
|
<el-form :model="queryParams" :inline="true">
|
<el-form-item label="任务编号">
|
<el-input
|
v-model="queryParams.taskNo"
|
placeholder="请输入任务编号"
|
clearable
|
style="width: 200px"
|
@keyup.enter="handleQuery"
|
/>
|
</el-form-item>
|
<el-form-item label="任务名称">
|
<el-input
|
v-model="queryParams.keywords"
|
placeholder="请输入任务名称"
|
clearable
|
style="width: 200px"
|
@keyup.enter="handleQuery"
|
/>
|
</el-form-item>
|
<el-form-item label="任务状态">
|
<el-select
|
v-model="queryParams.listStatus"
|
multiple
|
placeholder="请选择"
|
style="width: 240px"
|
>
|
<el-option
|
v-for="item in listEState"
|
:key="item.value"
|
:label="item.label"
|
:value="item.value"
|
/>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="创建时间">
|
<el-date-picker
|
v-model="dateRangeCreateTime"
|
value-format="YYYY-MM-DD HH:mm:ss"
|
type="daterange"
|
range-separator="-"
|
start-placeholder="开始日期"
|
end-placeholder="结束日期"
|
:default-time="[
|
new Date(2000, 1, 1, 0, 0, 0),
|
new Date(2000, 1, 1, 23, 59, 59),
|
]"
|
></el-date-picker>
|
</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-row>
|
|
<el-table
|
:stripe="true"
|
:border="true"
|
:data="dataList"
|
@selection-change="handleSelectionChange"
|
@row-dblclick="handleDetail"
|
>
|
<el-table-column label="任务编号" min-width="175" align="center" prop="taskNo"></el-table-column>
|
<el-table-column label="任务名称" min-width="300" align="center" prop="taskName"></el-table-column>
|
<el-table-column label="执行频率cron" min-width="110" align="center" prop="schedulerRule"></el-table-column>
|
<el-table-column label="执行器名称" min-width="200" align="center" prop="executor"></el-table-column>
|
<el-table-column label="任务状态" min-width="80" align="center" prop="status">
|
<template #default="scope">
|
{{ getEStateLabel(scope.row.status) }}
|
</template>
|
</el-table-column>
|
<el-table-column label="创建时间" min-width="155" align="center" prop="createTimeView"></el-table-column>
|
<el-table-column label="最后修改时间" align="center" min-width="185" prop="updateTimeView"></el-table-column>
|
<el-table-column
|
label="操作"
|
align="center"
|
min-width="220"
|
fixed="right"
|
class-name="small-padding fixed-width"
|
>
|
<template #default="scope">
|
<el-button
|
link
|
type="primary"
|
@click="handleDetail(scope.row)"
|
>详情</el-button>
|
<el-button
|
link
|
type="warning"
|
@click="handleListRecord(scope.row)"
|
>执行记录</el-button>
|
<el-dropdown style="margin-left:10px;">
|
<el-button size="small" type="danger">
|
<span style="padding:0px 8px;">操作</span><el-icon class="el-icon--right"><arrow-down /></el-icon>
|
</el-button>
|
<template #dropdown>
|
<el-dropdown-menu>
|
<el-dropdown-item @click="handleUpdate(scope.row)">修改</el-dropdown-item>
|
<el-dropdown-item @click="handleEnable(scope.row)" v-if="scope.row.status === 2">打开</el-dropdown-item>
|
<el-dropdown-item @click="handleStop(scope.row)" v-if="scope.row.status === 1">关闭</el-dropdown-item>
|
<el-dropdown-item @click="handleRunNow(scope.row)">立即执行</el-dropdown-item>
|
</el-dropdown-menu>
|
</template>
|
</el-dropdown>
|
</template>
|
</el-table-column>
|
</el-table>
|
|
<el-pagination
|
v-if="total > 0"
|
:background="tabConfig.background"
|
:hide-on-single-page="tabConfig.hideOnSinglePage"
|
:page-sizes="tabConfig.listPageSize"
|
:total="total"
|
v-model:current-page="queryParams.page"
|
v-model:page-size="queryParams.limit"
|
@change ="getList"
|
></el-pagination>
|
|
<!-- 添加对话框 -->
|
<el-dialog
|
title="添加任务"
|
v-model="dialogOpenCreate"
|
width="750px"
|
append-to-body
|
>
|
<el-form
|
:model="formCreate"
|
label-width="125px"
|
>
|
<el-form-item label="任务名称" prop="taskName">
|
<el-input v-model="formCreate.taskName" placeholder="" />
|
</el-form-item>
|
<el-form-item label="定时器策略" prop="schedulerRule">
|
<el-input v-model="formCreate.schedulerRule" placeholder="" clearable>
|
<template #append>
|
<el-tooltip content="配置定时器策略" placement="top">
|
<el-button type="success" icon="Edit" @click="() => { showCreateCronCore = !showCreateCronCore }" />
|
</el-tooltip>
|
</template>
|
</el-input>
|
</el-form-item>
|
<el-form-item label="执行器名称" prop="executor">
|
<el-input v-model="formCreate.executor" placeholder="" />
|
</el-form-item>
|
<el-form-item label="执行参数" prop="executeParameter">
|
<el-input
|
v-model="formCreate.executeParameter"
|
type="textarea"
|
:autosize="{ minRows: 2, maxRows: 4 }"
|
placeholder=""
|
/>
|
</el-form-item>
|
<el-form-item label="通知方式" prop="sendType">
|
<el-select
|
v-model="formCreate.sendType"
|
collapse-tags
|
collapse-tags-tooltip
|
placeholder="请选择"
|
style="width: 240px"
|
>
|
<el-option label="Http" value="1"/>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="通知地址" prop="url">
|
<el-input v-model="formCreate.url" placeholder="" />
|
</el-form-item>
|
</el-form>
|
<template #footer>
|
<div class="dialog-footer">
|
<el-button
|
:loading="createLoading"
|
type="primary"
|
@click="submitCreate"
|
>确 定</el-button>
|
<el-button @click="cancelCreate">取 消</el-button>
|
</div>
|
</template>
|
</el-dialog>
|
|
<!-- 修改对话框 -->
|
<el-dialog
|
:title="title"
|
v-model="dialogOpenModify"
|
width="750px"
|
append-to-body
|
>
|
<el-form
|
:disabled="isDetail"
|
:model="formModify"
|
label-width="125px"
|
>
|
<el-form-item label="任务编号" prop="taskNo">
|
<el-input v-model="formModify.id" type="hidden" />
|
{{ formModify.taskNo }}
|
</el-form-item>
|
<el-form-item label="任务名称" prop="taskName">
|
<el-input v-model="formModify.taskName" placeholder="" />
|
</el-form-item>
|
<el-form-item label="定时器策略" prop="schedulerRule">
|
<el-input v-model="formModify.schedulerRule" placeholder="" clearable>
|
<template #append>
|
<el-tooltip content="配置定时器策略" placement="top">
|
<el-button type="success" icon="Edit" @click="() => { showModifyCronCore = !showModifyCronCore }" />
|
</el-tooltip>
|
</template>
|
</el-input>
|
</el-form-item>
|
<el-form-item label="执行器名称" prop="executor">
|
<el-input v-model="formModify.executor" placeholder="" />
|
</el-form-item>
|
<el-form-item label="执行参数" prop="executeParameter">
|
<el-input
|
v-model="formModify.executeParameter"
|
type="textarea"
|
:autosize="{ minRows: 2, maxRows: 4 }"
|
placeholder=""
|
/>
|
</el-form-item>
|
<el-form-item label="状态" prop="status">
|
<el-radio-group v-model="formModify.status">
|
<el-radio :label="1">开启</el-radio>
|
<el-radio :label="2">关闭</el-radio>
|
</el-radio-group>
|
</el-form-item>
|
<el-form-item label="通知方式" prop="sendType">
|
<el-select
|
v-model="formModify.sendType"
|
collapse-tags
|
collapse-tags-tooltip
|
placeholder="请选择"
|
style="width: 240px"
|
>
|
<el-option label="Http" value="1"/>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="通知地址" prop="url">
|
<el-input v-model="formModify.url" placeholder="" />
|
</el-form-item>
|
<el-form-item label="创建时间" prop="createTimeView">
|
{{ formModify.createTimeView }}
|
</el-form-item>
|
<el-form-item label="更新时间" prop="updateTimeView">
|
{{ formModify.updateTimeView }}
|
</el-form-item>
|
</el-form>
|
<template #footer>
|
<div class="dialog-footer">
|
<el-button
|
v-if="isDetail === false"
|
:loading="modifyLoading"
|
type="primary"
|
@click="submitModify"
|
>确 定</el-button>
|
<el-button @click="cancelModify">{{ cancelModifyTxt }}</el-button>
|
<el-button
|
type="primary"
|
v-if="isDetail"
|
@click="changeModify"
|
>编 辑</el-button>
|
</div>
|
</template>
|
</el-dialog>
|
|
<!-- 立即执行对话框 -->
|
<el-dialog
|
:title="title"
|
v-model="dialogOpenRunNow"
|
width="450px"
|
append-to-body
|
>
|
<el-form
|
:model="formRunNow"
|
label-width="80px"
|
>
|
<el-form-item label="执行参数" prop="executeParameter">
|
<el-input v-model="formRunNow.id" type="hidden"></el-input>
|
<el-input
|
v-model="formRunNow.executeParameter"
|
type="textarea"
|
:autosize="{ minRows: 2, maxRows: 4 }"
|
placeholder=""
|
></el-input>
|
</el-form-item>
|
</el-form>
|
<template #footer>
|
<div class="dialog-footer">
|
<el-button
|
:loading="runNowLoading"
|
type="primary"
|
@click="submitRunNow"
|
>确 定</el-button>
|
<el-button @click="cancelRunNow">取 消</el-button>
|
</div>
|
</template>
|
</el-dialog>
|
|
<!-- 执行记录对话框 -->
|
<el-dialog
|
title="执行记录"
|
v-model="dialogOpenJobRecord"
|
:fullscreen="true"
|
:close-on-click-modal="false"
|
:destroy-on-close="true"
|
append-to-body
|
>
|
<!-- 设置对话框内容高度 -->
|
<div style="height:75vh;">
|
<el-scrollbar>
|
<iframe :src="jobRecordUrl" id="map" scrolling="no" frameborder="0" style="width:100%;height:100%;position:absolute;top:4px;left:10px;right:0px;bottom:10px;"></iframe>
|
</el-scrollbar>
|
</div>
|
</el-dialog>
|
|
<!-- cron表达式对话框 -->
|
<el-dialog
|
title="定时策略"
|
v-model="showCreateCronCore"
|
width="600px"
|
append-to-body
|
>
|
<!-- <vue3-cron
|
@change="onCreateChangeCron"
|
v-if="showCreateCronCore"
|
v-model:value="formCreate.schedulerRule"
|
@close="showCreateCronCore = false"
|
/> -->
|
<crontab
|
@hide="showCreateCronCore = false"
|
@fill="onCreateChangeCron"
|
:expression="formCreate.schedulerRule"
|
/>
|
</el-dialog>
|
<el-dialog
|
title="定时策略"
|
v-model="showModifyCronCore"
|
width="600px"
|
append-to-body
|
>
|
<!-- <vue3-cron
|
@change="onCreateChangeCron"
|
v-if="showModifyCronCore"
|
v-model:value="formModify.schedulerRule"
|
@close="showModifyCronCore = false"
|
/> -->
|
<crontab
|
@hide="showModifyCronCore = false"
|
@fill="onModifyChangeCron"
|
:expression="formModify.schedulerRule"
|
/>
|
</el-dialog>
|
</div>
|
<script type="module">
|
import { EState } from "/js/enums.js"
|
|
const { createApp, ref, onMounted, h } = Vue
|
|
const Http = axios.create({
|
baseURL: location.pathname.substr(0, location.pathname.lastIndexOf('/')),
|
timeout: 1000,
|
headers: {'X-Custom-Header': 'foobar'}
|
});
|
const $message = ElementPlus.ElMessage;
|
const $confirm = ElementPlus.ElMessageBox;
|
|
var app = Vue.createApp({
|
el: '#app',
|
// 相对路径引用参考
|
components: {
|
'job-record': httpVueLoader('./job-record.vue'),
|
'crontab': httpVueLoader('./vue3-cron/index.vue')
|
},
|
data() {
|
return {
|
recordConfig: {
|
close_on_click_modal: false,
|
destroy_on_close: true
|
}
|
}
|
},
|
methods: {
|
},
|
|
mounted: () => {
|
//$message('这是一条普通info消息');
|
},
|
|
setup() {
|
const tabConfig = ref({
|
background: true,
|
hideOnSinglePage: true,
|
listPageSize: [20, 50, 100, 200]
|
});
|
|
const showCreateCronCore = ref(false); // 是否打开cron表达式配置框
|
const onCreateChangeCron = (val) => {
|
if (typeof val !== "string") {
|
return false
|
}
|
formCreate.value.schedulerRule = val;
|
};
|
|
const showModifyCronCore = ref(false); // 是否打开cron表达式配置框
|
const onModifyChangeCron = (val) => {
|
if (typeof val !== "string") {
|
return false
|
}
|
formModify.value.schedulerRule = val;
|
};
|
|
const listEState = EState.enums;
|
const getEStateLabel = (value) => {
|
return EState.getLabelByValue(value)
|
}
|
|
const loading = ref(true)
|
const dataList = ref([]);
|
|
const createLoading = ref(false);
|
const dialogOpenCreate = ref(false);
|
|
const modifyLoading = ref(false);
|
const dialogOpenModify = ref(false);
|
|
const runNowLoading = ref(false);
|
const dialogOpenRunNow = ref(false);
|
|
const total = ref(0);
|
const dateRangeCreateTime = ref([]);
|
const ids = ref([]);
|
const single = ref(true);
|
const multiple = ref(true);
|
const title = ref("");
|
const cancelModifyTxt = ref("取 消");
|
const isDetail = ref(false);
|
|
const jobRecordTaskNo = ref("");
|
const dialogOpenJobRecord = ref(false);
|
const jobRecordUrl = ref("");
|
|
const queryParams = ref({
|
page: 1,
|
limit: 10,
|
createTimeRange: '',
|
keywords: '',
|
listStatus: [],
|
createTime: '',
|
taskNo: ''
|
});
|
|
const formCreate = ref({});
|
|
const formModify = ref({});
|
|
const formRunNow = ref({
|
id: 0,
|
executeParameter: "",
|
});
|
const rulesRunNow = ref({
|
//executeParameter: [{ required: true, message: "巡更人员列表不能为空", trigger: "blur" }]
|
});
|
|
/** 查询列表 */
|
function getList() {
|
loading.value = true;
|
if (
|
dateRangeCreateTime &&
|
dateRangeCreateTime.value &&
|
dateRangeCreateTime.value[0]
|
) {
|
queryParams.value.createTimeRange = dateRangeCreateTime.value.join(" ~ ");
|
}
|
Http.post('/quartz/listTask', queryParams.value)
|
.then((response) => {
|
let data = response.data.data;
|
dataList.value = data.list;
|
total.value = data.total;
|
loading.value = false;
|
});
|
}
|
/** 搜索按钮操作 */
|
function handleQuery() {
|
queryParams.value.page = 1;
|
getList();
|
}
|
/** 重置按钮操作 */
|
function resetQuery() {
|
dateRangeCreateTime.value = [];
|
queryParams.value = {
|
page: 1,
|
limit: 10,
|
createTimeRange: "",
|
keywords: undefined,
|
listStatus: undefined,
|
createTime: undefined,
|
taskNo: undefined
|
};
|
handleQuery();
|
}
|
/** 选择条数 */
|
function handleSelectionChange(selection) {
|
console.log('handleSelectionChange' + selection);
|
ids.value = selection.map((item) => item.id);
|
single.value = selection.length != 1;
|
multiple.value = !selection.length;
|
}
|
|
|
|
/** 取消新增按钮 */
|
function cancelCreate() {
|
dialogOpenCreate.value = false;
|
resetCreate();
|
}
|
/** 新增表单重置 */
|
function resetCreate() {
|
formCreate.value = {
|
taskName: undefined,
|
schedulerRule: undefined,
|
executor: undefined,
|
sendType: undefined,
|
url: undefined,
|
executeParameter: undefined,
|
};
|
}
|
/** 新增按钮 */
|
function handleAdd() {
|
resetCreate();
|
dialogOpenCreate.value = true;
|
title.value = "添加任务";
|
}
|
/** 新增提交 */
|
function submitCreate() {
|
let _self = this;
|
|
createLoading.value = true;
|
|
Http.post('/quartz/addTask', formCreate.value)
|
.then((response) => {
|
$message.success('新增成功');
|
dialogOpenCreate.value = false;
|
getList();
|
})
|
.finally(() => {
|
createLoading.value = false;
|
});
|
}
|
|
|
|
/** 详情按钮 */
|
function handleDetail(row) {
|
modifyLoading.value = true;
|
resetModify();
|
const id = row.id || ids.value[0];
|
|
isDetail.value = true;
|
modifyLoading.value = false;
|
|
formModify.value = {...row};
|
dialogOpenModify.value = true;
|
title.value = "任务信息";
|
cancelModifyTxt.value = "关 闭";
|
|
console.log('handleDetail: ' + JSON.stringify(formModify.value))
|
}
|
/** 详情编辑 */
|
function changeModify() {
|
isDetail.value = false;
|
title.value = "修改任务";
|
}
|
|
|
|
/** 编辑表单重置 */
|
function resetModify() {
|
formModify.value = {
|
id: undefined,
|
taskName: undefined,
|
schedulerRule: undefined,
|
executor: undefined,
|
sendType: undefined,
|
url: undefined,
|
executeParameter: undefined,
|
};
|
}
|
/** 取消编辑按钮 */
|
function cancelModify() {
|
dialogOpenModify.value = false;
|
resetModify();
|
}
|
/** 修改按钮 */
|
function handleUpdate(row) {
|
modifyLoading.value = true;
|
resetModify();
|
const id = row.id || ids.value[0];
|
|
isDetail.value = false;
|
modifyLoading.value = false;
|
formModify.value = {...row};
|
|
dialogOpenModify.value = true;
|
title.value = "修改任务";
|
cancelModifyTxt.value = "取 消";
|
|
console.log('handleUpdate: ' + JSON.stringify(formModify.value))
|
}
|
/** 修改提交 */
|
function submitModify() {
|
let _self = this;
|
modifyLoading.value = true;
|
console.log($message)
|
|
Http.post('/quartz/editTask', formModify.value)
|
.then((response) => {
|
$message.success('修改成功');
|
dialogOpenModify.value = false;
|
getList();
|
})
|
.finally(() => {
|
modifyLoading.value = false;
|
});
|
}
|
|
|
|
/** 停用按钮 */
|
function handleStop(row) {
|
$confirm.confirm(
|
'确定要关闭吗?',
|
'Warning',
|
{
|
confirmButtonText: '确认',
|
cancelButtonText: '取消',
|
type: 'warning',
|
}
|
)
|
.then(() => {
|
loading.value = true;
|
const id = row.id;
|
Http.post('/quartz/optionJob/' + id, {}).then((response) => {
|
// 调用列表查询
|
getList();
|
})
|
.finally(() => {
|
loading.value = false;
|
});
|
})
|
.catch(() => {
|
$message.info('操作取消')
|
})
|
}
|
|
|
|
/** 启用按钮 */
|
function handleEnable(row) {
|
$confirm.confirm(
|
'确定要开启吗?',
|
'Warning',
|
{
|
confirmButtonText: '确认',
|
cancelButtonText: '取消',
|
type: 'warning',
|
}
|
)
|
.then(() => {
|
loading.value = true;
|
const id = row.id;
|
Http.post('/quartz/optionJob/' + id, {}).then((response) => {
|
// 调用列表查询
|
getList();
|
})
|
.finally(() => {
|
loading.value = false;
|
});
|
})
|
.catch(() => {
|
$message.info('操作取消')
|
})
|
}
|
|
|
|
/** 立即执行按钮 */
|
function handleRunNow(row) {
|
console.log('handleRunNow: ' + JSON.stringify(row))
|
dialogOpenRunNow.value = true;
|
formRunNow.value.id = row.id;
|
formRunNow.value.executeParameter = row.executeParameter;
|
title.value = "执行任务";
|
}
|
/** 取消操作按钮 */
|
function cancelRunNow() {
|
dialogOpenRunNow.value = false;
|
}
|
/** 提交操作 */
|
function submitRunNow() {
|
runNowLoading.value = true;
|
|
Http.post('/quartz/runTaskRightNow', formRunNow.value).then((response) => {
|
dialogOpenRunNow.value = false;
|
// 调用列表查询
|
getList();
|
})
|
.finally(() => {
|
runNowLoading.value = false;
|
});
|
}
|
|
|
|
/** 执行记录 */
|
function handleListRecord(row) {
|
dialogOpenJobRecord.value = true;
|
jobRecordTaskNo.value = row.taskNo;
|
jobRecordUrl.value= '/job-record.html?taskNo=' + row.taskNo;
|
}
|
|
onMounted(() => {
|
loading.value = false
|
handleQuery()
|
})
|
return {
|
tabConfig,
|
listEState,
|
getEStateLabel,
|
showCreateCronCore,
|
onCreateChangeCron,
|
showModifyCronCore,
|
onModifyChangeCron,
|
loading,
|
dataList,
|
createLoading,
|
dialogOpenCreate,
|
modifyLoading,
|
dialogOpenModify,
|
runNowLoading,
|
dialogOpenRunNow,
|
total,
|
dateRangeCreateTime,
|
ids,
|
single,
|
multiple,
|
title,
|
cancelModifyTxt,
|
isDetail,
|
jobRecordTaskNo,
|
dialogOpenJobRecord,
|
jobRecordUrl,
|
queryParams,
|
formCreate,
|
formModify,
|
formRunNow,
|
getList,
|
handleQuery,
|
resetQuery,
|
handleSelectionChange,
|
cancelCreate,
|
resetCreate,
|
handleAdd,
|
submitCreate,
|
handleDetail,
|
changeModify,
|
resetModify,
|
cancelModify,
|
handleUpdate,
|
submitModify,
|
handleStop,
|
handleEnable,
|
handleRunNow,
|
cancelRunNow,
|
submitRunNow,
|
handleListRecord
|
}
|
}
|
})
|
app.use(httpVueLoader)
|
app.use(ElementPlus)
|
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
app.component(key, component)
|
}
|
app.mount("#app")
|
</script>
|
</body>
|
</html>
|