Files
parlz-domain/dashboard.php
T

413 lines
19 KiB
PHP
Raw Permalink 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.
<?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>