DPS_Manage/Component/ServerConsole.qml

187 lines
5.7 KiB
QML
Raw Normal View History

2025-05-29 14:04:05 +08:00
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import DelegateUI 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: DelTheme.Primary.fontPrimaryFamily
}
color: DelTheme.Primary.colorTextBase
background: Rectangle {
color: DelTheme.isDark ? "#2d2d2d" : "#f5f5f5"
radius: 4
}
// 自动滚动到底部
onTextChanged: {
if (length > 0) {
cursorPosition = length
}
}
}
}
}
DelInput {
id: inputField
width: consolearea.width
iconPosition: DelInput.Position_Left
iconSource: DelIcon.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("窗口关闭,已断开所有信号连接并清理资源。");
}
}