🔨 添加个性化配置.
This commit is contained in:
@@ -89,7 +89,6 @@ public class GuacdTunnel implements IGuacdTunnel {
|
|||||||
@Override
|
@Override
|
||||||
public void connect() throws GuacdException {
|
public void connect() throws GuacdException {
|
||||||
try {
|
try {
|
||||||
// TODO 端口转发
|
|
||||||
this.socket = new ConfiguredGuacamoleSocket(new InetGuacamoleSocket(serverAddress, serverPort), serverConfig, clientConfig);
|
this.socket = new ConfiguredGuacamoleSocket(new InetGuacamoleSocket(serverAddress, serverPort), serverConfig, clientConfig);
|
||||||
this.tunnel = new CustomGuacamoleTunnel(uuid, socket);
|
this.tunnel = new CustomGuacamoleTunnel(uuid, socket);
|
||||||
} catch (GuacamoleException e) {
|
} catch (GuacamoleException e) {
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
<terminal-ssh-action-bar-block />
|
<terminal-ssh-action-bar-block />
|
||||||
<!-- RDP 工具栏 -->
|
<!-- RDP 工具栏 -->
|
||||||
<terminal-rdp-action-bar-block />
|
<terminal-rdp-action-bar-block />
|
||||||
|
<!-- VNC 工具栏 -->
|
||||||
|
<terminal-vnc-action-bar-block />
|
||||||
<!-- SSH 右键菜单 -->
|
<!-- SSH 右键菜单 -->
|
||||||
<terminal-ssh-right-menu-block />
|
<terminal-ssh-right-menu-block />
|
||||||
</div>
|
</div>
|
||||||
@@ -26,6 +28,7 @@
|
|||||||
import TerminalSshActionBarBlock from './terminal-ssh-action-bar-block.vue';
|
import TerminalSshActionBarBlock from './terminal-ssh-action-bar-block.vue';
|
||||||
import TerminalSshRightMenuBlock from './terminal-ssh-right-menu-block.vue';
|
import TerminalSshRightMenuBlock from './terminal-ssh-right-menu-block.vue';
|
||||||
import TerminalRdpActionBarBlock from './terminal-rdp-action-bar-block.vue';
|
import TerminalRdpActionBarBlock from './terminal-rdp-action-bar-block.vue';
|
||||||
|
import TerminalVncActionBarBlock from './terminal-vnc-action-bar-block.vue';
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -12,12 +12,6 @@
|
|||||||
:model="formModel"
|
:model="formModel"
|
||||||
layout="vertical">
|
layout="vertical">
|
||||||
<a-space size="large">
|
<a-space size="large">
|
||||||
<!-- 工具栏按钮 -->
|
|
||||||
<a-form-item field="actions" label="工具栏按钮">
|
|
||||||
<icon-actions class="form-item-actions"
|
|
||||||
:actions="actions"
|
|
||||||
position="bottom" />
|
|
||||||
</a-form-item>
|
|
||||||
<!-- 工具栏方向 -->
|
<!-- 工具栏方向 -->
|
||||||
<a-form-item field="position" label="工具栏方向">
|
<a-form-item field="position" label="工具栏方向">
|
||||||
<a-select v-model="formModel.position"
|
<a-select v-model="formModel.position"
|
||||||
@@ -25,6 +19,12 @@
|
|||||||
placeholder="请选择工具栏方向"
|
placeholder="请选择工具栏方向"
|
||||||
:options="toOptions(graphActionBarPositionKey)" />
|
:options="toOptions(graphActionBarPositionKey)" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<!-- 工具栏按钮 -->
|
||||||
|
<a-form-item field="actions" label="工具栏按钮">
|
||||||
|
<icon-actions class="form-item-actions"
|
||||||
|
:actions="actions"
|
||||||
|
position="bottom" />
|
||||||
|
</a-form-item>
|
||||||
</a-space>
|
</a-space>
|
||||||
</a-form>
|
</a-form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
<template>
|
||||||
|
<div class="terminal-setting-block">
|
||||||
|
<!-- 顶部 -->
|
||||||
|
<div class="terminal-setting-subtitle-wrapper">
|
||||||
|
<h3 class="terminal-setting-subtitle">
|
||||||
|
VNC 工具栏设置
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<!-- 内容区域 -->
|
||||||
|
<div class="terminal-setting-body block-body setting-body">
|
||||||
|
<a-form class="terminal-setting-form"
|
||||||
|
:model="formModel"
|
||||||
|
layout="vertical">
|
||||||
|
<a-space size="large">
|
||||||
|
<!-- 工具栏方向 -->
|
||||||
|
<a-form-item field="position" label="工具栏方向">
|
||||||
|
<a-select v-model="formModel.position"
|
||||||
|
style="width: 148px;"
|
||||||
|
placeholder="请选择工具栏方向"
|
||||||
|
:options="toOptions(graphActionBarPositionKey)" />
|
||||||
|
</a-form-item>
|
||||||
|
<!-- 工具栏按钮 -->
|
||||||
|
<a-form-item field="actions" label="工具栏按钮">
|
||||||
|
<icon-actions class="form-item-actions"
|
||||||
|
:actions="actions"
|
||||||
|
position="bottom" />
|
||||||
|
</a-form-item>
|
||||||
|
</a-space>
|
||||||
|
</a-form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'terminalVncActionBarBlock'
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { TerminalVncActionBarSetting } from '@/store/modules/terminal/types';
|
||||||
|
import type { SidebarAction } from '@/views/terminal/types/define';
|
||||||
|
import { computed, ref, watch } from 'vue';
|
||||||
|
import { useTerminalStore, useDictStore } from '@/store';
|
||||||
|
import { TerminalPreferenceItem } from '@/store/modules/terminal';
|
||||||
|
import { VncActionBarItems, graphActionBarPositionKey } from '@/views/terminal/types/const';
|
||||||
|
import IconActions from '../../layout/icon-actions.vue';
|
||||||
|
|
||||||
|
const { toOptions } = useDictStore();
|
||||||
|
const { preference, updateTerminalPreference } = useTerminalStore();
|
||||||
|
|
||||||
|
const formModel = ref<TerminalVncActionBarSetting>({ ...preference.vncActionBarSetting });
|
||||||
|
|
||||||
|
// 监听同步
|
||||||
|
watch(formModel, (v) => {
|
||||||
|
if (!v) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 同步
|
||||||
|
updateTerminalPreference(TerminalPreferenceItem.VNC_ACTION_BAR_SETTING, formModel.value, true);
|
||||||
|
}, { deep: true });
|
||||||
|
|
||||||
|
// 操作项
|
||||||
|
const actions = computed<Array<SidebarAction>>(() => {
|
||||||
|
return VncActionBarItems.map(s => {
|
||||||
|
return {
|
||||||
|
icon: s.icon,
|
||||||
|
content: (formModel.value[s.item] === false ? '显示 ' : '隐藏 ') + s.content,
|
||||||
|
checked: formModel.value[s.item] !== false,
|
||||||
|
click: () => {
|
||||||
|
formModel.value[s.item] = formModel.value[s.item] === false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.form-item-actions {
|
||||||
|
display: flex;
|
||||||
|
background-color: var(--color-fill-2);
|
||||||
|
padding: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
:deep(.terminal-sidebar-icon-wrapper) {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.terminal-sidebar-icon) {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item-actions {
|
||||||
|
margin-right: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.arco-form) {
|
||||||
|
.arco-form-item-label {
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-form-item {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -14,7 +14,9 @@
|
|||||||
:cancel-button-props="{ disabled: loading }"
|
:cancel-button-props="{ disabled: loading }"
|
||||||
:on-before-ok="handlerOk"
|
:on-before-ok="handlerOk"
|
||||||
@close="handleClose">
|
@close="handleClose">
|
||||||
<a-spin class="full" :loading="loading">
|
<a-spin v-if="hostId"
|
||||||
|
class="full"
|
||||||
|
:loading="loading">
|
||||||
<a-tabs v-model:active-key="activeItem"
|
<a-tabs v-model:active-key="activeItem"
|
||||||
position="left"
|
position="left"
|
||||||
type="rounded"
|
type="rounded"
|
||||||
@@ -22,7 +24,7 @@
|
|||||||
<!-- 标签配置 -->
|
<!-- 标签配置 -->
|
||||||
<a-tab-pane :key="ExtraSettingItems.LABEL" title="标签配置">
|
<a-tab-pane :key="ExtraSettingItems.LABEL" title="标签配置">
|
||||||
<label-extra-form ref="labelForm"
|
<label-extra-form ref="labelForm"
|
||||||
:host-id="hostId as number"
|
:host-id="hostId"
|
||||||
:item="ExtraSettingItems.LABEL" />
|
:item="ExtraSettingItems.LABEL" />
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<!-- SSH 配置 -->
|
<!-- SSH 配置 -->
|
||||||
@@ -30,7 +32,7 @@
|
|||||||
:key="ExtraSettingItems.SSH"
|
:key="ExtraSettingItems.SSH"
|
||||||
title="SSH 配置">
|
title="SSH 配置">
|
||||||
<ssh-extra-form ref="sshForm"
|
<ssh-extra-form ref="sshForm"
|
||||||
:host-id="hostId as number"
|
:host-id="hostId"
|
||||||
:item="ExtraSettingItems.SSH" />
|
:item="ExtraSettingItems.SSH" />
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<!-- RDP 配置 -->
|
<!-- RDP 配置 -->
|
||||||
@@ -38,9 +40,17 @@
|
|||||||
:key="ExtraSettingItems.RDP"
|
:key="ExtraSettingItems.RDP"
|
||||||
title="RDP 配置">
|
title="RDP 配置">
|
||||||
<rdp-extra-form ref="rdpForm"
|
<rdp-extra-form ref="rdpForm"
|
||||||
:host-id="hostId as number"
|
:host-id="hostId"
|
||||||
:item="ExtraSettingItems.RDP" />
|
:item="ExtraSettingItems.RDP" />
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
|
<!-- VNC 配置 -->
|
||||||
|
<a-tab-pane v-if="host?.types.includes(HostType.VNC.value)"
|
||||||
|
:key="ExtraSettingItems.VNC"
|
||||||
|
title="VNC 配置">
|
||||||
|
<vnc-extra-form ref="vncForm"
|
||||||
|
:host-id="hostId"
|
||||||
|
:item="ExtraSettingItems.VNC" />
|
||||||
|
</a-tab-pane>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
</a-spin>
|
</a-spin>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
@@ -64,6 +74,7 @@
|
|||||||
import LabelExtraForm from './label-extra-form.vue';
|
import LabelExtraForm from './label-extra-form.vue';
|
||||||
import SshExtraForm from './ssh-extra-form.vue';
|
import SshExtraForm from './ssh-extra-form.vue';
|
||||||
import RdpExtraForm from './rdp-extra-form.vue';
|
import RdpExtraForm from './rdp-extra-form.vue';
|
||||||
|
import VncExtraForm from './vnc-extra-form.vue';
|
||||||
|
|
||||||
const { visible, setVisible } = useVisible();
|
const { visible, setVisible } = useVisible();
|
||||||
const { loading, setLoading } = useLoading();
|
const { loading, setLoading } = useLoading();
|
||||||
@@ -75,6 +86,7 @@
|
|||||||
const labelForm = ref();
|
const labelForm = ref();
|
||||||
const sshForm = ref();
|
const sshForm = ref();
|
||||||
const rdpForm = ref();
|
const rdpForm = ref();
|
||||||
|
const vncForm = ref();
|
||||||
|
|
||||||
// 打开配置
|
// 打开配置
|
||||||
const open = (record: HostQueryResponse) => {
|
const open = (record: HostQueryResponse) => {
|
||||||
@@ -101,6 +113,9 @@
|
|||||||
} else if (activeItem.value === ExtraSettingItems.RDP) {
|
} else if (activeItem.value === ExtraSettingItems.RDP) {
|
||||||
// RDP 配置
|
// RDP 配置
|
||||||
value = await rdpForm.value.getValue();
|
value = await rdpForm.value.getValue();
|
||||||
|
} else if (activeItem.value === ExtraSettingItems.VNC) {
|
||||||
|
// VNC 配置
|
||||||
|
value = await vncForm.value.getValue();
|
||||||
}
|
}
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
<template>
|
||||||
|
<a-form :model="formModel"
|
||||||
|
ref="formRef"
|
||||||
|
label-align="right"
|
||||||
|
:label-col-props="{ span: 5 }"
|
||||||
|
:wrapper-col-props="{ span: 18 }">
|
||||||
|
<!-- 自定义端口 -->
|
||||||
|
<a-form-item field="port"
|
||||||
|
label="自定义端口"
|
||||||
|
style="margin-bottom: 8px;"
|
||||||
|
help="通常情况下端口号为 5900 + N(屏幕)"
|
||||||
|
:rules="{ min: 1, max: 65535, message: '输入的端口不合法' }">
|
||||||
|
<a-input-number v-model="formModel.port"
|
||||||
|
placeholder="VNC 自定义端口"
|
||||||
|
allow-clear />
|
||||||
|
</a-form-item>
|
||||||
|
<!-- 低带宽模式 -->
|
||||||
|
<a-form-item field="lowBandwidthMode"
|
||||||
|
label="低带宽模式"
|
||||||
|
help="调整图形化配置以及禁用音频, 提升慢速网络下的响应速度">
|
||||||
|
<a-switch v-model="formModel.lowBandwidthMode" type="round" />
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'vncExtraForm'
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { HostVncExtraSettingModel } from '@/api/asset/host-extra';
|
||||||
|
import { onMounted, ref } from 'vue';
|
||||||
|
import { getHostExtraItem } from '@/api/asset/host-extra';
|
||||||
|
import { useDictStore } from '@/store';
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
hostId: number;
|
||||||
|
item: string;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const { toRadioOptions } = useDictStore();
|
||||||
|
|
||||||
|
const formRef = ref();
|
||||||
|
const formModel = ref<Partial<HostVncExtraSettingModel>>({});
|
||||||
|
|
||||||
|
// 渲染表单
|
||||||
|
const renderForm = async () => {
|
||||||
|
const { data } = await getHostExtraItem<HostVncExtraSettingModel>({ hostId: props.hostId, item: props.item });
|
||||||
|
formModel.value = data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取值
|
||||||
|
const getValue = async () => {
|
||||||
|
// 验证参数
|
||||||
|
const error = await formRef.value.validate();
|
||||||
|
if (error) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return JSON.stringify(formModel.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({ getValue });
|
||||||
|
|
||||||
|
onMounted(renderForm);
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -11,6 +11,8 @@
|
|||||||
<terminal-rdp-graph-block />
|
<terminal-rdp-graph-block />
|
||||||
<!-- RDP 会话设置 -->
|
<!-- RDP 会话设置 -->
|
||||||
<terminal-rdp-session-block />
|
<terminal-rdp-session-block />
|
||||||
|
<!-- VNC 图形化设置 -->
|
||||||
|
<terminal-vnc-graph-block />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -26,6 +28,7 @@
|
|||||||
import TerminalSshPluginsBlock from './terminal-ssh-plugins-block.vue';
|
import TerminalSshPluginsBlock from './terminal-ssh-plugins-block.vue';
|
||||||
import TerminalRdpGraphBlock from './terminal-rdp-graph-block.vue';
|
import TerminalRdpGraphBlock from './terminal-rdp-graph-block.vue';
|
||||||
import TerminalRdpSessionBlock from './terminal-rdp-session-block.vue';
|
import TerminalRdpSessionBlock from './terminal-rdp-session-block.vue';
|
||||||
|
import TerminalVncGraphBlock from './terminal-vnc-graph-block.vue';
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
<!-- 显示分辨率 -->
|
<!-- 显示分辨率 -->
|
||||||
<block-setting-item label="显示分辨率" desc="若选择为自适应, 则会根据窗口大小自动调整">
|
<block-setting-item label="显示分辨率" desc="若选择为自适应, 则会根据窗口大小自动调整">
|
||||||
<a-select v-model="formModel.displaySize"
|
<a-select v-model="formModel.displaySize"
|
||||||
style="width: 198px;"
|
style="width: 168px;"
|
||||||
size="small"
|
size="small"
|
||||||
:options="toOptions(screenResolutionKey)"
|
:options="toOptions(screenResolutionKey)"
|
||||||
allow-create />
|
allow-create />
|
||||||
@@ -22,14 +22,14 @@
|
|||||||
<!-- 颜色深度 -->
|
<!-- 颜色深度 -->
|
||||||
<block-setting-item label="颜色深度" desc="显示的颜色深度, 越高显示效果越好">
|
<block-setting-item label="颜色深度" desc="显示的颜色深度, 越高显示效果越好">
|
||||||
<a-select v-model="formModel.colorDepth"
|
<a-select v-model="formModel.colorDepth"
|
||||||
style="width: 198px;"
|
style="width: 168px;"
|
||||||
size="small"
|
size="small"
|
||||||
:options="toOptions(graphColorDepthKey)" />
|
:options="toOptions(graphColorDepthKey)" />
|
||||||
</block-setting-item>
|
</block-setting-item>
|
||||||
</a-row>
|
</a-row>
|
||||||
<a-row class="mb16" align="stretch" :gutter="16">
|
<a-row class="mb16" align="stretch" :gutter="16">
|
||||||
<!-- 无损压缩 -->
|
<!-- 无损压缩 -->
|
||||||
<block-setting-item label="无损压缩" desc="是否启用对图形更新的无损压缩">
|
<block-setting-item label="无损压缩" desc="是否启用对图像更新的无损压缩">
|
||||||
<a-switch v-model="formModel.forceLossless" type="round" />
|
<a-switch v-model="formModel.forceLossless" type="round" />
|
||||||
</block-setting-item>
|
</block-setting-item>
|
||||||
<!-- 启用壁纸 -->
|
<!-- 启用壁纸 -->
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
</a-row>
|
</a-row>
|
||||||
<a-row class="mb16" align="stretch" :gutter="16">
|
<a-row class="mb16" align="stretch" :gutter="16">
|
||||||
<!-- 禁用图形加速 -->
|
<!-- 禁用图形加速 -->
|
||||||
<block-setting-item label="禁用图形加速" desc="禁用后将不再使用 GFX 进行数据编码">
|
<block-setting-item label="禁用图像加速" desc="禁用后将不再使用 GFX 进行数据编码">
|
||||||
<a-switch v-model="formModel.disableGfx" type="round" />
|
<a-switch v-model="formModel.disableGfx" type="round" />
|
||||||
</block-setting-item>
|
</block-setting-item>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
<!-- 驱动挂载模式 -->
|
<!-- 驱动挂载模式 -->
|
||||||
<block-setting-item label="驱动挂载模式">
|
<block-setting-item label="驱动挂载模式">
|
||||||
<a-select v-model="formModel.driveMountMode"
|
<a-select v-model="formModel.driveMountMode"
|
||||||
style="width: 198px;"
|
style="width: 168px;"
|
||||||
size="small"
|
size="small"
|
||||||
:options="toOptions(driveMountModeKey)" />
|
:options="toOptions(driveMountModeKey)" />
|
||||||
<template #desc>
|
<template #desc>
|
||||||
|
|||||||
@@ -67,7 +67,7 @@
|
|||||||
<block-setting-item label="单词分隔符" desc="在终端中双击文本将使用该分隔符进行分割 (一般不用修改)">
|
<block-setting-item label="单词分隔符" desc="在终端中双击文本将使用该分隔符进行分割 (一般不用修改)">
|
||||||
<a-input v-model="formModel.wordSeparator"
|
<a-input v-model="formModel.wordSeparator"
|
||||||
size="small"
|
size="small"
|
||||||
style="width: 198px"
|
style="width: 168px"
|
||||||
placeholder="单词分隔符"
|
placeholder="单词分隔符"
|
||||||
allow-clear />
|
allow-clear />
|
||||||
</block-setting-item>
|
</block-setting-item>
|
||||||
@@ -76,14 +76,14 @@
|
|||||||
<!-- 终端类型 -->
|
<!-- 终端类型 -->
|
||||||
<block-setting-item label="终端类型" desc="若显示异常请尝试切换此选项 兼容性 vt100 > xterm > 16color > 256color">
|
<block-setting-item label="终端类型" desc="若显示异常请尝试切换此选项 兼容性 vt100 > xterm > 16color > 256color">
|
||||||
<a-select v-model="formModel.terminalEmulationType"
|
<a-select v-model="formModel.terminalEmulationType"
|
||||||
style="width: 198px;"
|
style="width: 168px;"
|
||||||
size="small"
|
size="small"
|
||||||
:options="toOptions(emulationTypeKey)" />
|
:options="toOptions(emulationTypeKey)" />
|
||||||
</block-setting-item>
|
</block-setting-item>
|
||||||
<!-- 缓冲区行数 -->
|
<!-- 缓冲区行数 -->
|
||||||
<block-setting-item label="缓冲区行数" desc="保存在缓冲区的行数, 多出的行数会被忽略, 此值越大占用内存的内存会更多">
|
<block-setting-item label="缓冲区行数" desc="保存在缓冲区的行数, 多出的行数会被忽略, 此值越大占用内存的内存会更多">
|
||||||
<a-input-number v-model="formModel.scrollBackLine"
|
<a-input-number v-model="formModel.scrollBackLine"
|
||||||
style="width: 198px"
|
style="width: 168px"
|
||||||
size="small"
|
size="small"
|
||||||
:min="1"
|
:min="1"
|
||||||
:max="100000"
|
:max="100000"
|
||||||
@@ -92,6 +92,12 @@
|
|||||||
hide-button />
|
hide-button />
|
||||||
</block-setting-item>
|
</block-setting-item>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
<a-row class="mb16" align="stretch" :gutter="16">
|
||||||
|
<!-- 替换退格符 -->
|
||||||
|
<block-setting-item label="替换退格符" desc="开启后会将退格符 (Backspace) 替换为 (Ctrl+H)">
|
||||||
|
<a-switch v-model="formModel.replaceBackspace" type="round" />
|
||||||
|
</block-setting-item>
|
||||||
|
</a-row>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -0,0 +1,133 @@
|
|||||||
|
<template>
|
||||||
|
<div class="terminal-setting-block">
|
||||||
|
<!-- 顶部 -->
|
||||||
|
<div class="terminal-setting-subtitle-wrapper">
|
||||||
|
<h3 class="terminal-setting-subtitle">
|
||||||
|
VNC 图形化设置
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<!-- 提示 -->
|
||||||
|
<a-alert class="mb16">修改后会立刻保存, 重新打开终端后生效. 配置调整后可能会占用更多的带宽, 若发生卡顿/无法加载请调整配置</a-alert>
|
||||||
|
<!-- 内容区域 -->
|
||||||
|
<div class="terminal-setting-body setting-body">
|
||||||
|
<a-row class="mb16" align="stretch" :gutter="16">
|
||||||
|
<!-- 显示分辨率 -->
|
||||||
|
<block-setting-item label="显示分辨率" desc="若选择为自适应, 则会根据窗口大小自动调整">
|
||||||
|
<a-select v-model="formModel.displaySize"
|
||||||
|
style="width: 168px;"
|
||||||
|
size="small"
|
||||||
|
:options="toOptions(screenResolutionKey)"
|
||||||
|
allow-create />
|
||||||
|
</block-setting-item>
|
||||||
|
<!-- 颜色深度 -->
|
||||||
|
<block-setting-item label="颜色深度" desc="显示的颜色深度, 越高显示效果越好">
|
||||||
|
<a-select v-model="formModel.colorDepth"
|
||||||
|
style="width: 168px;"
|
||||||
|
size="small"
|
||||||
|
:options="toOptions(graphColorDepthKey)" />
|
||||||
|
</block-setting-item>
|
||||||
|
</a-row>
|
||||||
|
<a-row class="mb16" align="stretch" :gutter="16">
|
||||||
|
<!-- 无损压缩 -->
|
||||||
|
<block-setting-item label="无损压缩" desc="是否启用对图像更新的无损压缩">
|
||||||
|
<a-switch v-model="formModel.forceLossless" type="round" />
|
||||||
|
</block-setting-item>
|
||||||
|
<!-- 交换红蓝 -->
|
||||||
|
<block-setting-item label="交换红蓝" desc="若显示的颜色出现错误(蓝色显示为橙色或红色等) 则需要启用此选项">
|
||||||
|
<a-switch v-model="formModel.swapRedBlue" type="round" />
|
||||||
|
</block-setting-item>
|
||||||
|
</a-row>
|
||||||
|
<a-row class="mb16" align="stretch" :gutter="16">
|
||||||
|
<!-- 压缩等级 -->
|
||||||
|
<block-setting-item label="压缩等级" desc="设置服务器请求的压缩级别 0表示不压缩, 9表示最高压缩级别">
|
||||||
|
<a-input-number v-model="formModel.compressLevel"
|
||||||
|
style="width: 168px;"
|
||||||
|
size="small"
|
||||||
|
mode="button"
|
||||||
|
:min="0"
|
||||||
|
:max="9"
|
||||||
|
placeholder="图像压缩等级 0 ~ 9" />
|
||||||
|
</block-setting-item>
|
||||||
|
<!-- 质量等级 -->
|
||||||
|
<block-setting-item label="质量等级" desc="设置图像的质量等级 0表示最低的图像质量, 9表示最高的图像质量">
|
||||||
|
<a-input-number v-model="formModel.qualityLevel"
|
||||||
|
style="width: 168px;"
|
||||||
|
size="small"
|
||||||
|
mode="button"
|
||||||
|
:min="0"
|
||||||
|
:max="9"
|
||||||
|
placeholder="图像质量等级 0 ~ 9" />
|
||||||
|
</block-setting-item>
|
||||||
|
</a-row>
|
||||||
|
<a-row class="mb16" align="stretch" :gutter="16">
|
||||||
|
<!-- 光标 -->
|
||||||
|
<block-setting-item label="光标" desc="光标渲染方式, 远程光标会比本地光标慢">
|
||||||
|
<a-select v-model="formModel.cursor"
|
||||||
|
style="width: 168px;"
|
||||||
|
size="small"
|
||||||
|
:options="toOptions(vcnCursorKey)" />
|
||||||
|
</block-setting-item>
|
||||||
|
</a-row>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'terminalVncGraphBlock'
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { TerminalVncGraphSetting } from '@/store/modules/terminal/types';
|
||||||
|
import { ref, watch } from 'vue';
|
||||||
|
import { useTerminalStore, useDictStore } from '@/store';
|
||||||
|
import { TerminalPreferenceItem } from '@/store/modules/terminal';
|
||||||
|
import { graphColorDepthKey, vcnCursorKey, fitDisplayValue, screenResolutionKey } from '@/views/terminal/types/const';
|
||||||
|
import { getDisplaySize } from '@/views/terminal/types/utils';
|
||||||
|
import BlockSettingItem from '../block-setting-item.vue';
|
||||||
|
|
||||||
|
const { toOptions, getDictValue } = useDictStore();
|
||||||
|
const { preference, updateTerminalPreference } = useTerminalStore();
|
||||||
|
|
||||||
|
const formModel = ref<TerminalVncGraphSetting>({ ...preference.vncGraphSetting });
|
||||||
|
|
||||||
|
// 监听内容变化
|
||||||
|
watch(formModel, (v) => {
|
||||||
|
if (!v) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 同步大小
|
||||||
|
if (v.displaySize) {
|
||||||
|
// 自适应大小
|
||||||
|
if (v.displaySize === fitDisplayValue) {
|
||||||
|
v.displayWidth = 0;
|
||||||
|
v.displayHeight = 0;
|
||||||
|
} else {
|
||||||
|
// 解析大小
|
||||||
|
try {
|
||||||
|
const [width, height] = getDisplaySize(v.displaySize, true);
|
||||||
|
v.displayWidth = width;
|
||||||
|
v.displayHeight = height;
|
||||||
|
} catch (e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 同步
|
||||||
|
updateTerminalPreference(TerminalPreferenceItem.VNC_GRAPH_SETTING, formModel.value, true);
|
||||||
|
}, { deep: true });
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.setting-body {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.arco-input-number) {
|
||||||
|
input {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -44,18 +44,31 @@ export const TerminalTabs = {
|
|||||||
export const TerminalSessionTypes = {
|
export const TerminalSessionTypes = {
|
||||||
SSH: {
|
SSH: {
|
||||||
type: 'SSH',
|
type: 'SSH',
|
||||||
|
protocol: 'SSH',
|
||||||
channel: 'ssh',
|
channel: 'ssh',
|
||||||
icon: 'icon-desktop'
|
icon: 'icon-desktop',
|
||||||
|
connectIcon: 'icon-thunderbolt',
|
||||||
},
|
},
|
||||||
SFTP: {
|
SFTP: {
|
||||||
type: 'SFTP',
|
type: 'SFTP',
|
||||||
|
protocol: 'SSH',
|
||||||
channel: 'sftp',
|
channel: 'sftp',
|
||||||
icon: 'icon-folder'
|
icon: 'icon-folder',
|
||||||
|
connectIcon: 'icon-folder',
|
||||||
},
|
},
|
||||||
RDP: {
|
RDP: {
|
||||||
type: 'RDP',
|
type: 'RDP',
|
||||||
|
protocol: 'RDP',
|
||||||
channel: 'rdp',
|
channel: 'rdp',
|
||||||
icon: 'icon-computer'
|
icon: 'icon-desktop',
|
||||||
|
connectIcon: 'icon-desktop',
|
||||||
|
},
|
||||||
|
VNC: {
|
||||||
|
type: 'VNC',
|
||||||
|
protocol: 'VNC',
|
||||||
|
channel: 'vnc',
|
||||||
|
icon: 'icon-computer',
|
||||||
|
connectIcon: 'icon-computer',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -72,6 +85,7 @@ export const ExtraSettingItems = {
|
|||||||
LABEL: 'LABEL',
|
LABEL: 'LABEL',
|
||||||
SSH: 'SSH',
|
SSH: 'SSH',
|
||||||
RDP: 'RDP',
|
RDP: 'RDP',
|
||||||
|
VNC: 'VNC',
|
||||||
};
|
};
|
||||||
|
|
||||||
// 主机额外配置认证方式
|
// 主机额外配置认证方式
|
||||||
@@ -97,7 +111,7 @@ export const TerminalMessages = {
|
|||||||
sessionClosed: '会话已结束...',
|
sessionClosed: '会话已结束...',
|
||||||
waitingReconnect: '输入回车重新连接...',
|
waitingReconnect: '输入回车重新连接...',
|
||||||
loggedElsewhere: '该账号已在另一台设备登录',
|
loggedElsewhere: '该账号已在另一台设备登录',
|
||||||
rdpConnectTimeout: '请检查远程计算机网络及其他配置是否正常',
|
connectTimeout: '请检查远程计算机网络及其他配置是否正常',
|
||||||
fileTransferError: '传输失败',
|
fileTransferError: '传输失败',
|
||||||
fileSaveError: '保存失败',
|
fileSaveError: '保存失败',
|
||||||
fileUploading: '已开始上传, 点击右侧传输列表查看进度',
|
fileUploading: '已开始上传, 点击右侧传输列表查看进度',
|
||||||
@@ -214,8 +228,8 @@ export const SshActionBarItems = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
// 终端操作栏键 - RDP
|
// guacd 终端操作栏键
|
||||||
export const RdpActionItemKeys = {
|
export const GuacdActionItemKeys = {
|
||||||
DISPLAY: 'display',
|
DISPLAY: 'display',
|
||||||
COMBINATION_KEY: 'combinationKey',
|
COMBINATION_KEY: 'combinationKey',
|
||||||
CLIPBOARD: 'clipboard',
|
CLIPBOARD: 'clipboard',
|
||||||
@@ -225,45 +239,71 @@ export const RdpActionItemKeys = {
|
|||||||
CLOSE: 'close',
|
CLOSE: 'close',
|
||||||
};
|
};
|
||||||
|
|
||||||
// 终端操作栏 - RDP
|
// guacd 终端操作栏
|
||||||
export const RdpActionBarItems = [
|
export const GuacdActionBarItemMap = {
|
||||||
{
|
[GuacdActionItemKeys.DISPLAY]: {
|
||||||
item: RdpActionItemKeys.DISPLAY,
|
item: GuacdActionItemKeys.DISPLAY,
|
||||||
icon: 'icon-desktop',
|
icon: 'icon-desktop',
|
||||||
content: '显示设置',
|
content: '显示设置',
|
||||||
},
|
},
|
||||||
{
|
[GuacdActionItemKeys.COMBINATION_KEY]: {
|
||||||
item: RdpActionItemKeys.COMBINATION_KEY,
|
item: GuacdActionItemKeys.COMBINATION_KEY,
|
||||||
icon: 'icon-command',
|
icon: 'icon-command',
|
||||||
content: '组合键',
|
content: '组合键',
|
||||||
},
|
},
|
||||||
{
|
[GuacdActionItemKeys.CLIPBOARD]: {
|
||||||
item: RdpActionItemKeys.CLIPBOARD,
|
item: GuacdActionItemKeys.CLIPBOARD,
|
||||||
icon: 'icon-paste',
|
icon: 'icon-paste',
|
||||||
content: '剪切板',
|
content: '剪切板',
|
||||||
},
|
},
|
||||||
{
|
[GuacdActionItemKeys.UPLOAD]: {
|
||||||
item: RdpActionItemKeys.UPLOAD,
|
item: GuacdActionItemKeys.UPLOAD,
|
||||||
icon: 'icon-upload',
|
icon: 'icon-upload',
|
||||||
content: '文件上传',
|
content: '文件上传',
|
||||||
},
|
},
|
||||||
{
|
[GuacdActionItemKeys.SAVE_RDP]: {
|
||||||
item: RdpActionItemKeys.SAVE_RDP,
|
item: GuacdActionItemKeys.SAVE_RDP,
|
||||||
icon: 'icon-save',
|
icon: 'icon-save',
|
||||||
content: '保存 rdp 文件',
|
content: '保存 rdp 文件',
|
||||||
},
|
},
|
||||||
{
|
[GuacdActionItemKeys.DISCONNECT]: {
|
||||||
item: RdpActionItemKeys.DISCONNECT,
|
item: GuacdActionItemKeys.DISCONNECT,
|
||||||
icon: 'icon-stop',
|
icon: 'icon-stop',
|
||||||
content: '断开连接',
|
content: '断开连接',
|
||||||
},
|
},
|
||||||
{
|
[GuacdActionItemKeys.CLOSE]: {
|
||||||
item: RdpActionItemKeys.CLOSE,
|
item: GuacdActionItemKeys.CLOSE,
|
||||||
icon: 'icon-close',
|
icon: 'icon-close',
|
||||||
content: '关闭工具栏',
|
content: '关闭工具栏',
|
||||||
},
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// 终端操作栏 - RDP
|
||||||
|
export const RdpActionBarItems = [
|
||||||
|
GuacdActionBarItemMap[GuacdActionItemKeys.DISPLAY],
|
||||||
|
GuacdActionBarItemMap[GuacdActionItemKeys.COMBINATION_KEY],
|
||||||
|
GuacdActionBarItemMap[GuacdActionItemKeys.CLIPBOARD],
|
||||||
|
GuacdActionBarItemMap[GuacdActionItemKeys.UPLOAD],
|
||||||
|
GuacdActionBarItemMap[GuacdActionItemKeys.SAVE_RDP],
|
||||||
|
GuacdActionBarItemMap[GuacdActionItemKeys.DISCONNECT],
|
||||||
|
GuacdActionBarItemMap[GuacdActionItemKeys.CLOSE],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// 终端操作栏 - VNC
|
||||||
|
export const VncActionBarItems = [
|
||||||
|
GuacdActionBarItemMap[GuacdActionItemKeys.DISPLAY],
|
||||||
|
GuacdActionBarItemMap[GuacdActionItemKeys.COMBINATION_KEY],
|
||||||
|
GuacdActionBarItemMap[GuacdActionItemKeys.CLIPBOARD],
|
||||||
|
GuacdActionBarItemMap[GuacdActionItemKeys.DISCONNECT],
|
||||||
|
GuacdActionBarItemMap[GuacdActionItemKeys.CLOSE],
|
||||||
|
];
|
||||||
|
|
||||||
|
// 终端操作栏方向
|
||||||
|
export const ActionBarPosition = {
|
||||||
|
TOP: 'top',
|
||||||
|
RIGHT: 'right',
|
||||||
|
};
|
||||||
|
|
||||||
// 终端快捷键操作类型
|
// 终端快捷键操作类型
|
||||||
export const TerminalShortcutType = {
|
export const TerminalShortcutType = {
|
||||||
GLOBAL: 1,
|
GLOBAL: 1,
|
||||||
@@ -403,8 +443,8 @@ export const TerminalShortcutItems: Array<ShortcutKeyItem> = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
// RDP 组合键元素
|
// Guacd 组合键元素
|
||||||
export const RdpCombinationKeyItems: Array<CombinationKeyItem> = [
|
export const GuacdCombinationKeyItems: Array<CombinationKeyItem> = [
|
||||||
{
|
{
|
||||||
keys: [65307],
|
keys: [65307],
|
||||||
name: 'Esc'
|
name: 'Esc'
|
||||||
@@ -444,9 +484,90 @@ export const RdpCombinationKeyItems: Array<CombinationKeyItem> = [
|
|||||||
{
|
{
|
||||||
keys: [65515, 120],
|
keys: [65515, 120],
|
||||||
name: 'Windows+X'
|
name: 'Windows+X'
|
||||||
|
}, {
|
||||||
|
keys: [65507, 99],
|
||||||
|
name: 'Ctrl+C'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
keys: [65507, 118],
|
||||||
|
name: 'Ctrl+V'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: [65507, 120],
|
||||||
|
name: 'Ctrl+X'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: [65507, 97],
|
||||||
|
name: 'Ctrl+A'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: [65507, 122],
|
||||||
|
name: 'Ctrl+Z'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: [65507, 65535],
|
||||||
|
name: 'Ctrl+Delete'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: [65507, 65288],
|
||||||
|
name: 'Ctrl+Backspace'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: [65507, 65513, 65470],
|
||||||
|
name: 'Ctrl+Alt+F1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: [65507, 65513, 65471],
|
||||||
|
name: 'Ctrl+Alt+F2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: [65507, 65513, 65472],
|
||||||
|
name: 'Ctrl+Alt+F3'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: [65507, 65513, 65473],
|
||||||
|
name: 'Ctrl+Alt+F4'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: [65507, 65513, 65474],
|
||||||
|
name: 'Ctrl+Alt+F5'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: [65507, 65513, 65475],
|
||||||
|
name: 'Ctrl+Alt+F6'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: [65507, 65513, 65476],
|
||||||
|
name: 'Ctrl+Alt+F7'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: [65507, 65513, 65477],
|
||||||
|
name: 'Ctrl+Alt+F8'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: [65507, 65513, 65478],
|
||||||
|
name: 'Ctrl+Alt+F9'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: [65507, 65513, 65479],
|
||||||
|
name: 'Ctrl+Alt+F10'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: [65507, 65513, 65480],
|
||||||
|
name: 'Ctrl+Alt+F11'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: [65507, 65513, 65481],
|
||||||
|
name: 'Ctrl+Alt+F12'
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// backspace 字符
|
||||||
|
export const BACKSPACE_CHAR = String.fromCharCode(127);
|
||||||
|
|
||||||
|
// ctrl^h 字符
|
||||||
|
export const CTRL_H_CHAR = String.fromCharCode(8);
|
||||||
|
|
||||||
// 传输状态
|
// 传输状态
|
||||||
export const TransferStatus = {
|
export const TransferStatus = {
|
||||||
WAITING: 'waiting',
|
WAITING: 'waiting',
|
||||||
|
|||||||
Reference in New Issue
Block a user