diff --git a/frontend/init.html b/frontend/init.html index 523a3ca..1c2d259 100644 --- a/frontend/init.html +++ b/frontend/init.html @@ -10,6 +10,12 @@ +
diff --git a/frontend/js/app.js b/frontend/js/app.js index ebe8b34..9df9313 100644 --- a/frontend/js/app.js +++ b/frontend/js/app.js @@ -81,8 +81,11 @@ async function handleEditConfig(originalFilename) { DOMElements.formTitle.textContent = '编辑配置'; fillForm(config, originalFilename); showRenderedConfig(rendered, originalFilename); + + // 关键修正: 在填充表单后, 根据数据更新服务模式的fieldset可见性 const mode = config.upstream_config?.enable_upstream ? 'reverse_proxy' : (config.file_server_config?.enable_file_server ? 'file_server' : 'none'); updateServiceModeView(mode); + state.initialFormState = getFormStateAsString(); } catch(error) { notification.toast(`加载配置详情失败: ${error.message}`, 'error'); } } diff --git a/frontend/js/ui.js b/frontend/js/ui.js index f971bde..fe24d58 100644 --- a/frontend/js/ui.js +++ b/frontend/js/ui.js @@ -82,45 +82,56 @@ export function addSingleInput(container, inputName, placeholder, value = '') { container.appendChild(div); } +// 修正: 确保正确更新分段控件的UI export function fillForm(config, originalFilename) { DOMElements.originalFilenameInput.value = originalFilename; DOMElements.domainInput.value = config.domain_config?.domain || ''; + // 确定模式 const enableUpstream = config.upstream_config?.enable_upstream || false; const enableFileServer = config.file_server_config?.enable_file_server || false; let mode = 'none'; - if (enableUpstream) mode = 'reverse_proxy'; - else if (enableFileServer) mode = 'file_server'; + if (enableUpstream) { + mode = 'reverse_proxy'; + } else if (enableFileServer) { + mode = 'file_server'; + } + // 关键修正: 找到对应的按钮并手动调用UI更新函数 const activeButton = DOMElements.serviceModeControl.querySelector(`[data-mode="${mode}"]`); - if (activeButton) updateSegmentedControl(activeButton); + if (activeButton) { + updateSegmentedControl(activeButton); + } + // 填充上游配置 const upstreamConfig = config.upstream_config || {}; DOMElements.mutiUpstreamCheckbox.checked = upstreamConfig.muti_upstream || false; document.getElementById('upstream').value = upstreamConfig.upstream || ''; - DOMElements.multiUpstreamContainer.innerHTML = ''; if (upstreamConfig.muti_upstream && upstreamConfig.upstream_servers) { upstreamConfig.upstream_servers.forEach(server => { addSingleInput(DOMElements.multiUpstreamContainer, 'upstream_servers', '例如: 127.0.0.1:8081', server); }); } - DOMElements.upstreamHeadersContainer.innerHTML = ''; if (upstreamConfig.upstream_headers) { Object.entries(upstreamConfig.upstream_headers).forEach(([k, v]) => v.forEach(val => addKeyValueInput(DOMElements.upstreamHeadersContainer, 'upstream_header_key', 'upstream_header_value', k, val))); } + // 填充文件服务配置 document.getElementById('file_dir_path').value = config.file_server_config?.file_dir_path || ''; document.getElementById('enable_browser').checked = config.file_server_config?.enable_browser || false; + // 填充全局请求头 DOMElements.headersContainer.innerHTML = ''; if (config.headers) Object.entries(config.headers).forEach(([k, v]) => v.forEach(val => addKeyValueInput(DOMElements.headersContainer, 'header_key', 'header_value', k, val))); + // 填充附加功能 document.getElementById('enable_log').checked = config.log_config?.enable_log || false; document.getElementById('enable_error_page').checked = config.error_page_config?.enable_error_page || false; document.getElementById('enable_encode').checked = config.encode_config?.enable_encode || false; + // 确保多上游UI的可见性正确 updateMultiUpstreamView(DOMElements.mutiUpstreamCheckbox.checked); } @@ -177,17 +188,17 @@ export function updateMultiUpstreamView(isMulti) { DOMElements.multiUpstreamGroup.classList.toggle('hidden', !isMulti); } +// 修正: 使用 offsetLeft 来进行更可靠的定位 export function updateSegmentedControl(activeButton) { const slider = document.getElementById('segmented-control-slider'); const control = DOMElements.serviceModeControl; if (!activeButton || !slider || !control) return; + // 更新按钮的 active 状态 control.querySelectorAll('button').forEach(btn => btn.classList.remove('active')); activeButton.classList.add('active'); - const controlRect = control.getBoundingClientRect(); - const buttonRect = activeButton.getBoundingClientRect(); - - slider.style.width = `${buttonRect.width}px`; - slider.style.transform = `translateX(${activeButton.offsetLeft - control.clientLeft - 4}px)`; + // 移动滑块到新位置 + slider.style.width = `${activeButton.offsetWidth}px`; + slider.style.transform = `translateX(${activeButton.offsetLeft}px)`; } \ No newline at end of file diff --git a/tmpl/file_server b/tmpl/.file_server similarity index 100% rename from tmpl/file_server rename to tmpl/.file_server diff --git a/tmpl/reverse_proxy b/tmpl/.reverse_proxy similarity index 100% rename from tmpl/reverse_proxy rename to tmpl/.reverse_proxy diff --git a/tmpl/uni b/tmpl/uni index 723823b..78b7863 100644 --- a/tmpl/uni +++ b/tmpl/uni @@ -1,14 +1,17 @@ {{- if .DomainConfig.MutiDomains -}} - {{- range .DomainConfig.Domains}}{{.}} {{end -}} + {{- range $i, $domain := .DomainConfig.Domains -}} + {{- if $i}} {{" "}}{{- end -}} + {{- . -}} + {{- end -}} { {{- else -}} - {{- .DomainConfig.Domain -}} -{{- end -}} { + {{- .DomainConfig.Domain}} { +{{- end -}} - {{- if .Upsteam.EnableUpStream}} + {{- if .Upstream.EnableUpStream}} reverse_proxy { - to{{if .Upsteam.MutiUpStreams}}{{range .Upsteam.UpStreams}} {{.}}{{end}}{{else}} {{.Upsteam.UpStream}}{{end}} + to{{if .Upstream.MutiUpStreams}}{{range .Upstream.UpStreams}} {{.}}{{end}}{{else}} {{.Upstream.UpStream}}{{end}} - {{- range $key, $values := .Upsteam.UpStreamHeaders}} + {{- range $key, $values := .Upstream.UpStreamHeaders}} {{- range $values}} header_up {{$key}} "{{.}}" {{- end}} @@ -16,7 +19,6 @@ } {{- else if .FileServer.EnableFileServer}} root * {{.FileServer.FileDirPath}} - file_server{{if .FileServer.EnableBrowser}} browse{{end}} {{- end}}