caddydash/frontend/js/global.js
2025-06-30 15:31:14 +08:00

153 lines
No EOL
7.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// js/global.js - 全局配置页面的逻辑
import { theme, activateNav } from './common.js';
import { api } from './api.js';
import { notification } from './notifications.js';
import { initCaddyStatus } from './caddy.js';
import { createCustomSelect } from './ui.js';
const DOMElements = {
globalForm: document.getElementById('global-caddy-form'),
themeToggleInput: document.getElementById('theme-toggle-input'),
logoutBtn: document.getElementById('logout-btn'),
toastContainer: document.getElementById('toast-container'),
dialogContainer: document.getElementById('dialog-container'),
enableDnsChallengeCheckbox: document.getElementById('enable_dns_challenge'),
globalTlsConfigGroup: document.getElementById('global-tls-config-group'),
enableEchCheckbox: document.getElementById('enable_ech'),
echConfigGroup: document.getElementById('ech-config-group'),
};
const submitButton = DOMElements.globalForm.querySelector('button[type="submit"]');
// 从表单收集数据, 构建成后端需要的JSON结构
function getGlobalConfigFromForm() {
const formData = new FormData(DOMElements.globalForm);
const enableEch = DOMElements.enableEchCheckbox.checked;
return {
debug: DOMElements.globalForm.querySelector('[name="debug"]').checked,
ports_config: {
admin_port: formData.get('admin_port'),
http_port: parseInt(formData.get('http_port'), 10) || 80,
https_port: parseInt(formData.get('https_port'), 10) || 443,
},
metrics: DOMElements.globalForm.querySelector('[name="metrics"]').checked,
log_config: {
level: DOMElements.globalForm.querySelector('input[name="log_level"]').value,
rotate_size: formData.get('log_rotate_size'),
rotate_keep: formData.get('log_rotate_keep'),
rotate_keep_for_time: formData.get('log_rotate_keep_for_time'),
},
tls_config: {
enable_dns_challenge: DOMElements.enableDnsChallengeCheckbox.checked,
provider: DOMElements.globalForm.querySelector('input[name="tls_provider"]').value,
token: formData.get('tls_token'),
echouter_sni: enableEch ? formData.get('tls_ech_sni') : "",
email: formData.get('tls_email'),
},
tls_snippet_config: {},
};
}
// 用从API获取的数据填充表单
function fillGlobalConfigForm(config) {
if (!config) return;
DOMElements.globalForm.querySelector('[name="debug"]').checked = config.debug || false;
DOMElements.globalForm.querySelector('[name="metrics"]').checked = config.metrics || false;
const ports = config.ports_config || {};
DOMElements.globalForm.querySelector('[name="admin_port"]').value = ports.admin_port || ':2019';
DOMElements.globalForm.querySelector('[name="http_port"]').value = ports.http_port || 80;
DOMElements.globalForm.querySelector('[name="https_port"]').value = ports.https_port || 443;
const log = config.log_config || {};
const logLevelSelect = document.getElementById('select-log-level');
const logLevel = log.level || 'INFO';
if (logLevelSelect && logLevelSelect.querySelector('.select-selected')) {
logLevelSelect.querySelector('.select-selected').textContent = logLevel;
const hiddenInput = logLevelSelect.querySelector('input[name="log_level"]');
if (hiddenInput) hiddenInput.value = logLevel;
}
DOMElements.globalForm.querySelector('[name="log_rotate_size"]').value = log.rotate_size || '10MB';
DOMElements.globalForm.querySelector('[name="log_rotate_keep"]').value = log.rotate_keep || '10';
DOMElements.globalForm.querySelector('[name="log_rotate_keep_for_time"]').value = log.rotate_keep_for_time || '24h';
const tls = config.tls_config || {};
DOMElements.enableDnsChallengeCheckbox.checked = tls.enable_dns_challenge || false;
DOMElements.globalTlsConfigGroup.classList.toggle('hidden', !DOMElements.enableDnsChallengeCheckbox.checked);
const tlsProviderSelect = document.getElementById('select-tls-provider');
const provider = tls.provider || '';
if (tlsProviderSelect && provider && tlsProviderSelect.querySelector('.select-selected')) {
tlsProviderSelect.querySelector('.select-selected').textContent = provider;
const hiddenProviderInput = tlsProviderSelect.querySelector('input[name="tls_provider"]');
if (hiddenProviderInput) hiddenProviderInput.value = provider;
}
DOMElements.globalForm.querySelector('[name="tls_token"]').value = tls.token || '';
DOMElements.globalForm.querySelector('[name="tls_email"]').value = tls.email || '';
const echOuterSni = tls.echouter_sni || '';
DOMElements.enableEchCheckbox.checked = !!echOuterSni;
DOMElements.echConfigGroup.classList.toggle('hidden', !DOMElements.enableEchCheckbox.checked);
DOMElements.globalForm.querySelector('[name="tls_ech_sni"]').value = echOuterSni;
}
async function handleSaveGlobalConfig(e) {
e.preventDefault();
const configData = getGlobalConfigFromForm();
submitButton.disabled = true;
submitButton.querySelector('span').textContent = "保存中...";
try {
// 修正: 更新API端点路径
const result = await api.put('/global/config', configData);
notification.toast(result.message || '全局配置已成功保存Caddy正在重载...', 'success');
} catch (error) {
notification.toast(`保存失败: ${error.message}`, 'error');
} finally {
submitButton.disabled = false;
submitButton.querySelector('span').textContent = "保存并重载";
}
}
async function handleLogout() {
if (await notification.confirm('您确定要退出登录吗?')) {
notification.toast('正在退出...', 'info');
setTimeout(() => { window.location.href = '/v0/api/auth/logout'; }, 500);
}
}
function init() {
theme.init(DOMElements.themeToggleInput);
notification.init(DOMElements.toastContainer, DOMElements.dialogContainer);
activateNav('global');
initCaddyStatus();
// 修正: 更新API端点路径
api.get('/global/log/levels')
.then(levels => createCustomSelect('select-log-level', Object.keys(levels)))
.catch(err => notification.toast(`加载日志级别失败: ${err.message}`, 'error'));
// 修正: 更新API端点路径
api.get('/global/tls/providers')
.then(providers => createCustomSelect('select-tls-provider', Object.keys(providers)))
.catch(err => notification.toast(`加载TLS提供商失败: ${err.message}`, 'error'));
// 修正: 更新API端点路径
api.get('/global/config')
.then(config => fillGlobalConfigForm(config))
.catch(err => notification.toast(`加载全局配置失败: ${err.message}`, 'error'));
DOMElements.globalForm.addEventListener('submit', handleSaveGlobalConfig);
DOMElements.logoutBtn.addEventListener('click', handleLogout);
DOMElements.enableDnsChallengeCheckbox.addEventListener('change', (e) => {
DOMElements.globalTlsConfigGroup.classList.toggle('hidden', !e.target.checked);
});
DOMElements.enableEchCheckbox.addEventListener('change', (e) => {
DOMElements.echConfigGroup.classList.toggle('hidden', !e.target.checked);
});
}
init();