DPS_Manage/Component/ServerConsole.qml

187 lines
5.7 KiB
QML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import HuskarUI.Basic 1.0
import "../MyGlobals" 1.0
import SSHManager 1.0
Item {
visible: true
// SSH控制台输出显示区域
Item {
id:consolearea
anchors {
fill: parent
margins: 10
bottomMargin: 46
}
ScrollView {
id: scrollView
anchors.fill: parent
clip: true
TextArea {
id: consoleOutput
selectByMouse: true
textFormat: Text.RichText
readOnly: true
wrapMode: Text.WrapAnywhere
font {
pixelSize: 14
family: HusTheme.Primary.fontPrimaryFamily
}
color: HusTheme.Primary.colorTextBase
background: Rectangle {
color: HusTheme.isDark ? "#2d2d2d" : "#f5f5f5"
radius: 4
}
// 自动滚动到底部
onTextChanged: {
if (length > 0) {
cursorPosition = length
}
}
}
}
}
HusInput {
id: inputField
width: consolearea.width
iconPosition: HusInput.Position_Left
iconSource: HusIcon.ForwardOutlined
placeholderText: qsTr("这里可以输入服务器命令")
anchors {
top: consolearea.bottom
topMargin: 6
horizontalCenter: parent.horizontalCenter
}
// 添加回车键事件
onAccepted: {
SSHManager.sendInput(text)
text = ""
}
// 监听 Ctrl+C
Keys.onPressed: (event) => {
if ((event.modifiers & Qt.ControlModifier) && event.key === Qt.Key_C) {
SSHManager.sendInput("\x03")
}
}
}
// ANSI转HTML的转换逻辑
function ansiToHtml(text) {
// 第一步:处理颜色代码
let colored = text.replace(/\x1B\[([0-9;]*)m/g, function(match, codes) {
let styles = [];
for (let code of codes.split(';')) {
switch (parseInt(code)) {
case 0:
return "</span>";
case 1:
styles.push("font-weight:bold");
break;
case 3:
styles.push("font-style:italic");
break;
case 4:
styles.push("text-decoration:underline");
break;
case 30:
styles.push("color:black");
break;
case 31:
styles.push("color:red");
break;
case 32:
styles.push("color:green");
break;
case 33:
styles.push("color:yellow");
break;
case 34:
styles.push("color:blue");
break;
case 35:
styles.push("color:magenta");
break;
case 36:
styles.push("color:cyan");
break;
case 37:
styles.push("color:white");
break;
case 40:
styles.push("background-color:black");
break;
// 其他颜色代码...
}
}
return styles.length ? `<span style="${styles.join(';')}">` : "";
});
// 第二步:清除所有 ANSI 转义序列(包括 XTerm 标题、控制序列等)
let cleaned = colored
//删除 XTerm 窗口标题序列(格式:\x1B]0;标题\x07 或 \x1B]0;标题\x1B\
.replace(/\x1B\][^\x07]*(?:\x07|\x1B\\)/g, '')
//删除其他 ANSI 控制序列(包括以 ? 开头的模式设置,如 ?1034h
.replace(/\x1B\[[1034h;?]*[A-Za-z]/g, '');
return cleaned;
}
function connectionSuccess(){
}
function connectionFailed(error){
consoleOutput.text += "连接服务器失败" + error + "\n"
}
function disconnected(){
consoleOutput.text += "服务器断开连接\n"
}
function updateStatus(msg) {
consoleOutput.text += (msg + "\n")
}
function appendOutput(msg) {
// 转义 HTML 特殊字符
const safeMsg = msg.replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\n/g, "<br>"); // 新增换行符转换
const zemsg = ansiToHtml("> " + safeMsg)
consoleOutput.text += zemsg;
}
// 初始化后自动连接示例(可选)
Component.onCompleted: {
SSHManager.connectionSuccess.connect(connectionSuccess)
SSHManager.connectionFailed.connect(connectionFailed)
SSHManager.statusMessage.connect(updateStatus)
SSHManager.disconnected.connect(disconnected)
SSHManager.shellOutput.connect(appendOutput)
consoleOutput.text = "控制台已就绪...\n"
}
// 窗口关闭时自动触发清理
Component.onDestruction: {
// 断开所有信号连接
SSHManager.connectionSuccess.disconnect(connectionSuccess);
SSHManager.connectionFailed.disconnect(connectionFailed);
SSHManager.statusMessage.disconnect(updateStatus);
SSHManager.disconnected.disconnect(disconnected);
SSHManager.shellOutput.disconnect(appendOutput);
console.log("窗口关闭,已断开所有信号连接并清理资源。");
}
}