update 使用SSE重写实时定时任务日志输出
parent
9ee30e5de3
commit
a3a418ad1b
@ -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
|
||||
Binary file not shown.
@ -0,0 +1,27 @@
|
||||
package com.ruoyi.cron.event;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
/**
|
||||
* 定时任务结束事件
|
||||
*/
|
||||
public class CronTaskEndEvent extends ApplicationEvent {
|
||||
|
||||
@Getter
|
||||
private String taskId;
|
||||
|
||||
|
||||
@Getter
|
||||
private Long cronId;
|
||||
|
||||
@Getter
|
||||
private Integer groupId;
|
||||
|
||||
public CronTaskEndEvent(Long cronId, String taskId, Integer groupId) {
|
||||
super(taskId);
|
||||
this.taskId = taskId;
|
||||
this.groupId = groupId;
|
||||
this.cronId = cronId;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package com.ruoyi.cron.event;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 定时任务开始事件
|
||||
*/
|
||||
public class CronTaskStartEvent extends ApplicationEvent {
|
||||
|
||||
@Getter
|
||||
private String taskId;
|
||||
|
||||
|
||||
@Getter
|
||||
private Long cronId;
|
||||
|
||||
@Getter
|
||||
private Integer groupId;
|
||||
|
||||
public CronTaskStartEvent(Long cronId, String taskId, Integer groupId) {
|
||||
super(taskId);
|
||||
this.taskId = taskId;
|
||||
this.groupId = groupId;
|
||||
this.cronId = cronId;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue