✨ 添加终端快捷键.
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
* 🌈 新增 主机终端书签路径
|
||||
* 🌈 新增 命令执行日志添加 `ansi` 日志 `app.exec-log.append-ansi`
|
||||
* 🌈 新增 定时删除命令执行日志文件 `app.exec-log.auto-clear`
|
||||
* 🌈 新增 终端设置添加了几个全局快捷键
|
||||
* 🔨 优化 通用分组模型添加 `userId`
|
||||
* 🔨 优化 退出登录不重定向
|
||||
* 🔨 优化 动态设置页面标题
|
||||
|
||||
@@ -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";
|
||||
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
|
||||
& > .arco-card-header {
|
||||
height: auto;
|
||||
padding: 16px;
|
||||
padding: 12px 16px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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: '打开新建连接弹框',
|
||||
|
||||
Reference in New Issue
Block a user