✨ 回车重连.
This commit is contained in:
@@ -3,6 +3,18 @@
|
|||||||
* ⚡ **sql 脚本可以在 adminer 中执行。**
|
* ⚡ **sql 脚本可以在 adminer 中执行。**
|
||||||
* ⚡ **应用不支持跨版本升级, 可以进行多次升级。**
|
* ⚡ **应用不支持跨版本升级, 可以进行多次升级。**
|
||||||
|
|
||||||
|
## v1.0.6
|
||||||
|
|
||||||
|
`2024-05-` `release`
|
||||||
|
|
||||||
|
* 🐞 修复 终端页签关闭后不会自动切换
|
||||||
|
* 🩰 修改 命令执行日志 UI 修改
|
||||||
|
* 🌈 新增 命令执行模板配置默认主机
|
||||||
|
* 🌈 新增 主机终端书签路径
|
||||||
|
* 🔨 优化 退出登录不重定向
|
||||||
|
* 🔨 优化 动态设置页面标题
|
||||||
|
* 🔨 优化 终端断开后回车重连
|
||||||
|
|
||||||
## v1.0.5
|
## v1.0.5
|
||||||
|
|
||||||
`2024-04-22` `release`
|
`2024-04-22` `release`
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
## 功能排期
|
## 功能排期
|
||||||
|
|
||||||
* 默认主机
|
|
||||||
* 批量上传
|
* 批量上传
|
||||||
* 文件夹书签
|
|
||||||
* 站内消息
|
* 站内消息
|
||||||
* 终端背景图片
|
* 终端背景图片
|
||||||
* 资产授权 UI 改版
|
* 资产授权 UI 改版
|
||||||
|
|||||||
@@ -169,9 +169,12 @@ export default defineStore('terminal', {
|
|||||||
async reOpenSession(sessionId: string, panelIndex: number = 0) {
|
async reOpenSession(sessionId: string, panelIndex: number = 0) {
|
||||||
// 切换到终端面板页面
|
// 切换到终端面板页面
|
||||||
this.tabManager.openTab(TerminalTabs.TERMINAL_PANEL);
|
this.tabManager.openTab(TerminalTabs.TERMINAL_PANEL);
|
||||||
// 获取当前面板并且分配新的 sessionId
|
// 获取当前面板 tab 并且分配新的 sessionId
|
||||||
const panel = this.panelManager.getPanel(panelIndex);
|
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);
|
const newSessionId = tab.sessionId = nextId(10);
|
||||||
// 添加到最近连接
|
// 添加到最近连接
|
||||||
this.hosts.latestHosts = [...new Set([tab.hostId, ...this.hosts.latestHosts])];
|
this.hosts.latestHosts = [...new Set([tab.hostId, ...this.hosts.latestHosts])];
|
||||||
|
|||||||
@@ -63,24 +63,21 @@
|
|||||||
|
|
||||||
// 监听 tab 切换
|
// 监听 tab 切换
|
||||||
watch(() => props.panel.active, (active, before) => {
|
watch(() => props.panel.active, (active, before) => {
|
||||||
console.log(active);
|
|
||||||
console.log(before);
|
|
||||||
console.log(props.panel);
|
|
||||||
// 失焦自动终端
|
// 失焦自动终端
|
||||||
if (before) {
|
if (before) {
|
||||||
const beforeTab = props.panel.items.find(s => s.key === before);
|
const beforeTab = props.panel.items.find(s => s.key === before);
|
||||||
if (beforeTab && beforeTab?.type === PanelSessionType.SSH.type) {
|
if (beforeTab && beforeTab?.type === PanelSessionType.SSH.type) {
|
||||||
sessionManager.getSession<ISshSession>(before)?.blur();
|
sessionManager.getSession<ISshSession>(beforeTab.sessionId)?.blur();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 终端自动聚焦
|
// 终端自动聚焦
|
||||||
if (active) {
|
if (active) {
|
||||||
const activeTab = props.panel.items.find(s => s.key === active);
|
const activeTab = props.panel.items.find(s => s.key === active);
|
||||||
if (activeTab && activeTab?.type === PanelSessionType.SSH.type) {
|
if (activeTab && activeTab?.type === PanelSessionType.SSH.type) {
|
||||||
sessionManager.getSession<ISshSession>(active)?.focus();
|
sessionManager.getSession<ISshSession>(activeTab.sessionId)?.focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 无终端自动关闭 FIXME
|
// 无终端自动关闭
|
||||||
if (!props.panel.items.length) {
|
if (!props.panel.items.length) {
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,8 +53,9 @@
|
|||||||
:title="closeMessage">
|
:title="closeMessage">
|
||||||
已断开: {{ closeMessage }}
|
已断开: {{ closeMessage }}
|
||||||
</a-tag>
|
</a-tag>
|
||||||
<!-- 重连 FIXME -->
|
<!-- 重连 -->
|
||||||
<a-tooltip position="top"
|
<a-tooltip v-if="session?.canReconnect"
|
||||||
|
position="top"
|
||||||
:mini="true"
|
:mini="true"
|
||||||
:overlay-inverse="true"
|
:overlay-inverse="true"
|
||||||
:auto-fix-position="false"
|
:auto-fix-position="false"
|
||||||
|
|||||||
@@ -168,7 +168,6 @@
|
|||||||
|
|
||||||
// 连接成功回调
|
// 连接成功回调
|
||||||
const connectCallback = () => {
|
const connectCallback = () => {
|
||||||
// FIXME TEST
|
|
||||||
loadFiles(currentPath.value || '~');
|
loadFiles(currentPath.value || '~');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -96,8 +96,11 @@ export default class SshSession implements ISshSession {
|
|||||||
if (this.handler.checkPreventDefault(e)) {
|
if (this.handler.checkPreventDefault(e)) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
// 重新连接
|
// 检查重新连接
|
||||||
if (!this.connected && this.canReconnect && e.key === 'Enter') {
|
if (!this.connected && this.canReconnect && e.key === 'Enter') {
|
||||||
|
// 防止重复回车
|
||||||
|
this.canReconnect = false;
|
||||||
|
// 异步作用域重新连接
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
await useTerminalStore().reOpenSession(this.sessionId);
|
await useTerminalStore().reOpenSession(this.sessionId);
|
||||||
}, 50);
|
}, 50);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { ITerminalPanelManager } from '../types/terminal.type';
|
import type { ITerminalPanelManager, TerminalPanelTabItem } from '../types/terminal.type';
|
||||||
import TerminalPanelTabManager from '../handler/terminal-panel-tab-manager';
|
import TerminalTabManager from '../handler/terminal-tab-manager';
|
||||||
|
|
||||||
// 终端面板管理器实现
|
// 终端面板管理器实现
|
||||||
export default class TerminalPanelManager implements ITerminalPanelManager {
|
export default class TerminalPanelManager implements ITerminalPanelManager {
|
||||||
@@ -7,15 +7,15 @@ export default class TerminalPanelManager implements ITerminalPanelManager {
|
|||||||
// 当前面板
|
// 当前面板
|
||||||
active: number;
|
active: number;
|
||||||
// 面板列表
|
// 面板列表
|
||||||
panels: Array<TerminalPanelTabManager>;
|
panels: Array<TerminalTabManager<TerminalPanelTabItem>>;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.active = 0;
|
this.active = 0;
|
||||||
this.panels = [new TerminalPanelTabManager()];
|
this.panels = [new TerminalTabManager()];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取当前面板
|
// 获取当前面板
|
||||||
getCurrentPanel(): TerminalPanelTabManager {
|
getCurrentPanel(): TerminalTabManager<TerminalPanelTabItem> {
|
||||||
return this.panels[this.active];
|
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];
|
return this.panels[index];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ export default class TerminalPanelManager implements ITerminalPanelManager {
|
|||||||
panel.clear();
|
panel.clear();
|
||||||
}
|
}
|
||||||
this.active = 0;
|
this.active = 0;
|
||||||
this.panels = [new TerminalPanelTabManager()];
|
this.panels = [new TerminalTabManager()];
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
import type { ITerminalTabManager, TerminalTabItem } from '../types/terminal.type';
|
import type { ITerminalTabManager, TerminalTabItem } from '../types/terminal.type';
|
||||||
|
|
||||||
// 终端 tab 管理器实现
|
// 终端 tab 管理器实现
|
||||||
export default class TerminalTabManager implements ITerminalTabManager {
|
export default class TerminalTabManager<T extends TerminalTabItem = TerminalTabItem> implements ITerminalTabManager<T> {
|
||||||
|
|
||||||
public active: string;
|
public active: string;
|
||||||
|
|
||||||
public items: Array<TerminalTabItem>;
|
public items: Array<T>;
|
||||||
|
|
||||||
constructor(def: TerminalTabItem | undefined = undefined) {
|
constructor(def: T | undefined = undefined) {
|
||||||
if (def) {
|
if (def) {
|
||||||
this.active = def.key;
|
this.active = def.key;
|
||||||
this.items = [def];
|
this.items = [def];
|
||||||
@@ -26,8 +26,8 @@ export default class TerminalTabManager implements ITerminalTabManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取 tab
|
// 获取 tab
|
||||||
getTab(key: string): TerminalTabItem {
|
getTab(key: string): T {
|
||||||
return this.items.find(s => s.key === key) as TerminalTabItem;
|
return this.items.find(s => s.key === key) as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 点击 tab
|
// 点击 tab
|
||||||
@@ -41,16 +41,18 @@ export default class TerminalTabManager implements ITerminalTabManager {
|
|||||||
const tabIndex = this.items.findIndex(s => s.key === key);
|
const tabIndex = this.items.findIndex(s => s.key === key);
|
||||||
// 删除 tab
|
// 删除 tab
|
||||||
this.items.splice(tabIndex, 1);
|
this.items.splice(tabIndex, 1);
|
||||||
if (key === this.active && this.items.length !== 0) {
|
if (this.items.length !== 0) {
|
||||||
// 切换为前一个 tab
|
if (key === this.active) {
|
||||||
|
// 关闭的为当前 tab 切换为前一个 tab
|
||||||
this.active = this.items[Math.max(tabIndex - 1, 0)].key;
|
this.active = this.items[Math.max(tabIndex - 1, 0)].key;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.active = undefined as unknown as string;
|
this.active = undefined as unknown as string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 打开 tab
|
// 打开 tab
|
||||||
openTab(tab: TerminalTabItem): void {
|
openTab(tab: T): void {
|
||||||
// 不存在则创建 tab
|
// 不存在则创建 tab
|
||||||
if (!this.items.find(s => s.key === tab.key)) {
|
if (!this.items.find(s => s.key === tab.key)) {
|
||||||
this.items.push(tab);
|
this.items.push(tab);
|
||||||
|
|||||||
Reference in New Issue
Block a user