From 220a0d40352af26a5d47ae93b0f14ce5efab46d9 Mon Sep 17 00:00:00 2001 From: lijiahang Date: Tue, 16 Jan 2024 17:25:01 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=BB=88=E7=AB=AF=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E5=BF=AB=E6=8D=B7=E9=94=AE.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/store/modules/terminal/index.ts | 13 ++- .../src/store/modules/terminal/types.ts | 3 +- .../components/layout/terminal-content.vue | 99 +++++++++++++--- .../view-setting/terminal-interact-block.vue | 2 +- .../handler/terminal-session-handler.ts | 107 ++---------------- .../host/terminal/handler/terminal-session.ts | 38 ++++--- .../terminal/handler/terminal-tab-manager.ts | 4 +- .../host/terminal/types/terminal.const.ts | 60 ++++++++++ .../host/terminal/types/terminal.type.ts | 22 ++-- 9 files changed, 202 insertions(+), 146 deletions(-) diff --git a/orion-ops-ui/src/store/modules/terminal/index.ts b/orion-ops-ui/src/store/modules/terminal/index.ts index c13f921d..21c753ba 100644 --- a/orion-ops-ui/src/store/modules/terminal/index.ts +++ b/orion-ops-ui/src/store/modules/terminal/index.ts @@ -57,7 +57,7 @@ export default defineStore('terminal', { pluginsSetting: {} as TerminalPluginsSetting, sessionSetting: {} as TerminalSessionSetting, shortcutSetting: { - enabled: true, + enabled: false, keys: [] } as TerminalShortcutSetting, }, @@ -79,7 +79,16 @@ export default defineStore('terminal', { // 更新默认主题偏好 await this.updateTerminalPreference(TerminalPreferenceItem.THEME, data.theme); } - // 选择赋值 + // 移除禁用的快捷键 + if (data.shortcutSetting?.enabled) { + data.shortcutSetting.keys = data.shortcutSetting.keys.filter(s => s.enabled); + } else { + data.shortcutSetting = { + enabled: false, + keys: [] + }; + } + // 选择赋值 (不能修改引用) const keys = Object.keys(this.preference); keys.forEach(key => { const item = data[key as keyof TerminalPreference]; diff --git a/orion-ops-ui/src/store/modules/terminal/types.ts b/orion-ops-ui/src/store/modules/terminal/types.ts index 8a1d9464..33d55162 100644 --- a/orion-ops-ui/src/store/modules/terminal/types.ts +++ b/orion-ops-ui/src/store/modules/terminal/types.ts @@ -76,9 +76,10 @@ export interface TerminalShortcutSetting { // 终端快捷键 export interface TerminalShortcutKey { - option: string; + item: string; ctrlKey: boolean; shiftKey: boolean; altKey: boolean; code: string; + enabled: boolean; } diff --git a/orion-ops-ui/src/views/host/terminal/components/layout/terminal-content.vue b/orion-ops-ui/src/views/host/terminal/components/layout/terminal-content.vue index 510ea2c1..deab98a8 100644 --- a/orion-ops-ui/src/views/host/terminal/components/layout/terminal-content.vue +++ b/orion-ops-ui/src/views/host/terminal/components/layout/terminal-content.vue @@ -35,9 +35,10 @@ diff --git a/orion-ops-ui/src/views/host/terminal/components/view-setting/terminal-interact-block.vue b/orion-ops-ui/src/views/host/terminal/components/view-setting/terminal-interact-block.vue index 1885cf74..898ca840 100644 --- a/orion-ops-ui/src/views/host/terminal/components/view-setting/terminal-interact-block.vue +++ b/orion-ops-ui/src/views/host/terminal/components/view-setting/terminal-interact-block.vue @@ -41,7 +41,7 @@ v-model="formModel.copyAutoTrim" /> - + diff --git a/orion-ops-ui/src/views/host/terminal/handler/terminal-session-handler.ts b/orion-ops-ui/src/views/host/terminal/handler/terminal-session-handler.ts index 5864f9b1..c17ed0df 100644 --- a/orion-ops-ui/src/views/host/terminal/handler/terminal-session-handler.ts +++ b/orion-ops-ui/src/views/host/terminal/handler/terminal-session-handler.ts @@ -29,94 +29,7 @@ export default class TerminalSessionHandler implements ITerminalSessionHandler { this.domRef = domRef; const { preference, tabManager } = useTerminalStore(); this.interactSetting = preference.interactSetting; - // this.shortcutKeys = preference.shortcutSetting.keys; - this.shortcutKeys = [ - { - option: 'copy', - ctrlKey: true, - shiftKey: true, - altKey: false, - code: 'KeyC' - }, { - option: 'paste', - ctrlKey: true, - shiftKey: true, - altKey: false, - code: 'KeyV' - }, { - option: 'toTop', - ctrlKey: true, - shiftKey: true, - altKey: false, - code: 'ArrowUp' - }, { - option: 'toBottom', - ctrlKey: true, - shiftKey: true, - altKey: false, - code: 'ArrowDown' - }, { - option: 'selectAll', - ctrlKey: true, - shiftKey: true, - altKey: false, - code: 'KeyA' - }, { - option: 'search', - ctrlKey: true, - shiftKey: true, - altKey: false, - code: 'KeyF' - }, { - option: 'fontSizePlus', - ctrlKey: true, - shiftKey: false, - altKey: true, - code: 'Equal' - }, { - option: 'fontSizeSubtract', - ctrlKey: true, - shiftKey: false, - altKey: true, - code: 'Minus' - }, { - option: 'commandEditor', - ctrlKey: true, - shiftKey: false, - altKey: true, - code: 'KeyE' - }, { - option: 'close', - ctrlKey: true, - shiftKey: false, - altKey: true, - code: 'KeyW' - }, { - option: 'changeToPrev', - ctrlKey: true, - shiftKey: false, - altKey: true, - code: 'ArrowLeft' - }, { - option: 'changeToNext', - ctrlKey: true, - shiftKey: false, - altKey: true, - code: 'ArrowRight' - }, { - option: 'openCopyTerminal', - ctrlKey: true, - shiftKey: false, - altKey: true, - code: 'KeyO' - }, { - option: 'openNewConnect', - ctrlKey: true, - shiftKey: false, - altKey: true, - code: 'KeyN' - }, - ]; + this.shortcutKeys = preference.shortcutSetting.keys; this.tabManager = tabManager; } @@ -158,7 +71,7 @@ export default class TerminalSessionHandler implements ITerminalSessionHandler { }); if (key) { // 调用处理方法 - this.invokeHandle.call(this, key.option); + this.invokeHandle.call(this, key.item); return false; } else { return true; @@ -271,22 +184,22 @@ export default class TerminalSessionHandler implements ITerminalSessionHandler { } // 切换到前一个 tab - changeToPrev() { - this.tabManager.changeToPrev(); + changeToPrevTab() { + this.tabManager.changeToPrevTab(); } // 切换到后一个 tab - changeToNext() { - this.tabManager.changeToNext(); + changeToNextTab() { + this.tabManager.changeToNextTab(); } - // 复制终端 - openCopyTerminal() { + // 复制终端 tab + openCopyTerminalTab() { useTerminalStore().openCopyTerminal(this.session.hostId); } - // 打开新建连接页面 - openNewConnect() { + // 打开新建连接 tab + openNewConnectTab() { this.tabManager.openTab(InnerTabs.NEW_CONNECTION); } diff --git a/orion-ops-ui/src/views/host/terminal/handler/terminal-session.ts b/orion-ops-ui/src/views/host/terminal/handler/terminal-session.ts index 9ebc1eca..4d6089c5 100644 --- a/orion-ops-ui/src/views/host/terminal/handler/terminal-session.ts +++ b/orion-ops-ui/src/views/host/terminal/handler/terminal-session.ts @@ -2,8 +2,8 @@ import type { UnwrapRef } from 'vue'; import type { TerminalPreference } from '@/store/modules/terminal/types'; import type { ITerminalChannel, ITerminalSession, ITerminalSessionHandler, TerminalAddons, TerminalDomRef } from '../types/terminal.type'; import { useTerminalStore } from '@/store'; -import { fontFamilySuffix, TerminalStatus } from '../types/terminal.const'; import { InputProtocol } from '../types/terminal.protocol'; +import { fontFamilySuffix, TerminalStatus } from '../types/terminal.const'; import { Terminal } from 'xterm'; import { FitAddon } from 'xterm-addon-fit'; import { WebLinksAddon } from 'xterm-addon-web-links'; @@ -13,6 +13,7 @@ import { CanvasAddon } from 'xterm-addon-canvas'; import { WebglAddon } from 'xterm-addon-webgl'; import { playBell } from '@/utils/bell'; import TerminalSessionHandler from './terminal-session-handler'; +import { addEventListen } from '@/utils/event'; // 终端会话实现 export default class TerminalSession implements ITerminalSession { @@ -82,16 +83,14 @@ export default class TerminalSession implements ITerminalSession { // 处理自定义按键 this.inst.attachCustomKeyEventHandler((e: KeyboardEvent) => { e.preventDefault(); - // 未开启 - if (!preference.shortcutSetting.enabled) { - return true; + // 触发快捷键检测 + if (e.type === 'keydown' + && preference.shortcutSetting.enabled + && preference.shortcutSetting.keys.length) { + // 触发快捷键 + return this.handler.triggerShortcutKey(e); } - // 只监听 keydown 事件 - if (e.type !== 'keydown') { - return true; - } - // 触发快捷键 - return this.handler.triggerShortcutKey(e); + return true; }); } @@ -134,7 +133,7 @@ export default class TerminalSession implements ITerminalSession { }); }); // 设置右键选项 - dom.addEventListener('contextmenu', async () => { + addEventListen(dom, 'contextmenu', async () => { // 右键粘贴逻辑 if (preference.interactSetting.rightClickPaste) { if (!this.canWrite || !this.connected) { @@ -195,16 +194,21 @@ export default class TerminalSession implements ITerminalSession { this.inst.write(value); } - // 自适应 - fit(): void { - this.addons.fit?.fit(); - } - // 聚焦 focus(): void { this.inst.focus(); } + // 失焦 + blur(): void { + this.inst.blur(); + } + + // 自适应 + fit(): void { + this.addons.fit?.fit(); + } + // 查找 find(word: string, next: boolean, options: ISearchOptions): void { if (next) { @@ -229,7 +233,7 @@ export default class TerminalSession implements ITerminalSession { Object.values(this.addons) .filter(Boolean) .forEach(s => s.dispose()); - // 卸载实体 + // 卸载终端 this.inst.dispose(); } catch (e) { } 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 303974a2..3be26542 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 @@ -45,12 +45,12 @@ export default class TerminalTabManager implements ITerminalTabManager { } // 切换到前一个 tab - changeToPrev() { + changeToPrevTab() { this.changeToIndex(this.getCurrentTabIndex() - 1); } // 切换到后一个 tab - changeToNext() { + changeToNextTab() { this.changeToIndex(this.getCurrentTabIndex() + 1); } diff --git a/orion-ops-ui/src/views/host/terminal/types/terminal.const.ts b/orion-ops-ui/src/views/host/terminal/types/terminal.const.ts index 0e089196..8badcd7a 100644 --- a/orion-ops-ui/src/views/host/terminal/types/terminal.const.ts +++ b/orion-ops-ui/src/views/host/terminal/types/terminal.const.ts @@ -127,6 +127,66 @@ export const ActionBarItems = [ } ]; +// 终端 tab 快捷键操作 +export const TerminalTabShortcutItems = { + CHANGE_TO_PREV_TAB: { + item: 'changeToPrevTab', + content: '切换为前一个 tab' + }, + CHANGE_TO_NEXT_TAB: { + item: 'changeToNextTab', + content: '切换为后一个 tab' + }, + CLOSE_TAB: { + item: 'closeTab', + content: '关闭当前 tab' + }, + OPEN_NEW_CONNECT_TAB: { + item: 'openNewConnectTab', + content: '打开新建连接 tab' + }, + OPEN_COPY_TERMINAL_TAB: { + item: 'openCopyTerminalTab', + content: '复制当前终端 tab' + }, + COPY: { + item: 'copy', + content: '复制' + }, + PASTE: { + item: 'paste', + content: '粘贴' + }, + TO_TOP: { + item: 'toTop', + content: '去顶部' + }, + TO_BOTTOM: { + item: 'toBottom', + content: '去底部' + }, + SELECT_ALL: { + item: 'selectAll', + content: '全选' + }, + SEARCH: { + item: 'search', + content: '搜索' + }, + FONT_SIZE_PLUS: { + item: 'fontSizePlus', + content: '增大字号' + }, + FONT_SIZE_SUBTRACT: { + item: 'fontSizeSubtract', + content: '减小字号' + }, + COMMAND_EDITOR: { + item: 'commandEditor', + content: '命令编辑器' + }, +}; + // 打开 sshModal key export const openSshModalKey = Symbol(); diff --git a/orion-ops-ui/src/views/host/terminal/types/terminal.type.ts b/orion-ops-ui/src/views/host/terminal/types/terminal.type.ts index e6edcc55..bcf4a2fd 100644 --- a/orion-ops-ui/src/views/host/terminal/types/terminal.type.ts +++ b/orion-ops-ui/src/views/host/terminal/types/terminal.type.ts @@ -45,6 +45,12 @@ export interface ContextMenuItem { content: string; } +// 快捷键元素 +export interface ShortcutKeyItem { + item: string; + content: string; +} + // ssh 额外配置 export interface SshExtraModel { authType?: string; @@ -98,9 +104,9 @@ export interface ITerminalTabManager { // 打开 tab openTab: (tab: TerminalTabItem) => void; // 切换到前一个 tab - changeToPrev: () => void; + changeToPrevTab: () => void; // 切换到后一个 tab - changeToNext: () => void; + changeToNextTab: () => void; // 切换索引 tab changeToIndex: (index: number) => void; // 清空 @@ -232,11 +238,11 @@ export interface ITerminalSessionHandler { // 关闭 tab closeTab: () => void; // 切换到前一个 tab - changeToPrev: () => void; + changeToPrevTab: () => void; // 切换到后一个 tab - changeToNext: () => void; - // 复制终端 - openCopyTerminal: () => void; - // 打开新建连接页面 - openNewConnect: () => void; + changeToNextTab: () => void; + // 复制终端 tab + openCopyTerminalTab: () => void; + // 打开新建连接 tab + openNewConnectTab: () => void; }