🔨 回车重连.

This commit is contained in:
lijiahang
2024-04-22 18:48:52 +08:00
parent be87c930e2
commit f1207be0ec
12 changed files with 81 additions and 11 deletions

View File

@@ -29,6 +29,11 @@ export default function setupPermissionGuard(router: Router) {
// 页面不存在 // 页面不存在
next({ name: NOT_FOUND_ROUTER_NAME }); next({ name: NOT_FOUND_ROUTER_NAME });
} }
// 修改页面标题
const locale = to.meta?.locale;
if (locale) {
document.title = locale;
}
NProgress.done(); NProgress.done();
}); });
} }

View File

@@ -17,6 +17,9 @@ export const ROOT_ROUTER: RouteRecordRaw = {
export const LOGIN_ROUTER: RouteRecordRaw = { export const LOGIN_ROUTER: RouteRecordRaw = {
path: '/login', path: '/login',
name: LOGIN_ROUTE_NAME, name: LOGIN_ROUTE_NAME,
meta: {
locale: '登录'
},
component: () => import('@/views/authentication/login/index.vue'), component: () => import('@/views/authentication/login/index.vue'),
}; };
@@ -26,6 +29,7 @@ export const REDIRECT_ROUTER: RouteRecordRaw = {
name: 'redirectWrapper', name: 'redirectWrapper',
component: DEFAULT_LAYOUT, component: DEFAULT_LAYOUT,
meta: { meta: {
locale: '重定向',
hideInMenu: true, hideInMenu: true,
}, },
children: [ children: [
@@ -34,6 +38,7 @@ export const REDIRECT_ROUTER: RouteRecordRaw = {
name: REDIRECT_ROUTE_NAME, name: REDIRECT_ROUTE_NAME,
component: () => import('@/views/base/redirect/index.vue'), component: () => import('@/views/base/redirect/index.vue'),
meta: { meta: {
locale: '重定向',
hideInMenu: true, hideInMenu: true,
noAffix: true noAffix: true
}, },
@@ -45,6 +50,9 @@ export const REDIRECT_ROUTER: RouteRecordRaw = {
export const FORBIDDEN_ROUTE: RouteRecordRaw = { export const FORBIDDEN_ROUTE: RouteRecordRaw = {
path: '/403', path: '/403',
name: FORBIDDEN_ROUTER_NAME, name: FORBIDDEN_ROUTER_NAME,
meta: {
locale: '403'
},
component: () => import('@/views/base/status/forbidden/index.vue'), component: () => import('@/views/base/status/forbidden/index.vue'),
}; };
@@ -53,6 +61,9 @@ export const NOT_FOUND_ROUTE: RouteRecordRaw = {
// path: '/:pathMatch(.*)*', // path: '/:pathMatch(.*)*',
path: '/404', path: '/404',
name: NOT_FOUND_ROUTER_NAME, name: NOT_FOUND_ROUTER_NAME,
meta: {
locale: '404'
},
component: () => import('@/views/base/status/not-found/index.vue'), component: () => import('@/views/base/status/not-found/index.vue'),
}; };

View File

@@ -135,7 +135,7 @@ export default defineStore('terminal', {
}, },
// 打开会话 // 打开会话
openSession(record: HostQueryResponse, session: PanelSessionTab, panelIndex: number = 0) { openSession(record: HostQueryResponse, type: PanelSessionTab, panelIndex: number = 0) {
// 添加到最近连接 // 添加到最近连接
this.hosts.latestHosts = [...new Set([record.id, ...this.hosts.latestHosts])]; this.hosts.latestHosts = [...new Set([record.id, ...this.hosts.latestHosts])];
// 切换到终端面板页面 // 切换到终端面板页面
@@ -154,15 +154,31 @@ export default defineStore('terminal', {
this.panelManager.getPanel(panelIndex).openTab({ this.panelManager.getPanel(panelIndex).openTab({
key: nextId(10), key: nextId(10),
seq: nextSeq, seq: nextSeq,
title: `(${nextSeq}) ${record.alias || record.name}`, title: `(${nextSeq}) ${record.alias || record.name}`,
hostId: record.id, hostId: record.id,
address: record.address, address: record.address,
color: record.color, color: record.color,
icon: session.icon, icon: type.icon,
type: session.type type: type.type
}); });
}, },
// 重新打开 terminal 会话
async reOpenTerminal(hostId: number, sessionId: string, panelIndex: number = 0) {
console.log('rec');
// 添加到最近连接
this.hosts.latestHosts = [...new Set([hostId, ...this.hosts.latestHosts])];
// 切换到终端面板页面
this.tabManager.openTab(TerminalTabs.TERMINAL_PANEL);
// 获取当前面板并且分配新的 sessionId
const panel = this.panelManager.getPanel(panelIndex);
const tab = panel.getTab(sessionId);
const newSessionId = nextId(10);
tab.key = newSessionId;
// 重新打开 ssh
await this.sessionManager.reOpenSsh(sessionId, newSessionId);
},
// 复制并且打开会话 // 复制并且打开会话
copySession(item: TerminalPanelTabItem, panelIndex: number = 0) { copySession(item: TerminalPanelTabItem, panelIndex: number = 0) {
const host = this.hosts.hostList const host = this.hosts.hostList

View File

@@ -60,7 +60,7 @@
{{ dateFormat(new Date(record.startTime)) }} {{ dateFormat(new Date(record.startTime)) }}
</a-descriptions-item> </a-descriptions-item>
<!-- 结束时间 --> <!-- 结束时间 -->
<a-descriptions-item label="结束时间"> <a-descriptions-item v-if="record.endTime" label="结束时间">
{{ dateFormat(new Date(record.endTime)) }} {{ dateFormat(new Date(record.endTime)) }}
</a-descriptions-item> </a-descriptions-item>
<!-- traceId --> <!-- traceId -->

View File

@@ -16,7 +16,7 @@
</span> </span>
</a-space> </a-space>
</template> </template>
<!-- 终端面板 --> <!-- 终端面板 FIXME -->
<a-tab-pane v-for="tab in panel.items" <a-tab-pane v-for="tab in panel.items"
:key="tab.key"> :key="tab.key">
<!-- 标题 --> <!-- 标题 -->
@@ -54,8 +54,8 @@
import SftpView from '../sftp/sftp-view.vue'; import SftpView from '../sftp/sftp-view.vue';
const props = defineProps<{ const props = defineProps<{
index: number, index: number;
panel: ITerminalTabManager<TerminalPanelTabItem>, panel: ITerminalTabManager<TerminalPanelTabItem>;
}>(); }>();
const emits = defineEmits(['close', 'openNewConnect']); const emits = defineEmits(['close', 'openNewConnect']);

View File

@@ -137,6 +137,7 @@
// 初始化会话 // 初始化会话
onMounted(async () => { onMounted(async () => {
console.log('onMounted', props.tab.key);
// 创建终端处理器 // 创建终端处理器
session.value = await sessionManager.openSsh(props.tab, { session.value = await sessionManager.openSsh(props.tab, {
el: terminalRef.value, el: terminalRef.value,

View File

@@ -85,6 +85,7 @@ export default class SshSession implements ISshSession {
if (e.type !== 'keydown') { if (e.type !== 'keydown') {
return true; return true;
} }
console.log(e);
// 检测是否为内置快捷键 // 检测是否为内置快捷键
if (this.handler.checkIsBuiltin(e)) { if (this.handler.checkIsBuiltin(e)) {
return true; return true;
@@ -93,6 +94,13 @@ export default class SshSession implements ISshSession {
if (this.handler.checkPreventDefault(e)) { if (this.handler.checkPreventDefault(e)) {
e.preventDefault(); e.preventDefault();
} }
if (e.key === 'Enter') {
console.log("enter start");
// TODO 回车 重新连接
useTerminalStore().reOpenTerminal(this.hostId, this.sessionId);
console.log("enter end");
}
// 自定义快捷键
if (preference.shortcutSetting.enabled && preference.shortcutSetting.keys.length) { if (preference.shortcutSetting.enabled && preference.shortcutSetting.keys.length) {
// 获取触发的快捷键 // 获取触发的快捷键
const shortcutKey = this.handler.getShortcutKey(e); const shortcutKey = this.handler.getShortcutKey(e);

View File

@@ -42,6 +42,7 @@ export default class TerminalChannel implements ITerminalChannel {
// 发送消息 // 发送消息
send(protocol: Protocol, payload: InputPayload): void { send(protocol: Protocol, payload: InputPayload): void {
console.log('send', payload);
// 检查是否连接 // 检查是否连接
if (!this.isConnected()) { if (!this.isConnected()) {
return; return;

View File

@@ -91,7 +91,7 @@ export default class TerminalOutputProcessor implements ITerminalOutputProcessor
} }
if (session instanceof SshSession) { if (session instanceof SshSession) {
// ssh 拼接关闭消息 // ssh 拼接关闭消息
session.write(`\r\n${msg || ''}`); session.write(`\r\n\r\n${msg || ''}\r\n\r\n`);
// 设置状态 // 设置状态
session.status = TerminalStatus.CLOSED; session.status = TerminalStatus.CLOSED;
session.connected = false; session.connected = false;

View File

@@ -7,6 +7,7 @@ import type {
TerminalTabItem, TerminalTabItem,
XtermDomRef XtermDomRef
} from '../types/terminal.type'; } from '../types/terminal.type';
import type { ISshSession } from '../types/terminal.type';
import { sleep } from '@/utils'; import { sleep } from '@/utils';
import { InputProtocol } from '../types/terminal.protocol'; import { InputProtocol } from '../types/terminal.protocol';
import { PanelSessionType } from '../types/terminal.const'; import { PanelSessionType } from '../types/terminal.const';
@@ -34,8 +35,7 @@ export default class TerminalSessionManager implements ITerminalSessionManager {
} }
// 打开 ssh 会话 // 打开 ssh 会话
async openSsh(tab: TerminalTabItem, async openSsh(tab: TerminalTabItem, domRef: XtermDomRef) {
domRef: XtermDomRef) {
const sessionId = tab.key; const sessionId = tab.key;
const hostId = tab.hostId as number; const hostId = tab.hostId as number;
// 初始化客户端 // 初始化客户端
@@ -61,6 +61,25 @@ export default class TerminalSessionManager implements ITerminalSessionManager {
return session; return session;
} }
// 重新打开 ssh 会话
async reOpenSsh(sessionId: string, newSessionId: string): Promise<void> {
console.log('sessionId', sessionId, 'newSessionId', newSessionId);
// 初始化客户端
await this.initChannel();
// 获取会话并且重新设置 sessionId
const session = this.sessions[sessionId] as ISshSession;
session.sessionId = newSessionId;
this.sessions[sessionId] = undefined as unknown as ISshSession;
this.sessions[newSessionId] = session;
console.log('ckckck');
// 发送会话初始化请求
this.channel.send(InputProtocol.CHECK, {
sessionId: newSessionId,
hostId: session.hostId,
connectType: PanelSessionType.SSH.type
});
}
// 打开 sftp 会话 // 打开 sftp 会话
async openSftp(tab: TerminalTabItem, resolver: ISftpSessionResolver): Promise<ISftpSession> { async openSftp(tab: TerminalTabItem, resolver: ISftpSessionResolver): Promise<ISftpSession> {
const sessionId = tab.key; const sessionId = tab.key;

View File

@@ -25,6 +25,11 @@ export default class TerminalTabManager<T extends TerminalTabItem = TerminalTabI
return this.items.find(s => s.key === this.active); return this.items.find(s => s.key === this.active);
} }
// 获取 tab
getTab(key: string): T {
return this.items.find(s => s.key === key) as T;
}
// 点击 tab // 点击 tab
clickTab(key: string): void { clickTab(key: string): void {
this.active = key; this.active = key;

View File

@@ -112,6 +112,8 @@ export interface ITerminalTabManager<T extends TerminalTabItem = TerminalTabItem
// 获取当前 tab // 获取当前 tab
getCurrentTab: () => T | undefined; getCurrentTab: () => T | undefined;
// 获取 tab
getTab: (key: string) => T;
// 点击 tab // 点击 tab
clickTab: (key: string) => void; clickTab: (key: string) => void;
// 删除 tab // 删除 tab
@@ -151,6 +153,8 @@ export interface ITerminalPanelManager<T extends TerminalPanelTabItem = Terminal
export interface ITerminalSessionManager { export interface ITerminalSessionManager {
// 打开 ssh 会话 // 打开 ssh 会话
openSsh: (tab: TerminalTabItem, domRef: XtermDomRef) => Promise<ISshSession>; openSsh: (tab: TerminalTabItem, domRef: XtermDomRef) => Promise<ISshSession>;
// 重新打开 ssh 会话
reOpenSsh: (sessionId: string, newSessionId: string) => Promise<void>;
// 打开 sftp 会话 // 打开 sftp 会话
openSftp: (tab: TerminalTabItem, resolver: ISftpSessionResolver) => Promise<ISftpSession>; openSftp: (tab: TerminalTabItem, resolver: ISftpSessionResolver) => Promise<ISftpSession>;
// 获取终端会话 // 获取终端会话