From 618599266e8f4c6f41381eeef2c02522629e8ede Mon Sep 17 00:00:00 2001 From: mofeng-git Date: Sun, 5 Jul 2026 22:01:33 +0800 Subject: [PATCH] =?UTF-8?q?fix=EF=BC=9A=E6=81=A2=E5=A4=8D=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E6=B6=88=E5=A4=B1=E7=9A=84=20redfish=20=E5=85=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/i18n/en-US.ts | 9 +- web/src/i18n/zh-CN.ts | 9 +- web/src/views/SettingsView.vue | 169 ++++++++++++++++++++++++++------- 3 files changed, 149 insertions(+), 38 deletions(-) diff --git a/web/src/i18n/en-US.ts b/web/src/i18n/en-US.ts index 0c6552d9..c0001cf9 100644 --- a/web/src/i18n/en-US.ts +++ b/web/src/i18n/en-US.ts @@ -521,7 +521,7 @@ export default { environmentSubtitle: 'System runtime environment and USB device maintenance', aboutSubtitle: 'Online upgrade, version info and hardware overview', extTtydSubtitle: 'Open a host Shell terminal in the browser', - thirdPartyAccessSubtitle: 'Configure external RustDesk, VNC, and RTSP access', + thirdPartyAccessSubtitle: 'Configure external RustDesk, VNC, RTSP, and Redfish access', extRemoteAccessSubtitle: 'Remote access through NAT-traversal services', extFrpcSubtitle: 'NAT traversal through the FRP client', aboutDesc: 'Open and Lightweight IP-KVM Solution', @@ -573,10 +573,13 @@ export default { httpsEnabledDesc: 'Serve over an encrypted connection. A self-signed certificate is generated automatically if none is provided.', portConfig: 'Port & Protocol', portConfigDesc: 'The service listens on a single port at a time, determined by the HTTPS toggle', - redfishTitle: 'Redfish API', + redfishTitle: 'Redfish', redfishDesc: 'DMTF Redfish standard management interface', redfishEnabled: 'Enable Redfish API', redfishEnabledDesc: 'When enabled, the standard Redfish management interface is available at /redfish/v1/', + redfishEndpoint: 'Redfish Endpoint', + copyRedfishUrl: 'Copy Redfish URL', + openRedfishEndpoint: 'Open Redfish endpoint', httpPortReserved: 'HTTP port (reserved)', httpsPortReserved: 'HTTPS port (reserved)', portActive: 'Active', @@ -1075,6 +1078,7 @@ export default { title: 'RTSP Streaming', desc: 'Configure RTSP video output service (H.264/H.265)', bind: 'Bind Address', + bindHint: 'Enter an IPv4 or IPv6 address; configure the port in the port field.', port: 'Port', path: 'Stream Path', pathPlaceholder: 'live', @@ -1092,6 +1096,7 @@ export default { title: 'VNC Remote', desc: 'Access via TigerVNC client', bind: 'Bind Address', + bindHint: 'Enter an IPv4 or IPv6 address; configure the port in the port field.', port: 'Port', encoding: 'Video Encoding', encodingTightJpeg: 'Tight JPEG', diff --git a/web/src/i18n/zh-CN.ts b/web/src/i18n/zh-CN.ts index 83f7d690..de7ab67e 100644 --- a/web/src/i18n/zh-CN.ts +++ b/web/src/i18n/zh-CN.ts @@ -520,7 +520,7 @@ export default { environmentSubtitle: '系统级运行环境与 USB 设备维护', aboutSubtitle: '在线升级、版本信息与设备硬件概览', extTtydSubtitle: '在浏览器中打开本机 Shell 终端', - thirdPartyAccessSubtitle: '集中配置 RustDesk、VNC 与 RTSP 外部接入', + thirdPartyAccessSubtitle: '集中配置 RustDesk、VNC、RTSP 与 Redfish 外部接入', extRemoteAccessSubtitle: '通过内网穿透服务实现远程访问', extFrpcSubtitle: '通过 FRP 客户端实现内网穿透', aboutDesc: '开放轻量的 IP-KVM 解决方案', @@ -572,10 +572,13 @@ export default { httpsEnabledDesc: '使用加密连接对外提供服务,未配置证书时自动生成自签名证书', portConfig: '端口与协议', portConfigDesc: '服务一次仅监听一个端口,由 HTTPS 开关决定生效端口', - redfishTitle: 'Redfish API', + redfishTitle: 'Redfish', redfishDesc: 'DMTF Redfish 标准管理接口', redfishEnabled: '启用 Redfish API', redfishEnabledDesc: '开启后可通过 /redfish/v1/ 访问标准 Redfish 管理接口', + redfishEndpoint: 'Redfish 入口', + copyRedfishUrl: '复制 Redfish 地址', + openRedfishEndpoint: '打开 Redfish 入口', httpPortReserved: 'HTTP 端口(备用)', httpsPortReserved: 'HTTPS 端口(备用)', portActive: '当前生效', @@ -1074,6 +1077,7 @@ export default { title: 'RTSP 视频流', desc: '配置 RTSP 推流服务(H.264/H.265)', bind: '监听地址', + bindHint: '填写 IPv4 或 IPv6 地址;端口请在端口字段配置。', port: '端口', path: '流路径', pathPlaceholder: 'live', @@ -1091,6 +1095,7 @@ export default { title: 'VNC 远程', desc: '通过 TigerVNC 客户端访问', bind: '监听地址', + bindHint: '填写 IPv4 或 IPv6 地址;端口请在端口字段配置。', port: '端口', encoding: '视频编码', encodingTightJpeg: 'Tight JPEG', diff --git a/web/src/views/SettingsView.vue b/web/src/views/SettingsView.vue index afa7b79a..a086353a 100644 --- a/web/src/views/SettingsView.vue +++ b/web/src/views/SettingsView.vue @@ -224,6 +224,7 @@ function normalizeSettingsSection(value: unknown): SettingsSectionId | null { if (typeof value !== 'string') return null if (value === 'access-control') return 'account' if (value === 'ext-frpc') return 'ext-remote-access' + if (value === 'redfish') return 'third-party-access' if (value === 'ext-rustdesk' || value === 'ext-vnc' || value === 'ext-rtsp') return 'third-party-access' return isSettingsSectionId(value) ? value : null } @@ -242,10 +243,7 @@ async function loadSectionData(section: SettingsSectionId) { await loadAuthConfig() return case 'network': - await Promise.all([ - loadWebServerConfig(), - loadRedfishConfig(), - ]) + await loadWebServerConfig() return case 'video': await Promise.all([ @@ -277,6 +275,8 @@ async function loadSectionData(section: SettingsSectionId) { return case 'third-party-access': await Promise.all([ + loadWebServerConfig(), + loadRedfishConfig(), loadRustdeskConfig(), loadRustdeskPassword(), loadRtspConfig(), @@ -520,9 +520,12 @@ const previewAccessUrl = computed(() => { const host = firstAddr.includes(':') ? `[${firstAddr}]` : firstAddr return `${scheme}://${host}:${port}` }) +const redfishAccessUrl = computed(() => `${previewAccessUrl.value}/redfish/v1/`) const previewUrlCopied = ref(false) +const redfishUrlCopied = ref(false) let previewUrlCopiedTimer: ReturnType | null = null +let redfishUrlCopiedTimer: ReturnType | null = null async function copyPreviewUrl() { const ok = await clipboardCopy(previewAccessUrl.value) @@ -538,6 +541,20 @@ function openPreviewUrl() { window.open(previewAccessUrl.value, '_blank', 'noopener,noreferrer') } +async function copyRedfishUrl() { + const ok = await clipboardCopy(redfishAccessUrl.value) + if (!ok) return + redfishUrlCopied.value = true + if (redfishUrlCopiedTimer) clearTimeout(redfishUrlCopiedTimer) + redfishUrlCopiedTimer = setTimeout(() => { + redfishUrlCopied.value = false + }, 1500) +} + +function openRedfishUrl() { + window.open(redfishAccessUrl.value, '_blank', 'noopener,noreferrer') +} + interface DeviceConfig { video: Array<{ path: string @@ -3890,34 +3907,6 @@ watch(isWindows, () => { - - - - - {{ t('settings.redfishTitle') }} - {{ t('settings.redfishDesc') }} - - -
-
- -

{{ t('settings.redfishEnabledDesc') }}

-
- -
-
- -

- - {{ t('settings.restartRequiredHint') }} -

- -
-
@@ -4726,7 +4715,10 @@ watch(isWindows, () => {
- +
+ +

{{ t('extensions.rtsp.bindHint') }}

+
@@ -4856,7 +4848,10 @@ watch(isWindows, () => {
- +
+ +

{{ t('extensions.vnc.bindHint') }}

+
@@ -5112,6 +5107,112 @@ watch(isWindows, () => {
+ +
+ +
+ +
+

{{ t('settings.autoRestarting') }}

+

+ {{ webServerConfig.https_enabled + ? t('settings.autoRestartingHttpsDesc', { sec: autoRestartCountdown }) + : t('settings.autoRestartingDesc') }} +

+
+ + {{ autoRestartCountdown }} + +
+ + +
+
+ +
+

{{ t('settings.httpsManualRedirectTitle') }}

+

{{ t('settings.httpsManualRedirectDesc') }}

+
+
+ + + {{ autoRestartManualUrl }} + +
+ + +
+

{{ t('settings.autoRestartFailed') }}

+ +
+ + + + {{ t('settings.redfishTitle') }} + {{ t('settings.redfishDesc') }} + + +
+
+ +

{{ t('settings.redfishEnabledDesc') }}

+
+ +
+
+

{{ t('settings.redfishEndpoint') }}

+
+ {{ redfishAccessUrl }} + + +
+
+
+ +

+ + {{ t('settings.restartRequiredHint') }} +

+ +
+
+
+