🔨 命令发送.
This commit is contained in:
@@ -1,18 +1,18 @@
|
||||
spring:
|
||||
datasource:
|
||||
druid:
|
||||
url: jdbc:mysql://116.62.194.246:3306/orion_visor?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true
|
||||
url: jdbc:mysql://127.0.0.1:3306/orion_visor?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true
|
||||
username: root
|
||||
password: Orionsec@0379
|
||||
password: Data@123456
|
||||
initial-size: 0
|
||||
min-idle: 1
|
||||
max-active: 5
|
||||
stat-view-servlet:
|
||||
enabled: false
|
||||
redis:
|
||||
host: 116.62.194.246
|
||||
host: 127.0.0.1
|
||||
port: 6379
|
||||
password: Orionsec@0379
|
||||
password: Data@123456
|
||||
redisson:
|
||||
threads: 2
|
||||
netty-threads: 2
|
||||
|
||||
@@ -259,11 +259,6 @@ public class TerminalPreferenceModel implements GenericsDataModel {
|
||||
@AllArgsConstructor
|
||||
public static class ActionBarSettingModel implements IJsonObject {
|
||||
|
||||
/**
|
||||
* 命令输入框
|
||||
*/
|
||||
private Boolean commandInput;
|
||||
|
||||
/**
|
||||
* 连接状态
|
||||
*/
|
||||
|
||||
@@ -115,7 +115,6 @@ public class TerminalPreferenceStrategy extends AbstractGenericsDataStrategy<Ter
|
||||
.toJsonString();
|
||||
// 操作栏设置
|
||||
String actionBarSetting = TerminalPreferenceModel.ActionBarSettingModel.builder()
|
||||
.commandInput(false)
|
||||
.connectStatus(true)
|
||||
.toTop(false)
|
||||
.toBottom(false)
|
||||
|
||||
@@ -65,6 +65,7 @@ export default defineStore('terminal', {
|
||||
keys: []
|
||||
} as TerminalShortcutSetting,
|
||||
},
|
||||
commandBarVisible: false,
|
||||
hosts: {} as AuthorizedHostQueryResponse,
|
||||
tabManager: new TerminalTabManager(),
|
||||
panelManager: new TerminalPanelManager(),
|
||||
@@ -124,6 +125,11 @@ export default defineStore('terminal', {
|
||||
}
|
||||
},
|
||||
|
||||
// 修改命令发送显示
|
||||
setCommandBarVisible(visible: boolean) {
|
||||
this.commandBarVisible = visible;
|
||||
},
|
||||
|
||||
// 加载主机列表
|
||||
async loadHosts() {
|
||||
if (this.hosts.hostList?.length) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import type { TerminalTheme } from '@/api/asset/terminal';
|
||||
|
||||
export interface TerminalState {
|
||||
preference: TerminalPreference;
|
||||
commandBarVisible: boolean;
|
||||
hosts: AuthorizedHostQueryResponse;
|
||||
tabManager: ITerminalTabManager;
|
||||
panelManager: ITerminalPanelManager;
|
||||
@@ -38,7 +39,6 @@ export interface TerminalDisplaySetting {
|
||||
|
||||
// 操作栏设置
|
||||
export interface TerminalActionBarSetting {
|
||||
commandInput?: boolean;
|
||||
connectStatus?: boolean;
|
||||
|
||||
[key: string]: unknown;
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
<template>
|
||||
<div class="command-bar">
|
||||
<div class="command-header">
|
||||
<!-- 左侧按钮 -->
|
||||
<div class="command-header-left">
|
||||
<!-- 粘贴 -->
|
||||
<a-button size="mini"
|
||||
class="mr8"
|
||||
@click="paste">
|
||||
粘贴
|
||||
<template #icon>
|
||||
<icon-send />
|
||||
</template>
|
||||
</a-button>
|
||||
<!-- 清空 -->
|
||||
<a-button size="mini" @click="clear">
|
||||
清空
|
||||
<template #icon>
|
||||
<icon-delete />
|
||||
</template>
|
||||
</a-button>
|
||||
</div>
|
||||
<!-- 右侧按钮 -->
|
||||
<div class="command-header-right">
|
||||
<!-- 隐藏 -->
|
||||
<a-button size="mini" @click="setCommandBarVisible(false)">
|
||||
<template #icon>
|
||||
<icon-down />
|
||||
</template>
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="command-body">
|
||||
<!-- 命令框 -->
|
||||
<div class="command-input">
|
||||
<a-textarea v-model="text"
|
||||
placeholder="输入命令, F8 发送"
|
||||
:auto-size="{ minRows: 3, maxRows: 3 }"
|
||||
@keyup="checkCommandKey" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'commandBar'
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { useTerminalStore } from '@/store';
|
||||
|
||||
const { setCommandBarVisible, appendCommandToCurrentSession } = useTerminalStore();
|
||||
|
||||
const text = ref('');
|
||||
|
||||
// 粘贴
|
||||
const paste = () => {
|
||||
appendCommandToCurrentSession(text.value);
|
||||
text.value = '';
|
||||
};
|
||||
|
||||
// 清空
|
||||
const clear = () => {
|
||||
text.value = '';
|
||||
};
|
||||
|
||||
// 检查命令快捷键
|
||||
const checkCommandKey = async (e: KeyboardEvent) => {
|
||||
if (text.value && e.code === 'F8') {
|
||||
paste();
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.command-bar {
|
||||
height: 122px;
|
||||
}
|
||||
|
||||
.command-header {
|
||||
border-top: 1px var(--color-bg-sidebar) solid;
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
padding: 0 12px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
&-left, &-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.command-body {
|
||||
width: 100%;
|
||||
height: 92px;
|
||||
padding: 0 12px 12px 12px;
|
||||
display: flex;
|
||||
|
||||
.command-input {
|
||||
width: 100%;
|
||||
|
||||
:deep(textarea) {
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -23,6 +23,8 @@
|
||||
</a-tabs>
|
||||
<!-- 承载页推荐 -->
|
||||
<empty-recommend v-else />
|
||||
<!-- 底部发送命令 -->
|
||||
<command-bar v-if="commandBarVisible" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -45,10 +47,11 @@
|
||||
import TerminalThemeSetting from '../setting/theme/terminal-theme-setting.vue';
|
||||
import TerminalGeneralSetting from '../setting/general/terminal-general-setting.vue';
|
||||
import TerminalShortcutSetting from '../setting/shortcut/terminal-shortcut-setting.vue';
|
||||
import CommandBar from '../command-bar/index.vue';
|
||||
|
||||
const emits = defineEmits(['openCommandSnippet', 'openPathBookmark', 'openTransferList', 'screenshot']);
|
||||
const emits = defineEmits(['openCommandSnippet', 'openPathBookmark', 'openTransferList', 'openCommandBar', 'screenshot']);
|
||||
|
||||
const { preference, tabManager, getCurrentSession } = useTerminalStore();
|
||||
const { commandBarVisible, preference, tabManager, getCurrentSession } = useTerminalStore();
|
||||
|
||||
// 监听 tab 切换
|
||||
watch(() => tabManager.active, (active, before) => {
|
||||
@@ -111,6 +114,10 @@
|
||||
// 打开文件传输列表
|
||||
emits('openTransferList');
|
||||
break;
|
||||
case TerminalShortcutKeys.OPEN_COMMAND_BAR:
|
||||
// 打开发送命令
|
||||
emits('openCommandBar');
|
||||
break;
|
||||
case TerminalShortcutKeys.SCREENSHOT:
|
||||
// 截图
|
||||
emits('screenshot');
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
import type { SidebarAction } from '../../types/define';
|
||||
import IconActions from './icon-actions.vue';
|
||||
|
||||
const emits = defineEmits(['openCommandSnippet', 'openPathBookmark', 'openTransferList', 'screenshot']);
|
||||
const emits = defineEmits(['openCommandSnippet', 'openPathBookmark', 'openTransferList', 'openCommandBar', 'screenshot']);
|
||||
|
||||
// 顶部操作
|
||||
const topActions = [
|
||||
@@ -46,6 +46,10 @@
|
||||
// 底部操作
|
||||
const bottomActions: Array<SidebarAction> = [
|
||||
{
|
||||
icon: 'icon-send',
|
||||
content: '发送命令',
|
||||
click: () => emits('openCommandBar')
|
||||
}, {
|
||||
icon: 'icon-camera',
|
||||
content: '截图',
|
||||
click: () => emits('screenshot')
|
||||
|
||||
@@ -24,12 +24,6 @@
|
||||
:actions="actions"
|
||||
position="bottom" />
|
||||
</a-form-item>
|
||||
<!-- 命令输入框 -->
|
||||
<a-form-item field="commandInput" label="命令输入框">
|
||||
<a-switch v-model="formModel.commandInput"
|
||||
:default-checked="true"
|
||||
type="round" />
|
||||
</a-form-item>
|
||||
<!-- 终端连接状态 -->
|
||||
<a-form-item field="showStatus" label="终端连接状态">
|
||||
<a-switch v-model="formModel.connectStatus"
|
||||
|
||||
@@ -152,6 +152,7 @@
|
||||
// 非初始化则修改终端样式
|
||||
if (before) {
|
||||
Object.values(sessionManager.sessions)
|
||||
.filter(Boolean)
|
||||
.filter(s => s.type === PanelSessionType.SSH.type)
|
||||
.map(s => s as ISshSession)
|
||||
.forEach(s => {
|
||||
|
||||
@@ -77,6 +77,7 @@
|
||||
document.body.setAttribute('terminal-theme', theme.dark ? 'dark' : 'light');
|
||||
// 修改终端主题
|
||||
Object.values(sessionManager.sessions)
|
||||
.filter(Boolean)
|
||||
.filter(s => s.type === PanelSessionType.SSH.type)
|
||||
.map(s => s as ISshSession)
|
||||
.forEach(s => {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<a-doption v-for="(action, index) in actions"
|
||||
:key="index"
|
||||
:disabled="!session.handler.enabledStatus(action.item)"
|
||||
@click="emits('click', action.item)">
|
||||
@click="emits('handle', action.item)">
|
||||
<!-- 图标 -->
|
||||
<div class="terminal-context-menu-icon">
|
||||
<component :is="action.icon" />
|
||||
@@ -39,7 +39,7 @@
|
||||
session?: ISshSession;
|
||||
}>();
|
||||
|
||||
const emits = defineEmits(['click']);
|
||||
const emits = defineEmits(['handle']);
|
||||
|
||||
const { preference } = useTerminalStore();
|
||||
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
<template>
|
||||
<!-- 头部 -->
|
||||
<div class="ssh-header">
|
||||
<!-- 左侧操作 -->
|
||||
<div class="ssh-header-left">
|
||||
<!-- 主机地址 -->
|
||||
<span class="address-wrapper">
|
||||
<span class="text-copy"
|
||||
:title="address"
|
||||
@click="copy(address as string, true)">
|
||||
{{ address }}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<!-- 右侧操作 -->
|
||||
<div class="ssh-header-right">
|
||||
<!-- 操作按钮 -->
|
||||
<icon-actions class="ssh-header-right-action-bar"
|
||||
wrapper-class="ssh-header-icon-wrapper"
|
||||
icon-class="ssh-header-icon"
|
||||
:actions="rightActions"
|
||||
position="bottom" />
|
||||
<!-- 连接状态 -->
|
||||
<a-badge v-if="preference.actionBarSetting.connectStatus !== false"
|
||||
class="status-bridge"
|
||||
:status="getDictValue(sessionStatusKey, session ? session.status : 0, 'status')"
|
||||
:text="getDictValue(sessionStatusKey, session ? session.status : 0)" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'sshHeader'
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { ISshSession, SidebarAction } from '../../types/define';
|
||||
import { computed } from 'vue';
|
||||
import { useDictStore, useTerminalStore } from '@/store';
|
||||
import { ActionBarItems, sessionStatusKey } from '../../types/const';
|
||||
import { copy } from '@/hooks/copy';
|
||||
import IconActions from '../layout/icon-actions.vue';
|
||||
|
||||
const emits = defineEmits(['handle']);
|
||||
|
||||
const props = defineProps<{
|
||||
address: string;
|
||||
session?: ISshSession;
|
||||
}>();
|
||||
|
||||
const { getDictValue } = useDictStore();
|
||||
const { preference } = useTerminalStore();
|
||||
|
||||
// 右侧操作
|
||||
const rightActions = computed<Array<SidebarAction>>(() => {
|
||||
return ActionBarItems.map(s => {
|
||||
return {
|
||||
icon: s.icon,
|
||||
content: s.content,
|
||||
visible: preference.actionBarSetting[s.item] !== false,
|
||||
disabled: props.session?.handler.enabledStatus(s.item) === false,
|
||||
click: () => emits('handle', s.item)
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@ssh-header-height: 36px;
|
||||
|
||||
.ssh-header {
|
||||
width: 100%;
|
||||
height: @ssh-header-height;
|
||||
padding: 0 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background: var(--color-bg-panel-bar);
|
||||
|
||||
&-left, &-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&-left {
|
||||
width: 25%;
|
||||
|
||||
.address-wrapper {
|
||||
height: 100%;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
user-select: none;
|
||||
|
||||
&:before {
|
||||
content: 'IP:';
|
||||
padding-right: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-right {
|
||||
width: 75%;
|
||||
justify-content: flex-end;
|
||||
|
||||
.command-input {
|
||||
width: 36%;
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
|
||||
&-right-action-bar {
|
||||
display: flex;
|
||||
|
||||
:deep(.ssh-header-icon-wrapper) {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
:deep(.ssh-header-icon) {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.status-bridge {
|
||||
height: 100%;
|
||||
margin: 0 2px 0 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
user-select: none;
|
||||
|
||||
:deep(.arco-badge-status-text) {
|
||||
width: 36px;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
height: 56%;
|
||||
margin: 0 12px 0 6px;
|
||||
border-left: 2px solid var(--color-fill-4);
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -1,44 +1,12 @@
|
||||
<template>
|
||||
<div class="ssh-container">
|
||||
<!-- 头部 -->
|
||||
<div class="ssh-header">
|
||||
<!-- 左侧操作 -->
|
||||
<div class="ssh-header-left">
|
||||
<!-- 主机地址 -->
|
||||
<span class="address-wrapper">
|
||||
<span class="text-copy"
|
||||
:title="tab.address"
|
||||
@click="copy(tab.address as string, true)">
|
||||
{{ tab.address }}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<!-- 右侧操作 -->
|
||||
<div class="ssh-header-right">
|
||||
<!-- 命令输入框 -->
|
||||
<a-textarea class="command-input mr8"
|
||||
v-if="preference.actionBarSetting.commandInput !== false"
|
||||
v-model="commandInput"
|
||||
:auto-size="{ minRows: 1, maxRows: 1 }"
|
||||
placeholder="F8 发送命令"
|
||||
allow-clear
|
||||
@keyup="writeCommandInput" />
|
||||
<!-- 操作按钮 -->
|
||||
<icon-actions class="ssh-header-right-action-bar"
|
||||
wrapper-class="ssh-header-icon-wrapper"
|
||||
icon-class="ssh-header-icon"
|
||||
:actions="rightActions"
|
||||
position="bottom" />
|
||||
<!-- 连接状态 -->
|
||||
<a-badge v-if="preference.actionBarSetting.connectStatus !== false"
|
||||
class="status-bridge"
|
||||
:status="getDictValue(sessionStatusKey, session ? session.status : 0, 'status')"
|
||||
:text="getDictValue(sessionStatusKey, session ? session.status : 0)" />
|
||||
</div>
|
||||
</div>
|
||||
<ssh-header :address="tab.address"
|
||||
:session="session"
|
||||
@handle="doTerminalHandle" />
|
||||
<!-- 终端右键菜单 -->
|
||||
<ssh-context-menu :session="session"
|
||||
@click="doTerminalHandle">
|
||||
@handle="doTerminalHandle">
|
||||
<!-- 终端容器 -->
|
||||
<div class="ssh-wrapper"
|
||||
:style="{ background: preference.theme.schema.background }">
|
||||
@@ -49,10 +17,11 @@
|
||||
class="search-modal"
|
||||
@find="findWords"
|
||||
@close="focus" />
|
||||
<!-- 上传文件模态框 -->
|
||||
<sftp-upload-modal ref="uploadModal" @closed="focus" />
|
||||
|
||||
</div>
|
||||
</ssh-context-menu>
|
||||
<!-- 上传文件模态框 -->
|
||||
<sftp-upload-modal ref="uploadModal" @closed="focus" />
|
||||
<!-- 命令编辑器 -->
|
||||
<shell-editor-modal ref="editorModal"
|
||||
:closable="false"
|
||||
@@ -71,13 +40,11 @@
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { ISshSession, TerminalPanelTabItem, SidebarAction } from '../../types/define';
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue';
|
||||
import type { ISshSession, TerminalPanelTabItem } from '../../types/define';
|
||||
import { onMounted, onUnmounted, ref } from 'vue';
|
||||
import { useDictStore, useTerminalStore } from '@/store';
|
||||
import { copy } from '@/hooks/copy';
|
||||
import { ActionBarItems, sessionStatusKey } from '../../types/const';
|
||||
import SshHeader from './ssh-header.vue';
|
||||
import ShellEditorModal from '@/components/view/shell-editor/modal/index.vue';
|
||||
import IconActions from '../layout/icon-actions.vue';
|
||||
import SshContextMenu from './ssh-context-menu.vue';
|
||||
import SftpUploadModal from '../sftp/sftp-upload-modal.vue';
|
||||
import XtermSearchModal from '@/components/xterm/search-modal/index.vue';
|
||||
@@ -92,19 +59,9 @@
|
||||
const editorModal = ref();
|
||||
const searchModal = ref();
|
||||
const uploadModal = ref();
|
||||
const commandInput = ref();
|
||||
const terminalRef = ref();
|
||||
const session = ref<ISshSession>();
|
||||
|
||||
// 发送命令
|
||||
const writeCommandInput = async (e: KeyboardEvent) => {
|
||||
const value = commandInput.value;
|
||||
if (value && e.code === 'F8') {
|
||||
writeCommand(value);
|
||||
commandInput.value = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
// 发送命令
|
||||
const writeCommand = (value: string) => {
|
||||
if (session.value?.canWrite) {
|
||||
@@ -127,19 +84,6 @@
|
||||
session.value?.handler.invokeHandle.call(session.value?.handler, handle);
|
||||
};
|
||||
|
||||
// 右侧操作
|
||||
const rightActions = computed<Array<SidebarAction>>(() => {
|
||||
return ActionBarItems.map(s => {
|
||||
return {
|
||||
icon: s.icon,
|
||||
content: s.content,
|
||||
visible: preference.actionBarSetting[s.item] !== false,
|
||||
disabled: session.value?.handler.enabledStatus(s.item) === false,
|
||||
click: () => doTerminalHandle(s.item)
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
// 初始化会话
|
||||
onMounted(async () => {
|
||||
// 创建终端处理器
|
||||
@@ -167,84 +111,6 @@
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.ssh-header {
|
||||
width: 100%;
|
||||
height: @ssh-header-height;
|
||||
padding: 0 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background: var(--color-bg-panel-bar);
|
||||
|
||||
&-left, &-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&-left {
|
||||
width: 25%;
|
||||
|
||||
.address-wrapper {
|
||||
height: 100%;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
user-select: none;
|
||||
|
||||
&:before {
|
||||
content: 'IP:';
|
||||
padding-right: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-right {
|
||||
width: 75%;
|
||||
justify-content: flex-end;
|
||||
|
||||
.command-input {
|
||||
width: 36%;
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
|
||||
&-right-action-bar {
|
||||
display: flex;
|
||||
|
||||
:deep(.ssh-header-icon-wrapper) {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
:deep(.ssh-header-icon) {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.status-bridge {
|
||||
height: 100%;
|
||||
margin: 0 2px 0 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
user-select: none;
|
||||
|
||||
:deep(.arco-badge-status-text) {
|
||||
width: 36px;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
height: 56%;
|
||||
margin: 0 12px 0 6px;
|
||||
border-left: 2px solid var(--color-fill-4);
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ssh-wrapper {
|
||||
width: 100%;
|
||||
height: calc(100% - @ssh-header-height);
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
@open-command-snippet="() => snippetRef.open()"
|
||||
@open-path-bookmark="() => pathRef.open()"
|
||||
@open-transfer-list="() => transferRef.open()"
|
||||
@open-command-bar="setCommandBarVisible(true)"
|
||||
@screenshot="screenshot" />
|
||||
</main>
|
||||
<!-- 右侧操作栏 -->
|
||||
@@ -28,6 +29,7 @@
|
||||
<right-sidebar @open-command-snippet="() => snippetRef.open()"
|
||||
@open-path-bookmark="() => pathRef.open()"
|
||||
@open-transfer-list="() => transferRef.open()"
|
||||
@open-command-bar="setCommandBarVisible(true)"
|
||||
@screenshot="screenshot" />
|
||||
</div>
|
||||
</main>
|
||||
@@ -75,7 +77,11 @@
|
||||
import '@/assets/style/host-terminal-layout.less';
|
||||
import '@xterm/xterm/css/xterm.css';
|
||||
|
||||
const { fetchPreference, getCurrentSession, openSession, preference, loadHosts, hosts, tabManager } = useTerminalStore();
|
||||
const {
|
||||
fetchPreference, getCurrentSession, openSession,
|
||||
preference, loadHosts, hosts, tabManager,
|
||||
setCommandBarVisible
|
||||
} = useTerminalStore();
|
||||
const { loading, setLoading } = useLoading(true);
|
||||
const { enter: enterFull, exit: exitFull } = useFullscreen();
|
||||
const route = useRoute();
|
||||
|
||||
@@ -211,6 +211,8 @@ export const TerminalShortcutKeys = {
|
||||
OPEN_PATH_BOOKMARK: 'openPathBookmark',
|
||||
// 打开文件传输列表
|
||||
OPEN_TRANSFER_LIST: 'openTransferList',
|
||||
// 打开发送命令
|
||||
OPEN_COMMAND_BAR: 'openCommandBar',
|
||||
// 截图
|
||||
SCREENSHOT: 'screenshot',
|
||||
// 打开新建连接弹框
|
||||
@@ -257,6 +259,10 @@ export const TerminalShortcutItems: Array<ShortcutKeyItem> = [
|
||||
item: TerminalShortcutKeys.OPEN_TRANSFER_LIST,
|
||||
content: '打开文件传输列表',
|
||||
type: TerminalShortcutType.GLOBAL
|
||||
}, {
|
||||
item: TerminalShortcutKeys.OPEN_COMMAND_BAR,
|
||||
content: '打开发送命令',
|
||||
type: TerminalShortcutType.GLOBAL
|
||||
}, {
|
||||
item: TerminalShortcutKeys.SCREENSHOT,
|
||||
content: '截图',
|
||||
|
||||
Reference in New Issue
Block a user