diff --git a/docs/about/change-log.md b/docs/about/change-log.md index 0a958145..323fab1c 100644 --- a/docs/about/change-log.md +++ b/docs/about/change-log.md @@ -1,8 +1,20 @@ > 版本号严格遵循 Semver 规范。 -* ⚡ **sql 脚本可以在 adminer 中执行。** +* ⚡ **sql 脚本可以在 adminer 中执行。** * ⚡ **应用不支持跨版本升级, 可以进行多次升级。** +## v1.0.6 + +`2024-05-` `release` + +* 🐞 修复 终端页签关闭后不会自动切换 +* 🩰 修改 命令执行日志 UI 修改 +* 🌈 新增 命令执行模板配置默认主机 +* 🌈 新增 主机终端书签路径 +* 🔨 优化 退出登录不重定向 +* 🔨 优化 动态设置页面标题 +* 🔨 优化 终端断开后回车重连 + ## v1.0.5 `2024-04-22` `release` diff --git a/docs/about/roadmap.md b/docs/about/roadmap.md index 429fbf22..066aede7 100644 --- a/docs/about/roadmap.md +++ b/docs/about/roadmap.md @@ -1,8 +1,6 @@ ## 功能排期 -* 默认主机 * 批量上传 -* 文件夹书签 * 站内消息 * 终端背景图片 * 资产授权 UI 改版 diff --git a/orion-ops-ui/src/store/modules/terminal/index.ts b/orion-ops-ui/src/store/modules/terminal/index.ts index 519c1359..1347aa6f 100644 --- a/orion-ops-ui/src/store/modules/terminal/index.ts +++ b/orion-ops-ui/src/store/modules/terminal/index.ts @@ -169,9 +169,12 @@ export default defineStore('terminal', { async reOpenSession(sessionId: string, panelIndex: number = 0) { // 切换到终端面板页面 this.tabManager.openTab(TerminalTabs.TERMINAL_PANEL); - // 获取当前面板并且分配新的 sessionId + // 获取当前面板 tab 并且分配新的 sessionId const panel = this.panelManager.getPanel(panelIndex); - const tab = panel.getTab(sessionId); + const tab = panel.items.find(s => s.sessionId === sessionId); + if (!tab) { + return; + } const newSessionId = tab.sessionId = nextId(10); // 添加到最近连接 this.hosts.latestHosts = [...new Set([tab.hostId, ...this.hosts.latestHosts])]; diff --git a/orion-ops-ui/src/views/host/terminal/components/layout/terminal-panel.vue b/orion-ops-ui/src/views/host/terminal/components/layout/terminal-panel.vue index 441988db..b14961cf 100644 --- a/orion-ops-ui/src/views/host/terminal/components/layout/terminal-panel.vue +++ b/orion-ops-ui/src/views/host/terminal/components/layout/terminal-panel.vue @@ -63,24 +63,21 @@ // 监听 tab 切换 watch(() => props.panel.active, (active, before) => { - console.log(active); - console.log(before); - console.log(props.panel); // 失焦自动终端 if (before) { const beforeTab = props.panel.items.find(s => s.key === before); if (beforeTab && beforeTab?.type === PanelSessionType.SSH.type) { - sessionManager.getSession(before)?.blur(); + sessionManager.getSession(beforeTab.sessionId)?.blur(); } } // 终端自动聚焦 if (active) { const activeTab = props.panel.items.find(s => s.key === active); if (activeTab && activeTab?.type === PanelSessionType.SSH.type) { - sessionManager.getSession(active)?.focus(); + sessionManager.getSession(activeTab.sessionId)?.focus(); } } - // 无终端自动关闭 FIXME + // 无终端自动关闭 if (!props.panel.items.length) { close(); } diff --git a/orion-ops-ui/src/views/host/terminal/components/sftp/sftp-table-header.vue b/orion-ops-ui/src/views/host/terminal/components/sftp/sftp-table-header.vue index a23b5f92..d965fbbd 100644 --- a/orion-ops-ui/src/views/host/terminal/components/sftp/sftp-table-header.vue +++ b/orion-ops-ui/src/views/host/terminal/components/sftp/sftp-table-header.vue @@ -53,8 +53,9 @@ :title="closeMessage"> 已断开: {{ closeMessage }} - - + { - // FIXME TEST loadFiles(currentPath.value || '~'); }; diff --git a/orion-ops-ui/src/views/host/terminal/handler/ssh-session.ts b/orion-ops-ui/src/views/host/terminal/handler/ssh-session.ts index 311d8ee9..78b17f95 100644 --- a/orion-ops-ui/src/views/host/terminal/handler/ssh-session.ts +++ b/orion-ops-ui/src/views/host/terminal/handler/ssh-session.ts @@ -96,8 +96,11 @@ export default class SshSession implements ISshSession { if (this.handler.checkPreventDefault(e)) { e.preventDefault(); } - // 重新连接 + // 检查重新连接 if (!this.connected && this.canReconnect && e.key === 'Enter') { + // 防止重复回车 + this.canReconnect = false; + // 异步作用域重新连接 setTimeout(async () => { await useTerminalStore().reOpenSession(this.sessionId); }, 50); diff --git a/orion-ops-ui/src/views/host/terminal/handler/terminal-panel-manager.ts b/orion-ops-ui/src/views/host/terminal/handler/terminal-panel-manager.ts index 9307adbc..a0645da1 100644 --- a/orion-ops-ui/src/views/host/terminal/handler/terminal-panel-manager.ts +++ b/orion-ops-ui/src/views/host/terminal/handler/terminal-panel-manager.ts @@ -1,5 +1,5 @@ -import type { ITerminalPanelManager } from '../types/terminal.type'; -import TerminalPanelTabManager from '../handler/terminal-panel-tab-manager'; +import type { ITerminalPanelManager, TerminalPanelTabItem } from '../types/terminal.type'; +import TerminalTabManager from '../handler/terminal-tab-manager'; // 终端面板管理器实现 export default class TerminalPanelManager implements ITerminalPanelManager { @@ -7,15 +7,15 @@ export default class TerminalPanelManager implements ITerminalPanelManager { // 当前面板 active: number; // 面板列表 - panels: Array; + panels: Array>; constructor() { this.active = 0; - this.panels = [new TerminalPanelTabManager()]; + this.panels = [new TerminalTabManager()]; } // 获取当前面板 - getCurrentPanel(): TerminalPanelTabManager { + getCurrentPanel(): TerminalTabManager { return this.panels[this.active]; } @@ -25,7 +25,7 @@ export default class TerminalPanelManager implements ITerminalPanelManager { }; // 获取面板 - getPanel(index: number): TerminalPanelTabManager { + getPanel(index: number): TerminalTabManager { return this.panels[index]; }; @@ -41,7 +41,7 @@ export default class TerminalPanelManager implements ITerminalPanelManager { panel.clear(); } this.active = 0; - this.panels = [new TerminalPanelTabManager()]; + this.panels = [new TerminalTabManager()]; }; } diff --git a/orion-ops-ui/src/views/host/terminal/handler/terminal-panel-tab-manager.ts b/orion-ops-ui/src/views/host/terminal/handler/terminal-panel-tab-manager.ts deleted file mode 100644 index 24a84569..00000000 --- a/orion-ops-ui/src/views/host/terminal/handler/terminal-panel-tab-manager.ts +++ /dev/null @@ -1,91 +0,0 @@ -import type { ITerminalTabManager, TerminalPanelTabItem } from '../types/terminal.type'; - -// 终端面板 tab 管理器实现 -export default class TerminalPanelTabManager implements ITerminalTabManager { - - public active: string; - - public items: Array; - - constructor(def: TerminalPanelTabItem | undefined = undefined) { - if (def) { - this.active = def.sessionId; - this.items = [def]; - } else { - this.active = undefined as unknown as string; - this.items = []; - } - } - - // 获取当前 tab - getCurrentTab() { - if (!this.active) { - return undefined; - } - return this.items.find(s => s.sessionId === this.active); - } - - // 获取 tab - getTab(sessionId: string): TerminalPanelTabItem { - return this.items.find(s => s.sessionId === sessionId) as TerminalPanelTabItem; - } - - // 点击 tab - clickTab(sessionId: string): void { - this.active = sessionId; - } - - // 删除 tab - deleteTab(sessionId: string): void { - // 获取当前 tab - const tabIndex = this.items.findIndex(s => s.sessionId === sessionId); - // 删除 tab - this.items.splice(tabIndex, 1); - if (sessionId === this.active && this.items.length !== 0) { - // 切换为前一个 tab - this.active = this.items[Math.max(tabIndex - 1, 0)].sessionId; - } else { - this.active = undefined as unknown as string; - } - } - - // 打开 tab - openTab(tab: TerminalPanelTabItem): void { - // 不存在则创建 tab - if (!this.items.find(s => s.sessionId === tab.sessionId)) { - this.items.push(tab); - } - this.active = tab.sessionId; - } - - // 切换到前一个 tab - changeToPrevTab() { - this.changeToIndex(this.getCurrentTabIndex() - 1); - } - - // 切换到后一个 tab - changeToNextTab() { - this.changeToIndex(this.getCurrentTabIndex() + 1); - } - - // 切换索引 tab - changeToIndex(index: number) { - if (index < 0 || index >= this.items.length) { - return; - } - // 切换 tab - this.active = this.items[index].sessionId; - } - - // 获取当前索引 - private getCurrentTabIndex(): number { - return this.items.findIndex(s => s.sessionId === this.active); - } - - // 清空 - clear() { - this.active = undefined as unknown as string; - this.items = []; - } - -} diff --git a/orion-ops-ui/src/views/host/terminal/handler/terminal-tab-manager.ts b/orion-ops-ui/src/views/host/terminal/handler/terminal-tab-manager.ts index 82580e73..3422f11a 100644 --- a/orion-ops-ui/src/views/host/terminal/handler/terminal-tab-manager.ts +++ b/orion-ops-ui/src/views/host/terminal/handler/terminal-tab-manager.ts @@ -1,13 +1,13 @@ import type { ITerminalTabManager, TerminalTabItem } from '../types/terminal.type'; // 终端 tab 管理器实现 -export default class TerminalTabManager implements ITerminalTabManager { +export default class TerminalTabManager implements ITerminalTabManager { public active: string; - public items: Array; + public items: Array; - constructor(def: TerminalTabItem | undefined = undefined) { + constructor(def: T | undefined = undefined) { if (def) { this.active = def.key; this.items = [def]; @@ -26,8 +26,8 @@ export default class TerminalTabManager implements ITerminalTabManager { } // 获取 tab - getTab(key: string): TerminalTabItem { - return this.items.find(s => s.key === key) as TerminalTabItem; + getTab(key: string): T { + return this.items.find(s => s.key === key) as T; } // 点击 tab @@ -41,16 +41,18 @@ export default class TerminalTabManager implements ITerminalTabManager { const tabIndex = this.items.findIndex(s => s.key === key); // 删除 tab this.items.splice(tabIndex, 1); - if (key === this.active && this.items.length !== 0) { - // 切换为前一个 tab - this.active = this.items[Math.max(tabIndex - 1, 0)].key; + if (this.items.length !== 0) { + if (key === this.active) { + // 关闭的为当前 tab 切换为前一个 tab + this.active = this.items[Math.max(tabIndex - 1, 0)].key; + } } else { this.active = undefined as unknown as string; } } // 打开 tab - openTab(tab: TerminalTabItem): void { + openTab(tab: T): void { // 不存在则创建 tab if (!this.items.find(s => s.key === tab.key)) { this.items.push(tab);