This commit is contained in:
2023-04-21 16:53:32 +08:00
parent 6cb6bfd65c
commit 5b2bba6a78
58 changed files with 420 additions and 288 deletions

View File

@@ -1,5 +1,4 @@
<template>
<el-dialog :visible.sync="visible" :title="!dataForm.id ? $t('add') : $t('update')" :close-on-click-modal="false" :close-on-press-escape="false">
<el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmitHandle()" label-width="120px">
<el-form-item prop="beanName" :label="$t('schedule.beanName')">
<el-input v-model="dataForm.beanName" :placeholder="$t('schedule.beanNameTips')"></el-input>
@@ -17,20 +16,21 @@
<el-input v-model="dataForm.remark" :placeholder="$t('schedule.remark')"></el-input>
</el-form-item>
</el-form>
<template slot="footer">
<el-button @click="visible = false">{{ $t('cancel') }}</el-button>
<el-button type="primary" @click="dataFormSubmitHandle()">{{ $t('confirm') }}</el-button>
</template>
</el-dialog>
</template>
<script>
import basicAdd from '@/mixins/basic-add'
import debounce from 'lodash/debounce'
import { cron } from 'vue-cron'
export default {
mixins: [basicAdd],
data () {
return {
visible: false,
urlOptions: {
submitURL: '/sys/schedule/',
infoURL: '/sys/schedule'
},
dataForm: {
id: '',
beanName: '',
@@ -58,7 +58,8 @@ export default {
}
},
methods: {
init () {
init (id) {
this.dataForm.id = id || "";
this.visible = true
this.$nextTick(() => {
this.$refs['dataForm'].resetFields()

View File

@@ -1,71 +1,39 @@
<template>
<el-card shadow="never" class="aui-card--fill">
<div class="mod-job__schedule">
<el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()">
<el-form-item>
<el-input v-model="dataForm.beanName" :placeholder="$t('schedule.beanName')" clearable></el-input>
</el-form-item>
<el-form-item>
<el-button @click="getDataList()">{{ $t('query') }}</el-button>
</el-form-item>
<el-form-item>
<el-button v-if="$hasPermission('sys:schedule:save')" type="primary" @click="addOrUpdateHandle()">{{ $t('add') }}</el-button>
</el-form-item>
<el-form-item>
<el-button v-if="$hasPermission('sys:schedule:delete')" type="danger" @click="deleteHandle()">{{ $t('deleteBatch') }}</el-button>
</el-form-item>
<el-form-item>
<el-button v-if="$hasPermission('sys:schedule:pause')" type="danger" @click="pauseHandle()">{{ $t('schedule.pauseBatch') }}</el-button>
</el-form-item>
<el-form-item>
<el-button v-if="$hasPermission('sys:schedule:resume')" type="danger" @click="resumeHandle()">{{ $t('schedule.resumeBatch') }}</el-button>
</el-form-item>
<el-form-item>
<el-button v-if="$hasPermission('sys:schedule:run')" type="danger" @click="runHandle()">{{ $t('schedule.runBatch') }}</el-button>
</el-form-item>
<el-form-item>
<el-button v-if="$hasPermission('sys:schedule:log')" type="success" @click="logHandle()">{{ $t('schedule.log') }}</el-button>
</el-form-item>
</el-form>
<el-table
v-loading="dataListLoading"
:data="dataList"
border
@selection-change="dataListSelectionChangeHandle"
@sort-change="dataListSortChangeHandle"
style="width: 100%;">
<el-table-column type="selection" header-align="center" align="center" width="50"></el-table-column>
<el-table-column prop="beanName" :label="$t('schedule.beanName')" header-align="center" align="center"></el-table-column>
<el-table-column prop="params" :label="$t('schedule.params')" header-align="center" align="center"></el-table-column>
<el-table-column prop="cronExpression" :label="$t('schedule.cronExpression')" header-align="center" align="center"></el-table-column>
<el-table-column prop="remark" :label="$t('schedule.remark')" header-align="center" align="center"></el-table-column>
<el-table-column prop="status" :label="$t('schedule.status')" sortable="custom" header-align="center" align="center">
<template slot-scope="scope">
<el-tag v-if="scope.row.status === 1" size="small">{{ $t('schedule.status1') }}</el-tag>
<el-tag v-else size="small" type="danger">{{ $t('schedule.status0') }}</el-tag>
</template>
</el-table-column>
<el-table-column :label="$t('handle')" fixed="right" header-align="center" align="center" width="150">
<template slot-scope="scope">
<el-button v-if="$hasPermission('sys:schedule:update')" type="text" size="small" @click="addOrUpdateHandle(scope.row.id)">{{ $t('update') }}</el-button>
<el-button v-if="$hasPermission('sys:schedule:pause')" type="text" size="small" @click="pauseHandle(scope.row.id)">{{ $t('schedule.pause') }}</el-button>
<el-button v-if="$hasPermission('sys:schedule:resume')" type="text" size="small" @click="resumeHandle(scope.row.id)">{{ $t('schedule.resume') }}</el-button>
<el-button v-if="$hasPermission('sys:schedule:run')" type="text" size="small" @click="runHandle(scope.row.id)">{{ $t('schedule.run') }}</el-button>
<el-button v-if="$hasPermission('sys:schedule:delete')" type="text" size="small" @click="deleteHandle(scope.row.id)">{{ $t('delete') }}</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
:current-page="page"
:page-sizes="[10, 20, 50, 100]"
:page-size="limit"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@size-change="pageSizeChangeHandle"
@current-change="pageCurrentChangeHandle">
</el-pagination>
<search-bar :formConfigs="formConfig" ref="searchBarForm" @headBtnClick="buttonClick" />
<base-table
:table-props="tableProps"
:page="listQuery.page"
:limit="listQuery.limit"
:table-data="tableData"
>
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
:width="200"
label="操作"
:method-list="tableBtn"
@clickBtn="handleClick"
/>
</base-table>
<pagination
:limit.sync="listQuery.limit"
:page.sync="listQuery.page"
:total="listQuery.total"
@pagination="getDataList"
/>
<!-- 弹窗, 新增 / 修改 -->
<add-or-update v-if="addOrUpdateVisible" ref="addOrUpdate" @successSubmit="getDataList"></add-or-update>
<base-dialog
:dialogTitle="addOrEditTitle"
:dialogVisible="addOrUpdateVisible"
@cancel="handleCancel"
@confirm="handleConfirm"
:before-close="handleCancel"
>
<add-or-update ref="addOrUpdate" @successSubmit="successSubmit"></add-or-update>
</base-dialog>
<!-- 弹窗, 日志列表 -->
<log v-if="logVisible" ref="log"></log>
</div>
@@ -73,124 +41,255 @@
</template>
<script>
import mixinViewModule from '@/mixins/view-module'
import AddOrUpdate from './schedule-add-or-update'
import Log from './schedule-log'
import basicPage from "@/mixins/basic-page";
import AddOrUpdate from "./schedule-add-or-update";
import Log from "./schedule-log";
import i18n from "@/i18n";
import sysFilter from "@/filters/sys-filter";
const tableProps = [
{
prop: "beanName",
label: i18n.t("schedule.beanName"),
},
{
prop: "params",
label: i18n.t("schedule.params"),
},
{
prop: "cronExpression",
label: i18n.t("schedule.cronExpression"),
},
{
prop: "remark",
label: i18n.t("schedule.remark"),
},
{
prop: "status",
label: i18n.t("schedule.status"),
filter: sysFilter("scheduleStatus"),
},
];
const tableBtn = [
{
type: "edit",
btnName: "编辑",
},
{
type: "pause",
btnName: "暂停",
},
{
type: "restore",
btnName: "恢复",
},
{
type: "run",
btnName: "执行",
},
{
type: "delete",
btnName: "删除",
},
];
export default {
mixins: [mixinViewModule],
data () {
mixins: [basicPage],
data() {
return {
mixinViewModuleOptions: {
getDataListURL: '/sys/schedule/page',
getDataListIsPage: true,
deleteURL: '/sys/schedule',
deleteIsBatch: true
urlOptions: {
getDataListURL: "/sys/schedule/page",
deleteURL: "/sys/schedule",
},
dataForm: {
beanName: ''
beanName: "",
},
logVisible: false
}
tableProps,
tableBtn,
addDeleteURL: true,
logVisible: false,
formConfig: [
{
type: "input",
label: i18n.t("schedule.beanName"),
placeholder: i18n.t("schedule.beanName"),
param: "beanName",
},
{
type: "button",
btnName: "查询",
name: "search",
color: "primary",
},
{
type: "button",
btnName: "新增",
name: "add",
color: "primary",
plain: true,
},
{
type: "button",
btnName: "日志",
name: "log",
color: "success",
},
],
};
},
components: {
AddOrUpdate,
Log
Log,
},
methods: {
//search-bar点击
buttonClick(val) {
switch (val.btnName) {
case "search":
this.listQuery.beanName = val.beanName;
this.listQuery.page = 1;
this.getDataList();
break;
case "add":
this.addOrEditTitle = '新增'
this.addOrUpdateVisible = true;
this.addOrUpdateHandle()
break;
case "log":
this.logHandle()
break;
default:
console.log(val)
}
},
btnFun(val) {
if (val.type === "pause") {
this.pauseHandle(val.data.id);
} else if (val.type === "restore") {
this.resumeHandle(val.data.id);
} else {
this.runHandle(val.data.id);
}
},
// 暂停
pauseHandle (id) {
pauseHandle(id) {
if (!id && this.dataListSelections.length <= 0) {
return this.$message({
message: this.$t('prompt.deleteBatch'),
type: 'warning',
duration: 500
})
message: this.$t("prompt.deleteBatch"),
type: "warning",
duration: 500,
});
}
this.$confirm(this.$t('prompt.info', { 'handle': this.$t('schedule.pause') }), this.$t('prompt.title'), {
confirmButtonText: this.$t('confirm'),
cancelButtonText: this.$t('cancel'),
type: 'warning'
}).then(() => {
this.$http.put('/sys/schedule/pause', id ? [id] : this.dataListSelections.map(item => item.id)).then(({ data: res }) => {
if (res.code !== 0) {
return this.$message.error(res.msg)
}
this.$message({
message: this.$t('prompt.success'),
type: 'success',
duration: 500,
onClose: () => {
this.getDataList()
}
})
}).catch(() => {})
}).catch(() => {})
this.$confirm(
this.$t("prompt.info", { handle: this.$t("schedule.pause") }),
this.$t("prompt.title"),
{
confirmButtonText: this.$t("confirm"),
cancelButtonText: this.$t("cancel"),
type: "warning",
}
)
.then(() => {
this.$http
.put("/sys/schedule/pause", id ? [id] : this.dataListSelections.map((item) => item.id))
.then(({ data: res }) => {
if (res.code !== 0) {
return this.$message.error(res.msg);
}
this.$message({
message: this.$t("prompt.success"),
type: "success",
duration: 500,
onClose: () => {
this.getDataList();
},
});
})
.catch(() => {});
})
.catch(() => {});
},
// 恢复
resumeHandle (id) {
resumeHandle(id) {
if (!id && this.dataListSelections.length <= 0) {
return this.$message({
message: this.$t('prompt.deleteBatch'),
type: 'warning',
duration: 500
})
message: this.$t("prompt.deleteBatch"),
type: "warning",
duration: 500,
});
}
this.$confirm(this.$t('prompt.info', { 'handle': this.$t('schedule.resume') }), this.$t('prompt.title'), {
confirmButtonText: this.$t('confirm'),
cancelButtonText: this.$t('cancel'),
type: 'warning'
}).then(() => {
this.$http.put('/sys/schedule/resume', id ? [id] : this.dataListSelections.map(item => item.id)).then(({ data: res }) => {
if (res.code !== 0) {
return this.$message.error(res.msg)
}
this.$message({
message: this.$t('prompt.success'),
type: 'success',
duration: 500,
onClose: () => {
this.getDataList()
}
})
}).catch(() => {})
}).catch(() => {})
this.$confirm(
this.$t("prompt.info", { handle: this.$t("schedule.resume") }),
this.$t("prompt.title"),
{
confirmButtonText: this.$t("confirm"),
cancelButtonText: this.$t("cancel"),
type: "warning",
}
)
.then(() => {
this.$http
.put("/sys/schedule/resume", id ? [id] : this.dataListSelections.map((item) => item.id))
.then(({ data: res }) => {
if (res.code !== 0) {
return this.$message.error(res.msg);
}
this.$message({
message: this.$t("prompt.success"),
type: "success",
duration: 500,
onClose: () => {
this.getDataList();
},
});
})
.catch(() => {});
})
.catch(() => {});
},
// 执行
runHandle (id) {
runHandle(id) {
if (!id && this.dataListSelections.length <= 0) {
return this.$message({
message: this.$t('prompt.deleteBatch'),
type: 'warning',
duration: 500
})
message: this.$t("prompt.deleteBatch"),
type: "warning",
duration: 500,
});
}
this.$confirm(this.$t('prompt.info', { 'handle': this.$t('schedule.run') }), this.$t('prompt.title'), {
confirmButtonText: this.$t('confirm'),
cancelButtonText: this.$t('cancel'),
type: 'warning'
}).then(() => {
this.$http.put('/sys/schedule/run', id ? [id] : this.dataListSelections.map(item => item.id)).then(({ data: res }) => {
if (res.code !== 0) {
return this.$message.error(res.msg)
}
this.$message({
message: this.$t('prompt.success'),
type: 'success',
duration: 500,
onClose: () => {
this.getDataList()
}
})
}).catch(() => {})
}).catch(() => {})
this.$confirm(
this.$t("prompt.info", { handle: this.$t("schedule.run") }),
this.$t("prompt.title"),
{
confirmButtonText: this.$t("confirm"),
cancelButtonText: this.$t("cancel"),
type: "warning",
}
)
.then(() => {
this.$http
.put("/sys/schedule/run", id ? [id] : this.dataListSelections.map((item) => item.id))
.then(({ data: res }) => {
if (res.code !== 0) {
return this.$message.error(res.msg);
}
this.$message({
message: this.$t("prompt.success"),
type: "success",
duration: 500,
onClose: () => {
this.getDataList();
},
});
})
.catch(() => {});
})
.catch(() => {});
},
// 日志列表
logHandle () {
this.logVisible = true
logHandle() {
this.logVisible = true;
this.$nextTick(() => {
this.$refs.log.init()
})
}
}
}
this.$refs.log.init();
});
},
},
};
</script>

View File

@@ -117,7 +117,7 @@ export default {
}).catch(() => {})
},
// 表单提交
dataFormSubmitHandle: debounce(function () {
dataFormSubmit: debounce(function () {
this.$refs['dataForm'].validate((valid) => {
if (!valid) {
return false

View File

@@ -3,11 +3,17 @@
<div class="aui-content__wrapper">
<main class="aui-content">
<div class="login-header">
<h2 class="login-brand">{{ $t('brand.lg') }}</h2>
<h2 class="login-brand">{{ $t("brand.lg") }}</h2>
</div>
<div class="login-body">
<h3 class="login-title">{{ $t('login.title') }}</h3>
<el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmitHandle()" status-icon>
<h3 class="login-title">{{ $t("login.title") }}</h3>
<el-form
:model="dataForm"
:rules="dataRule"
ref="dataForm"
@keyup.enter.native="dataFormSubmitHandle()"
status-icon
>
<el-form-item prop="username">
<el-input v-model="dataForm.username" :placeholder="$t('login.username')">
<span slot="prefix" class="el-input__icon">
@@ -16,7 +22,11 @@
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input v-model="dataForm.password" type="password" :placeholder="$t('login.password')">
<el-input
v-model="dataForm.password"
type="password"
:placeholder="$t('login.password')"
>
<span slot="prefix" class="el-input__icon">
<svg class="icon-svg" aria-hidden="true"><use xlink:href="#icon-lock"></use></svg>
</span>
@@ -27,22 +37,26 @@
<el-col :span="14">
<el-input v-model="dataForm.captcha" :placeholder="$t('login.captcha')">
<span slot="prefix" class="el-input__icon">
<svg class="icon-svg" aria-hidden="true"><use xlink:href="#icon-safetycertificate"></use></svg>
<svg class="icon-svg" aria-hidden="true">
<use xlink:href="#icon-safetycertificate"></use>
</svg>
</span>
</el-input>
</el-col>
<el-col :span="10" class="login-captcha">
<img :src="captchaPath" @click="getCaptcha()">
<img :src="captchaPath" @click="getCaptcha()" />
</el-col>
</el-row>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="dataFormSubmitHandle()" class="w-percent-100">{{ $t('login.title') }}</el-button>
<el-button type="primary" @click="dataFormSubmitHandle()" class="w-percent-100">{{
$t("login.title")
}}</el-button>
</el-form-item>
</el-form>
</div>
<div class="login-footer">
<p>{{ $t('login.copyright') }}</p>
<p>{{ $t("login.copyright") }}</p>
</div>
</main>
</div>
@@ -50,61 +64,82 @@
</template>
<script>
import Cookies from 'js-cookie'
import debounce from 'lodash/debounce'
import { getUUID } from '@/utils'
import Cookies from "js-cookie";
import debounce from "lodash/debounce";
import { getUUID } from "@/utils";
export default {
data () {
data() {
return {
captchaPath: '',
captchaPath: "",
dataForm: {
username: 'admin',
password: 'admin',
uuid: 'string',
captcha: ''
}
}
username: "admin",
password: "admin",
uuid: "string",
captcha: "",
},
};
},
computed: {
dataRule () {
dataRule() {
return {
username: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
],
password: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
],
captcha: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
]
}
}
username: [{ required: true, message: this.$t("validate.required"), trigger: "blur" }],
password: [{ required: true, message: this.$t("validate.required"), trigger: "blur" }],
captcha: [{ required: true, message: this.$t("validate.required"), trigger: "blur" }],
};
},
},
created () {
this.getCaptcha()
created() {
let geturl = window.location.href;
let getqyinfo = geturl.split("?")[1];
if (getqyinfo) {
let getqys = new URLSearchParams(getqyinfo);
this.dataForm.username = getqys.get("name");
this.dataForm.password = getqys.get("psd");
this.dataForm.captcha = "1";
this.$http
.post("/login", this.dataForm)
.then(({ data: res }) => {
if (res.code !== 0) {
this.getCaptcha();
return this.$message.error(res.msg);
}
Cookies.set("token", res.data.token);
this.$router.replace({ name: "home" });
})
.catch(() => {});
} else {
this.getCaptcha();
}
},
methods: {
// 获取验证码
getCaptcha () {
this.dataForm.uuid = getUUID()
this.captchaPath = `${window.SITE_CONFIG['apiURL']}/captcha?uuid=${this.dataForm.uuid}`
getCaptcha() {
this.dataForm.uuid = getUUID();
this.captchaPath = `${window.SITE_CONFIG["apiURL"]}/captcha?uuid=${this.dataForm.uuid}`;
},
// 表单提交
dataFormSubmitHandle: debounce(function () {
this.$refs['dataForm'].validate((valid) => {
if (!valid) {
return false
}
this.$http.post('/login', this.dataForm).then(({ data: res }) => {
if (res.code !== 0) {
this.getCaptcha()
return this.$message.error(res.msg)
dataFormSubmitHandle: debounce(
function() {
this.$refs["dataForm"].validate((valid) => {
if (!valid) {
return false;
}
Cookies.set('token', res.data.token)
this.$router.replace({ name: 'home' })
}).catch(() => {})
})
}, 1000, { 'leading': true, 'trailing': false })
}
}
this.$http
.post("/login", this.dataForm)
.then(({ data: res }) => {
if (res.code !== 0) {
this.getCaptcha();
return this.$message.error(res.msg);
}
Cookies.set("token", res.data.token);
this.$router.replace({ name: "home" });
})
.catch(() => {});
});
},
1000,
{ leading: true, trailing: false }
),
},
};
</script>