const InstallWizard = { currentStep: 1, totalSteps: 5, init() { this.checkEnv(); this.addProvider(); // 默认添加一个供应商表单 }, checkEnv() { const checks = document.getElementById('envCheckData'); if (!checks) return; const data = JSON.parse(checks.textContent); const container = document.getElementById('envChecks'); container.innerHTML = data.map(c => `
${c.name} ${c.pass ? ' 通过' : ' 未通过' }
`).join(''); }, nextStep() { if (this.currentStep === 4) { // 验证管理员密码 const pwd = document.getElementById('adminPassword').value; const confirm = document.getElementById('adminPasswordConfirm').value; const username = document.getElementById('adminUsername').value; if (!username) { alert('请输入管理员用户名'); return; } if (pwd.length < 6) { alert('密码至少6位'); return; } if (pwd !== confirm) { alert('两次密码不一致'); return; } } if (this.currentStep < this.totalSteps) { this.currentStep++; this.updateSteps(); } }, prevStep() { if (this.currentStep > 1) { this.currentStep--; this.updateSteps(); } }, updateSteps() { document.querySelectorAll('.step-content').forEach((el, i) => { el.classList.toggle('active', i + 1 === this.currentStep); }); document.querySelectorAll('.step-indicator .step').forEach((el, i) => { el.classList.remove('active', 'completed'); if (i + 1 === this.currentStep) el.classList.add('active'); if (i + 1 < this.currentStep) el.classList.add('completed'); }); }, async testDb() { const result = document.getElementById('dbTestResult'); try { const response = await fetch('/api/install/test-db', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ host: document.getElementById('dbHost').value, port: parseInt(document.getElementById('dbPort').value), user: document.getElementById('dbUser').value, password: document.getElementById('dbPassword').value, database: document.getElementById('dbName').value }) }); const text = await response.text(); let data; try { data = JSON.parse(text); } catch (parseErr) { result.innerHTML = '
服务器返回了非 JSON 响应(HTTP ' + response.status + ')。请检查 Web 服务器是否正确配置了 /api/ 路由转发。
原始响应
' + text.replace(/
'; return; } result.innerHTML = `
${data.message}
`; } catch (err) { result.innerHTML = '
请求失败: ' + err.message + '
'; } }, addProvider() { const list = document.getElementById('providerList'); const index = list.children.length; const html = `
供应商 #${index + 1} ${index > 0 ? '' : ''}
`; list.insertAdjacentHTML('beforeend', html); }, generateSecret() { const chars = '0123456789abcdef'; let result = ''; for (let i = 0; i < 64; i++) { result += chars[Math.floor(Math.random() * chars.length)]; } return result; }, async runInstall() { const btn = document.getElementById('installBtn'); const result = document.getElementById('installResult'); // 收集供应商数据 const providers = []; document.querySelectorAll('.provider-item').forEach(item => { const models = item.querySelector('.provider-models').value.split(',').map(m => m.trim()).filter(m => m); providers.push({ name: item.querySelector('.provider-name').value, apiUrl: item.querySelector('.provider-url').value, apiKey: item.querySelector('.provider-key').value, models: models, type: item.querySelector('.provider-type').value, enabled: true }); }); // 供应商配置可选,跳过不完整的条目 const validProviders = providers.filter(p => p.name && p.apiKey); if (validProviders.length === 0 && providers.length > 0) { alert('供应商信息不完整,请填写名称和 API Key,或删除该条目'); return; } btn.disabled = true; btn.textContent = '安装中...'; const setupData = { username: document.getElementById('adminUsername').value, password: document.getElementById('adminPassword').value, dbConfig: { host: document.getElementById('dbHost').value, port: parseInt(document.getElementById('dbPort').value), user: document.getElementById('dbUser').value, password: document.getElementById('dbPassword').value, database: document.getElementById('dbName').value }, appConfig: { jwtSecret: document.getElementById('jwtSecret').value || undefined, jwtExpiry: parseInt(document.getElementById('jwtExpiry').value) || 86400 }, providers: validProviders.length > 0 ? validProviders : [] }; try { const response = await fetch('/api/install/setup', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(setupData) }); const data = await response.json(); if (data.success) { result.innerHTML = '
安装成功!正在跳转到登录页...
'; setTimeout(() => { window.location.href = '/login.php'; }, 2000); } else { result.innerHTML = '
安装失败: ' + data.message + '
'; btn.disabled = false; btn.textContent = '完成安装'; } } catch (err) { result.innerHTML = '
安装失败: ' + err.message + '
'; btn.disabled = false; btn.textContent = '完成安装'; } } }; InstallWizard.init();