✨ 添加终端快捷键.
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
* 🌈 新增 主机终端书签路径
|
* 🌈 新增 主机终端书签路径
|
||||||
* 🌈 新增 命令执行日志添加 `ansi` 日志 `app.exec-log.append-ansi`
|
* 🌈 新增 命令执行日志添加 `ansi` 日志 `app.exec-log.append-ansi`
|
||||||
* 🌈 新增 定时删除命令执行日志文件 `app.exec-log.auto-clear`
|
* 🌈 新增 定时删除命令执行日志文件 `app.exec-log.auto-clear`
|
||||||
|
* 🌈 新增 终端设置添加了几个全局快捷键
|
||||||
* 🔨 优化 通用分组模型添加 `userId`
|
* 🔨 优化 通用分组模型添加 `userId`
|
||||||
* 🔨 优化 退出登录不重定向
|
* 🔨 优化 退出登录不重定向
|
||||||
* 🔨 优化 动态设置页面标题
|
* 🔨 优化 动态设置页面标题
|
||||||
|
|||||||
@@ -22,6 +22,6 @@ public interface AppConst extends OrionConst {
|
|||||||
|
|
||||||
String GITEE = "https://gitee.com/lijiahangmax/orion-ops-pro";
|
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("changeToPrevTab", true, true, true, "BracketLeft", true),
|
||||||
new TerminalPreferenceModel.ShortcutKeysModel("changeToNextTab", true, true, true, "BracketRight", true),
|
new TerminalPreferenceModel.ShortcutKeysModel("changeToNextTab", true, true, true, "BracketRight", true),
|
||||||
new TerminalPreferenceModel.ShortcutKeysModel("openNewConnectTab", true, true, true, "KeyN", 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("openNewConnectModal", true, false, true, "KeyN", true),
|
||||||
new TerminalPreferenceModel.ShortcutKeysModel("copySession", true, false, true, "KeyO", 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.RedisUtils;
|
||||||
import com.orion.ops.framework.redis.core.utils.barrier.CacheBarriers;
|
import com.orion.ops.framework.redis.core.utils.barrier.CacheBarriers;
|
||||||
import com.orion.ops.framework.security.core.utils.SecurityUtils;
|
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.convert.SystemUserConvert;
|
||||||
import com.orion.ops.module.infra.dao.OperatorLogDAO;
|
import com.orion.ops.module.infra.dao.OperatorLogDAO;
|
||||||
import com.orion.ops.module.infra.dao.SystemRoleDAO;
|
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.TipsCacheKeyDefine;
|
||||||
import com.orion.ops.module.infra.define.cache.UserCacheKeyDefine;
|
import com.orion.ops.module.infra.define.cache.UserCacheKeyDefine;
|
||||||
import com.orion.ops.module.infra.define.config.AppAuthenticationConfig;
|
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.domain.SystemUserDO;
|
||||||
import com.orion.ops.module.infra.entity.dto.UserInfoDTO;
|
import com.orion.ops.module.infra.entity.dto.UserInfoDTO;
|
||||||
import com.orion.ops.module.infra.entity.request.user.*;
|
import com.orion.ops.module.infra.entity.request.user.*;
|
||||||
@@ -160,11 +162,15 @@ public class SystemUserServiceImpl implements SystemUserService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SystemUserVO getSystemUserById(Long id) {
|
public SystemUserVO getSystemUserById(Long id) {
|
||||||
// 查询
|
// 查询用户
|
||||||
SystemUserDO record = systemUserDAO.selectById(id);
|
SystemUserDO record = systemUserDAO.selectById(id);
|
||||||
Valid.notNull(record, ErrorMessage.USER_ABSENT);
|
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
|
@Override
|
||||||
|
|||||||
@@ -28,4 +28,11 @@
|
|||||||
AND role_id IN (SELECT id FROM system_role WHERE CODE = #{code} AND deleted = 0) LIMIT 1
|
AND role_id IN (SELECT id FROM system_role WHERE CODE = #{code} AND deleted = 0) LIMIT 1
|
||||||
</select>
|
</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>
|
</mapper>
|
||||||
|
|||||||
@@ -74,7 +74,7 @@
|
|||||||
|
|
||||||
& > .arco-card-header {
|
& > .arco-card-header {
|
||||||
height: auto;
|
height: auto;
|
||||||
padding: 16px;
|
padding: 12px 16px;
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,8 @@
|
|||||||
import TerminalShortcutSetting from '../setting/shortcut/terminal-shortcut-setting.vue';
|
import TerminalShortcutSetting from '../setting/shortcut/terminal-shortcut-setting.vue';
|
||||||
import TerminalPanelsView from '@/views/host/terminal/components/layout/terminal-panels-view.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();
|
const { preference, tabManager, getCurrentSession } = useTerminalStore();
|
||||||
|
|
||||||
// 监听 tab 切换
|
// 监听 tab 切换
|
||||||
@@ -97,6 +99,22 @@
|
|||||||
// 切换到新建连接 tab
|
// 切换到新建连接 tab
|
||||||
tabManager.openTab(TerminalTabs.NEW_CONNECTION);
|
tabManager.openTab(TerminalTabs.NEW_CONNECTION);
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,12 +8,6 @@
|
|||||||
<icon-actions class="bottom-actions"
|
<icon-actions class="bottom-actions"
|
||||||
:actions="bottomActions"
|
:actions="bottomActions"
|
||||||
position="left" />
|
position="left" />
|
||||||
<!-- 命令片段列表抽屉 -->
|
|
||||||
<command-snippet-list-drawer ref="snippetRef" />
|
|
||||||
<!-- 路径书签列表抽屉 -->
|
|
||||||
<path-bookmark-list-drawer ref="pathRef" />
|
|
||||||
<!-- 传输列表 -->
|
|
||||||
<transfer-drawer ref="transferRef" />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -24,38 +18,28 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { ISshSession, SidebarAction } from '../../types/terminal.type';
|
import type { SidebarAction } from '../../types/terminal.type';
|
||||||
import { useTerminalStore } from '@/store';
|
|
||||||
import { ref } from 'vue';
|
|
||||||
import { PanelSessionType } from '../../types/terminal.const';
|
|
||||||
import IconActions from './icon-actions.vue';
|
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 emits = defineEmits(['openCommandSnippet', 'openPathBookmark', 'openTransferList', 'screenshot']);
|
||||||
|
|
||||||
const snippetRef = ref();
|
|
||||||
const pathRef = ref();
|
|
||||||
const transferRef = ref();
|
|
||||||
|
|
||||||
// 顶部操作
|
// 顶部操作
|
||||||
const topActions = [
|
const topActions = [
|
||||||
{
|
{
|
||||||
icon: 'icon-code-block',
|
icon: 'icon-code-block',
|
||||||
content: '打开命令片段',
|
content: '打开命令片段',
|
||||||
click: () => snippetRef.value.open()
|
click: () => emits('openCommandSnippet')
|
||||||
}, {
|
}, {
|
||||||
icon: 'icon-bookmark',
|
icon: 'icon-bookmark',
|
||||||
content: '打开路径书签',
|
content: '打开路径书签',
|
||||||
click: () => pathRef.value.open()
|
click: () => emits('openPathBookmark')
|
||||||
}, {
|
}, {
|
||||||
icon: 'icon-swap',
|
icon: 'icon-swap',
|
||||||
content: '文件传输列表',
|
content: '文件传输列表',
|
||||||
iconStyle: {
|
iconStyle: {
|
||||||
transform: 'rotate(90deg)'
|
transform: 'rotate(90deg)'
|
||||||
},
|
},
|
||||||
click: () => transferRef.value.open()
|
click: () => emits('openTransferList')
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -64,18 +48,10 @@
|
|||||||
{
|
{
|
||||||
icon: 'icon-camera',
|
icon: 'icon-camera',
|
||||||
content: '截图',
|
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>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|||||||
@@ -15,13 +15,26 @@
|
|||||||
<!-- 主机加载中骨架 -->
|
<!-- 主机加载中骨架 -->
|
||||||
<loading-skeleton v-if="contentLoading" />
|
<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>
|
</main>
|
||||||
<!-- 右侧操作栏 -->
|
<!-- 右侧操作栏 -->
|
||||||
<div class="host-terminal-layout-right">
|
<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>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
<!-- 命令片段列表抽屉 -->
|
||||||
|
<command-snippet-list-drawer ref="snippetRef" />
|
||||||
|
<!-- 路径书签列表抽屉 -->
|
||||||
|
<path-bookmark-list-drawer ref="pathRef" />
|
||||||
|
<!-- 传输列表 -->
|
||||||
|
<transfer-drawer ref="transferRef" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -32,8 +45,9 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import type { ISshSession } from './types/terminal.type';
|
||||||
import { ref, onBeforeMount, onUnmounted, onMounted } from 'vue';
|
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 { useCacheStore, useDictStore, useTerminalStore } from '@/store';
|
||||||
import useLoading from '@/hooks/loading';
|
import useLoading from '@/hooks/loading';
|
||||||
import debug from '@/utils/env';
|
import debug from '@/utils/env';
|
||||||
@@ -42,6 +56,9 @@
|
|||||||
import RightSidebar from './components/layout/right-sidebar.vue';
|
import RightSidebar from './components/layout/right-sidebar.vue';
|
||||||
import MainContent from './components/layout/main-content.vue';
|
import MainContent from './components/layout/main-content.vue';
|
||||||
import LoadingSkeleton from './components/layout/loading-skeleton.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 '@/assets/style/host-terminal-layout.less';
|
||||||
import 'xterm/css/xterm.css';
|
import 'xterm/css/xterm.css';
|
||||||
|
|
||||||
@@ -52,6 +69,17 @@
|
|||||||
|
|
||||||
const originTitle = document.title;
|
const originTitle = document.title;
|
||||||
const render = ref(false);
|
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) => {
|
const handleBeforeUnload = (event: any) => {
|
||||||
|
|||||||
@@ -202,6 +202,14 @@ export const TerminalShortcutKeys = {
|
|||||||
CLOSE_TAB: 'closeTab',
|
CLOSE_TAB: 'closeTab',
|
||||||
// 打开新建连接 tab
|
// 打开新建连接 tab
|
||||||
OPEN_NEW_CONNECT_TAB: 'openNewConnectTab',
|
OPEN_NEW_CONNECT_TAB: 'openNewConnectTab',
|
||||||
|
// 打开命令片段
|
||||||
|
OPEN_COMMAND_SNIPPET: 'openCommandSnippet',
|
||||||
|
// 打开书签路径
|
||||||
|
OPEN_PATH_BOOKMARK: 'openPathBookmark',
|
||||||
|
// 打开文件传输列表
|
||||||
|
OPEN_TRANSFER_LIST: 'openTransferList',
|
||||||
|
// 截图
|
||||||
|
SCREENSHOT: 'screenshot',
|
||||||
// 打开新建连接弹框
|
// 打开新建连接弹框
|
||||||
OPEN_NEW_CONNECT_MODAL: 'openNewConnectModal',
|
OPEN_NEW_CONNECT_MODAL: 'openNewConnectModal',
|
||||||
// 复制会话
|
// 复制会话
|
||||||
@@ -234,6 +242,22 @@ export const TerminalShortcutItems: Array<ShortcutKeyItem> = [
|
|||||||
item: TerminalShortcutKeys.OPEN_NEW_CONNECT_TAB,
|
item: TerminalShortcutKeys.OPEN_NEW_CONNECT_TAB,
|
||||||
content: '打开新建连接 tab',
|
content: '打开新建连接 tab',
|
||||||
type: TerminalShortcutType.GLOBAL
|
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,
|
item: TerminalShortcutKeys.OPEN_NEW_CONNECT_MODAL,
|
||||||
content: '打开新建连接弹框',
|
content: '打开新建连接弹框',
|
||||||
|
|||||||
Reference in New Issue
Block a user