上传文件至「/」
This commit is contained in:
@@ -0,0 +1,197 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'functions.php';
|
||||||
|
|
||||||
|
if (!isLoggedIn() || !isAdmin()) {
|
||||||
|
header('Location: auth.php');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdo = getDB();
|
||||||
|
$message = null;
|
||||||
|
|
||||||
|
// 处理管理操作
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$action = $_POST['action'] ?? '';
|
||||||
|
|
||||||
|
switch ($action) {
|
||||||
|
case 'update_credits':
|
||||||
|
$targetUser = intval($_POST['user_id']);
|
||||||
|
$amount = intval($_POST['amount']);
|
||||||
|
$type = $_POST['type'];
|
||||||
|
|
||||||
|
if ($type === 'add') {
|
||||||
|
addCredits($targetUser, $amount);
|
||||||
|
$message = ['success' => true, 'message' => '积分添加成功。'];
|
||||||
|
} else {
|
||||||
|
$result = deductCredits($targetUser, $amount);
|
||||||
|
$message = $result;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'delete_user':
|
||||||
|
$userId = intval($_POST['user_id']);
|
||||||
|
if ($userId == getCurrentUserId()) {
|
||||||
|
$message = ['success' => false, 'message' => '不能删除自己的账号。'];
|
||||||
|
} else {
|
||||||
|
$stmt = $pdo->prepare("DELETE FROM users WHERE id = ?");
|
||||||
|
$stmt->execute([$userId]);
|
||||||
|
$message = ['success' => true, 'message' => '用户已删除。'];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'toggle_admin':
|
||||||
|
$userId = intval($_POST['user_id']);
|
||||||
|
$isAdmin = intval($_POST['is_admin']);
|
||||||
|
$newStatus = $isAdmin ? 0 : 1;
|
||||||
|
$stmt = $pdo->prepare("UPDATE users SET is_admin = ? WHERE id = ?");
|
||||||
|
$stmt->execute([$newStatus, $userId]);
|
||||||
|
$message = ['success' => true, 'message' => '成功更新管理员的状态。'];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取所有用户
|
||||||
|
$users = $pdo->query("SELECT * FROM users ORDER BY created_at DESC")->fetchAll();
|
||||||
|
|
||||||
|
$currentTheme = getTheme();
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN" data-theme="<?php echo $currentTheme; ?>">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>后台管理 - <?php echo SITE_NAME; ?></title>
|
||||||
|
<link rel="preload" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.0/css/all.min.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<header>
|
||||||
|
<div class="header-content">
|
||||||
|
<h1><i class="fas fa-crown"></i> 管理面板</h1>
|
||||||
|
<div class="header-actions">
|
||||||
|
<a href="dashboard.php" class="btn btn-primary btn-sm">
|
||||||
|
<i class="fas fa-arrow-left"></i> 返回面板
|
||||||
|
</a>
|
||||||
|
<form method="POST" style="display: inline;">
|
||||||
|
<input type="hidden" name="action" value="toggle_theme">
|
||||||
|
<button type="submit" class="theme-toggle" title="切换主题">
|
||||||
|
<i class="fas <?php echo $currentTheme === 'dark' ? 'fa-sun' : 'fa-moon'; ?>"></i>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
<form method="POST" style="display: inline;">
|
||||||
|
<input type="hidden" name="action" value="logout">
|
||||||
|
<button type="submit" class="btn btn-danger btn-sm" style="background:transparent;border:1px solid var(--border-color);color:var(--text-secondary);">
|
||||||
|
<i class="fas fa-sign-out-alt"></i> 退出
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<?php if ($message): ?>
|
||||||
|
<div class="alert alert-<?php echo $message['success'] ? 'success' : 'error'; ?>">
|
||||||
|
<i class="fas <?php echo $message['success'] ? 'fa-check-circle' : 'fa-exclamation-circle'; ?>"></i>
|
||||||
|
<?php echo htmlspecialchars($message['message']); ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<!-- 统计 -->
|
||||||
|
<div class="stats-grid">
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="number"><?php echo count($users); ?></div>
|
||||||
|
<div class="label"><i class="fas fa-users"></i> 总用户</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="number" style="color:var(--accent-green);">
|
||||||
|
<?php
|
||||||
|
$verified = array_filter($users, fn($u) => $u['is_verified']);
|
||||||
|
echo count($verified);
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<div class="label"><i class="fas fa-check-circle"></i> 已验证</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card">
|
||||||
|
<div class="number" style="color:var(--accent-yellow);">
|
||||||
|
<?php
|
||||||
|
$admins = array_filter($users, fn($u) => $u['is_admin']);
|
||||||
|
echo count($admins);
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<div class="label"><i class="fas fa-crown"></i> 管理员</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 用户列表 -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h2><i class="fas fa-list"></i> 用户管理</h2>
|
||||||
|
<span class="badge"><?php echo count($users); ?></span>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<?php foreach ($users as $user): ?>
|
||||||
|
<div class="user-row">
|
||||||
|
<div class="user-info">
|
||||||
|
<strong><?php echo htmlspecialchars($user['username']); ?></strong>
|
||||||
|
<span style="color:var(--text-secondary);font-size:13px;">
|
||||||
|
<?php echo htmlspecialchars($user['email']); ?>
|
||||||
|
</span>
|
||||||
|
<span class="user-badge <?php echo $user['is_admin'] ? 'admin' : 'user'; ?>">
|
||||||
|
<?php echo $user['is_admin'] ? '👑 管理员' : '用户'; ?>
|
||||||
|
</span>
|
||||||
|
<span class="user-badge <?php echo $user['is_verified'] ? 'verified' : 'unverified'; ?>">
|
||||||
|
<?php echo $user['is_verified'] ? '✅ 已验证' : '❌ 未验证'; ?>
|
||||||
|
</span>
|
||||||
|
<span style="color:var(--accent-yellow);font-size:14px;">
|
||||||
|
<i class="fas fa-coins"></i> <?php echo $user['credits']; ?>
|
||||||
|
</span>
|
||||||
|
<span style="font-size:12px;color:var(--text-muted);">
|
||||||
|
<?php echo date('Y-m-d', strtotime($user['created_at'])); ?>
|
||||||
|
</span>
|
||||||
|
<?php if ($user['invite_code']): ?>
|
||||||
|
<span style="font-size:12px;color:var(--text-muted);">
|
||||||
|
<i class="fas fa-gift"></i> <?php echo htmlspecialchars($user['invite_code']); ?>
|
||||||
|
</span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
<div class="admin-actions">
|
||||||
|
<!-- 修改积分 -->
|
||||||
|
<form method="POST" style="display:inline-flex;gap:4px;align-items:center;" onsubmit="return confirm('确定要修改积分吗?');">
|
||||||
|
<input type="hidden" name="action" value="update_credits">
|
||||||
|
<input type="hidden" name="user_id" value="<?php echo $user['id']; ?>">
|
||||||
|
<input type="number" name="amount" value="5" style="width:60px;padding:4px 6px;border-radius:4px;border:1px solid var(--border-color);background:var(--bg-input);color:var(--text-primary);">
|
||||||
|
<select name="type" style="padding:4px 6px;border-radius:4px;border:1px solid var(--border-color);background:var(--bg-input);color:var(--text-primary);">
|
||||||
|
<option value="add">+</option>
|
||||||
|
<option value="deduct">-</option>
|
||||||
|
</select>
|
||||||
|
<button type="submit" class="btn btn-primary btn-sm" style="padding:4px 10px;">积分</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<!-- 切换管理员 -->
|
||||||
|
<form method="POST" style="display:inline;" onsubmit="return confirm('确定要切换管理员状态吗?');">
|
||||||
|
<input type="hidden" name="action" value="toggle_admin">
|
||||||
|
<input type="hidden" name="user_id" value="<?php echo $user['id']; ?>">
|
||||||
|
<input type="hidden" name="is_admin" value="<?php echo $user['is_admin']; ?>">
|
||||||
|
<button type="submit" class="btn btn-sm" style="background:var(--bg-primary);border:1px solid var(--border-color);color:var(--text-secondary);padding:4px 10px;">
|
||||||
|
<?php echo $user['is_admin'] ? '降级' : '升级'; ?>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<!-- 删除用户 -->
|
||||||
|
<?php if ($user['id'] != getCurrentUserId()): ?>
|
||||||
|
<form method="POST" style="display:inline;" onsubmit="return confirm('确定要删除用户 <?php echo htmlspecialchars($user['username']); ?> 吗?此操作不可恢复!');">
|
||||||
|
<input type="hidden" name="action" value="delete_user">
|
||||||
|
<input type="hidden" name="user_id" value="<?php echo $user['id']; ?>">
|
||||||
|
<button type="submit" class="btn btn-danger btn-sm" style="padding:4px 10px;">
|
||||||
|
<i class="fas fa-trash"></i>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'functions.php';
|
||||||
|
|
||||||
|
$action = $_GET['action'] ?? 'login';
|
||||||
|
$message = null;
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$action = $_POST['action'] ?? 'login';
|
||||||
|
|
||||||
|
if ($action === 'register') {
|
||||||
|
$username = trim($_POST['username']);
|
||||||
|
$email = trim($_POST['email']);
|
||||||
|
$password = $_POST['password'];
|
||||||
|
$confirmPassword = $_POST['confirm_password'];
|
||||||
|
$inviteCode = trim($_POST['invite_code'] ?? '');
|
||||||
|
|
||||||
|
if ($password !== $confirmPassword) {
|
||||||
|
$message = ['success' => false, 'message' => '两次密码输入不一致。'];
|
||||||
|
} elseif (strlen($password) < 6) {
|
||||||
|
$message = ['success' => false, 'message' => '密码长度至少 6 位。'];
|
||||||
|
} else {
|
||||||
|
$message = registerUser($username, $email, $password, $inviteCode);
|
||||||
|
}
|
||||||
|
} elseif ($action === 'login') {
|
||||||
|
$username = trim($_POST['username']);
|
||||||
|
$password = $_POST['password'];
|
||||||
|
$message = loginUser($username, $password);
|
||||||
|
|
||||||
|
if ($message['success']) {
|
||||||
|
header('Location: dashboard.php');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$currentTheme = getTheme();
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN" data-theme="<?php echo $currentTheme; ?>">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title><?php echo $action === 'login' ? '登录' : '注册'; ?> - <?php echo SITE_NAME; ?></title>
|
||||||
|
<link rel="preload" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.0/css/all.min.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container auth-container">
|
||||||
|
<div class="auth-card">
|
||||||
|
<h2><i class="fas fa-<?php echo $action === 'login' ? 'sign-in-alt' : 'user-plus'; ?>"></i>
|
||||||
|
<?php echo $action === 'login' ? '登录' : '注册'; ?>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<?php if ($message): ?>
|
||||||
|
<div class="alert alert-<?php echo $message['success'] ? 'success' : 'error'; ?>">
|
||||||
|
<i class="fas <?php echo $message['success'] ? 'fa-check-circle' : 'fa-exclamation-circle'; ?>"></i>
|
||||||
|
<?php echo htmlspecialchars($message['message']); ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if ($action === 'login'): ?>
|
||||||
|
<form method="POST">
|
||||||
|
<input type="hidden" name="action" value="login">
|
||||||
|
<div class="form-group">
|
||||||
|
<label><i class="fas fa-user"></i> 账号</label>
|
||||||
|
<input type="text" name="username" placeholder="请输入用户名或邮箱..." required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label><i class="fas fa-lock"></i> 密码</label>
|
||||||
|
<input type="password" name="password" placeholder="请输入密码..." required>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary" style="width:100%;justify-content:center;">
|
||||||
|
<i class="fas fa-sign-in-alt"></i> 登录
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
<div class="auth-switch">
|
||||||
|
还没有账号?<a href="?action=register">立即注册</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php else: ?>
|
||||||
|
<form method="POST">
|
||||||
|
<input type="hidden" name="action" value="register">
|
||||||
|
<div class="form-group">
|
||||||
|
<label><i class="fas fa-user"></i> 用户名</label>
|
||||||
|
<input type="text" name="username" placeholder="请输入用户名..." required minlength="3" maxlength="30">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label><i class="fas fa-envelope"></i> 邮箱</label>
|
||||||
|
<input type="email" name="email" placeholder="请输入邮箱地址..." required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label><i class="fas fa-lock"></i> 密码</label>
|
||||||
|
<input type="password" name="password" placeholder="请输入至少 6 位数的密码..." required minlength="6">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label><i class="fas fa-lock"></i> 确认密码</label>
|
||||||
|
<input type="password" name="confirm_password" placeholder="请再次输入密码" required minlength="6">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label><i class="fas fa-gift"></i> 邀请码(选填)</label>
|
||||||
|
<input type="text" name="invite_code" placeholder="输入邀请码可获得额外积分...">
|
||||||
|
<div class="invite-hint"><i class="fas fa-info-circle"></i> 使用邀请码注册可让邀请人获得 <?php echo INVITE_CREDIT; ?> 积分</div>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary" style="width:100%;justify-content:center;">
|
||||||
|
<i class="fas fa-user-plus"></i> 注册
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
<div class="auth-switch">
|
||||||
|
已有账号?<a href="?action=login">立即登录</a>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"require": {
|
||||||
|
"phpmailer/phpmailer": "*"
|
||||||
|
}
|
||||||
|
}
|
||||||
+72
@@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
define('DB_HOST', '');
|
||||||
|
define('DB_NAME', '');
|
||||||
|
define('DB_USER', '');
|
||||||
|
define('DB_PASS', '');
|
||||||
|
define('DB_CHARSET', 'utf8mb4');
|
||||||
|
|
||||||
|
$DOMAINS_CONFIG = [
|
||||||
|
'Domain1' => [
|
||||||
|
'zone_id' => '',
|
||||||
|
'api_token' => ''
|
||||||
|
],
|
||||||
|
'Domain2' => [
|
||||||
|
'zone_id' => '',
|
||||||
|
'api_token' => ''
|
||||||
|
],
|
||||||
|
'Domain3' => [
|
||||||
|
'zone_id' => '',
|
||||||
|
'api_token' => ''
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
define('SMTP_HOST', '');
|
||||||
|
define('SMTP_PORT', 587);
|
||||||
|
define('SMTP_SECURE', 'tls');
|
||||||
|
define('SMTP_USERNAME', '');
|
||||||
|
define('SMTP_PASSWORD', '');
|
||||||
|
define('SMTP_FROM_EMAIL', '');
|
||||||
|
define('SMTP_FROM_NAME', '');
|
||||||
|
define('SITE_URL', '');
|
||||||
|
define('SITE_NAME', '');
|
||||||
|
define('CREDIT_PER_DOMAIN', 5);
|
||||||
|
define('MAX_DOMAINS_PER_USER', 10);
|
||||||
|
define('SIGN_IN_CREDIT', 2);
|
||||||
|
define('INVITE_CREDIT', 10);
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
function getDB() {
|
||||||
|
static $pdo = null;
|
||||||
|
if ($pdo === null) {
|
||||||
|
try {
|
||||||
|
$dsn = "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=" . DB_CHARSET;
|
||||||
|
$pdo = new PDO($dsn, DB_USER, DB_PASS, [
|
||||||
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||||
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||||
|
PDO::ATTR_EMULATE_PREPARES => false
|
||||||
|
]);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
die("数据库连接失败: " . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $pdo;
|
||||||
|
}
|
||||||
|
|
||||||
|
function initConfig() {
|
||||||
|
$pdo = getDB();
|
||||||
|
try {
|
||||||
|
$stmt = $pdo->query("SELECT setting_key, setting_value FROM settings");
|
||||||
|
while ($row = $stmt->fetch()) {
|
||||||
|
$key = $row['setting_key'];
|
||||||
|
$value = $row['setting_value'];
|
||||||
|
if (!defined(strtoupper($key))) {
|
||||||
|
define(strtoupper($key), $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initConfig();
|
||||||
|
?>
|
||||||
+413
@@ -0,0 +1,413 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'functions.php';
|
||||||
|
if (!isLoggedIn()) {
|
||||||
|
header('Location: auth.php');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
$userId = getCurrentUserId();
|
||||||
|
$userInfo = getUserInfo($userId);
|
||||||
|
$domains = getUserDomains($userId);
|
||||||
|
$domainCount = count($domains);
|
||||||
|
$credits = $userInfo['credits'];
|
||||||
|
$canAdd = canAddDomain($userId);
|
||||||
|
$signInToday = hasSignedInToday($userId);
|
||||||
|
$signInStats = getSignInStats($userId);
|
||||||
|
$inviteStats = getInviteStats($userId);
|
||||||
|
$mainDomains = getMainDomains();
|
||||||
|
$recordTypes = getRecordTypes();
|
||||||
|
$message = null;
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$action = $_POST['action'] ?? '';
|
||||||
|
switch ($action) {
|
||||||
|
case 'add_domain':
|
||||||
|
$mainDomain = trim($_POST['main_domain']);
|
||||||
|
$subdomain = trim($_POST['subdomain']);
|
||||||
|
$type = $_POST['type'];
|
||||||
|
$value = trim($_POST['value']);
|
||||||
|
|
||||||
|
if (empty($mainDomain) || empty($subdomain) || empty($value)) {
|
||||||
|
$message = ['success' => false, 'message' => '请填写完整的表单。'];
|
||||||
|
} else {
|
||||||
|
$message = addDomain($userId, $mainDomain, $subdomain, $type, $value);
|
||||||
|
if ($message['success']) {
|
||||||
|
header('Location: dashboard.php?success=1');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'delete_domain':
|
||||||
|
$domainId = intval($_POST['domain_id']);
|
||||||
|
$message = deleteDomain($userId, $domainId);
|
||||||
|
if ($message['success']) {
|
||||||
|
header('Location: dashboard.php?deleted=1');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'sign_in':
|
||||||
|
$message = signIn($userId);
|
||||||
|
if ($message['success']) {
|
||||||
|
header('Location: dashboard.php?signed=1');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'toggle_theme':
|
||||||
|
toggleTheme();
|
||||||
|
header('Location: dashboard.php');
|
||||||
|
exit;
|
||||||
|
|
||||||
|
case 'logout':
|
||||||
|
session_destroy();
|
||||||
|
header('Location: auth.php');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$userInfo = getUserInfo($userId);
|
||||||
|
$domains = getUserDomains($userId);
|
||||||
|
$domainCount = count($domains);
|
||||||
|
$credits = $userInfo['credits'];
|
||||||
|
$canAdd = canAddDomain($userId);
|
||||||
|
$signInToday = hasSignedInToday($userId);
|
||||||
|
$signInStats = getSignInStats($userId);
|
||||||
|
$inviteStats = getInviteStats($userId);
|
||||||
|
$currentTheme = getTheme();
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN" data-theme="<?php echo $currentTheme; ?>">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>用户面板 - <?php echo SITE_NAME; ?></title>
|
||||||
|
<link rel="preload" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.0/css/all.min.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<header>
|
||||||
|
<div class="header-content">
|
||||||
|
<h1><i class="fas fa-globe"></i> <?php echo SITE_NAME; ?></h1>
|
||||||
|
<div class="header-actions">
|
||||||
|
<span class="domain-badge"><i class="fas fa-user"></i> <?php echo htmlspecialchars($userInfo['username']); ?></span>
|
||||||
|
<form method="POST" style="display: inline;">
|
||||||
|
<input type="hidden" name="action" value="toggle_theme">
|
||||||
|
<button type="submit" class="theme-toggle" title="切换主题">
|
||||||
|
<i class="fas <?php echo $currentTheme === 'dark' ? 'fa-sun' : 'fa-moon'; ?>"></i>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
<form method="POST" style="display: inline;">
|
||||||
|
<input type="hidden" name="action" value="logout">
|
||||||
|
<button type="submit" class="btn btn-danger btn-sm" style="background:transparent;border:1px solid var(--border-color);color:var(--text-secondary);">
|
||||||
|
<i class="fas fa-sign-out-alt"></i> 退出
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!-- 消息提示 -->
|
||||||
|
<?php if (isset($_GET['success']) || isset($_GET['deleted']) || isset($_GET['signed'])): ?>
|
||||||
|
<div class="alert alert-success">
|
||||||
|
<i class="fas fa-check-circle"></i>
|
||||||
|
<?php
|
||||||
|
if (isset($_GET['success'])) echo '成功添加了域名!';
|
||||||
|
elseif (isset($_GET['deleted'])) echo '成功删除了域名!';
|
||||||
|
elseif (isset($_GET['signed'])) echo '成功签到!';
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if ($message): ?>
|
||||||
|
<div class="alert alert-<?php echo $message['success'] ? 'success' : 'error'; ?>">
|
||||||
|
<i class="fas <?php echo $message['success'] ? 'fa-check-circle' : 'fa-exclamation-circle'; ?>"></i>
|
||||||
|
<?php echo htmlspecialchars($message['message']); ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<!-- 欢迎区域 -->
|
||||||
|
<div class="welcome-header">
|
||||||
|
<div>
|
||||||
|
<h1>👋 欢迎回来,<?php echo htmlspecialchars($userInfo['username']); ?>!</h1>
|
||||||
|
<p style="color:var(--text-secondary);font-size:14px;">
|
||||||
|
<p id="hitokoto">
|
||||||
|
“<b id="hitokoto_text">:D 获取中...</b>”
|
||||||
|
</p>
|
||||||
|
您在 <?php echo date('Y-m-d', strtotime($userInfo['created_at'])); ?> 注册
|
||||||
|
<?php if ($userInfo['is_admin']): ?>
|
||||||
|
<span style="background:var(--accent-blue);color:#fff;padding:2px 12px;border-radius:4px;font-size:12px;margin-left:10px;">
|
||||||
|
<i class="fas fa-crown"></i> 管理员
|
||||||
|
</span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="user-actions">
|
||||||
|
<?php if ($userInfo['is_admin']): ?>
|
||||||
|
<a href="admin.php" class="btn btn-primary">
|
||||||
|
<i class="fas fa-cog"></i> 后台管理
|
||||||
|
</a>
|
||||||
|
<?php endif; ?>
|
||||||
|
<form method="POST" style="display:inline;">
|
||||||
|
<input type="hidden" name="action" value="sign_in">
|
||||||
|
<button type="submit" class="btn btn-primary" <?php echo $signInToday ? 'disabled' : ''; ?>>
|
||||||
|
<i class="fas fa-calendar-check"></i>
|
||||||
|
<?php echo $signInToday ? '已签到' : '签到 (+' . SIGN_IN_CREDIT . '积分)'; ?>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 统计卡片 -->
|
||||||
|
<div class="stats-grid">
|
||||||
|
<div class="stat-card credits">
|
||||||
|
<div class="number"><?php echo $credits; ?></div>
|
||||||
|
<div class="label"><i class="fas fa-coins"></i> 当前积分</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card domains">
|
||||||
|
<div class="number"><?php echo $domainCount; ?> / <?php echo MAX_DOMAINS_PER_USER; ?></div>
|
||||||
|
<div class="label"><i class="fas fa-globe"></i> 域名数量</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card signin">
|
||||||
|
<div class="number"><?php echo $signInStats['total'] ?? 0; ?></div>
|
||||||
|
<div class="label"><i class="fas fa-calendar-alt"></i> 签到次数</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-card" style="border-color:var(--accent-yellow);">
|
||||||
|
<div class="number" style="color:var(--accent-yellow);"><?php echo $inviteStats['count'] ?? 0; ?></div>
|
||||||
|
<div class="label"><i class="fas fa-users"></i> 邀请人数</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 邀请码区域 -->
|
||||||
|
<div class="invite-box">
|
||||||
|
<div style="display:flex;align-items:center;gap:12px;flex-wrap:wrap;">
|
||||||
|
<span><i class="fas fa-gift" style="color:var(--accent-yellow);"></i> 你的邀请码</span>
|
||||||
|
<span class="invite-code" id="inviteCode"><?php echo htmlspecialchars($userInfo['invite_code']); ?></span>
|
||||||
|
<span style="font-size:13px;color:var(--text-secondary);">
|
||||||
|
<i class="fas fa-users"></i> 已邀请 <?php echo $inviteStats['count'] ?? 0; ?> 人
|
||||||
|
(获得 <?php echo $inviteStats['total_credits'] ?? 0; ?> 积分)
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<button class="copy-btn" onclick="copyInviteCode()">
|
||||||
|
<i class="fas fa-copy"></i> 复制链接
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 添加域名 -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h2><i class="fas fa-plus-circle"></i> 添加新域名</h2>
|
||||||
|
<span class="badge" style="background:var(--accent-yellow);">
|
||||||
|
<i class="fas fa-coins"></i> 消耗 <?php echo CREDIT_PER_DOMAIN; ?> 积分
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<?php if (!$canAdd['success']): ?>
|
||||||
|
<div class="alert alert-error">
|
||||||
|
<i class="fas fa-exclamation-circle"></i>
|
||||||
|
<?php echo htmlspecialchars($canAdd['message']); ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<form method="POST" class="add-form" id="addDomainForm">
|
||||||
|
<input type="hidden" name="action" value="add_domain">
|
||||||
|
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group">
|
||||||
|
<label><i class="fas fa-globe"></i> 主域名</label>
|
||||||
|
<select name="main_domain" required <?php echo !$canAdd['success'] ? 'disabled' : ''; ?>>
|
||||||
|
<?php foreach ($mainDomains as $domain): ?>
|
||||||
|
<option value="<?php echo htmlspecialchars($domain); ?>">
|
||||||
|
<?php echo htmlspecialchars($domain); ?>
|
||||||
|
</option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label><i class="fas fa-tag"></i> 子域前缀</label>
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" name="subdomain" placeholder="至少 3 个字符..." required
|
||||||
|
pattern="[a-z0-9\-]+" title="只能包含小写字母、数字和连字符。"
|
||||||
|
minlength="3" maxlength="20"
|
||||||
|
<?php echo !$canAdd['success'] ? 'disabled' : ''; ?>>
|
||||||
|
</div>
|
||||||
|
<div class="form-hint">
|
||||||
|
<i class="fas fa-info-circle"></i>
|
||||||
|
3 - 20 个字符,只能包含小写字母、数字和连字符。不能以连字符开头或结尾。
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group">
|
||||||
|
<label><i class="fas fa-code-branch"></i> 记录类型</label>
|
||||||
|
<select name="type" required id="recordType" <?php echo !$canAdd['success'] ? 'disabled' : ''; ?>>
|
||||||
|
<?php foreach ($recordTypes as $key => $desc): ?>
|
||||||
|
<option value="<?php echo $key; ?>">
|
||||||
|
<?php echo $key . ' - ' . $desc; ?>
|
||||||
|
</option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label><i class="fas fa-map-pin"></i> 记录值</label>
|
||||||
|
<input type="text" name="value" placeholder="根据记录类型填写合适的值..." required
|
||||||
|
id="recordValue"
|
||||||
|
<?php echo !$canAdd['success'] ? 'disabled' : ''; ?>>
|
||||||
|
<div class="record-type-help" id="recordTypeHelp">
|
||||||
|
<i class="fas fa-lightbulb"></i>
|
||||||
|
<span id="recordTypeHint">请选择记录类型查看格式说明</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-primary" <?php echo !$canAdd['success'] ? 'disabled' : ''; ?>>
|
||||||
|
<i class="fas fa-plus"></i> 添加域名 (消耗 <?php echo CREDIT_PER_DOMAIN; ?> 积分)
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 域名列表 -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h2><i class="fas fa-list"></i> 我的域名</h2>
|
||||||
|
<span class="badge"><?php echo $domainCount; ?></span>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<?php if (empty($domains)): ?>
|
||||||
|
<div class="empty-state">
|
||||||
|
<i class="fas fa-inbox"></i>
|
||||||
|
<p>还没有添加...</p>
|
||||||
|
<p style="font-size:13px;margin-top:6px;color:var(--text-muted);">
|
||||||
|
添加域名需要 <?php echo CREDIT_PER_DOMAIN; ?> 积分
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<?php else: ?>
|
||||||
|
<div>
|
||||||
|
<?php foreach ($domains as $domain): ?>
|
||||||
|
<div class="domain-item">
|
||||||
|
<div class="domain-info">
|
||||||
|
<span class="domain-full">
|
||||||
|
<?php echo htmlspecialchars($domain['subdomain']); ?>
|
||||||
|
<small>.<?php echo htmlspecialchars($domain['main_domain']); ?></small>
|
||||||
|
</span>
|
||||||
|
<span class="domain-type"><?php echo htmlspecialchars($domain['record_type']); ?></span>
|
||||||
|
<span class="domain-value">→ <?php echo htmlspecialchars($domain['record_value']); ?></span>
|
||||||
|
<span style="font-size:12px;color:var(--text-muted);">
|
||||||
|
<?php echo date('Y-m-d', strtotime($domain['created_at'])); ?>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<form method="POST" style="display:inline;" onsubmit="return confirm('确定要删除此域名吗?');">
|
||||||
|
<input type="hidden" name="action" value="delete_domain">
|
||||||
|
<input type="hidden" name="domain_id" value="<?php echo $domain['id']; ?>">
|
||||||
|
<button type="submit" class="btn btn-danger btn-sm">
|
||||||
|
<i class="fas fa-trash"></i> 删除
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("get", "https://v1.hitokoto.cn/?c=i");
|
||||||
|
xhr.onreadystatechange = function () {
|
||||||
|
if (xhr.readyState === 4) {
|
||||||
|
const data = JSON.parse(xhr.responseText);
|
||||||
|
const hitokoto = document.querySelector("#hitokoto_text");
|
||||||
|
hitokoto.href = `https://hitokoto.cn/?uuid=${data.uuid}`;
|
||||||
|
hitokoto.innerText = data.hitokoto;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.send();
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const typeSelect = document.getElementById('recordType');
|
||||||
|
const valueInput = document.getElementById('recordValue');
|
||||||
|
const hintSpan = document.getElementById('recordTypeHint');
|
||||||
|
|
||||||
|
// 完整的提示信息
|
||||||
|
const hints = {
|
||||||
|
'A': 'A 记录格式: IPv4 地址(127.0.0.1)',
|
||||||
|
'AAAA': 'AAAA 记录格式: IPv6 地址(2002:7f00:1::)',
|
||||||
|
'CNAME': 'CNAME 记录格式: 目标域名(example.com)',
|
||||||
|
'MX': 'MX 记录格式: 优先级 域名(10 mail.example.com)',
|
||||||
|
'NS': 'NS 记录格式: 域名服务器地址(ns1.example.com)',
|
||||||
|
'TXT': 'TXT 记录格式: 任意文本(admin=me)',
|
||||||
|
'SRV': 'SRV 记录格式: 优先级 权重 端口 目标域名(10 5 5060 sip.example.com)'
|
||||||
|
};
|
||||||
|
|
||||||
|
// 完整的占位符
|
||||||
|
const placeholders = {
|
||||||
|
'A': '192.168.1.1',
|
||||||
|
'AAAA': '2001:db8::1',
|
||||||
|
'CNAME': 'example.com',
|
||||||
|
'MX': '10 mail.example.com',
|
||||||
|
'NS': 'ns1.example.com',
|
||||||
|
'TXT': 'v=spf1 include:example.com ~all',
|
||||||
|
'SRV': '10 5 5060 sip.example.com'
|
||||||
|
};
|
||||||
|
|
||||||
|
// 完整的格式说明(用于提示框底部)
|
||||||
|
const formatDetails = {
|
||||||
|
'A': 'IPv4 地址,例如: 192.168.1.1',
|
||||||
|
'AAAA': 'IPv6 地址,例如: 2001:db8::1',
|
||||||
|
'CNAME': '目标域名,例如: example.com',
|
||||||
|
'MX': '优先级 域名,例如: 10 mail.example.com',
|
||||||
|
'NS': '域名服务器,例如: ns1.example.com',
|
||||||
|
'TXT': '任意文本,最多 255 字符,例如: v=spf1 include:example.com ~all',
|
||||||
|
'SRV': '优先级 权重 端口 目标域名,例如: 10 5 5060 sip.example.com'
|
||||||
|
};
|
||||||
|
|
||||||
|
// 初始显示
|
||||||
|
const initialType = typeSelect.value;
|
||||||
|
hintSpan.innerHTML = hints[initialType] || '请输入记录值。';
|
||||||
|
valueInput.placeholder = placeholders[initialType] || '请输入记录值。';
|
||||||
|
|
||||||
|
// 切换事件
|
||||||
|
typeSelect.addEventListener('change', function() {
|
||||||
|
const type = this.value;
|
||||||
|
hintSpan.innerHTML = hints[type] || '请输入记录值'。;
|
||||||
|
valueInput.placeholder = placeholders[type] || '请输入记录值。';
|
||||||
|
|
||||||
|
// 添加小字提示
|
||||||
|
const helpDiv = document.getElementById('recordTypeHelp');
|
||||||
|
if (formatDetails[type]) {
|
||||||
|
const existingContent = hintSpan.innerHTML;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 当用户输入时,实时显示格式提示
|
||||||
|
valueInput.addEventListener('focus', function() {
|
||||||
|
const type = typeSelect.value;
|
||||||
|
const detail = formatDetails[type] || '';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// ===== 复制邀请码 =====
|
||||||
|
function copyInviteCode() {
|
||||||
|
const code = document.getElementById('inviteCode').textContent;
|
||||||
|
const url = window.location.origin + window.location.pathname.replace(/\/[^\/]*$/, '/') + 'auth.php?action=register&invite=' + code;
|
||||||
|
|
||||||
|
if (navigator.clipboard) {
|
||||||
|
navigator.clipboard.writeText(url).then(() => {
|
||||||
|
alert('邀请链接已复制!\n' + url);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const input = document.createElement('input');
|
||||||
|
input.value = url;
|
||||||
|
document.body.appendChild(input);
|
||||||
|
input.select();
|
||||||
|
document.execCommand('copy');
|
||||||
|
document.body.removeChild(input);
|
||||||
|
alert('邀请链接已复制!\n' + url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user