mirror of
https://gitee.com/xiarenalofs/squad-rain-ops-mini.git
synced 2026-08-05 21:15:52 +08:00
253 lines
9.6 KiB
HTML
253 lines
9.6 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>系统初始化 - RCON 面板</title>
|
||
<link rel="stylesheet" href="/lib/css/bootstrap.min.css">
|
||
<link rel="stylesheet" href="/lib/css/font-awesome.min.css">
|
||
<style>
|
||
:root {
|
||
/* Modern Palette */
|
||
--primary-color: #4361ee;
|
||
--secondary-color: #3f37c9;
|
||
--success-color: #4caf50;
|
||
--info-color: #00b4d8;
|
||
--warning-color: #f72585;
|
||
--danger-color: #f44336;
|
||
--bg-color: #f8f9fa;
|
||
--text-primary: #2b2d42;
|
||
--text-secondary: #8d99ae;
|
||
--border-color: #edf2f4;
|
||
}
|
||
body {
|
||
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
min-height: 100vh;
|
||
background-color: var(--bg-color);
|
||
margin: 0;
|
||
padding: 20px;
|
||
color: var(--text-primary);
|
||
-webkit-font-smoothing: antialiased;
|
||
}
|
||
.setup-container {
|
||
background: white;
|
||
padding: 3rem;
|
||
border-radius: 12px;
|
||
box-shadow: 0 10px 25px rgba(0,0,0,0.05);
|
||
width: 100%;
|
||
max-width: 500px;
|
||
border: 1px solid var(--border-color);
|
||
}
|
||
h2 {
|
||
text-align: center;
|
||
color: var(--text-primary);
|
||
margin-bottom: 2rem;
|
||
border-bottom: 2px solid var(--border-color);
|
||
padding-bottom: 1rem;
|
||
font-weight: 700;
|
||
}
|
||
.section-title {
|
||
font-size: 1.1rem;
|
||
font-weight: 600;
|
||
color: var(--text-primary);
|
||
margin: 1.5rem 0 1rem;
|
||
padding-left: 0.75rem;
|
||
border-left: 4px solid var(--primary-color);
|
||
}
|
||
.form-group {
|
||
margin-bottom: 1.5rem;
|
||
}
|
||
label {
|
||
display: block;
|
||
margin-bottom: 0.5rem;
|
||
color: var(--text-secondary);
|
||
font-weight: 500;
|
||
font-size: 0.95rem;
|
||
}
|
||
input {
|
||
width: 100%;
|
||
padding: 0.8rem;
|
||
border: 1px solid var(--border-color);
|
||
border-radius: 6px;
|
||
box-sizing: border-box;
|
||
font-size: 1rem;
|
||
transition: all 0.2s;
|
||
color: var(--text-primary);
|
||
background-color: #f8f9fa;
|
||
}
|
||
input:focus {
|
||
border-color: var(--primary-color);
|
||
background-color: white;
|
||
outline: none;
|
||
box-shadow: 0 0 0 3px rgba(67, 97, 238, 0.15);
|
||
}
|
||
.hint {
|
||
font-size: 0.85rem;
|
||
color: var(--text-secondary);
|
||
margin-top: 0.4rem;
|
||
}
|
||
button {
|
||
width: 100%;
|
||
padding: 1rem;
|
||
background-color: var(--success-color);
|
||
color: white;
|
||
border: none;
|
||
border-radius: 6px;
|
||
font-size: 1.1rem;
|
||
cursor: pointer;
|
||
margin-top: 2rem;
|
||
font-weight: 600;
|
||
transition: all 0.2s ease;
|
||
box-shadow: 0 4px 6px rgba(76, 175, 80, 0.2);
|
||
}
|
||
button:hover {
|
||
background-color: #43a047;
|
||
transform: translateY(-1px);
|
||
box-shadow: 0 6px 8px rgba(76, 175, 80, 0.3);
|
||
}
|
||
.error {
|
||
color: #721c24;
|
||
background-color: #f8d7da;
|
||
border: 1px solid #f5c6cb;
|
||
padding: 1rem;
|
||
border-radius: 6px;
|
||
margin-bottom: 1.5rem;
|
||
display: none;
|
||
}
|
||
.btn-secondary {
|
||
background-color: var(--secondary-color);
|
||
margin-top: 0.5rem;
|
||
}
|
||
.btn-secondary:hover {
|
||
background-color: #5a6268;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="setup-container">
|
||
<h2>系统初始化向导</h2>
|
||
<div id="error-msg" class="error"></div>
|
||
|
||
<form id="setupForm" onsubmit="submitSetup(event)">
|
||
<div class="section-title"><i class="fas fa-network-wired"></i> RCON 连接配置</div>
|
||
<div class="form-group">
|
||
<label for="ip"><i class="fas fa-server"></i> 服务器 IP</label>
|
||
<input type="text" id="ip" placeholder="例如: 127.0.0.1" required>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="port"><i class="fas fa-ethernet"></i> RCON 端口</label>
|
||
<input type="number" id="port" placeholder="例如: 34889" required min="1" max="65535">
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="password"><i class="fas fa-key"></i> RCON 密码</label>
|
||
<input type="text" id="password" required>
|
||
</div>
|
||
|
||
<div class="section-title"><i class="fas fa-user-cog"></i> Web 面板登录配置</div>
|
||
<div class="form-group">
|
||
<label for="webUser"><i class="fas fa-user"></i> 管理员用户名</label>
|
||
<input type="text" id="webUser" value="admin" required>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="webPassword"><i class="fas fa-lock"></i> 管理员密码</label>
|
||
<input type="text" id="webPassword" placeholder="留空则自动生成随机密码">
|
||
<div class="hint">要求:长度≥6,且包含数字、字母、符号中至少2种</div>
|
||
</div>
|
||
<button type="button" class="btn-secondary" onclick="generatePwd()"><i class="fas fa-random"></i> 生成强密码</button>
|
||
|
||
<button type="submit"><i class="fas fa-check-circle"></i> 完成配置并启动</button>
|
||
</form>
|
||
</div>
|
||
|
||
<script>
|
||
document.addEventListener('DOMContentLoaded', async () => {
|
||
try {
|
||
const res = await fetch('/api/setup/detect-config');
|
||
if (res.ok) {
|
||
const config = await res.json();
|
||
|
||
// 若在同一台机器上运行,使用127.0.0.1通常更稳妥。
|
||
if(config.ip=="0.0.0.0"){
|
||
config.ip="127.0.0.1";
|
||
}
|
||
|
||
if (config.ip) document.getElementById('ip').value = config.ip;
|
||
if (config.port) document.getElementById('port').value = config.port;
|
||
if (config.password) document.getElementById('password').value = config.password;
|
||
|
||
const errorDiv = document.getElementById('error-msg');
|
||
errorDiv.style.backgroundColor = '#d4edda';
|
||
errorDiv.style.borderColor = '#c3e6cb';
|
||
errorDiv.style.color = '#155724';
|
||
errorDiv.textContent = '已自动检测并加载本地 RCON 配置 (SquadGame/ServerConfig/Rcon.cfg)';
|
||
errorDiv.style.display = 'block';
|
||
}
|
||
} catch (e) {
|
||
console.log('No local config detected or API error', e);
|
||
}
|
||
});
|
||
|
||
function generatePwd() {
|
||
const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||
const digits = "0123456789";
|
||
const symbols = "!@#$%^&*()_+-=[]{}|;:,.<>?";
|
||
|
||
let pwd = "";
|
||
pwd += chars.charAt(Math.floor(Math.random() * chars.length));
|
||
pwd += digits.charAt(Math.floor(Math.random() * digits.length));
|
||
pwd += symbols.charAt(Math.floor(Math.random() * symbols.length));
|
||
|
||
const all = chars + digits + symbols;
|
||
for(let i=0; i<9; i++) {
|
||
pwd += all.charAt(Math.floor(Math.random() * all.length));
|
||
}
|
||
|
||
// Shuffle
|
||
pwd = pwd.split('').sort(() => 0.5 - Math.random()).join('');
|
||
document.getElementById('webPassword').value = pwd;
|
||
}
|
||
|
||
async function submitSetup(e) {
|
||
e.preventDefault();
|
||
const errorDiv = document.getElementById('error-msg');
|
||
errorDiv.style.display = 'none';
|
||
|
||
const data = {
|
||
ip: document.getElementById('ip').value,
|
||
port: parseInt(document.getElementById('port').value),
|
||
password: document.getElementById('password').value,
|
||
webUser: document.getElementById('webUser').value,
|
||
webPassword: document.getElementById('webPassword').value
|
||
};
|
||
|
||
try {
|
||
const res = await fetch('/api/setup', {
|
||
method: 'POST',
|
||
headers: {'Content-Type': 'application/json'},
|
||
body: JSON.stringify(data)
|
||
});
|
||
|
||
const result = await res.json();
|
||
|
||
if (res.ok) {
|
||
if (result.generatedPassword) {
|
||
alert('系统已为您生成随机密码:\n' + result.generatedPassword + '\n\n请务必记录!确认后将跳转登录页。');
|
||
} else {
|
||
alert('配置成功!即将跳转登录页。');
|
||
}
|
||
window.location.href = '/login.html';
|
||
} else {
|
||
errorDiv.textContent = result.error || '配置失败';
|
||
errorDiv.style.display = 'block';
|
||
}
|
||
} catch (err) {
|
||
errorDiv.textContent = '请求失败: ' + err.message;
|
||
errorDiv.style.display = 'block';
|
||
}
|
||
}
|
||
</script>
|
||
</body>
|
||
</html> |