From a3a418ad1b7fbda53249dc4b4675194c8f6a8994 Mon Sep 17 00:00:00 2001 From: jlzhou <12020042@qq.com> Date: Wed, 8 Jan 2025 15:09:32 +0800 Subject: [PATCH] =?UTF-8?q?update=20=E4=BD=BF=E7=94=A8SSE=E9=87=8D?= =?UTF-8?q?=E5=86=99=E5=AE=9E=E6=97=B6=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E8=BE=93=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- admin-ui/package.json | 1 + admin-ui/pnpm-lock.yaml | 8 + admin-ui/src/api/SSE.js | 173 +++++++++++++ .../system/cron/components/WCronList.vue | 4 +- admin-ui/src/views/system/cron/cron.js | 5 +- admin-ui/src/views/system/cron/index.vue | 232 ++++++++++++------ ruoyi-system-cron/README.md | 7 + ruoyi-system-cron/cron.zip | Bin 8462 -> 0 bytes .../java/com/ruoyi/cron/api/CronTaskApi.java | 74 ++---- .../com/ruoyi/cron/document/CronTask.java | 2 + .../ruoyi/cron/event/CronTaskChangeEvent.java | 3 + .../ruoyi/cron/event/CronTaskEndEvent.java | 27 ++ .../com/ruoyi/cron/event/CronTaskEvent.java | 4 + .../ruoyi/cron/event/CronTaskLogEvent.java | 9 +- .../ruoyi/cron/event/CronTaskStartEvent.java | 29 +++ .../com/ruoyi/cron/runner/CronRunner.java | 4 + .../com/ruoyi/cron/runner/TaskLogImpl.java | 2 +- 17 files changed, 450 insertions(+), 134 deletions(-) create mode 100644 admin-ui/src/api/SSE.js delete mode 100644 ruoyi-system-cron/cron.zip create mode 100644 ruoyi-system-cron/src/main/java/com/ruoyi/cron/event/CronTaskEndEvent.java create mode 100644 ruoyi-system-cron/src/main/java/com/ruoyi/cron/event/CronTaskStartEvent.java diff --git a/admin-ui/package.json b/admin-ui/package.json index de3fbc2..2c8191c 100644 --- a/admin-ui/package.json +++ b/admin-ui/package.json @@ -14,6 +14,7 @@ "url": "https://gitee.com/JavaLionLi/RuoYi-Vue-Plus-UI.git" }, "dependencies": { + "@microsoft/fetch-event-source": "2.0.1", "@element-plus/icons-vue": "2.3.1", "@vueup/vue-quill": "1.1.0", "@vueuse/core": "9.5.0", diff --git a/admin-ui/pnpm-lock.yaml b/admin-ui/pnpm-lock.yaml index 12ae261..382e07c 100644 --- a/admin-ui/pnpm-lock.yaml +++ b/admin-ui/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: '@element-plus/icons-vue': specifier: 2.3.1 version: 2.3.1(vue@3.5.13) + '@microsoft/fetch-event-source': + specifier: 2.0.1 + version: 2.0.1 '@vueup/vue-quill': specifier: 1.1.0 version: 1.1.0(vue@3.5.13) @@ -278,6 +281,9 @@ packages: '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@microsoft/fetch-event-source@2.0.1': + resolution: {integrity: sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA==} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -1943,6 +1949,8 @@ snapshots: '@jridgewell/sourcemap-codec@1.5.0': {} + '@microsoft/fetch-event-source@2.0.1': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 diff --git a/admin-ui/src/api/SSE.js b/admin-ui/src/api/SSE.js new file mode 100644 index 0000000..d137106 --- /dev/null +++ b/admin-ui/src/api/SSE.js @@ -0,0 +1,173 @@ +import { fetchEventSource } from '@microsoft/fetch-event-source' +import { getToken } from '@/utils/auth' + +/** + * @description: 创建sse连接 + */ +class ServerSentEvents { + static defaultConfig = { + base: import.meta.env.VITE_APP_BASE_API, // 基础地址 + url: '/sse', // 地址 + data: undefined, // 请求正文 + params: undefined, // 请求参数 + method: 'get', // 提交方式 + auth: true, // 是否携带token + json: true, // 是否返回json + returnData: false, // json数据是否返回data属性 + reconnect: true, //是否重连 + headers: { + 'Content-Type': 'application/json' + }, + onopen: () => { }, + onmessage: () => { }, + onerror: () => { }, + onclose: () => { } + } + + constructor(config) { + if (config) { + this.setConfig(config) + this.init() + } + } + + static get(url, onmessage, config = {}) { + config.onmessage = onmessage + config.url = url + return new ServerSentEvents(config) + } + + static post(url, data, onmessage, config = {}) { + config.onmessage = onmessage + config.url = url + config.method = 'post' + config.data = data + return new ServerSentEvents(config) + } + + setConfig(config) { + this.config = { + ctrl: new AbortController(), + ...ServerSentEvents.defaultConfig, + ...config + } + console.debug('this.config', this.config) + } + init() { + if (this.config.auth) { + this.config.headers.Authorization = 'Bearer ' + getToken() + } + let url = this.config.url + // 如果url不含协议 + if (url.indexOf("//") == -1) { + url = this.config.base + url + } + + if (this.config.params) { + if (url.indexOf("?") > -1) { + url += '&' + this.params(this.config.params) + } else { + url += '?' + this.params(this.config.params) + } + } + + let body = undefined + + if (this.config.data && (this.config.method === 'post' || this.config.method === 'put')) { + if (this.config.data.constructor == URLSearchParams) { + this.config.headers['Content-Type'] = 'application/x-www-form-urlencoded' + body = this.params(this.config.data).toString() + } else if (this.config.data.constructor == FormData) { + this.config.headers['Content-Type'] = 'multipart/form-data' + body = this.config.data + } else { + body = JSON.stringify(body) + } + } + this.config._url = url + this.config._body = body + console.debug(this.config) + + this.send() + + } + + send() { + fetchEventSource(this.config._url, { + method: this.config.method, + headers: this.config.headers, + body: this.config._body, + signal: this.config.ctrl.signal, + onopen: this.config.onopen, + onmessage: (msg) => { + if (this.config.json) { + let data = JSON.parse(msg.data) + if (this.config.returnData) { + data = data.data + } + this.config.onmessage(data) + } else { + this.config.onmessage(msg) + } + }, + onclose: () => { + console.info('onclose') + this.abort() + this.config.onclose() + if (this.config.reconnect) { + this.send() + } + }, + onerror: (err) => { + console.error(err) + this.abort() + this.config.onerror(err) + } + }) + } + + abort() { + if (this.config.ctrl && !this.config.reconnect) { + try { + this.config.ctrl.abort() + } catch (e) { + console.error(e) + } + } + } + + close() { + this.abort() + } + + params(param) { + if (param == null || param == "") { + return new URLSearchParams(); + } + if (param.constructor == Array) { + let param1 = new URLSearchParams(); + for (let obj of param) { + param1.append(obj.name, obj.value); + } + param = param1; + } else if (param.constructor == Object) { + let param1 = new URLSearchParams(); + for (let name in param) { + param1.append(name, param[name]); + } + param = param1; + } else { + if (param.constructor == HTMLFormElement) { + param = new FormData(param); + } + if (param.constructor == FormData || param.constructor == String) { + param = new URLSearchParams(param); + } + } + + return param; + } + +} + +export default ServerSentEvents diff --git a/admin-ui/src/views/system/cron/components/WCronList.vue b/admin-ui/src/views/system/cron/components/WCronList.vue index 03a0660..a4c1df2 100644 --- a/admin-ui/src/views/system/cron/components/WCronList.vue +++ b/admin-ui/src/views/system/cron/components/WCronList.vue @@ -29,10 +29,10 @@ - +