优化 编辑组件可能出现行错和内容错乱问题

优化 查看系统日志的多次切换内容返回错乱问题
This commit is contained in:
bwcx_jzy 2022-12-20 18:05:10 +08:00
parent 419b31d297
commit dfe14fd74f
No known key found for this signature in database
GPG Key ID: 5E48E9372088B9E5
7 changed files with 102 additions and 82 deletions

View File

@ -22,6 +22,8 @@
5. 【server】修复 初次安装服务端初始化数据库失败问题 (感谢@lg
6. 【server】优化 日志显示组件(取消正则搜索),日志删除 `ansi` 颜色
(感谢[@苏生不语](https://gitee.com/sushengbuyu) [Gitee issues I657JR](https://gitee.com/dromara/Jpom/issues/I657JR)
7. 【server】优化 编辑组件可能出现行错和内容错乱问题
8. 【server】优化 查看系统日志的多次切换内容返回错乱问题
### ❌ 不兼容功能

View File

@ -23,7 +23,6 @@
package io.jpom.socket.handler;
import cn.hutool.core.io.FileUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSONObject;
import io.jpom.JpomApplication;
import io.jpom.common.forward.NodeUrl;
@ -35,7 +34,6 @@ import io.jpom.socket.ConsoleCommandOp;
import io.jpom.socket.ProxySession;
import io.jpom.socket.ServiceFileTailWatcher;
import io.jpom.system.LogbackConfig;
import io.jpom.system.WebAopLog;
import io.jpom.util.SocketSessionUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.socket.WebSocketSession;
@ -54,57 +52,57 @@ import java.util.Map;
@Slf4j
public class TomcatHandler extends BaseProxyHandler {
public TomcatHandler() {
super(NodeUrl.Tomcat_Socket);
}
public TomcatHandler() {
super(NodeUrl.Tomcat_Socket);
}
@Override
protected Object[] getParameters(Map<String, Object> attributes) {
return new Object[]{"tomcatId", attributes.get("tomcatId")};
}
@Override
protected Object[] getParameters(Map<String, Object> attributes) {
return new Object[]{"tomcatId", attributes.get("tomcatId")};
}
@Override
protected String handleTextMessage(Map<String, Object> attributes, WebSocketSession session, JSONObject json, ConsoleCommandOp consoleCommandOp) throws IOException {
String tomcatId = (String) attributes.get("tomcatId");
String fileName = json.getString("fileName");
if (!JpomApplication.SYSTEM_ID.equals(tomcatId) && consoleCommandOp == ConsoleCommandOp.heart) {
// 服务端心跳
return null;
}
@Override
protected String handleTextMessage(Map<String, Object> attributes, WebSocketSession session, JSONObject json, ConsoleCommandOp consoleCommandOp) throws IOException {
String tomcatId = (String) attributes.get("tomcatId");
String fileName = json.getString("fileName");
if (!JpomApplication.SYSTEM_ID.equals(tomcatId) && consoleCommandOp == ConsoleCommandOp.heart) {
// 服务端心跳
return null;
}
super.logOpt(this.getClass(), attributes, json);
super.logOpt(this.getClass(), attributes, json);
//
if (consoleCommandOp == ConsoleCommandOp.showlog && JpomApplication.SYSTEM_ID.equals(tomcatId)) {
WebAopLog webAopLog = SpringUtil.getBean(WebAopLog.class);
// 进入管理页面后需要实时加载日志
File file = FileUtil.file(LogbackConfig.getPath(), fileName);
//
File nowFile = (File) attributes.get("nowFile");
if (nowFile != null && !nowFile.equals(file)) {
// 离线上一个日志
ServiceFileTailWatcher.offlineFile(file, session);
}
try {
ServiceFileTailWatcher.addWatcher(file, session);
attributes.put("nowFile", file);
} catch (Exception io) {
log.error("监听日志变化", io);
SocketSessionUtil.send(session, io.getMessage());
}
}
return null;
}
//
if (consoleCommandOp == ConsoleCommandOp.showlog && JpomApplication.SYSTEM_ID.equals(tomcatId)) {
@Override
protected String handleTextMessage(Map<String, Object> attributes, ProxySession proxySession, JSONObject json, ConsoleCommandOp consoleCommandOp) {
proxySession.send(json.toString());
return null;
}
// 进入管理页面后需要实时加载日志
File file = FileUtil.file(LogbackConfig.getPath(), fileName);
//
File nowFile = (File) attributes.get("nowFile");
if (nowFile != null && !nowFile.equals(file)) {
// 离线上一个日志
ServiceFileTailWatcher.offlineFile(file, session);
}
try {
ServiceFileTailWatcher.addWatcher(file, session);
attributes.put("nowFile", file);
} catch (Exception io) {
log.error("监听日志变化", io);
SocketSessionUtil.send(session, io.getMessage());
}
}
return null;
}
@Override
public void destroy(WebSocketSession session) {
super.destroy(session);
ServiceFileTailWatcher.offline(session);
}
@Override
protected String handleTextMessage(Map<String, Object> attributes, ProxySession proxySession, JSONObject json, ConsoleCommandOp consoleCommandOp) {
proxySession.send(json.toString());
return null;
}
@Override
public void destroy(WebSocketSession session) {
super.destroy(session);
ServiceFileTailWatcher.offline(session);
}
}

View File

@ -182,7 +182,13 @@ export default {
// true
smartIndent: false,
autocorrect: true,
dragDrop: false,
spellcheck: true,
// scrollbarStyle: "Addons",
// 10 - [integer]
// //
// Infinity -
viewportMargin: 10,
hintOptions: this.cmHintOptions || {},
extraKeys: {
"Alt-Q": "autocomplete",
@ -257,13 +263,16 @@ export default {
immediate: true,
},
code(n) {
if (n != this.editorValue) {
try {
this.editorValue = this.formatStrInJson(n);
} catch (error) {
this.editorValue = n;
//
}
if (n !== this.editorValue) {
setTimeout(() => {
// ,
try {
this.editorValue = this.formatStrInJson(n);
} catch (error) {
this.editorValue = n;
//
}
}, 100);
}
},
},
@ -346,10 +355,9 @@ export default {
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0;
},
scrollToBottom() {
// codemirror.codemirror
const sc = this.$refs.myCm.codemirror.getScrollInfo();
// codemirror.codemirror
this.$refs.myCm.codemirror.scrollTo(sc.left, sc.height + sc.top);
this.$nextTick(() => {
this.$refs.myCm.codemirror.execCommand("goDocEnd");
});
},
},
};

View File

@ -12,22 +12,20 @@
<a-tooltip title="清空当前缓冲区内容">
<a-button type="link" style="padding: 0" @click="clearLogCache" icon="delete"><span style="margin-left: 2px">清空</span></a-button>
</a-tooltip>
<a-dropdown>
<a-tooltip title="内容超过边界自动换行">
<a-switch v-model="temp.wordBreak" checked-children="自动换行" un-checked-children="不换行" @change="onChange" />
</a-tooltip>
<a-tooltip title="有新内容后是否自动滚动到底部">
<a-switch v-model="temp.logScroll" checked-children="自动滚动" un-checked-children="不滚动" @change="onChange" />
</a-tooltip>
<!-- <a-dropdown>
<a-button type="link" style="padding: 0" icon="setting"> 设置 <a-icon type="down" /></a-button>
<a-menu slot="overlay">
<a-menu-item key="0">
<a-tooltip title="内容超过边界自动换行">
<a-switch v-model="temp.wordBreak" checked-children="自动换行" un-checked-children="不换行" @change="onChange" />
</a-tooltip>
</a-menu-item>
<a-menu-item key="0"> </a-menu-item>
<a-menu-divider />
<a-menu-item key="3">
<a-tooltip title="有新内容后是否自动滚动到底部">
<a-switch v-model="temp.logScroll" checked-children="自动滚动" un-checked-children="不滚动" @change="onChange" />
</a-tooltip>
</a-menu-item>
<a-menu-item key="3"> </a-menu-item>
</a-menu>
</a-dropdown>
</a-dropdown> -->
</a-space>
</a-col>
</a-row>

View File

@ -4,7 +4,7 @@
ref="codemirror"
:style="`height:${this.height}`"
v-model="showContext"
:options="{ theme: 'panda-syntax', mode: 'verilog', tabSize: 2, readOnly: true, styleActiveLine: true, lineWrapping: this.config.wordBreak }"
:options="{ theme: 'panda-syntax', mode: 'verilog', cursorBlinkRate: -1, tabSize: 2, readOnly: true, styleActiveLine: true, lineWrapping: this.config.wordBreak }"
></code-editor>
</div>
</template>
@ -67,10 +67,13 @@ export default {
);
})
.join("");
if (this.config.logScroll) {
//
this.$refs.codemirror.scrollToBottom();
setTimeout(() => {
//
this.$nextTick(() => {
this.$refs.codemirror.scrollToBottom();
});
}, 500);
}
},

View File

@ -132,6 +132,12 @@ export default {
},
//
select(selectedKeys, { node }) {
if (this.temp?.path === node.dataRef?.path) {
return;
}
if (!node.dataRef.isLeaf) {
return;
}
const data = {
op: "showlog",
tomcatId: this.tomcatId,
@ -139,9 +145,10 @@ export default {
};
this.temp = node.dataRef;
this.$refs.logView.clearLogCache();
if (!this.socket || this.socket.readyState !== this.socket.OPEN || this.socket.readyState !== this.socket.CONNECTING) {
this.socket = new WebSocket(this.socketUrl);
}
this.socket?.close();
this.socket = new WebSocket(this.socketUrl);
//
this.socket.onopen = () => {
this.socket.send(JSON.stringify(data));

View File

@ -134,6 +134,9 @@ export default {
if (this.temp?.path === node.dataRef?.path) {
return;
}
if (!node.dataRef.isLeaf) {
return;
}
const data = {
op: "showlog",
tomcatId: this.tomcatId,
@ -141,9 +144,10 @@ export default {
};
this.temp = node.dataRef;
this.$refs.logView.clearLogCache();
if (!this.socket || this.socket.readyState !== this.socket.OPEN || this.socket.readyState !== this.socket.CONNECTING) {
this.socket = new WebSocket(this.socketUrl);
}
this.socket?.close();
this.socket = new WebSocket(this.socketUrl);
//
this.socket.onopen = () => {
this.socket.send(JSON.stringify(data));