diff --git a/orion-ops-ui/src/router/guard/router-permission.ts b/orion-ops-ui/src/router/guard/router-permission.ts index 23e9a67d..a6b1f4df 100644 --- a/orion-ops-ui/src/router/guard/router-permission.ts +++ b/orion-ops-ui/src/router/guard/router-permission.ts @@ -29,6 +29,11 @@ export default function setupPermissionGuard(router: Router) { // 页面不存在 next({ name: NOT_FOUND_ROUTER_NAME }); } + // 修改页面标题 + const locale = to.meta?.locale; + if (locale) { + document.title = locale; + } NProgress.done(); }); } diff --git a/orion-ops-ui/src/router/routes/base.ts b/orion-ops-ui/src/router/routes/base.ts index 9277d5d7..3d31c384 100644 --- a/orion-ops-ui/src/router/routes/base.ts +++ b/orion-ops-ui/src/router/routes/base.ts @@ -17,6 +17,9 @@ export const ROOT_ROUTER: RouteRecordRaw = { export const LOGIN_ROUTER: RouteRecordRaw = { path: '/login', name: LOGIN_ROUTE_NAME, + meta: { + locale: '登录' + }, component: () => import('@/views/authentication/login/index.vue'), }; @@ -26,6 +29,7 @@ export const REDIRECT_ROUTER: RouteRecordRaw = { name: 'redirectWrapper', component: DEFAULT_LAYOUT, meta: { + locale: '重定向', hideInMenu: true, }, children: [ @@ -34,6 +38,7 @@ export const REDIRECT_ROUTER: RouteRecordRaw = { name: REDIRECT_ROUTE_NAME, component: () => import('@/views/base/redirect/index.vue'), meta: { + locale: '重定向', hideInMenu: true, noAffix: true }, @@ -45,6 +50,9 @@ export const REDIRECT_ROUTER: RouteRecordRaw = { export const FORBIDDEN_ROUTE: RouteRecordRaw = { path: '/403', name: FORBIDDEN_ROUTER_NAME, + meta: { + locale: '403' + }, component: () => import('@/views/base/status/forbidden/index.vue'), }; @@ -53,6 +61,9 @@ export const NOT_FOUND_ROUTE: RouteRecordRaw = { // path: '/:pathMatch(.*)*', path: '/404', name: NOT_FOUND_ROUTER_NAME, + meta: { + locale: '404' + }, component: () => import('@/views/base/status/not-found/index.vue'), }; diff --git a/orion-ops-ui/src/store/modules/terminal/index.ts b/orion-ops-ui/src/store/modules/terminal/index.ts index aed77edf..b4316f9f 100644 --- a/orion-ops-ui/src/store/modules/terminal/index.ts +++ b/orion-ops-ui/src/store/modules/terminal/index.ts @@ -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])]; // 切换到终端面板页面 @@ -154,15 +154,31 @@ export default defineStore('terminal', { this.panelManager.getPanel(panelIndex).openTab({ key: nextId(10), seq: nextSeq, - title: `(${nextSeq}) ${record.alias || record.name}`, + title: `(${nextSeq}) ${record.alias || record.name}`, hostId: record.id, address: record.address, color: record.color, - icon: session.icon, - type: session.type + icon: type.icon, + 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) { const host = this.hosts.hostList diff --git a/orion-ops-ui/src/views/asset-audit/connect-log/components/connect-log-detail-drawer.vue b/orion-ops-ui/src/views/asset-audit/connect-log/components/connect-log-detail-drawer.vue index a929f1b2..4c7f050b 100644 --- a/orion-ops-ui/src/views/asset-audit/connect-log/components/connect-log-detail-drawer.vue +++ b/orion-ops-ui/src/views/asset-audit/connect-log/components/connect-log-detail-drawer.vue @@ -60,7 +60,7 @@ {{ dateFormat(new Date(record.startTime)) }} - + {{ dateFormat(new Date(record.endTime)) }} 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 8afad332..2206cfc8 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 @@ -16,7 +16,7 @@ - + @@ -54,8 +54,8 @@ import SftpView from '../sftp/sftp-view.vue'; const props = defineProps<{ - index: number, - panel: ITerminalTabManager, + index: number; + panel: ITerminalTabManager; }>(); const emits = defineEmits(['close', 'openNewConnect']); diff --git a/orion-ops-ui/src/views/host/terminal/components/ssh/ssh-view.vue b/orion-ops-ui/src/views/host/terminal/components/ssh/ssh-view.vue index 22a80366..16818dee 100644 --- a/orion-ops-ui/src/views/host/terminal/components/ssh/ssh-view.vue +++ b/orion-ops-ui/src/views/host/terminal/components/ssh/ssh-view.vue @@ -137,6 +137,7 @@ // 初始化会话 onMounted(async () => { + console.log('onMounted', props.tab.key); // 创建终端处理器 session.value = await sessionManager.openSsh(props.tab, { el: terminalRef.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 5bfafe46..22d71ab4 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 @@ -85,6 +85,7 @@ export default class SshSession implements ISshSession { if (e.type !== 'keydown') { return true; } + console.log(e); // 检测是否为内置快捷键 if (this.handler.checkIsBuiltin(e)) { return true; @@ -93,6 +94,13 @@ export default class SshSession implements ISshSession { if (this.handler.checkPreventDefault(e)) { 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) { // 获取触发的快捷键 const shortcutKey = this.handler.getShortcutKey(e); diff --git a/orion-ops-ui/src/views/host/terminal/handler/terminal-channel.ts b/orion-ops-ui/src/views/host/terminal/handler/terminal-channel.ts index de2881d5..eae6ab49 100644 --- a/orion-ops-ui/src/views/host/terminal/handler/terminal-channel.ts +++ b/orion-ops-ui/src/views/host/terminal/handler/terminal-channel.ts @@ -42,6 +42,7 @@ export default class TerminalChannel implements ITerminalChannel { // 发送消息 send(protocol: Protocol, payload: InputPayload): void { + console.log('send', payload); // 检查是否连接 if (!this.isConnected()) { return; diff --git a/orion-ops-ui/src/views/host/terminal/handler/terminal-output-processor.ts b/orion-ops-ui/src/views/host/terminal/handler/terminal-output-processor.ts index 5dadd999..4d52f818 100644 --- a/orion-ops-ui/src/views/host/terminal/handler/terminal-output-processor.ts +++ b/orion-ops-ui/src/views/host/terminal/handler/terminal-output-processor.ts @@ -91,7 +91,7 @@ export default class TerminalOutputProcessor implements ITerminalOutputProcessor } if (session instanceof SshSession) { // ssh 拼接关闭消息 - session.write(`\r\n${msg || ''}`); + session.write(`\r\n\r\n${msg || ''}\r\n\r\n`); // 设置状态 session.status = TerminalStatus.CLOSED; session.connected = false; diff --git a/orion-ops-ui/src/views/host/terminal/handler/terminal-session-manager.ts b/orion-ops-ui/src/views/host/terminal/handler/terminal-session-manager.ts index 2c675da1..93ca8bca 100644 --- a/orion-ops-ui/src/views/host/terminal/handler/terminal-session-manager.ts +++ b/orion-ops-ui/src/views/host/terminal/handler/terminal-session-manager.ts @@ -7,6 +7,7 @@ import type { TerminalTabItem, XtermDomRef } from '../types/terminal.type'; +import type { ISshSession } from '../types/terminal.type'; import { sleep } from '@/utils'; import { InputProtocol } from '../types/terminal.protocol'; import { PanelSessionType } from '../types/terminal.const'; @@ -34,8 +35,7 @@ export default class TerminalSessionManager implements ITerminalSessionManager { } // 打开 ssh 会话 - async openSsh(tab: TerminalTabItem, - domRef: XtermDomRef) { + async openSsh(tab: TerminalTabItem, domRef: XtermDomRef) { const sessionId = tab.key; const hostId = tab.hostId as number; // 初始化客户端 @@ -61,6 +61,25 @@ export default class TerminalSessionManager implements ITerminalSessionManager { return session; } + // 重新打开 ssh 会话 + async reOpenSsh(sessionId: string, newSessionId: string): Promise { + 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 会话 async openSftp(tab: TerminalTabItem, resolver: ISftpSessionResolver): Promise { const sessionId = tab.key; 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 2c7bea42..c9934e18 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 @@ -25,6 +25,11 @@ export default class TerminalTabManager s.key === this.active); } + // 获取 tab + getTab(key: string): T { + return this.items.find(s => s.key === key) as T; + } + // 点击 tab clickTab(key: string): void { this.active = key; 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 b7cecc9c..f06e05e3 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 @@ -112,6 +112,8 @@ export interface ITerminalTabManager T | undefined; + // 获取 tab + getTab: (key: string) => T; // 点击 tab clickTab: (key: string) => void; // 删除 tab @@ -151,6 +153,8 @@ export interface ITerminalPanelManager Promise; + // 重新打开 ssh 会话 + reOpenSsh: (sessionId: string, newSessionId: string) => Promise; // 打开 sftp 会话 openSftp: (tab: TerminalTabItem, resolver: ISftpSessionResolver) => Promise; // 获取终端会话