From 9e9c390baf4f5d31846548ae361f3faaed789af0 Mon Sep 17 00:00:00 2001 From: lijiahangmax Date: Fri, 4 Jul 2025 17:43:59 +0800 Subject: [PATCH] =?UTF-8?q?:hammer:=20=E9=85=8D=E7=BD=AE=20vnc=20=E8=B5=84?= =?UTF-8?q?=E4=BA=A7.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- orion-visor-ui/src/api/asset/host-config.ts | 10 ++ orion-visor-ui/src/api/asset/host-extra.ts | 6 + orion-visor-ui/src/api/asset/host.ts | 2 +- .../host-list/components/host-form-drawer.vue | 30 +++- .../host-list/components/host-form-rdp.vue | 141 ++------------- .../host-list/components/host-form-ssh.vue | 132 ++------------ .../host-list/components/host-form-vnc.vue | 168 ++++++++++++++++++ .../src/views/asset/host-list/types/const.ts | 4 + .../views/asset/host-list/types/form.rules.ts | 71 +++++++- .../asset/host-list/types/use-host-config.ts | 99 +++++++++++ 10 files changed, 417 insertions(+), 246 deletions(-) create mode 100644 orion-visor-ui/src/views/asset/host-list/components/host-form-vnc.vue create mode 100644 orion-visor-ui/src/views/asset/host-list/types/use-host-config.ts diff --git a/orion-visor-ui/src/api/asset/host-config.ts b/orion-visor-ui/src/api/asset/host-config.ts index 7a089263..281d34a0 100644 --- a/orion-visor-ui/src/api/asset/host-config.ts +++ b/orion-visor-ui/src/api/asset/host-config.ts @@ -51,6 +51,16 @@ export interface HostRdpConfig extends HostBaseConfig { remoteAppArgs?: string; } +// 主机 VNC 配置 +export interface HostVncConfig extends HostBaseConfig { + identityId?: number; + noUsername?: boolean; + noPassword?: boolean; + portForwardId?: number; + timezone?: string; + clipboardEncoding?: string; +} + /** * 更新主机配置 */ diff --git a/orion-visor-ui/src/api/asset/host-extra.ts b/orion-visor-ui/src/api/asset/host-extra.ts index 9fb2b142..08ebbbca 100644 --- a/orion-visor-ui/src/api/asset/host-extra.ts +++ b/orion-visor-ui/src/api/asset/host-extra.ts @@ -33,6 +33,12 @@ export interface HostRdpExtraSettingModel { initialProgram: string; } +// VNC 额外配置 +export interface HostVncExtraSettingModel { + port: number; + lowBandwidthMode: boolean; +} + // 标签额外配置 export interface HostLabelExtraSettingModel { alias: string; diff --git a/orion-visor-ui/src/api/asset/host.ts b/orion-visor-ui/src/api/asset/host.ts index 08320dd9..a01dd48e 100644 --- a/orion-visor-ui/src/api/asset/host.ts +++ b/orion-visor-ui/src/api/asset/host.ts @@ -5,7 +5,7 @@ import axios from 'axios'; import qs from 'query-string'; // 主机类型 -export type HostType = 'SSH' | string | undefined; +export type HostType = 'SSH' | 'RDP' | 'VNC' | string | undefined; /** * 主机创建请求 diff --git a/orion-visor-ui/src/views/asset/host-list/components/host-form-drawer.vue b/orion-visor-ui/src/views/asset/host-list/components/host-form-drawer.vue index 85dc3ed0..03ea8519 100644 --- a/orion-visor-ui/src/views/asset/host-list/components/host-form-drawer.vue +++ b/orion-visor-ui/src/views/asset/host-list/components/host-form-drawer.vue @@ -51,6 +51,15 @@ class="form-panel" :hostId="hostId" /> + + + + @@ -64,14 +73,15 @@ diff --git a/orion-visor-ui/src/views/asset/host-list/components/host-form-ssh.vue b/orion-visor-ui/src/views/asset/host-list/components/host-form-ssh.vue index 301fbcc1..33367941 100644 --- a/orion-visor-ui/src/views/asset/host-list/components/host-form-ssh.vue +++ b/orion-visor-ui/src/views/asset/host-list/components/host-form-ssh.vue @@ -4,8 +4,9 @@ + :label-col-props="{ span: 6 }" + :wrapper-col-props="{ span: 18 }" + :rules="formRules"> + label="主机密码"> @@ -105,7 +104,6 @@ mini> 测试连接 @@ -123,17 +121,13 @@ + + + + diff --git a/orion-visor-ui/src/views/asset/host-list/types/const.ts b/orion-visor-ui/src/views/asset/host-list/types/const.ts index d06b91c2..7883334a 100644 --- a/orion-visor-ui/src/views/asset/host-list/types/const.ts +++ b/orion-visor-ui/src/views/asset/host-list/types/const.ts @@ -24,6 +24,10 @@ export const HostType = { value: 'RDP', port: 3389, }, + VNC: { + value: 'VNC', + port: 5900, + }, }; // 系统类型 diff --git a/orion-visor-ui/src/views/asset/host-list/types/form.rules.ts b/orion-visor-ui/src/views/asset/host-list/types/form.rules.ts index da956171..3903c283 100644 --- a/orion-visor-ui/src/views/asset/host-list/types/form.rules.ts +++ b/orion-visor-ui/src/views/asset/host-list/types/form.rules.ts @@ -1,4 +1,7 @@ import type { FieldRule } from '@arco-design/web-vue'; +import type { Ref } from 'vue'; +import type { HostBaseConfig } from '@/api/asset/host-config'; +import { HostAuthType } from './const'; // 主机表单规则 export const hostFormRules = { @@ -62,11 +65,11 @@ export const hostFormRules = { export const sshFormRules = { port: [{ required: true, - message: '请输入 SSH 端口' + message: '请输入端口' }, { min: 1, max: 65535, - message: 'SSH 端口不合法' + message: '端口不合法' }], authType: [{ required: true, @@ -116,11 +119,11 @@ export const sshFormRules = { export const rdpFormRules = { port: [{ required: true, - message: '请输入 RDP 端口' + message: '请输入端口' }, { min: 1, max: 65535, - message: 'RDP 端口不合法' + message: '端口不合法' }], authType: [{ required: true, @@ -132,4 +135,64 @@ export const rdpFormRules = { }], } as Record; +// vnc 表单规则 +export const vncFormRules = { + port: [{ + required: true, + message: '请输入端口' + }, { + min: 1, + max: 65535, + message: '端口不合法' + }], + authType: [{ + required: true, + message: '请选择认证方式' + }], + identityId: [{ + required: true, + message: '请选择主机身份' + }], + clipboardEncoding: [{ + required: true, + message: '请选择剪切板编码' + }], +} as Record; + +// 基础规则 +export const baseFormRules = { + // 用户名验证规则 + username(formModel: Ref) { + return [{ + validator: (value: string, cb: (msg?: string) => void) => { + if (value && value.length > 128) { + cb('用户名长度不能大于128位'); + return; + } + if (formModel.value.authType !== HostAuthType.IDENTITY && !value) { + cb('请输入用户名'); + return; + } + cb(); + } + }] as FieldRule[]; + }, + // 密码验证规则 + password(formModel: Ref) { + return [{ + validator: (value: string, cb: (msg?: string) => void) => { + if (value && value.length > 256) { + cb('密码长度不能大于256位'); + return; + } + if (formModel.value.useNewPassword && !value) { + cb('请输入密码'); + return; + } + cb(); + } + }] as FieldRule[]; + } +}; + export default null; diff --git a/orion-visor-ui/src/views/asset/host-list/types/use-host-config.ts b/orion-visor-ui/src/views/asset/host-list/types/use-host-config.ts new file mode 100644 index 00000000..34ff1af4 --- /dev/null +++ b/orion-visor-ui/src/views/asset/host-list/types/use-host-config.ts @@ -0,0 +1,99 @@ +import type { Ref } from 'vue'; +import { ref } from 'vue'; +import type { HostBaseConfig } from '@/api/asset/host-config'; +import { getHostConfig, updateHostConfig } from '@/api/asset/host-config'; +import type { FieldRule } from '@arco-design/web-vue'; +import { Message } from '@arco-design/web-vue'; +import { baseFormRules } from './form.rules'; +import { encrypt } from '@/utils/rsa'; +import { testHostConnect } from '@/api/asset/host'; + +// 主机配置表单信息 +export interface UseHostConfigFormOptions { + type: string; + hostId: number; + formModel: Ref; + rules?: Record; + setLoading: (loading: boolean) => void; +} + +// 使用主机配置表单 +export default function useHostConfigForm(options: UseHostConfigFormOptions) { + const { type, hostId, formModel, rules, setLoading } = options; + + const formRef = ref(); + const formRules = ref({ ...rules, username: baseFormRules.username(formModel), password: baseFormRules.password(formModel) }); + + // 加载配置 + const fetchHostConfig = async () => { + try { + setLoading(true); + const { data } = await getHostConfig({ hostId, type }); + data.useNewPassword = !data.hasPassword; + formModel.value = data; + } catch (err: any) { + Message.error('配置加载失败'); + } finally { + setLoading(false); + } + }; + + // 测试连接 + const testConnect = async () => { + if (!formRef?.value) { + return; + } + const error = await formRef.value.validate(); + if (error) { + return; + } + try { + setLoading(true); + // 测试连接 + await testHostConnect({ id: hostId, type }); + Message.success('连接成功'); + } catch (e) { + } finally { + setLoading(false); + } + }; + + // 保存配置 + const saveConfig = async () => { + if (!formRef?.value) { + return; + } + const error = await formRef.value.validate(); + if (error) { + return; + } + // 加密密码 + const data = { ...formModel.value }; + try { + data.password = await encrypt(data.password); + } catch (e) { + return; + } + try { + setLoading(true); + // 更新 + await updateHostConfig({ + hostId, + type, + config: JSON.stringify(data), + }); + Message.success('修改成功'); + } catch (e) { + } finally { + setLoading(false); + } + }; + + return { + formRef, + formRules, + fetchHostConfig, + testConnect, + saveConfig, + }; +}