265 lines
9.5 KiB
JavaScript
265 lines
9.5 KiB
JavaScript
document.addEventListener('DOMContentLoaded', () => {
|
||
const hostInput = document.getElementById('host');
|
||
const portInput = document.getElementById('port');
|
||
const userInput = document.getElementById('user');
|
||
const passwordInput = document.getElementById('password');
|
||
const databaseInput = document.getElementById('database');
|
||
const vHostInput = document.getElementById('vHost');
|
||
const vPortInput = document.getElementById('vPort');
|
||
const vPasswordInput = document.getElementById('vPassword');
|
||
|
||
const btnTest = document.getElementById('btnTest');
|
||
const btnTestValkey = document.getElementById('btnTestValkey');
|
||
const btnInit = document.getElementById('btnInit');
|
||
const messageBox = document.getElementById('messageBox');
|
||
|
||
const initHeaderTitle = document.querySelector('.init-header h2');
|
||
const initHeaderDesc = document.querySelector('.init-header p');
|
||
|
||
const promForm = document.getElementById('promForm');
|
||
const initForm = document.getElementById('initForm');
|
||
const promName = document.getElementById('promSourceName');
|
||
const promUrl = document.getElementById('promUrl');
|
||
const promDesc = document.getElementById('promDesc');
|
||
const btnPromTest = document.getElementById('btnPromTest');
|
||
const btnPromAdd = document.getElementById('btnPromAdd');
|
||
const promMessageBox = document.getElementById('promMessageBox');
|
||
|
||
const adminForm = document.getElementById('adminForm');
|
||
const adminUsername = document.getElementById('adminUsername');
|
||
const adminPassword = document.getElementById('adminPassword');
|
||
const adminPasswordConfirm = document.getElementById('adminPasswordConfirm');
|
||
const btnAdminCreate = document.getElementById('btnAdminCreate');
|
||
const adminMessageBox = document.getElementById('adminMessageBox');
|
||
|
||
function showMessage(msg, isError = false) {
|
||
messageBox.textContent = msg;
|
||
messageBox.className = 'form-message ' + (isError ? 'error' : 'success');
|
||
}
|
||
|
||
function showAdminMessage(msg, isError = false) {
|
||
adminMessageBox.textContent = msg;
|
||
adminMessageBox.className = 'form-message ' + (isError ? 'error' : 'success');
|
||
}
|
||
|
||
function showPromMessage(msg, isError = false) {
|
||
promMessageBox.textContent = msg;
|
||
promMessageBox.className = 'form-message ' + (isError ? 'error' : 'success');
|
||
}
|
||
|
||
// --- Step Controller ---
|
||
async function checkStatus() {
|
||
try {
|
||
const res = await fetch('/api/setup/status');
|
||
const data = await res.json();
|
||
|
||
initForm.style.display = 'none';
|
||
adminForm.style.display = 'none';
|
||
promForm.style.display = 'none';
|
||
|
||
if (!data.initialized) {
|
||
initForm.style.display = 'block';
|
||
initHeaderTitle.textContent = '数据库初始化';
|
||
initHeaderDesc.textContent = '请配置您的 MySQL 数据库连接信息以完成首次设置';
|
||
} else if (data.needsAdmin) {
|
||
adminForm.style.display = 'block';
|
||
initHeaderTitle.textContent = '创建管理员账户';
|
||
initHeaderDesc.textContent = '请设置系统的第一个管理员账号和密码';
|
||
} else {
|
||
promForm.style.display = 'block';
|
||
initHeaderTitle.textContent = '配置 Prometheus';
|
||
initHeaderDesc.textContent = '配置您的第一个 Prometheus 数据源监控连接';
|
||
if (promName) promName.value = ''; // Ensure it's clear on load
|
||
}
|
||
} catch (err) {
|
||
initForm.style.display = 'block';
|
||
}
|
||
}
|
||
|
||
checkStatus();
|
||
|
||
btnTest.addEventListener('click', async () => {
|
||
btnTest.disabled = true;
|
||
const oldText = btnTest.textContent;
|
||
btnTest.textContent = '测试中...';
|
||
try {
|
||
const res = await fetch('/api/setup/test', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({
|
||
host: hostInput.value,
|
||
port: portInput.value,
|
||
user: userInput.value,
|
||
password: passwordInput.value
|
||
})
|
||
});
|
||
const data = await res.json();
|
||
if (data.success) {
|
||
showMessage('连接成功!可以进行初始化。');
|
||
} else {
|
||
showMessage('连接失败: ' + (data.error || '未知错误'), true);
|
||
}
|
||
} catch (err) {
|
||
showMessage('请求失败: ' + err.message, true);
|
||
} finally {
|
||
btnTest.disabled = false;
|
||
btnTest.textContent = oldText;
|
||
}
|
||
});
|
||
|
||
btnTestValkey.addEventListener('click', async () => {
|
||
btnTestValkey.disabled = true;
|
||
const oldText = btnTestValkey.textContent;
|
||
btnTestValkey.textContent = '测试中...';
|
||
try {
|
||
const res = await fetch('/api/setup/test-valkey', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({
|
||
host: vHostInput.value,
|
||
port: vPortInput.value,
|
||
password: vPasswordInput.value
|
||
})
|
||
});
|
||
const data = await res.json();
|
||
if (data.success) {
|
||
showMessage('Valkey 连接成功!');
|
||
} else {
|
||
showMessage('Valkey 连接失败: ' + (data.error || '未知错误'), true);
|
||
}
|
||
} catch (err) {
|
||
showMessage('Valkey 请求失败: ' + err.message, true);
|
||
} finally {
|
||
btnTestValkey.disabled = false;
|
||
btnTestValkey.textContent = oldText;
|
||
}
|
||
});
|
||
|
||
btnInit.addEventListener('click', async () => {
|
||
btnInit.disabled = true;
|
||
const oldText = btnInit.textContent;
|
||
btnInit.textContent = '初始化中...';
|
||
try {
|
||
const res = await fetch('/api/setup/init', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({
|
||
host: hostInput.value,
|
||
port: portInput.value,
|
||
user: userInput.value,
|
||
password: passwordInput.value,
|
||
database: databaseInput.value,
|
||
vHost: vHostInput.value,
|
||
vPort: vPortInput.value,
|
||
vPassword: vPasswordInput.value
|
||
})
|
||
});
|
||
const data = await res.json();
|
||
if (data.success) {
|
||
showMessage('数据库初始化成功!进入下一步...');
|
||
setTimeout(checkStatus, 1000);
|
||
} else {
|
||
showMessage('初始化失败: ' + (data.error || '未知错误'), true);
|
||
btnInit.disabled = false;
|
||
btnInit.textContent = oldText;
|
||
}
|
||
} catch (err) {
|
||
showMessage('请求失败: ' + err.message, true);
|
||
btnInit.disabled = false;
|
||
btnInit.textContent = oldText;
|
||
}
|
||
});
|
||
|
||
btnAdminCreate.addEventListener('click', async () => {
|
||
const username = adminUsername.value.trim();
|
||
const password = adminPassword.value;
|
||
const confirm = adminPasswordConfirm.value;
|
||
|
||
if (!username || !password) return showAdminMessage('请填写用户名和密码', true);
|
||
if (password !== confirm) return showAdminMessage('两次输入的密码不一致', true);
|
||
|
||
btnAdminCreate.disabled = true;
|
||
btnAdminCreate.textContent = '创建中...';
|
||
|
||
try {
|
||
const res = await fetch('/api/setup/admin', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ username, password })
|
||
});
|
||
const data = await res.json();
|
||
if (res.ok) {
|
||
showAdminMessage('管理员账户创建成功!');
|
||
setTimeout(checkStatus, 1000);
|
||
} else {
|
||
showAdminMessage('创建失败: ' + (data.error || '未知错误'), true);
|
||
btnAdminCreate.disabled = false;
|
||
btnAdminCreate.textContent = '创建账户';
|
||
}
|
||
} catch (err) {
|
||
showAdminMessage('请求失败: ' + err.message, true);
|
||
btnAdminCreate.disabled = false;
|
||
btnAdminCreate.textContent = '创建账户';
|
||
}
|
||
});
|
||
|
||
btnPromTest.addEventListener('click', async () => {
|
||
const url = promUrl.value.trim();
|
||
if (!url) return showPromMessage('请输入 Prometheus URL', true);
|
||
|
||
btnPromTest.disabled = true;
|
||
const oldText = btnPromTest.textContent;
|
||
btnPromTest.textContent = '测试中...';
|
||
try {
|
||
const res = await fetch('/api/sources/test', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ url })
|
||
});
|
||
const data = await res.json();
|
||
if (data.status === 'ok') {
|
||
showPromMessage(`连接成功!Prometheus 版本: ${data.version}`);
|
||
} else {
|
||
showPromMessage(`连接失败: ${data.message || '未知错误'}`, true);
|
||
}
|
||
} catch (err) {
|
||
showPromMessage('请求失败: ' + err.message, true);
|
||
} finally {
|
||
btnPromTest.disabled = false;
|
||
btnPromTest.textContent = oldText;
|
||
}
|
||
});
|
||
|
||
btnPromAdd.addEventListener('click', async () => {
|
||
const name = promName.value.trim();
|
||
const url = promUrl.value.trim();
|
||
const description = promDesc.value.trim();
|
||
if (!name || !url) return showPromMessage('请填写名称和URL', true);
|
||
|
||
btnPromAdd.disabled = true;
|
||
const oldText = btnPromAdd.textContent;
|
||
btnPromAdd.textContent = '保存中...';
|
||
try {
|
||
const res = await fetch('/api/sources', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ name, url, description })
|
||
});
|
||
if (res.ok) {
|
||
showPromMessage('数据源添加成功!即将跳转...');
|
||
setTimeout(() => window.location.href = '/', 1500);
|
||
} else {
|
||
const err = await res.json();
|
||
// If 401, it means we somehow bypassed auth on this step, but it might be okay during init
|
||
showPromMessage(`添加失败: ${err.error || '未知错误'}`, true);
|
||
btnPromAdd.disabled = false;
|
||
btnPromAdd.textContent = oldText;
|
||
}
|
||
} catch (err) {
|
||
showPromMessage('请求失败: ' + err.message, true);
|
||
btnPromAdd.disabled = false;
|
||
btnPromAdd.textContent = oldText;
|
||
}
|
||
});
|
||
});
|