回车重连.

This commit is contained in:
lijiahang
2024-04-23 11:07:01 +08:00
parent c8c947d8a8
commit b6ee28731b
10 changed files with 46 additions and 122 deletions

View File

@@ -1,8 +1,20 @@
> 版本号严格遵循 Semver 规范。
***sql 脚本可以在 adminer 中执行。**
***sql 脚本可以在 adminer 中执行。**
***应用不支持跨版本升级, 可以进行多次升级。**
## v1.0.6
`2024-05-` `release`
* 🐞 修复 终端页签关闭后不会自动切换
* 🩰 修改 命令执行日志 UI 修改
* 🌈 新增 命令执行模板配置默认主机
* 🌈 新增 主机终端书签路径
* 🔨 优化 退出登录不重定向
* 🔨 优化 动态设置页面标题
* 🔨 优化 终端断开后回车重连
## v1.0.5
`2024-04-22` `release`

View File

@@ -1,8 +1,6 @@
## 功能排期
* 默认主机
* 批量上传
* 文件夹书签
* 站内消息
* 终端背景图片
* 资产授权 UI 改版

View File

@@ -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])];

View File

@@ -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<ISshSession>(before)?.blur();
sessionManager.getSession<ISshSession>(beforeTab.sessionId)?.blur();
}
}
// 终端自动聚焦
if (active) {
const activeTab = props.panel.items.find(s => s.key === active);
if (activeTab && activeTab?.type === PanelSessionType.SSH.type) {
sessionManager.getSession<ISshSession>(active)?.focus();
sessionManager.getSession<ISshSession>(activeTab.sessionId)?.focus();
}
}
// 无终端自动关闭 FIXME
// 无终端自动关闭
if (!props.panel.items.length) {
close();
}

View File

@@ -53,8 +53,9 @@
:title="closeMessage">
已断开: {{ closeMessage }}
</a-tag>
<!-- 重连 FIXME -->
<a-tooltip position="top"
<!-- 重连 -->
<a-tooltip v-if="session?.canReconnect"
position="top"
:mini="true"
:overlay-inverse="true"
:auto-fix-position="false"

View File

@@ -168,7 +168,6 @@
// 连接成功回调
const connectCallback = () => {
// FIXME TEST
loadFiles(currentPath.value || '~');
};

View File

@@ -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);

View File

@@ -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<TerminalPanelTabManager>;
panels: Array<TerminalTabManager<TerminalPanelTabItem>>;
constructor() {
this.active = 0;
this.panels = [new TerminalPanelTabManager()];
this.panels = [new TerminalTabManager()];
}
// 获取当前面板
getCurrentPanel(): TerminalPanelTabManager {
getCurrentPanel(): TerminalTabManager<TerminalPanelTabItem> {
return this.panels[this.active];
}
@@ -25,7 +25,7 @@ export default class TerminalPanelManager implements ITerminalPanelManager {
};
// 获取面板
getPanel(index: number): TerminalPanelTabManager {
getPanel(index: number): TerminalTabManager<TerminalPanelTabItem> {
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()];
};
}

View File

@@ -1,91 +0,0 @@
import type { ITerminalTabManager, TerminalPanelTabItem } from '../types/terminal.type';
// 终端面板 tab 管理器实现
export default class TerminalPanelTabManager implements ITerminalTabManager<TerminalPanelTabItem> {
public active: string;
public items: Array<TerminalPanelTabItem>;
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 = [];
}
}

View File

@@ -1,13 +1,13 @@
import type { ITerminalTabManager, TerminalTabItem } from '../types/terminal.type';
// 终端 tab 管理器实现
export default class TerminalTabManager implements ITerminalTabManager {
export default class TerminalTabManager<T extends TerminalTabItem = TerminalTabItem> implements ITerminalTabManager<T> {
public active: string;
public items: Array<TerminalTabItem>;
public items: Array<T>;
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);