添加终端快捷键.

This commit is contained in:
lijiahang
2024-04-26 16:00:24 +08:00
parent 91b25b8d0c
commit 1decd92bd9
10 changed files with 102 additions and 38 deletions

View File

@@ -17,6 +17,7 @@
* 🌈 新增 主机终端书签路径
* 🌈 新增 命令执行日志添加 `ansi` 日志 `app.exec-log.append-ansi`
* 🌈 新增 定时删除命令执行日志文件 `app.exec-log.auto-clear`
* 🌈 新增 终端设置添加了几个全局快捷键
* 🔨 优化 通用分组模型添加 `userId`
* 🔨 优化 退出登录不重定向
* 🔨 优化 动态设置页面标题

View File

@@ -22,6 +22,6 @@ public interface AppConst extends OrionConst {
String GITEE = "https://gitee.com/lijiahangmax/orion-ops-pro";
String ISSUES = "https://gitee.com/lijiahangmax/orion-ops-pro/issues";
String ISSUES = "https://github.com/lijiahangmax/orion-ops-pro/issues";
}

View File

@@ -66,6 +66,10 @@ public class TerminalPreferenceStrategy implements IPreferenceStrategy<TerminalP
new TerminalPreferenceModel.ShortcutKeysModel("changeToPrevTab", true, true, true, "BracketLeft", true),
new TerminalPreferenceModel.ShortcutKeysModel("changeToNextTab", true, true, true, "BracketRight", true),
new TerminalPreferenceModel.ShortcutKeysModel("openNewConnectTab", true, true, true, "KeyN", true),
new TerminalPreferenceModel.ShortcutKeysModel("openCommandSnippet", true, true, true, "KeyC", true),
new TerminalPreferenceModel.ShortcutKeysModel("openPathBookmark", true, true, true, "KeyP", true),
new TerminalPreferenceModel.ShortcutKeysModel("openTransferList", true, true, true, "KeyT", true),
new TerminalPreferenceModel.ShortcutKeysModel("screenshot", true, true, true, "KeyS", true),
// 会话快捷键
new TerminalPreferenceModel.ShortcutKeysModel("openNewConnectModal", true, false, true, "KeyN", true),
new TerminalPreferenceModel.ShortcutKeysModel("copySession", true, false, true, "KeyO", true),

View File

@@ -14,6 +14,7 @@ import com.orion.ops.framework.redis.core.utils.RedisStrings;
import com.orion.ops.framework.redis.core.utils.RedisUtils;
import com.orion.ops.framework.redis.core.utils.barrier.CacheBarriers;
import com.orion.ops.framework.security.core.utils.SecurityUtils;
import com.orion.ops.module.infra.convert.SystemRoleConvert;
import com.orion.ops.module.infra.convert.SystemUserConvert;
import com.orion.ops.module.infra.dao.OperatorLogDAO;
import com.orion.ops.module.infra.dao.SystemRoleDAO;
@@ -23,6 +24,7 @@ import com.orion.ops.module.infra.define.RoleDefine;
import com.orion.ops.module.infra.define.cache.TipsCacheKeyDefine;
import com.orion.ops.module.infra.define.cache.UserCacheKeyDefine;
import com.orion.ops.module.infra.define.config.AppAuthenticationConfig;
import com.orion.ops.module.infra.entity.domain.SystemRoleDO;
import com.orion.ops.module.infra.entity.domain.SystemUserDO;
import com.orion.ops.module.infra.entity.dto.UserInfoDTO;
import com.orion.ops.module.infra.entity.request.user.*;
@@ -160,11 +162,15 @@ public class SystemUserServiceImpl implements SystemUserService {
@Override
public SystemUserVO getSystemUserById(Long id) {
// 查询
// 查询用户
SystemUserDO record = systemUserDAO.selectById(id);
Valid.notNull(record, ErrorMessage.USER_ABSENT);
// 转换
return SystemUserConvert.MAPPER.to(record);
// 查询角色
List<SystemRoleDO> roles = systemRoleDAO.selectRoleByUserId(id);
// 返回
SystemUserVO user = SystemUserConvert.MAPPER.to(record);
user.setRoles(SystemRoleConvert.MAPPER.to(roles));
return user;
}
@Override

View File

@@ -28,4 +28,11 @@
AND role_id IN (SELECT id FROM system_role WHERE CODE = #{code} AND deleted = 0) LIMIT 1
</select>
<select id="selectRoleByUserId" resultMap="BaseResultMap">
SELECT <include refid="Base_Column_List"/>
FROM system_role
WHERE deleted = 0
AND id IN (SELECT role_id FROM system_user_role WHERE user_id = #{userId} AND deleted = 0)
</select>
</mapper>

View File

@@ -74,7 +74,7 @@
& > .arco-card-header {
height: auto;
padding: 16px;
padding: 12px 16px;
border: none;
}

View File

@@ -46,6 +46,8 @@
import TerminalShortcutSetting from '../setting/shortcut/terminal-shortcut-setting.vue';
import TerminalPanelsView from '@/views/host/terminal/components/layout/terminal-panels-view.vue';
const emits = defineEmits(['openCommandSnippet', 'openPathBookmark', 'openTransferList', 'screenshot']);
const { preference, tabManager, getCurrentSession } = useTerminalStore();
// 监听 tab 切换
@@ -97,6 +99,22 @@
// 切换到新建连接 tab
tabManager.openTab(TerminalTabs.NEW_CONNECTION);
break;
case TerminalShortcutKeys.OPEN_COMMAND_SNIPPET:
// 打开命令片段
emits('openCommandSnippet');
break;
case TerminalShortcutKeys.OPEN_PATH_BOOKMARK:
// 打开书签路径
emits('openPathBookmark');
break;
case TerminalShortcutKeys.OPEN_TRANSFER_LIST:
// 打开文件传输列表
emits('openTransferList');
break;
case TerminalShortcutKeys.SCREENSHOT:
// 截图
emits('screenshot');
break;
default:
break;
}

View File

@@ -8,12 +8,6 @@
<icon-actions class="bottom-actions"
:actions="bottomActions"
position="left" />
<!-- 命令片段列表抽屉 -->
<command-snippet-list-drawer ref="snippetRef" />
<!-- 路径书签列表抽屉 -->
<path-bookmark-list-drawer ref="pathRef" />
<!-- 传输列表 -->
<transfer-drawer ref="transferRef" />
</div>
</template>
@@ -24,38 +18,28 @@
</script>
<script lang="ts" setup>
import type { ISshSession, SidebarAction } from '../../types/terminal.type';
import { useTerminalStore } from '@/store';
import { ref } from 'vue';
import { PanelSessionType } from '../../types/terminal.const';
import type { SidebarAction } from '../../types/terminal.type';
import IconActions from './icon-actions.vue';
import CommandSnippetListDrawer from '@/views/host/command-snippet/components/command-snippet-list-drawer.vue';
import PathBookmarkListDrawer from '@/views/host/path-bookmark/components/path-bookmark-list-drawer.vue';
import TransferDrawer from '@/views/host/terminal/components/transfer/transfer-drawer.vue';
const { getCurrentSession } = useTerminalStore();
const snippetRef = ref();
const pathRef = ref();
const transferRef = ref();
const emits = defineEmits(['openCommandSnippet', 'openPathBookmark', 'openTransferList', 'screenshot']);
// 顶部操作
const topActions = [
{
icon: 'icon-code-block',
content: '打开命令片段',
click: () => snippetRef.value.open()
click: () => emits('openCommandSnippet')
}, {
icon: 'icon-bookmark',
content: '打开路径书签',
click: () => pathRef.value.open()
click: () => emits('openPathBookmark')
}, {
icon: 'icon-swap',
content: '文件传输列表',
iconStyle: {
transform: 'rotate(90deg)'
},
click: () => transferRef.value.open()
click: () => emits('openTransferList')
},
];
@@ -64,18 +48,10 @@
{
icon: 'icon-camera',
content: '截图',
click: () => screenshot()
click: () => emits('screenshot')
},
];
// 终端截屏
const screenshot = () => {
const handler = getCurrentSession<ISshSession>(PanelSessionType.SSH.type, true)?.handler;
if (handler && handler.enabledStatus('screenshot')) {
handler.screenshot();
}
};
</script>
<style lang="less" scoped>

View File

@@ -15,13 +15,26 @@
<!-- 主机加载中骨架 -->
<loading-skeleton v-if="contentLoading" />
<!-- 终端内容区域 -->
<main-content v-else />
<main-content v-else
@open-command-snippet="() => snippetRef.open()"
@open-path-bookmark="() => pathRef.open()"
@open-transfer-list="() => transferRef.open()"
@screenshot="screenshot" />
</main>
<!-- 右侧操作栏 -->
<div class="host-terminal-layout-right">
<right-sidebar />
<right-sidebar @open-command-snippet="() => snippetRef.open()"
@open-path-bookmark="() => pathRef.open()"
@open-transfer-list="() => transferRef.open()"
@screenshot="screenshot" />
</div>
</main>
<!-- 命令片段列表抽屉 -->
<command-snippet-list-drawer ref="snippetRef" />
<!-- 路径书签列表抽屉 -->
<path-bookmark-list-drawer ref="pathRef" />
<!-- 传输列表 -->
<transfer-drawer ref="transferRef" />
</div>
</template>
@@ -32,8 +45,9 @@
</script>
<script lang="ts" setup>
import type { ISshSession } from './types/terminal.type';
import { ref, onBeforeMount, onUnmounted, onMounted } from 'vue';
import { dictKeys, TerminalTabs } from './types/terminal.const';
import { dictKeys, PanelSessionType, TerminalTabs } from './types/terminal.const';
import { useCacheStore, useDictStore, useTerminalStore } from '@/store';
import useLoading from '@/hooks/loading';
import debug from '@/utils/env';
@@ -42,6 +56,9 @@
import RightSidebar from './components/layout/right-sidebar.vue';
import MainContent from './components/layout/main-content.vue';
import LoadingSkeleton from './components/layout/loading-skeleton.vue';
import TransferDrawer from '@/views/host/terminal/components/transfer/transfer-drawer.vue';
import CommandSnippetListDrawer from '@/views/host/command-snippet/components/command-snippet-list-drawer.vue';
import PathBookmarkListDrawer from '@/views/host/path-bookmark/components/path-bookmark-list-drawer.vue';
import '@/assets/style/host-terminal-layout.less';
import 'xterm/css/xterm.css';
@@ -52,6 +69,17 @@
const originTitle = document.title;
const render = ref(false);
const snippetRef = ref();
const pathRef = ref();
const transferRef = ref();
// 终端截屏
const screenshot = () => {
const handler = terminalStore.getCurrentSession<ISshSession>(PanelSessionType.SSH.type, true)?.handler;
if (handler && handler.enabledStatus('screenshot')) {
handler.screenshot();
}
};
// 关闭视口处理
const handleBeforeUnload = (event: any) => {

View File

@@ -202,6 +202,14 @@ export const TerminalShortcutKeys = {
CLOSE_TAB: 'closeTab',
// 打开新建连接 tab
OPEN_NEW_CONNECT_TAB: 'openNewConnectTab',
// 打开命令片段
OPEN_COMMAND_SNIPPET: 'openCommandSnippet',
// 打开书签路径
OPEN_PATH_BOOKMARK: 'openPathBookmark',
// 打开文件传输列表
OPEN_TRANSFER_LIST: 'openTransferList',
// 截图
SCREENSHOT: 'screenshot',
// 打开新建连接弹框
OPEN_NEW_CONNECT_MODAL: 'openNewConnectModal',
// 复制会话
@@ -234,6 +242,22 @@ export const TerminalShortcutItems: Array<ShortcutKeyItem> = [
item: TerminalShortcutKeys.OPEN_NEW_CONNECT_TAB,
content: '打开新建连接 tab',
type: TerminalShortcutType.GLOBAL
}, {
item: TerminalShortcutKeys.OPEN_COMMAND_SNIPPET,
content: '打开命令片段',
type: TerminalShortcutType.GLOBAL
}, {
item: TerminalShortcutKeys.OPEN_PATH_BOOKMARK,
content: '打开书签路径',
type: TerminalShortcutType.GLOBAL
}, {
item: TerminalShortcutKeys.OPEN_TRANSFER_LIST,
content: '打开文件传输列表',
type: TerminalShortcutType.GLOBAL
}, {
item: TerminalShortcutKeys.SCREENSHOT,
content: '截图',
type: TerminalShortcutType.GLOBAL
}, {
item: TerminalShortcutKeys.OPEN_NEW_CONNECT_MODAL,
content: '打开新建连接弹框',