Init 1.0 codes
This commit is contained in:
381
admin/addapp.php
Normal file
381
admin/addapp.php
Normal file
@@ -0,0 +1,381 @@
|
||||
<?php
|
||||
require_once '../config.php';
|
||||
|
||||
session_start();
|
||||
// 检查是否已登录
|
||||
if (!isset($_SESSION['admin'])) {
|
||||
header('Location: login.php');
|
||||
exit();
|
||||
}
|
||||
|
||||
// 非全部权限管理员重定向到对应权限页面
|
||||
if ($_SESSION['admin']['permission'] != 'all') {
|
||||
$redirect = $_SESSION['admin']['permission'] == 'say' ? 'announcements.php' : 'review_apps.php';
|
||||
header("Location: $redirect");
|
||||
exit();
|
||||
}
|
||||
|
||||
$success = '';
|
||||
$error = '';
|
||||
// 处理添加App请求
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_app'])) {
|
||||
$name = $_POST['name'];
|
||||
$description = $_POST['description'];
|
||||
$ageRating = $_POST['age_rating'];
|
||||
$platforms = isset($_POST['platforms']) ? json_encode($_POST['platforms']) : json_encode([]);
|
||||
|
||||
// 处理表单提交
|
||||
// 验证必填字段
|
||||
$required = ['name', 'description', 'age_rating', 'platforms'];
|
||||
$errors = [];
|
||||
foreach ($required as $field) {
|
||||
if (empty($_POST[$field])) {
|
||||
$errors[] = ucfirst($field) . ' 不能为空';
|
||||
}
|
||||
}
|
||||
|
||||
// 年龄分级说明验证
|
||||
if (($_POST['age_rating'] === '12+' || $_POST['age_rating'] === '17+') && empty($_POST['age_rating_description'])) {
|
||||
$errors[] = '年龄分级为12+或以上时,年龄分级说明不能为空';
|
||||
}
|
||||
|
||||
|
||||
// 处理应用图标上传
|
||||
|
||||
// 处理平台数据
|
||||
$platforms = json_encode($_POST['platforms']);
|
||||
// 插入应用数据
|
||||
$stmt = $conn->prepare("INSERT INTO apps (name, description, age_rating, age_rating_description, platforms) VALUES (?, ?, ?, ?, ?)");
|
||||
if (!$stmt) {
|
||||
$error = "Database error: " . $conn->error;
|
||||
}
|
||||
if ($stmt) {
|
||||
$stmt->bind_param("sssss", $name, $description, $ageRating, $_POST['age_rating_description'], $platforms);
|
||||
if ($stmt->execute() === TRUE) {
|
||||
$appId = $stmt->insert_id;
|
||||
|
||||
// 保存标签关联
|
||||
if (!empty($_POST['tags'])) {
|
||||
$stmt = $conn->prepare("INSERT INTO app_tags (app_id, tag_id) VALUES (?, ?)");
|
||||
foreach ($_POST['tags'] as $tagId) {
|
||||
$stmt->bind_param("ii", $appId, $tagId);
|
||||
$stmt->execute();
|
||||
}
|
||||
$stmt->close();
|
||||
}
|
||||
|
||||
// 处理上传的预览图片
|
||||
if (!empty($_FILES['images']['name'][0])) {
|
||||
$uploadDir = '../images/';
|
||||
foreach ($_FILES['images']['tmp_name'] as $key => $tmpName) {
|
||||
$fileName = basename($_FILES['images']['name'][$key]);
|
||||
$targetPath = $uploadDir . $fileName;
|
||||
if (move_uploaded_file($tmpName, $targetPath)) {
|
||||
$insertImageSql = "INSERT INTO app_images (app_id, image_path) VALUES (?, ?)";
|
||||
$imgStmt = $conn->prepare($insertImageSql);
|
||||
$imgStmt->bind_param("is", $appId, $targetPath);
|
||||
$imgStmt->execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理上传的App文件
|
||||
if (!empty($_FILES['app_file']['name'])) {
|
||||
$uploadDir = '../files/';
|
||||
$fileName = basename($_FILES['app_file']['name']);
|
||||
$targetPath = $uploadDir . $fileName;
|
||||
if (move_uploaded_file($_FILES['app_file']['tmp_name'], $targetPath)) {
|
||||
$version = $_POST['version'];
|
||||
$changelog = $_POST['changelog'];
|
||||
$insertVersionSql = "INSERT INTO app_versions (app_id, version, changelog, file_path) VALUES (?, ?, ?, ?)";
|
||||
$verStmt = $conn->prepare($insertVersionSql);
|
||||
$verStmt->bind_param("isss", $appId, $version, $changelog, $targetPath);
|
||||
$verStmt->execute();
|
||||
}
|
||||
}
|
||||
|
||||
echo '<script>Swal.fire("成功", "App 添加成功", "success").then(() => { window.location.href = "index.php"; });</script>';
|
||||
exit;
|
||||
} else {
|
||||
echo '<script>Swal.fire("错误", "App 添加失败: '. $conn->error .'", "error");</script>';
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>添加App - <?php echo APP_STORE_NAME; ?></title>
|
||||
<!-- Bootstrap CSS -->
|
||||
<link href="../css/bootstrap.min.css" rel="stylesheet">
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="/css/all.min.css">
|
||||
<!-- 自定义CSS -->
|
||||
<link rel="stylesheet" href="../styles.css">
|
||||
<script src="/js/sweetalert.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="admin-header">
|
||||
<h1>应用管理系统</h1>
|
||||
<div class="admin-actions">
|
||||
<span>欢迎, <?php echo htmlspecialchars($_SESSION['admin']['username']); ?></span>
|
||||
<a href="#" onclick="confirmLogout()" class="logout-btn">登出</a>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
function confirmLogout() {
|
||||
Swal.fire({
|
||||
title: '确定要登出吗?',
|
||||
icon: 'question',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
window.location.href = 'logout.php';
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<!DOCTYPE html>\n<html lang="zh-CN">\n<head>\n <meta charset="UTF-8">\n <meta name="viewport" content="width=device-width, initial-scale=1.0">\n <title>添加App - <?php echo APP_STORE_NAME; ?></title>\n <!-- Bootstrap CSS -->\n <link href="../css/bootstrap.min.css" rel="stylesheet">\n <!-- 自定义CSS -->\n <link rel="stylesheet" href="../styles.css">\n <script src="/js/sweetalert.js"></script>\n <script>\n function confirmLogout() {\n Swal.fire({\n title: '确定要登出吗?',\n icon: 'question',\n showCancelButton: true,\n confirmButtonText: '确定',\n cancelButtonText: '取消'\n }).then((result) => {\n if (result.isConfirmed) {\n window.location.href = 'logout.php';\n }\n });\n }\n </script>\n <!-- Fluent Design 模糊效果 -->\n <style>\n .blur-bg {
|
||||
backdrop-filter: blur(10px);
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.page-transition {
|
||||
animation: fadeIn 0.5s ease-in-out;
|
||||
}
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="page-transition">
|
||||
<?php if (isset($error)): ?>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.body.classList.add('page-transition');
|
||||
});
|
||||
</script>
|
||||
<div style='color: red; padding: 10px; background-color: #ffeeee; border-radius: 5px; margin-bottom: 20px;'>
|
||||
<?php echo htmlspecialchars($error); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<!-- 导航栏 -->
|
||||
<nav class="navbar navbar-expand-lg navbar-light blur-bg">
|
||||
<div class="container">
|
||||
<a href="../index.php"><img src="/favicon.jpeg" alt="Logo" style="height: 30px; margin-right: 10px; border-radius: var(--border-radius);"></a>
|
||||
<a class="navbar-brand" href="../index.php"><?php echo APP_STORE_NAME; ?></a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="index.php">App列表</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" aria-current="page" href="addapp.php">添加App</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#" onclick="confirmLogout()">退出登录</a>\n </li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container mt-4">
|
||||
<?php if (!empty($success)): ?>
|
||||
<div class="alert alert-success"><?php echo $success; ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($error)): ?>
|
||||
<div class="alert alert-danger"><?php echo $error; ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<h2>添加App</h2>
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" class="form-control" id="name" name="name" required>
|
||||
<label for="name"><i class="fas fa-file-signature me-2"></i>App名称</label>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="description" class="form-label"><i class="fas fa-align-left me-2"></i>描述</label>
|
||||
<textarea class="form-control" id="description" name="description" rows="3" required></textarea>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="age_rating" class="form-label"><i class="fas fa-shield-alt me-2"></i>年龄分级</label>
|
||||
<select class="form-select" id="age_rating" name="age_rating" required>
|
||||
<option value="3+">3+</option>
|
||||
<option value="7+">7+</option>
|
||||
<option value="12+">12+</option>
|
||||
<option value="17+">17+</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-floating mb-3" id="ageRatingDescriptionGroup" style="display: none;">
|
||||
<textarea class="form-control" id="age_rating_description" name="age_rating_description" rows="3" placeholder="请说明为何需要此年龄分级"></textarea>
|
||||
<label for="age_rating_description">年龄分级说明</label>
|
||||
<div class="form-text">当年龄分级为12+或以上时,此项为必填</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">适用平台</label>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="android" id="android" name="platforms[]">
|
||||
<label class="form-check-label" for="android">Android</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="ios" id="ios" name="platforms[]">
|
||||
<label class="form-check-label" for="ios">iOS</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="windows" id="windows" name="platforms[]">
|
||||
<label class="form-check-label" for="windows">Windows</label>
|
||||
</div>
|
||||
<div id="windows_suboptions" class="ms-4 mt-2" style="display: none;">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="windows_version" id="windows_xp" value="windows_xp">
|
||||
<label class="form-check-label" for="windows_xp">XP以前</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="windows_version" id="windows_win7" value="windows_win7">
|
||||
<label class="form-check-label" for="windows_win7">Win7以后</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="macos" id="macos" name="platforms[]">
|
||||
<label class="form-check-label" for="macos">macOS</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="linux" id="linux" name="platforms[]">
|
||||
<label class="form-check-label" for="linux">Linux</label>
|
||||
</div>
|
||||
<div id="linux_suboptions" class="ms-4 mt-2" style="display: none;">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="linux_distribution" id="linux_ubuntu" value="linux_ubuntu">
|
||||
<label class="form-check-label" for="linux_ubuntu">Ubuntu</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="linux_distribution" id="linux_arch" value="linux_arch">
|
||||
<label class="form-check-label" for="linux_arch">Arch Linux</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="linux_distribution" id="linux_centos" value="linux_centos">
|
||||
<label class="form-check-label" for="linux_centos">CentOS</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" class="form-control" id="version" name="version" required>
|
||||
<label for="version" class="form-label"><i class="fas fa-code-branch me-2"></i>版本号</label>
|
||||
</div>
|
||||
<div class="form-floating mb-3">
|
||||
<textarea class="form-control" id="changelog" name="changelog" rows="3" required></textarea>
|
||||
<label for="changelog" class="form-label"><i class="fas fa-history me-2"></i>更新日志</label>
|
||||
</div>
|
||||
<div class="form-floating mb-3">
|
||||
<input class="form-control" type="file" id="app_file" name="app_file" required>
|
||||
<label for="app_file" class="form-label"><i class="fas fa-file-archive me-2"></i>App文件</label>
|
||||
</div>
|
||||
<div class="form-floating mb-3">
|
||||
<input class="form-control" type="file" id="images" name="images[]" multiple>
|
||||
<label for="images" class="form-label"><i class="fas fa-upload me-2"></i>预览图片 (可多选)</label>
|
||||
</div>
|
||||
<button type="submit" name="add_app" class="btn btn-primary"><i class="fas fa-plus-circle me-2"></i>添加App</button>
|
||||
<a href="index.php" class="btn btn-secondary ms-2"><i class="fas fa-times me-1"></i>取消</a>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap JS Bundle with Popper -->
|
||||
<script src="/js/bootstrap.bundle.js"></script>
|
||||
<script>
|
||||
// 年龄分级说明显示控制
|
||||
const ageRatingSelect = document.getElementById('age_rating');
|
||||
const descriptionGroup = document.getElementById('ageRatingDescriptionGroup');
|
||||
const descriptionInput = document.getElementById('age_rating_description');
|
||||
|
||||
function toggleAgeDescription() {
|
||||
const selectedRating = ageRatingSelect.value;
|
||||
if (selectedRating === '12+' || selectedRating === '17+') {
|
||||
descriptionGroup.style.display = 'block';
|
||||
descriptionInput.required = true;
|
||||
} else {
|
||||
descriptionGroup.style.display = 'none';
|
||||
descriptionInput.required = false;
|
||||
}
|
||||
}
|
||||
|
||||
ageRatingSelect.addEventListener('change', toggleAgeDescription);
|
||||
// 初始加载时检查
|
||||
toggleAgeDescription();
|
||||
|
||||
|
||||
// 导航栏滚动效果
|
||||
window.addEventListener('scroll', function() {
|
||||
const navbar = document.querySelector('.navbar');
|
||||
if (window.scrollY > 10) {
|
||||
navbar.classList.add('scrolled');
|
||||
} else {
|
||||
navbar.classList.remove('scrolled');
|
||||
}
|
||||
});
|
||||
|
||||
// 平台子选项显示控制
|
||||
document.getElementById('windows').addEventListener('change', function() {
|
||||
const suboptions = document.getElementById('windows_suboptions');
|
||||
suboptions.style.display = this.checked ? 'block' : 'none';
|
||||
if (!this.checked) {
|
||||
document.querySelectorAll('input[name="windows_version"]').forEach(radio => radio.checked = false);
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('linux').addEventListener('change', function() {
|
||||
const suboptions = document.getElementById('linux_suboptions');
|
||||
suboptions.style.display = this.checked ? 'block' : 'none';
|
||||
if (!this.checked) {
|
||||
document.querySelectorAll('input[name="linux_distribution"]').forEach(radio => radio.checked = false);
|
||||
}
|
||||
});
|
||||
|
||||
// 表单提交验证
|
||||
document.querySelector('form').addEventListener('submit', function(e) {
|
||||
// 验证Windows子选项
|
||||
if (document.getElementById('windows').checked && !document.querySelector('input[name="windows_version"]:checked')) {
|
||||
e.preventDefault();
|
||||
Swal.fire({
|
||||
title: '提示',
|
||||
text: '请选择Windows版本(XP以前或Win7以后)',
|
||||
icon: 'warning',
|
||||
confirmButtonText: '确定'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证Linux子选项
|
||||
if (document.getElementById('linux').checked && !document.querySelector('input[name="linux_distribution"]:checked')) {
|
||||
e.preventDefault();
|
||||
Swal.fire({
|
||||
title: '提示',
|
||||
text: '请选择Linux发行版(Ubuntu、Arch Linux或CentOS)',
|
||||
icon: 'warning',
|
||||
confirmButtonText: '确定'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新平台值包含子选项信息
|
||||
if (document.getElementById('windows').checked) {
|
||||
document.getElementById('windows').value = document.querySelector('input[name="windows_version"]:checked').value;
|
||||
}
|
||||
if (document.getElementById('linux').checked) {
|
||||
document.getElementById('linux').value = document.querySelector('input[name="linux_distribution"]:checked').value;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
225
admin/announcements.php
Normal file
225
admin/announcements.php
Normal file
@@ -0,0 +1,225 @@
|
||||
<?php
|
||||
require_once '../config.php';
|
||||
session_start();
|
||||
// 检查管理员登录状态
|
||||
if (!isset($_SESSION['admin']) || !isset($_SESSION['admin']['id'])) {
|
||||
header('Location: login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
// 检查权限 - 允许all和say权限
|
||||
if (!in_array($_SESSION['admin']['permission'], ['all', 'say'])) {
|
||||
$redirect = $_SESSION['admin']['permission'] == 'say' ? 'announcements.php' : 'review_apps.php';
|
||||
header("Location: $redirect");
|
||||
exit();
|
||||
}
|
||||
|
||||
// 处理公告发布
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$title = $_POST['title'] ?? '';
|
||||
$content = $_POST['content'] ?? '';
|
||||
$admin_id = $_SESSION['admin']['id'];
|
||||
|
||||
if (!empty($title) && !empty($content)) {
|
||||
$stmt = $conn->prepare('INSERT INTO announcements (title, content, admin_id) VALUES (?, ?, ?)');
|
||||
$stmt->bind_param('ssi', $title, $content, $admin_id);
|
||||
if ($stmt->execute()) {
|
||||
echo '<script>Swal.fire("成功", "公告发布成功", "success").then(() => { window.location.reload(); });</script>';
|
||||
exit;
|
||||
} else {
|
||||
echo '<script>Swal.fire("错误", "公告发布失败: ' . $conn->error . '", "error");</script>';
|
||||
}
|
||||
$stmt->close();
|
||||
} else {
|
||||
echo '<script>Swal.fire("错误", "标题和内容不能为空", "error");</script>';
|
||||
}
|
||||
}
|
||||
|
||||
// 获取公告列表
|
||||
$sql = 'SELECT a.*, ad.username FROM announcements a JOIN admins ad ON a.admin_id = ad.id ORDER BY a.created_at DESC';
|
||||
$result = $conn->query($sql);
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<style>
|
||||
.page-transition {
|
||||
animation: fadeIn 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>公告管理 - <?php echo APP_STORE_NAME; ?></title>
|
||||
<!-- Bootstrap CSS -->
|
||||
<link href="../css/bootstrap.min.css" rel="stylesheet">
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="/css/all.min.css">
|
||||
<!-- SweetAlert2 CSS -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.min.css">
|
||||
<!-- 自定义CSS -->
|
||||
<link rel="stylesheet" href="../styles.css">
|
||||
<!-- Fluent Design 模糊效果 -->
|
||||
<style>
|
||||
.blur-bg {
|
||||
backdrop-filter: blur(10px);
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="page-transition">
|
||||
<!-- 导航栏 -->
|
||||
<nav class="navbar navbar-expand-lg navbar-light blur-bg">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="../index.php"><?php echo APP_STORE_NAME; ?></a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="index.php">App列表</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="addapp.php">添加App</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="review_apps.php">审核APP</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="manage_developers.php">管理开发者</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="system_info.php">系统信息</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" aria-current="page" href="announcements.php">公告管理</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#" onclick="confirmLogout()">退出登录</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container mt-4">
|
||||
<script>
|
||||
function confirmLogout() {
|
||||
Swal.fire({
|
||||
title: '确定要登出吗?',
|
||||
icon: 'question',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
window.location.href = 'logout.php';
|
||||
}
|
||||
});
|
||||
}
|
||||
function confirmDelete(id) {
|
||||
Swal.fire({
|
||||
title: '确定要删除这条公告吗?',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
window.location.href = 'delete_announcement.php?id=' + id;
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<?php if (isset($_GET['success'])): ?>
|
||||
<script>
|
||||
Swal.fire({
|
||||
icon: "success",
|
||||
title: "成功",
|
||||
text: "<?php echo addslashes($_GET['success']); ?>",
|
||||
});
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($error)): ?>
|
||||
<script>
|
||||
Swal.fire({
|
||||
icon: "error",
|
||||
title: "错误",
|
||||
text: "<?php echo addslashes($error); ?>",
|
||||
});
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
|
||||
<h2><i class="fas fa-bullhorn me-2"></i>发布公告</h2>
|
||||
<form method="post">
|
||||
<div class="mb-3">
|
||||
<label for="title" class="form-label"><i class="fas fa-heading me-2"></i>标题</label>
|
||||
<input type="text" class="form-control" id="title" name="title" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="content" class="form-label"><i class="fas fa-paragraph me-2"></i>内容</label>
|
||||
<textarea class="form-control" id="content" name="content" rows="4" required></textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary"><i class="fas fa-paper-plane me-2"></i>发布</button>
|
||||
</form>
|
||||
|
||||
<h2 class="mt-4"><i class="fas fa-list-alt me-2"></i>公告列表</h2>
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><i class="fas fa-id-card me-2"></i>ID</th>
|
||||
<th><i class="fas fa-heading me-2"></i>标题</th>
|
||||
<th><i class="fas fa-user me-2"></i>发布者</th>
|
||||
<th><i class="fas fa-clock me-2"></i>发布时间</th>
|
||||
<th><i class="fas fa-cog me-2"></i>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php while ($row = $result->fetch_assoc()): ?>
|
||||
<tr>
|
||||
<td><?php echo $row['id']; ?></td>
|
||||
<td><?php echo htmlspecialchars($row['title']); ?></td>
|
||||
<td><?php echo htmlspecialchars($row['username']); ?></td>
|
||||
<td><?php echo $row['created_at']; ?></td>
|
||||
<td>
|
||||
<button class="btn btn-danger btn-sm" onclick="confirmDelete(<?php echo $row['id']; ?>)"><i class="fas fa-trash-alt me-1"></i>删除</button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endwhile; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap JS Bundle with Popper -->
|
||||
<script src="/js/bootstrap.bundle.js"></script>
|
||||
<!-- SweetAlert2 JS -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.all.min.js"></script>
|
||||
<script>
|
||||
// 导航栏滚动效果
|
||||
window.addEventListener('scroll', function() {
|
||||
const navbar = document.querySelector('.navbar');
|
||||
if (window.scrollY > 10) {
|
||||
navbar.classList.add('scrolled');
|
||||
} else {
|
||||
navbar.classList.remove('scrolled');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.body.classList.add('page-transition');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
89
admin/debug_redirect.php
Normal file
89
admin/debug_redirect.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
// 设置错误报告级别以查看详细错误
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
// 记录重定向链
|
||||
session_start();
|
||||
if (!isset($_SESSION['redirect_chain'])) {
|
||||
$_SESSION['redirect_chain'] = [];
|
||||
}
|
||||
|
||||
// 获取当前文件名
|
||||
$current_file = basename($_SERVER['PHP_SELF']);
|
||||
|
||||
// 添加到重定向链
|
||||
if (!in_array($current_file, $_SESSION['redirect_chain'])) {
|
||||
$_SESSION['redirect_chain'][] = $current_file;
|
||||
}
|
||||
|
||||
// 如果重定向链太长,说明存在循环重定向
|
||||
if (count($_SESSION['redirect_chain']) > 5) {
|
||||
echo '<!DOCTYPE html><html><head><title>循环重定向检测</title></head><body>';
|
||||
echo '<h1>检测到循环重定向!</h1>';
|
||||
echo '<p>重定向链:' . implode(' -> ', $_SESSION['redirect_chain']) . '</p>';
|
||||
echo '<p>请查看以下详细信息来排查问题:</p>';
|
||||
|
||||
// 输出会话信息
|
||||
echo '<h2>会话信息</h2>';
|
||||
echo '<pre>';
|
||||
print_r($_SESSION);
|
||||
echo '</pre>';
|
||||
|
||||
// 尝试加载配置文件
|
||||
echo '<h2>配置文件检测</h2>';
|
||||
if (file_exists('../config.php')) {
|
||||
echo 'config.php 文件存在<br>';
|
||||
// 尝试加载配置但捕获错误
|
||||
try {
|
||||
require_once '../config.php';
|
||||
echo '配置文件加载成功<br>';
|
||||
|
||||
// 检查管理员账户配置
|
||||
echo '<h3>管理员账户配置</h3>';
|
||||
if (isset($admin_accounts) && is_array($admin_accounts)) {
|
||||
echo '找到 ' . count($admin_accounts) . ' 个管理员账户<br>';
|
||||
foreach ($admin_accounts as $account) {
|
||||
echo '用户名: ' . $account['username'] . ', 权限: ' . $account['permission'] . '<br>';
|
||||
}
|
||||
} else {
|
||||
echo '未找到管理员账户配置<br>';
|
||||
}
|
||||
|
||||
// 检查数据库连接
|
||||
echo '<h3>数据库连接</h3>';
|
||||
if (isset($conn) && $conn instanceof mysqli) {
|
||||
echo '数据库连接对象存在<br>';
|
||||
if ($conn->ping()) {
|
||||
echo '数据库连接成功<br>';
|
||||
} else {
|
||||
echo '数据库连接失败: ' . $conn->error . '<br>';
|
||||
}
|
||||
} else {
|
||||
echo '数据库连接对象不存在<br>';
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
echo '配置文件加载错误: ' . $e->getMessage() . '<br>';
|
||||
}
|
||||
} else {
|
||||
echo 'config.php 文件不存在<br>';
|
||||
}
|
||||
|
||||
// 重置重定向链
|
||||
echo '<h2>修复选项</h2>';
|
||||
echo '<a href="?reset=1">重置重定向链</a>';
|
||||
|
||||
if (isset($_GET['reset']) && $_GET['reset'] == 1) {
|
||||
unset($_SESSION['redirect_chain']);
|
||||
echo '<script>alert("重定向链已重置"); window.location.href = "login.php";</script>';
|
||||
}
|
||||
|
||||
echo '</body></html>';
|
||||
exit;
|
||||
}
|
||||
|
||||
// 正常情况:重定向到登录页面进行测试
|
||||
echo '<!DOCTYPE html><html><head><title>重定向调试</title></head><body>';
|
||||
echo '<p>正在重定向到登录页面进行测试...</p>';
|
||||
echo '<script>setTimeout(function(){ window.location.href = "login.php"; }, 1000);</script>';
|
||||
echo '</body></html>';
|
||||
41
admin/delete_announcement.php
Normal file
41
admin/delete_announcement.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
require_once '../config.php';
|
||||
session_start();
|
||||
|
||||
// 检查管理员登录状态
|
||||
if (!isset($_SESSION['admin']) || !isset($_SESSION['admin']['id'])) {
|
||||
header('Location: login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
// 检查权限 - 只允许all权限
|
||||
if ($_SESSION['admin']['permission'] !== 'all') {
|
||||
header('Location: announcements.php?error=没有删除公告的权限');
|
||||
exit();
|
||||
}
|
||||
|
||||
// 验证公告ID
|
||||
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
||||
header('Location: announcements.php?error=无效的公告ID');
|
||||
exit();
|
||||
}
|
||||
|
||||
$announcement_id = intval($_GET['id']);
|
||||
|
||||
// 执行删除操作
|
||||
$stmt = $conn->prepare('DELETE FROM announcements WHERE id = ?');
|
||||
$stmt->bind_param('i', $announcement_id);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
$success = '公告已成功删除';
|
||||
} else {
|
||||
$error = '删除公告失败: ' . $conn->error;
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
$conn->close();
|
||||
|
||||
// 重定向回公告管理页面并显示结果
|
||||
$redirect = 'announcements.php?' . ($success ? 'success=' . urlencode($success) : 'error=' . urlencode($error));
|
||||
header('Location: ' . $redirect);
|
||||
exit;
|
||||
41
admin/deleteapp.php
Normal file
41
admin/deleteapp.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
require_once '../config.php';
|
||||
|
||||
session_start();
|
||||
// 检查管理员登录状态
|
||||
if (!isset($_SESSION['admin'])) {
|
||||
header('Location: login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
// 验证App ID
|
||||
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
||||
echo '<script>Swal.fire("错误", "无效的App ID", "error").then(() => { window.location.href = "index.php"; });</script>';
|
||||
exit;
|
||||
}
|
||||
$appId = $_GET['id'];
|
||||
|
||||
// 删除App
|
||||
$deleteAppSql = "DELETE FROM apps WHERE id = ?";
|
||||
$stmt = $conn->prepare($deleteAppSql);
|
||||
$stmt->bind_param("i", $appId);
|
||||
|
||||
if ($stmt->execute() === TRUE) {
|
||||
// 删除关联的图片
|
||||
$deleteImagesSql = "DELETE FROM app_images WHERE app_id = ?";
|
||||
$imgStmt = $conn->prepare($deleteImagesSql);
|
||||
$imgStmt->bind_param("i", $appId);
|
||||
$imgStmt->execute();
|
||||
|
||||
// 删除关联的版本
|
||||
$deleteVersionsSql = "DELETE FROM app_versions WHERE app_id = ?";
|
||||
$verStmt = $conn->prepare($deleteVersionsSql);
|
||||
$verStmt->bind_param("i", $appId);
|
||||
$verStmt->execute();
|
||||
|
||||
echo '<script>Swal.fire("成功", "App 删除成功", "success").then(() => { window.location.href = "index.php"; });</script>';
|
||||
} else {
|
||||
echo '<script>Swal.fire("错误", "App 删除失败: '. $conn->error .'", "error").then(() => { window.location.href = "index.php"; });</script>';
|
||||
}
|
||||
exit;
|
||||
?>
|
||||
402
admin/editapp.php
Normal file
402
admin/editapp.php
Normal file
@@ -0,0 +1,402 @@
|
||||
<?php
|
||||
require_once '../config.php';
|
||||
|
||||
session_start();
|
||||
// 检查是否已登录
|
||||
if (!isset($_SESSION['admin'])) {
|
||||
header('Location: login.php');
|
||||
exit();
|
||||
}
|
||||
|
||||
// 非全部权限管理员重定向到对应权限页面
|
||||
if ($_SESSION['admin']['permission'] != 'all') {
|
||||
$redirect = $_SESSION['admin']['permission'] == 'say' ? 'announcements.php' : 'review_apps.php';
|
||||
header("Location: $redirect");
|
||||
exit();
|
||||
}
|
||||
|
||||
// 验证App ID
|
||||
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
||||
echo '<script>Swal.fire("错误", "无效的App ID", "error").then(() => { window.location.href = "index.php"; });</script>';
|
||||
exit;
|
||||
}
|
||||
$appId = $_GET['id'];
|
||||
|
||||
// 获取App信息
|
||||
$app = null;
|
||||
$getAppSql = "SELECT * FROM apps WHERE id = ?";
|
||||
$stmt = $conn->prepare($getAppSql);
|
||||
$stmt->bind_param("i", $appId);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
if ($result->num_rows === 0) {
|
||||
echo '<script>Swal.fire("错误", "App不存在", "error").then(() => { window.location.href = "index.php"; });</script>';
|
||||
exit;
|
||||
}
|
||||
$app = $result->fetch_assoc();
|
||||
$platforms = json_decode($app['platforms'], true);
|
||||
|
||||
$success = '';
|
||||
$error = '';
|
||||
// 处理编辑App请求
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['edit_app'])) {
|
||||
$name = $_POST['name'];
|
||||
$description = $_POST['description'];
|
||||
$ageRating = $_POST['age_rating'];
|
||||
$newPlatforms = json_encode($_POST['platforms'] ?? []);
|
||||
|
||||
// 处理表单提交
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
// 验证必填字段
|
||||
$required = ['name', 'description', 'age_rating', 'platforms'];
|
||||
$errors = [];
|
||||
foreach ($required as $field) {
|
||||
if (empty($_POST[$field])) {
|
||||
$errors[] = ucfirst($field) . ' 不能为空';
|
||||
}
|
||||
}
|
||||
|
||||
// 年龄分级验证
|
||||
if (($_POST['age_rating'] === '12+' || $_POST['age_rating'] === '17+') && empty($_POST['age_rating_description'])) {
|
||||
$errors[] = '年龄分级为12+或以上时,年龄分级说明不能为空';
|
||||
}
|
||||
|
||||
// 处理应用图标上传(如果有新上传)
|
||||
if (!empty($_FILES['images']['name'][0])) {
|
||||
$uploadDir = '../images/';
|
||||
foreach ($_FILES['images']['tmp_name'] as $key => $tmpName) {
|
||||
$fileName = basename($_FILES['images']['name'][$key]);
|
||||
$targetPath = $uploadDir . $fileName;
|
||||
if (move_uploaded_file($tmpName, $targetPath)) {
|
||||
$insertImageSql = "INSERT INTO app_images (app_id, image_path) VALUES (?, ?)";
|
||||
$imgStmt = $conn->prepare($insertImageSql);
|
||||
$imgStmt->bind_param("is", $appId, $targetPath);
|
||||
$imgStmt->execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理新上传的App文件
|
||||
if (!empty($_FILES['app_file']['name'])) {
|
||||
$uploadDir = '../files/';
|
||||
$fileName = basename($_FILES['app_file']['name']);
|
||||
$targetPath = $uploadDir . $fileName;
|
||||
if (move_uploaded_file($_FILES['app_file']['tmp_name'], $targetPath)) {
|
||||
$version = $_POST['version'];
|
||||
$changelog = $_POST['changelog'];
|
||||
$insertVersionSql = "INSERT INTO app_versions (app_id, version, changelog, file_path) VALUES (?, ?, ?, ?)";
|
||||
$verStmt = $conn->prepare($insertVersionSql);
|
||||
$verStmt->bind_param("isss", $appId, $version, $changelog, $targetPath);
|
||||
$verStmt->execute();
|
||||
}
|
||||
}
|
||||
|
||||
// 更新标签关联
|
||||
$stmt = $conn->prepare("DELETE FROM app_tags WHERE app_id = ?");
|
||||
$stmt->bind_param("i", $appId);
|
||||
$stmt->execute();
|
||||
$stmt->close();
|
||||
|
||||
if (!empty($_POST['tags'])) {
|
||||
$stmt = $conn->prepare("INSERT INTO app_tags (app_id, tag_id) VALUES (?, ?)");
|
||||
foreach ($_POST['tags'] as $tagId) {
|
||||
$stmt->bind_param("ii", $appId, $tagId);
|
||||
$stmt->execute();
|
||||
}
|
||||
$stmt->close();
|
||||
}
|
||||
|
||||
$updateAppSql = "UPDATE apps SET name = ?, description = ?, age_rating = ?, platforms = ? WHERE id = ?";
|
||||
$updateStmt = $conn->prepare($updateAppSql);
|
||||
$updateStmt->bind_param("ssssi", $name, $description, $ageRating, $newPlatforms, $appId);
|
||||
if ($updateStmt->execute() === TRUE) {
|
||||
echo '<script>Swal.fire("成功", "App 更新成功", "success").then(() => { window.location.href = "index.php"; });</script>';
|
||||
exit;
|
||||
} else {
|
||||
echo '<script>Swal.fire("错误", "App 更新失败: '. $conn->error .'", "error");</script>';
|
||||
}
|
||||
$updateStmt->close();
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>编辑App - <?php echo APP_STORE_NAME; ?></title>
|
||||
<!-- Bootstrap CSS -->
|
||||
<link href="../css/bootstrap.min.css" rel="stylesheet">
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="/css/all.min.css">
|
||||
<!-- 自定义CSS -->
|
||||
<link rel="stylesheet" href="../styles.css">
|
||||
<script src="/js/sweetalert.js"></script>
|
||||
<script>
|
||||
function confirmLogout() {
|
||||
Swal.fire({
|
||||
title: '确定要登出吗?',
|
||||
icon: 'question',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
window.location.href = 'logout.php';
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<!-- Fluent Design 模糊效果 -->
|
||||
<style>
|
||||
.blur-bg {
|
||||
backdrop-filter: blur(10px);
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- 导航栏 -->
|
||||
<nav class="navbar navbar-expand-lg navbar-light blur-bg">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="../index.php"><?php echo APP_STORE_NAME; ?></a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="index.php">App列表</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="addapp.php">添加App</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" aria-current="page" href="editapp.php?id=<?php echo $appId; ?>">编辑App</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#" onclick="confirmLogout()">退出登录</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container mt-4">
|
||||
<?php if (!empty($success)): ?>
|
||||
<div class="alert alert-success"><?php echo $success; ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($error)): ?>
|
||||
<div class="alert alert-danger"><?php echo $error; ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<h2>编辑App: <?php echo htmlspecialchars($app['name']); ?></h2>
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" class="form-control" id="name" name="name" value="<?php echo htmlspecialchars($app['name']); ?>" required>
|
||||
<label for="name"><i class="fas fa-file-signature me-2"></i>App名称</label>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="description" class="form-label"><i class="fas fa-align-left me-2"></i>描述</label>
|
||||
<textarea class="form-control" id="description" name="description" rows="3" required><?php echo htmlspecialchars($app['description']); ?></textarea>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="age_rating" class="form-label"><i class="fas fa-shield-alt me-2"></i>年龄分级</label>
|
||||
<select class="form-select" id="age_rating" name="age_rating" required>
|
||||
<option value="3+" <?php echo $app['age_rating'] === '3+' ? 'selected' : ''; ?>>3+</option>
|
||||
<option value="7+" <?php echo $app['age_rating'] === '7+' ? 'selected' : ''; ?>>7+</option>
|
||||
<option value="12+" <?php echo $app['age_rating'] === '12+' ? 'selected' : ''; ?>>12+</option>
|
||||
<option value="17+" <?php echo $app['age_rating'] === '17+' ? 'selected' : ''; ?>>17+</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3" id="ageRatingDescriptionGroup" style="display: none;">
|
||||
<label for="age_rating_description" class="form-label">年龄分级说明</label>
|
||||
<textarea class="form-control" id="age_rating_description" name="age_rating_description" rows="3" placeholder="请说明为何需要此年龄分级"><?php echo htmlspecialchars($app['age_rating_description'] ?? ''); ?></textarea>
|
||||
<div class="form-text">当年龄分级为12+或以上时,此项为必填</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">适用平台</label>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="android" id="android" name="platforms[]" <?php echo in_array('android', $platforms) ? 'checked' : ''; ?>>
|
||||
<label class="form-check-label" for="android">Android</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="ios" id="ios" name="platforms[]" <?php echo in_array('ios', $platforms) ? 'checked' : ''; ?>>
|
||||
<label class="form-check-label" for="ios">iOS</label>
|
||||
</div>
|
||||
<?php
|
||||
$windowsChecked = false;
|
||||
$windowsVersion = '';
|
||||
foreach ($platforms as $p) {
|
||||
if (strpos($p, 'windows_') === 0) {
|
||||
$windowsChecked = true;
|
||||
$windowsVersion = $p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
?>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="windows" id="windows" name="platforms[]" <?php echo $windowsChecked ? 'checked' : ''; ?>>
|
||||
<label class="form-check-label" for="windows">Windows</label>
|
||||
</div>
|
||||
<div id="windows_suboptions" class="ms-4 mt-2" style="display: <?php echo $windowsChecked ? 'block' : 'none'; ?>">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="windows_version" id="windows_xp" value="windows_xp" <?php echo $windowsVersion === 'windows_xp' ? 'checked' : ''; ?>>
|
||||
<label class="form-check-label" for="windows_xp">XP以前</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="windows_version" id="windows_win7" value="windows_win7" <?php echo $windowsVersion === 'windows_win7' ? 'checked' : ''; ?>>
|
||||
<label class="form-check-label" for="windows_win7">Win7以后</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="macos" id="macos" name="platforms[]" <?php echo in_array('macos', $platforms) ? 'checked' : ''; ?>>
|
||||
<label class="form-check-label" for="macos">macOS</label>
|
||||
</div>
|
||||
<?php
|
||||
$linuxChecked = false;
|
||||
$linuxVersion = '';
|
||||
foreach ($platforms as $p) {
|
||||
if (strpos($p, 'linux_') === 0) {
|
||||
$linuxChecked = true;
|
||||
$linuxVersion = $p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
?>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="linux" id="linux" name="platforms[]" <?php echo $linuxChecked ? 'checked' : ''; ?>>
|
||||
<label class="form-check-label" for="linux">Linux</label>
|
||||
</div>
|
||||
<div id="linux_suboptions" class="ms-4 mt-2" style="display: <?php echo $linuxChecked ? 'block' : 'none'; ?>">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="linux_distribution" id="linux_ubuntu" value="linux_ubuntu" <?php echo $linuxVersion === 'linux_ubuntu' ? 'checked' : ''; ?>>
|
||||
<label class="form-check-label" for="linux_ubuntu">Ubuntu</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="linux_distribution" id="linux_arch" value="linux_arch" <?php echo $linuxVersion === 'linux_arch' ? 'checked' : ''; ?>>
|
||||
<label class="form-check-label" for="linux_arch">Arch Linux</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="linux_distribution" id="linux_centos" value="linux_centos" <?php echo $linuxVersion === 'linux_centos' ? 'checked' : ''; ?>>
|
||||
<label class="form-check-label" for="linux_centos">CentOS</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" class="form-control" id="version" name="version" placeholder="如: 1.0.1">
|
||||
<label for="version" class="form-label"><i class="fas fa-code-branch me-2"></i>版本号</label>
|
||||
<div class="form-text">仅在上传新安装包时填写</div>
|
||||
</div>
|
||||
<div class="form-floating mb-3">
|
||||
<textarea class="form-control" id="changelog" name="changelog" rows="3" placeholder="描述本次更新内容"></textarea>
|
||||
<label for="changelog" class="form-label"><i class="fas fa-history me-2"></i>更新日志</label>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="app_file" class="form-label">新App文件 (可选)</label>
|
||||
<input class="form-control" type="file" id="app_file" name="app_file">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="images" class="form-label"><i class="fas fa-upload me-2"></i>预览图片 (可多选)</label>
|
||||
<input class="form-control" type="file" id="images" name="images[]" multiple>
|
||||
</div>
|
||||
<button type="submit" name="edit_app" class="btn btn-primary"><i class="fas fa-save me-2"></i>保存修改</button>
|
||||
<a href="index.php" class="btn btn-secondary ms-2"><i class="fas fa-times me-1"></i>取消</a>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap JS Bundle with Popper -->
|
||||
<script src="/js/bootstrap.bundle.js"></script>
|
||||
<script>
|
||||
// 年龄分级说明显示控制
|
||||
// 年龄分级说明显示控制
|
||||
const ageRatingSelect = document.getElementById('age_rating');
|
||||
const descriptionGroup = document.getElementById('ageRatingDescriptionGroup');
|
||||
const descriptionInput = document.getElementById('age_rating_description');
|
||||
|
||||
function toggleAgeDescription() {
|
||||
const selectedRating = ageRatingSelect.value;
|
||||
if (selectedRating === '12+' || selectedRating === '17+') {
|
||||
descriptionGroup.style.display = 'block';
|
||||
descriptionInput.required = true;
|
||||
} else {
|
||||
descriptionGroup.style.display = 'none';
|
||||
descriptionInput.required = false;
|
||||
}
|
||||
}
|
||||
|
||||
ageRatingSelect.addEventListener('change', toggleAgeDescription);
|
||||
// 初始加载时检查
|
||||
toggleAgeDescription();
|
||||
|
||||
// 导航栏滚动效果
|
||||
window.addEventListener('scroll', function() {
|
||||
const navbar = document.querySelector('.navbar');
|
||||
if (window.scrollY > 10) {
|
||||
navbar.classList.add('scrolled');
|
||||
} else {
|
||||
navbar.classList.remove('scrolled');
|
||||
}
|
||||
});
|
||||
|
||||
// 平台子选项显示控制
|
||||
document.getElementById('windows').addEventListener('change', function() {
|
||||
const suboptions = document.getElementById('windows_suboptions');
|
||||
suboptions.style.display = this.checked ? 'block' : 'none';
|
||||
if (!this.checked) {
|
||||
document.querySelectorAll('input[name="windows_version"]').forEach(radio => radio.checked = false);
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('linux').addEventListener('change', function() {
|
||||
const suboptions = document.getElementById('linux_suboptions');
|
||||
suboptions.style.display = this.checked ? 'block' : 'none';
|
||||
if (!this.checked) {
|
||||
document.querySelectorAll('input[name="linux_distribution"]').forEach(radio => radio.checked = false);
|
||||
}
|
||||
});
|
||||
|
||||
// 表单提交验证
|
||||
document.querySelector('form').addEventListener('submit', function(e) {
|
||||
// 验证Windows子选项
|
||||
if (document.getElementById('windows').checked && !document.querySelector('input[name="windows_version"]:checked')) {
|
||||
e.preventDefault();
|
||||
Swal.fire({
|
||||
title: '提示',
|
||||
text: '请选择Windows版本(XP以前或Win7以后)',
|
||||
icon: 'warning',
|
||||
confirmButtonText: '确定'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证Linux子选项
|
||||
if (document.getElementById('linux').checked && !document.querySelector('input[name="linux_distribution"]:checked')) {
|
||||
e.preventDefault();
|
||||
Swal.fire({
|
||||
title: '提示',
|
||||
text: '请选择Linux发行版(Ubuntu、Arch Linux或CentOS)',
|
||||
icon: 'warning',
|
||||
confirmButtonText: '确定'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新平台值包含子选项信息
|
||||
if (document.getElementById('windows').checked) {
|
||||
document.getElementById('windows').value = document.querySelector('input[name="windows_version"]:checked').value;
|
||||
}
|
||||
if (document.getElementById('linux').checked) {
|
||||
document.getElementById('linux').value = document.querySelector('input[name="linux_distribution"]:checked').value;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<?php
|
||||
// 更新应用数据
|
||||
$stmt = $conn->prepare("UPDATE apps SET name=?, description=?, age_rating=?, age_rating_description=?, platforms=?, updated_at=NOW() WHERE id=?");
|
||||
$stmt->bind_param("sssssi", $name, $description, $age_rating, $_POST['age_rating_description'], $platformsJson, $appId);
|
||||
|
||||
?>
|
||||
215
admin/index.php
Normal file
215
admin/index.php
Normal file
@@ -0,0 +1,215 @@
|
||||
<?php
|
||||
require_once '../config.php';
|
||||
|
||||
session_start();
|
||||
|
||||
if (!isset($conn) || !$conn instanceof mysqli) {
|
||||
die('数据库连接失败,请检查配置文件。');
|
||||
}
|
||||
|
||||
// 获取最新公告
|
||||
$sql = 'SELECT title, content FROM announcements ORDER BY created_at DESC LIMIT 1';
|
||||
$result = $conn->query($sql);
|
||||
$announcement = $result ? $result->fetch_assoc() : null;
|
||||
// 检查是否已登录
|
||||
if (!isset($_SESSION['admin'])) {
|
||||
header('Location: login.php');
|
||||
exit();
|
||||
}
|
||||
|
||||
// 非全部权限管理员重定向到对应权限页面
|
||||
if ($_SESSION['admin']['permission'] != 'all') {
|
||||
$redirect = $_SESSION['admin']['permission'] == 'say' ? 'announcements.php' : 'review_apps.php';
|
||||
header("Location: $redirect");
|
||||
exit();
|
||||
}
|
||||
|
||||
// 处理退出登录
|
||||
if (isset($_GET['logout'])) {
|
||||
unset($_SESSION['admin']);
|
||||
header('Location: login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
// 获取App列表
|
||||
$sqlApps = "SELECT * FROM apps WHERE status = 'approved' ORDER BY created_at DESC";
|
||||
$resultApps = $conn->query($sqlApps);
|
||||
|
||||
if (!$resultApps) {
|
||||
error_log("Database query failed: " . $conn->error);
|
||||
echo '<script>Swal.fire("错误", "获取App列表失败,请联系管理员。", "error");</script>';
|
||||
} else {
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<style>
|
||||
.page-transition {
|
||||
animation: fadeIn 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>App管理 - <?php echo APP_STORE_NAME; ?></title>
|
||||
<!-- Bootstrap CSS -->
|
||||
<link href="../css/bootstrap.min.css" rel="stylesheet">
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="/css/all.min.css">
|
||||
<!-- 自定义CSS -->
|
||||
<link rel="stylesheet" href="../styles.css">
|
||||
<script src="/js/sweetalert.js"></script>
|
||||
<script>
|
||||
function confirmLogout() {
|
||||
Swal.fire({
|
||||
title: '确定要登出吗?',
|
||||
icon: 'question',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
window.location.href = 'logout.php';
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<!-- Fluent Design 模糊效果 -->
|
||||
<style>
|
||||
.blur-bg {
|
||||
backdrop-filter: blur(10px);
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="page-transition">
|
||||
<!-- 导航栏 -->
|
||||
<nav class="navbar navbar-expand-lg navbar-light blur-bg">
|
||||
<div class="container">
|
||||
<a href="../index.php"><img src="/favicon.jpeg" alt="Logo" style="height: 30px; margin-right: 10px; border-radius: var(--border-radius);"></a>
|
||||
<a class="navbar-brand" href="../index.php"><?php echo APP_STORE_NAME; ?></a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" aria-current="page" href="index.php">App列表</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="addapp.php">添加App</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="review_apps.php">审核APP</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="manage_developers.php">管理开发者</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="system_info.php">系统信息</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="announcements.php">公告管理</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#" onclick="confirmLogout()">退出登录</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container mt-4">
|
||||
<script>
|
||||
<?php if (isset($_GET['success'])): ?>
|
||||
Swal.fire({
|
||||
icon: "success",
|
||||
title: "成功",
|
||||
text: "<?php echo addslashes($_GET['success']); ?>",
|
||||
});
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_GET['error'])): ?>
|
||||
Swal.fire({
|
||||
icon: "error",
|
||||
title: "错误",
|
||||
text: "<?php echo addslashes($_GET['error']); ?>",
|
||||
});
|
||||
<?php endif; ?>
|
||||
</script>
|
||||
<h2>App列表</h2>
|
||||
<div class="mb-3">
|
||||
<a href="manage_tags.php" class="btn btn-info"><i class="fas fa-tags me-2"></i>标签管理</a>
|
||||
</div>
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>名称</th>
|
||||
<th>年龄分级</th>
|
||||
<th>创建时间</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php while ($app = $resultApps->fetch_assoc()): ?>
|
||||
<tr>
|
||||
<td><?php echo $app['id']; ?></td>
|
||||
<td><?php echo htmlspecialchars($app['name']); ?></td>
|
||||
<td><?php echo $app['age_rating']; ?></td>
|
||||
<td><?php echo $app['created_at']; ?></td>
|
||||
<td>
|
||||
<a href="editapp.php?id=<?php echo $app['id']; ?>" class="btn btn-sm btn-outline-primary"><i class="fas fa-edit me-1"></i>编辑</a>
|
||||
<a href="manage_versions.php?app_id=<?php echo $app['id']; ?>" class="btn btn-sm btn-outline-secondary"><i class="fas fa-code-branch me-1"></i>版本管理</a>
|
||||
<a href="deleteapp.php?id=<?php echo $app['id']; ?>" class="btn btn-sm btn-outline-danger" onclick="event.preventDefault(); Swal.fire({
|
||||
title: '确定要删除吗?',
|
||||
text: '删除后将无法恢复!',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#d33',
|
||||
cancelButtonColor: '#3085d6',
|
||||
confirmButtonText: '确定删除'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
window.location.href = this.href;
|
||||
}
|
||||
});"><i class="fas fa-trash-alt me-1"></i>删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endwhile; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap JS Bundle with Popper -->
|
||||
<script src="/js/bootstrap.bundle.js"></script>
|
||||
<script>
|
||||
// 导航栏滚动效果
|
||||
window.addEventListener('scroll', function() {
|
||||
const navbar = document.querySelector('.navbar');
|
||||
if (window.scrollY > 10) {
|
||||
navbar.classList.add('scrolled');
|
||||
} else {
|
||||
navbar.classList.remove('scrolled');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.body.classList.add('page-transition');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
165
admin/login.php
Normal file
165
admin/login.php
Normal file
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
require_once '../config.php';
|
||||
|
||||
// 检查管理员登录状态
|
||||
session_start();
|
||||
|
||||
if (!isset($_SESSION['admin'])) {
|
||||
$error = '';
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['username']) && isset($_POST['password'])) {
|
||||
$username = $_POST['username'];
|
||||
$password = $_POST['password'];
|
||||
|
||||
$adminFound = false;
|
||||
foreach ($admin_accounts as $account) {
|
||||
if ($username === $account['username'] && $password === $account['password']) {
|
||||
$_SESSION['admin'] = [
|
||||
'id' => $account['id'],
|
||||
'username' => $account['username'],
|
||||
'permission' => $account['permission']
|
||||
];
|
||||
$adminFound = true;
|
||||
|
||||
// 处理自动登录
|
||||
if (isset($_POST['remember_me']) && $_POST['remember_me'] === 'on') {
|
||||
$cookie_lifetime = 30 * 24 * 60 * 60; // 30天
|
||||
$cookie_params = session_get_cookie_params();
|
||||
setcookie(
|
||||
session_name(),
|
||||
session_id(),
|
||||
time() + $cookie_lifetime,
|
||||
$cookie_params['path'],
|
||||
$cookie_params['domain'],
|
||||
$cookie_params['secure'],
|
||||
$cookie_params['httponly']
|
||||
);
|
||||
ini_set('session.gc_maxlifetime', $cookie_lifetime);
|
||||
}
|
||||
|
||||
// 根据权限设置重定向页面
|
||||
$redirectPage = 'index.php';
|
||||
if ($_SESSION['admin']['permission'] == 'say') {
|
||||
$redirectPage = 'announcements.php';
|
||||
} elseif ($_SESSION['admin']['permission'] == 'review') {
|
||||
$redirectPage = 'review_apps.php';
|
||||
}
|
||||
header("Location: $redirectPage");
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
if (!$adminFound) {
|
||||
$error = '用户名或密码错误';
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>管理员登录 - <?php echo APP_STORE_NAME; ?></title>
|
||||
<!-- Bootstrap CSS -->
|
||||
<link href="../css/bootstrap.min.css" rel="stylesheet">
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="/css/all.min.css">
|
||||
<!-- 自定义CSS -->
|
||||
<link rel="stylesheet" href="../styles.css">
|
||||
<!-- 顶栏样式 -->
|
||||
<style>
|
||||
.navbar.scrolled {
|
||||
background-color: rgba(255, 255, 255, 0.95) !important;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.blur-bg {
|
||||
backdrop-filter: blur(10px);
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.page-transition {
|
||||
animation: fadeIn 0.5s ease-in-out;
|
||||
}
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script src="/js/sweetalert.js"></script>
|
||||
</head>
|
||||
<body class="page-transition">
|
||||
<!-- 导航栏 -->
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.body.classList.add('page-transition');
|
||||
});
|
||||
</script>
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light fixed-top">
|
||||
<div class="container">
|
||||
<a href="../index.php"><img src="/favicon.jpeg" alt="Logo" style="height: 30px; margin-right: 10px; border-radius: var(--border-radius);"></a>
|
||||
<a class="navbar-brand" href="../index.php"><?php echo APP_STORE_NAME; ?></a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../index.php">首页</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="index.php">管理后台</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- 为内容添加顶部内边距 -->
|
||||
<div style="padding-top: 70px;">
|
||||
<div class="container mt-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<div class="card blur-bg">
|
||||
<div class="card-header"><i class="fas fa-sign-in-alt me-2"></i>管理员登录</div>
|
||||
<div class="card-body">
|
||||
<!-- <?php if (isset($error)): ?>
|
||||
<script>
|
||||
Swal.fire({
|
||||
icon: "error",
|
||||
title: "错误",
|
||||
text: "<?php echo addslashes($error); ?>",
|
||||
});
|
||||
</script>
|
||||
<?php endif; ?> -->
|
||||
<form method="post">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" class="form-control" id="username" name="username" placeholder="请输入用户名" required>
|
||||
<label for="username"><i class="fas fa-user me-2"></i>用户名</label>
|
||||
</div>
|
||||
<div class="form-floating mb-3">
|
||||
<input type="password" class="form-control" id="password" name="password" placeholder="请输入密码" required>
|
||||
<label for="password"><i class="fas fa-lock me-2"></i>密码</label>
|
||||
</div>
|
||||
<div class="form-check mb-3">
|
||||
<input class="form-check-input" type="checkbox" name="remember_me" id="remember_me">
|
||||
<label class="form-check-label" for="remember_me">
|
||||
<i class="fas fa-clock me-2"></i>自动登录
|
||||
</label>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary"><i class="fas fa-sign-in-alt me-2"></i>登录</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Bootstrap JS Bundle with Popper -->
|
||||
<script src="/js/bootstrap.bundle.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
<?php
|
||||
exit;
|
||||
}
|
||||
37
admin/logout.php
Normal file
37
admin/logout.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
require_once '../config.php';
|
||||
|
||||
session_start();
|
||||
// 销毁所有会话变量
|
||||
$_SESSION = [];
|
||||
|
||||
// 如果使用了基于cookie的会话,也需要删除cookie
|
||||
if (ini_get("session.use_cookies")) {
|
||||
$params = session_get_cookie_params();
|
||||
setcookie(
|
||||
session_name(),
|
||||
'',
|
||||
time() - 42000,
|
||||
$params["path"],
|
||||
$params["domain"],
|
||||
$params["secure"],
|
||||
$params["httponly"]
|
||||
);
|
||||
}
|
||||
|
||||
// 销毁会话
|
||||
session_destroy();
|
||||
|
||||
// 使用Sweet Alert弹窗提示并跳转登录页
|
||||
echo '<script src="/js/sweetalert.js"></script>';
|
||||
echo '<script>document.addEventListener("DOMContentLoaded", function() {
|
||||
Swal.fire({
|
||||
title: "登出成功",
|
||||
text: "您已安全登出系统",
|
||||
icon: "success",
|
||||
timer: 1500,
|
||||
showConfirmButton: false,
|
||||
target: document.body
|
||||
}).then(() => { window.location.href = "login.php"; });
|
||||
});</script>';
|
||||
exit();
|
||||
323
admin/manage_developers.php
Normal file
323
admin/manage_developers.php
Normal file
@@ -0,0 +1,323 @@
|
||||
<?php
|
||||
require_once '../config.php';
|
||||
|
||||
// 设置会话cookie路径为根目录以确保跨目录访问
|
||||
session_set_cookie_params(0, '/');
|
||||
session_start();
|
||||
// 检查是否已登录
|
||||
if (!isset($_SESSION['admin'])) {
|
||||
header('Location: login.php');
|
||||
exit();
|
||||
}
|
||||
|
||||
// 检查权限
|
||||
if ($_SESSION['admin']['permission'] != 'all') {
|
||||
$redirect = $_SESSION['admin']['permission'] == 'say' ? 'announcements.php' : 'review_apps.php';
|
||||
header("Location: $redirect");
|
||||
exit();
|
||||
}
|
||||
|
||||
// 处理退出登录
|
||||
if (isset($_GET['logout'])) {
|
||||
unset($_SESSION['admin']);
|
||||
header('Location: login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
// 导航栏
|
||||
?>
|
||||
<nav class="navbar navbar-expand-lg navbar-light blur-bg">
|
||||
<div class="container mt-4">
|
||||
<a href="../index.php"><img src="/favicon.jpeg" alt="Logo" style="height: 30px; margin-right: 10px; border-radius: var(--border-radius);"></a>
|
||||
<a class="navbar-brand" href="../index.php"><?php echo APP_STORE_NAME; ?></a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="index.php">App列表</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="addapp.php">添加App</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="review_apps.php">审核APP</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" aria-current="page" href="manage_developers.php">管理开发者</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#" onclick="confirmLogout()">退出登录</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<?php
|
||||
// 检查管理员权限
|
||||
// 设置会话cookie路径为根目录以确保跨目录访问
|
||||
session_set_cookie_params(0, '/');
|
||||
// 检查会话是否已启动,避免重复启动
|
||||
if (session_status() == PHP_SESSION_NONE) {
|
||||
if (!session_start()) {
|
||||
error_log('会话启动失败');
|
||||
header('Location: login.php');
|
||||
exit;
|
||||
|
||||
error_log('会话启动失败');
|
||||
header('Location: login.php');
|
||||
exit;
|
||||
// 从数据库验证用户角色,确保权限检查准确性
|
||||
if (isset($_SESSION['user_id'])) {
|
||||
$userId = $_SESSION['user_id'];
|
||||
$stmt = $conn->prepare("SELECT role FROM users WHERE id = ?");
|
||||
if (!$stmt) {
|
||||
error_log('Database prepare failed: ' . $conn->error);
|
||||
header('Location: login.php');
|
||||
exit;
|
||||
}
|
||||
$stmt->bind_param("i", $userId);
|
||||
if (!$stmt->execute()) {
|
||||
error_log('Query execution failed: ' . $stmt->error);
|
||||
header('Location: login.php');
|
||||
exit;
|
||||
}
|
||||
$result = $stmt->get_result();
|
||||
if (!$result) {
|
||||
error_log('Failed to get result: ' . $stmt->error);
|
||||
header('Location: login.php');
|
||||
exit;
|
||||
}
|
||||
$user = $result->fetch_assoc();
|
||||
|
||||
if (!$user || $user['role'] !== 'admin') {
|
||||
error_log('用户 ' . $userId . ' 不是管理员,拒绝访问');
|
||||
header('Location: login.php');
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
error_log('未找到用户会话,重定向到登录页');
|
||||
header('Location: login.php');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理删除用户请求
|
||||
if (isset($_POST['delete_user'])) {
|
||||
$userId = $_POST['user_id'];
|
||||
$stmt = $conn->prepare("DELETE FROM users WHERE id = ? AND role = 'developer'");
|
||||
if (!$stmt) {
|
||||
error_log('Database prepare failed: ' . $conn->error);
|
||||
header('Location: manage_developers.php?error=delete');
|
||||
exit;
|
||||
}
|
||||
$stmt->bind_param("i", $userId);
|
||||
if (!$stmt->execute()) {
|
||||
error_log('Delete query execution failed: ' . $stmt->error);
|
||||
header('Location: manage_developers.php?error=delete');
|
||||
exit;
|
||||
}
|
||||
$affected_rows = $stmt->affected_rows;
|
||||
$stmt->close();
|
||||
if ($affected_rows > 0) {
|
||||
header("Location: manage_developers.php?deleted=true");
|
||||
} else {
|
||||
error_log('No user deleted with ID: ' . $userId);
|
||||
header('Location: manage_developers.php?error=delete&user_id=' . $userId);
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
// 处理更新用户请求
|
||||
if (isset($_POST['update_user'])) {
|
||||
$userId = $_POST['user_id'];
|
||||
$username = $_POST['username'];
|
||||
$email = $_POST['email'];
|
||||
|
||||
// 使用mysqli语法更新用户信息
|
||||
$stmt = $conn->prepare("UPDATE developers SET username = ?, email = ? WHERE id = ?");
|
||||
if (!$stmt) {
|
||||
$error = $conn->error ?? 'Unknown error';
|
||||
error_log("Prepare failed: $error");
|
||||
die("更新用户信息失败: $error");
|
||||
}
|
||||
$stmt->bind_param("ssi", $username, $email, $userId);
|
||||
if (!$stmt->execute()) {
|
||||
$error = $stmt->error ?? 'Unknown error';
|
||||
error_log("Execute failed: $error");
|
||||
die("更新用户信息失败: $error");
|
||||
}
|
||||
$stmt->close();
|
||||
header("Location: manage_developers.php?updated=true");
|
||||
exit;
|
||||
}
|
||||
|
||||
// 获取所有开发者用户
|
||||
$developers = [];
|
||||
// 检查developers表是否存在
|
||||
$tableExists = $conn->query("SELECT 1 FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = 'developers'");
|
||||
if (!$tableExists || $tableExists->num_rows === 0) {
|
||||
error_log('Developers table does not exist');
|
||||
die('获取开发者列表失败: 开发者数据表不存在');
|
||||
}
|
||||
|
||||
$sql = "SELECT * FROM developers ORDER BY id DESC";
|
||||
$result = $conn->query($sql);
|
||||
if (!$result) {
|
||||
error_log('Failed to fetch developers. SQL: ' . $sql . ', Error: ' . $conn->error);
|
||||
die('获取开发者列表失败: ' . $conn->error . ' (SQL: ' . $sql . ')');
|
||||
}
|
||||
|
||||
// 检查是否有数据
|
||||
$rowCount = $result->num_rows;
|
||||
error_log('Developer query executed. Rows returned: ' . $rowCount);
|
||||
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$developers[] = $row;
|
||||
}
|
||||
|
||||
// 获取要编辑的用户信息
|
||||
$editUser = null;
|
||||
if (isset($_GET['edit'])) {
|
||||
$editId = (int)$_GET['edit'];
|
||||
$stmt = $conn->prepare("SELECT id, username, email FROM developers WHERE id = ?");
|
||||
if (!$stmt) {
|
||||
error_log('Prepare failed for edit user: ' . $conn->error);
|
||||
die('获取编辑用户信息失败: ' . $conn->error);
|
||||
}
|
||||
$stmt->bind_param("i", $editId);
|
||||
$stmt->execute();
|
||||
$editUser = $stmt->get_result()->fetch_assoc();
|
||||
$stmt->close();
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>管理开发者用户 - 应用商店管理</title>
|
||||
<!-- Bootstrap CSS -->
|
||||
<link href="../css/bootstrap.min.css" rel="stylesheet">
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="/css/all.min.css">
|
||||
<!-- 自定义CSS -->
|
||||
<link rel="stylesheet" href="../styles.css">
|
||||
<!-- Fluent Design 模糊效果 -->
|
||||
<style>
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script src="/js/sweetalert.js"></script>
|
||||
<script>
|
||||
function confirmLogout() {
|
||||
Swal.fire({
|
||||
title: '确定要登出吗?',
|
||||
icon: 'question',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
window.location.href = 'logout.php';
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Bootstrap JS Bundle with Popper -->
|
||||
<script src="/js/bootstrap.bundle.js"></script>
|
||||
<script>
|
||||
// 导航栏滚动效果
|
||||
window.addEventListener('scroll', function() {
|
||||
const navbar = document.querySelector('.navbar');
|
||||
if (window.scrollY > 10) {
|
||||
navbar.classList.add('scrolled');
|
||||
} else {
|
||||
navbar.classList.remove('scrolled');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<div class="container">
|
||||
<h1><i class="fas fa-users me-2"></i>管理开发者用户</h1>
|
||||
<pre>调试信息:
|
||||
查询SQL: <?php echo $sql; ?>
|
||||
查询结果行数: <?php echo $rowCount; ?>
|
||||
数据表存在: <?php echo $tableExists ? '是' : '否'; ?>
|
||||
开发者数据: <?php print_r($developers); ?></pre>
|
||||
|
||||
<?php if (isset($_GET['deleted'])): ?>
|
||||
<div class="alert alert-success">用户已成功删除</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($_GET['updated'])): ?>
|
||||
<div class="alert alert-success">用户信息已成功更新</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($editUser): ?>
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h2><i class="fas fa-edit me-2"></i>编辑开发者用户</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="post" action="manage_developers.php">
|
||||
<input type="hidden" name="user_id" value="<?php echo $editUser['id']; ?>">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" class="form-control" id="username" name="username" value="<?php echo htmlspecialchars($editUser['username']); ?>" required>
|
||||
<label for="username"><i class="fas fa-user me-2"></i>用户名</label>
|
||||
</div>
|
||||
<div class="form-floating mb-3">
|
||||
<input type="email" class="form-control" id="email" name="email" value="<?php echo htmlspecialchars($editUser['email']); ?>" required>
|
||||
<label for="email"><i class="fas fa-envelope me-2"></i>邮箱</label>
|
||||
</div>
|
||||
<button type="submit" name="update_user" class="btn btn-primary me-2"><i class="fas fa-save me-2"></i>更新用户</button>
|
||||
<a href="manage_developers.php" class="btn btn-secondary"><i class="fas fa-times-circle me-2"></i>取消</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><i class="fas fa-id-card me-2"></i>ID</th>
|
||||
<th><i class="fas fa-user me-2"></i>用户名</th>
|
||||
<th><i class="fas fa-envelope me-2"></i>邮箱</th>
|
||||
<th><i class="fas fa-clock me-2"></i>注册时间</th>
|
||||
<th><i class="fas fa-cog me-2"></i>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($developers as $developer): ?>
|
||||
<tr>
|
||||
<td><?php echo $developer['id']; ?></td>
|
||||
<td><?php echo htmlspecialchars($developer['username']); ?></td>
|
||||
<td><?php echo htmlspecialchars($developer['email']); ?></td>
|
||||
<td><?php echo $developer['created_at']; ?></td>
|
||||
<td>
|
||||
<a href="manage_developers.php?edit=<?php echo $developer['id']; ?>" class="btn btn-sm btn-outline-primary"><i class="fas fa-edit me-1"></i>编辑</a>
|
||||
<form method="post" action="manage_developers.php" style="display: inline-block;" onsubmit="return confirm('确定要删除这个用户吗?');">
|
||||
<input type="hidden" name="user_id" value="<?php echo $developer['id']; ?>">
|
||||
<button type="submit" name="delete_user" class="btn btn-sm btn-outline-danger"><i class="fas fa-trash-alt me-1"></i>删除</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php if (empty($developers)): ?>
|
||||
<tr>
|
||||
<td colspan="5" class="text-center">暂无开发者数据</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
184
admin/manage_tags.php
Normal file
184
admin/manage_tags.php
Normal file
@@ -0,0 +1,184 @@
|
||||
<?php
|
||||
require_once '../config.php';
|
||||
require_once 'login.php'; // 确保管理员已登录
|
||||
|
||||
// 检查权限
|
||||
if ($_SESSION['admin']['permission'] != 'all') {
|
||||
$redirect = $_SESSION['admin']['permission'] == 'say' ? 'announcements.php' : 'review_apps.php';
|
||||
header("Location: $redirect");
|
||||
exit();
|
||||
}
|
||||
|
||||
// 处理标签添加
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_tag'])) {
|
||||
$name = trim($_POST['tag_name']);
|
||||
if (!empty($name)) {
|
||||
$stmt = $conn->prepare("INSERT INTO tags (name) VALUES (?)");
|
||||
$stmt->bind_param("s", $name);
|
||||
if ($stmt->execute()) {
|
||||
header('Location: manage_tags.php?success=标签添加成功');
|
||||
exit;
|
||||
} else {
|
||||
$error = '添加失败: ' . $conn->error;
|
||||
}
|
||||
} else {
|
||||
$error = '标签名称不能为空';
|
||||
}
|
||||
}
|
||||
|
||||
// 处理标签删除
|
||||
if (isset($_GET['delete'])) {
|
||||
$tagId = intval($_GET['delete']);
|
||||
$stmt = $conn->prepare("DELETE FROM tags WHERE id = ?");
|
||||
$stmt->bind_param("i", $tagId);
|
||||
if ($stmt->execute()) {
|
||||
header('Location: manage_tags.php?success=标签删除成功');
|
||||
exit;
|
||||
} else {
|
||||
$error = '删除失败: ' . $conn->error;
|
||||
}
|
||||
}
|
||||
|
||||
// 处理标签编辑
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['edit_tag'])) {
|
||||
$tagId = intval($_POST['tag_id']);
|
||||
$name = trim($_POST['tag_name']);
|
||||
if (!empty($name)) {
|
||||
$stmt = $conn->prepare("UPDATE tags SET name = ? WHERE id = ?");
|
||||
$stmt->bind_param("si", $name, $tagId);
|
||||
if ($stmt->execute()) {
|
||||
header('Location: manage_tags.php?success=标签更新成功');
|
||||
exit;
|
||||
} else {
|
||||
$error = '更新失败: ' . $conn->error;
|
||||
}
|
||||
} else {
|
||||
$error = '标签名称不能为空';
|
||||
}
|
||||
}
|
||||
|
||||
// 获取所有标签
|
||||
$tagsResult = $conn->query("SELECT * FROM tags ORDER BY created_at DESC");
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>标签管理 - 应用商店后台</title>
|
||||
<link href="../css/bootstrap.min.css" rel="stylesheet">
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="/css/all.min.css">
|
||||
<link rel="stylesheet" href="../styles.css">
|
||||
<script src="/js/sweetalert.js"></script>
|
||||
<script>
|
||||
function confirmLogout() {
|
||||
Swal.fire({
|
||||
title: '确定要登出吗?',
|
||||
icon: 'question',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
window.location.href = 'logout.php';
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-5">
|
||||
<h1 class="mb-4">标签管理</h1>
|
||||
<a href="index.php" class="btn btn-secondary mb-3"><i class="fas fa-arrow-left me-2"></i>返回应用列表</a>
|
||||
|
||||
<?php if (isset($_GET['success'])): ?>
|
||||
<div class="alert alert-success"><?php echo $_GET['success']; ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($error)): ?>
|
||||
<div class="alert alert-danger"><?php echo $error; ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- 添加标签表单 -->
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0"><i class="fas fa-plus-circle me-2"></i>添加新标签</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="post">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" class="form-control" id="tag_name" name="tag_name" required>
|
||||
<label for="tag_name"><i class="fas fa-tag me-2"></i>标签名称</label>
|
||||
</div>
|
||||
<button type="submit" name="add_tag" class="btn btn-primary"><i class="fas fa-save me-2"></i>添加标签</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 标签列表 -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0"><i class="fas fa-list me-2"></i>现有标签</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>标签名称</th>
|
||||
<th>创建时间</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php while ($tag = $tagsResult->fetch_assoc()): ?>
|
||||
<tr>
|
||||
<td><?php echo $tag['id']; ?></td>
|
||||
<td><?php echo htmlspecialchars($tag['name']); ?></td>
|
||||
<td><?php echo $tag['created_at']; ?></td>
|
||||
<td>
|
||||
<!-- 编辑按钮触发模态框 -->
|
||||
<button type="button" class="btn btn-sm btn-outline-primary" data-bs-toggle="modal" data-bs-target="#editModal<?php echo $tag['id']; ?>">
|
||||
<i class="fas fa-edit me-1"></i>编辑
|
||||
</button>
|
||||
<a href="manage_tags.php?delete=<?php echo $tag['id']; ?>" class="btn btn-sm btn-outline-danger" onclick="return confirm('确定要删除这个标签吗?关联的应用标签也会被删除。');"><i class="fas fa-trash-alt me-1"></i>删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- 编辑标签模态框 -->
|
||||
<div class="modal fade" id="editModal<?php echo $tag['id']; ?>" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title"><i class="fas fa-edit me-2"></i>编辑标签</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form method="post">
|
||||
<input type="hidden" name="tag_id" value="<?php echo $tag['id']; ?>">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" class="form-control" id="edit_tag_name<?php echo $tag['id']; ?>" name="tag_name" value="<?php echo htmlspecialchars($tag['name']); ?>" required>
|
||||
<label for="edit_tag_name<?php echo $tag['id']; ?>"><i class="fas fa-tag me-2"></i>标签名称</label>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><i class="fas fa-times-circle me-2"></i>取消</button>
|
||||
<button type="submit" name="edit_tag" class="btn btn-primary"><i class="fas fa-save me-2"></i>保存修改</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#" onclick="confirmLogout()">退出登录</a>
|
||||
</li>
|
||||
</body>
|
||||
</html>
|
||||
383
admin/manage_versions.php
Normal file
383
admin/manage_versions.php
Normal file
@@ -0,0 +1,383 @@
|
||||
<?php
|
||||
require_once '../config.php';
|
||||
|
||||
session_start();
|
||||
// 检查是否已登录
|
||||
if (!isset($_SESSION['admin'])) {
|
||||
header('Location: login.php');
|
||||
exit();
|
||||
}
|
||||
|
||||
// 非全部权限管理员重定向到对应权限页面
|
||||
if ($_SESSION['admin']['permission'] != 'all') {
|
||||
$redirect = $_SESSION['admin']['permission'] == 'say' ? 'announcements.php' : 'review_apps.php';
|
||||
header("Location: $redirect");
|
||||
exit();
|
||||
}
|
||||
|
||||
// 验证App ID
|
||||
if (!isset($_GET['app_id']) || !is_numeric($_GET['app_id'])) {
|
||||
header('Location: index.php?error=无效的App ID');
|
||||
exit;
|
||||
}
|
||||
$appId = $_GET['app_id'];
|
||||
|
||||
// 获取App信息
|
||||
$app = null;
|
||||
$getAppSql = "SELECT * FROM apps WHERE id = ?";
|
||||
$stmt = $conn->prepare($getAppSql);
|
||||
$stmt->bind_param("i", $appId);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
if ($result->num_rows === 0) {
|
||||
header('Location: index.php?error=App不存在');
|
||||
exit;
|
||||
}
|
||||
$app = $result->fetch_assoc();
|
||||
|
||||
// 获取所有版本
|
||||
$versions = [];
|
||||
$getVersionsSql = "SELECT * FROM app_versions WHERE app_id = ? ORDER BY created_at DESC";
|
||||
$stmt = $conn->prepare($getVersionsSql);
|
||||
$stmt->bind_param("i", $appId);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$versions[] = $row;
|
||||
}
|
||||
|
||||
$success = '';
|
||||
$error = '';
|
||||
|
||||
// 处理添加版本
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_version'])) {
|
||||
$version = $_POST['version'];
|
||||
$changelog = $_POST['changelog'];
|
||||
|
||||
if (empty($version)) {
|
||||
$error = '版本号不能为空';
|
||||
} elseif (empty($_FILES['app_file']['name'])) {
|
||||
$error = '请上传App文件';
|
||||
} else {
|
||||
$uploadDir = '../files/';
|
||||
$fileName = basename($_FILES['app_file']['name']);
|
||||
$targetPath = $uploadDir . $fileName;
|
||||
|
||||
if (move_uploaded_file($_FILES['app_file']['tmp_name'], $targetPath)) {
|
||||
$insertVersionSql = "INSERT INTO app_versions (app_id, version, changelog, file_path, created_at) VALUES (?, ?, ?, ?, NOW())";
|
||||
$stmt = $conn->prepare($insertVersionSql);
|
||||
$stmt->bind_param("isss", $appId, $version, $changelog, $targetPath);
|
||||
|
||||
if ($stmt->execute() === TRUE) {
|
||||
header('Location: manage_versions.php?app_id=' . $appId . '&success=版本添加成功');
|
||||
exit;
|
||||
} else {
|
||||
$error = '版本添加失败: ' . $conn->error;
|
||||
unlink($targetPath); // 删除已上传的文件
|
||||
}
|
||||
} else {
|
||||
$error = '文件上传失败';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理删除版本
|
||||
if (isset($_GET['delete_id']) && is_numeric($_GET['delete_id'])) {
|
||||
$versionId = $_GET['delete_id'];
|
||||
|
||||
// 获取版本信息
|
||||
$getVersionSql = "SELECT file_path FROM app_versions WHERE id = ? AND app_id = ?";
|
||||
$stmt = $conn->prepare($getVersionSql);
|
||||
$stmt->bind_param("ii", $versionId, $appId);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
if ($result->num_rows === 1) {
|
||||
$version = $result->fetch_assoc();
|
||||
|
||||
// 删除文件
|
||||
if (file_exists($version['file_path'])) {
|
||||
unlink($version['file_path']);
|
||||
}
|
||||
|
||||
// 删除数据库记录
|
||||
$deleteVersionSql = "DELETE FROM app_versions WHERE id = ? AND app_id = ?";
|
||||
$stmt = $conn->prepare($deleteVersionSql);
|
||||
$stmt->bind_param("ii", $versionId, $appId);
|
||||
|
||||
if ($stmt->execute() === TRUE) {
|
||||
header('Location: manage_versions.php?app_id=' . $appId . '&success=版本删除成功');
|
||||
exit;
|
||||
} else {
|
||||
$error = '版本删除失败: ' . $conn->error;
|
||||
}
|
||||
} else {
|
||||
$error = '版本不存在';
|
||||
}
|
||||
}
|
||||
|
||||
// 处理编辑版本
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['edit_version'])) {
|
||||
$versionId = $_POST['version_id'];
|
||||
$version = $_POST['version'];
|
||||
$changelog = $_POST['changelog'];
|
||||
|
||||
if (empty($version)) {
|
||||
$error = '版本号不能为空';
|
||||
} else {
|
||||
// 检查是否上传了新文件
|
||||
$fileUpdate = '';
|
||||
$params = ['ss', $version, $changelog, $versionId, $appId];
|
||||
|
||||
if (!empty($_FILES['new_app_file']['name'])) {
|
||||
$uploadDir = '../files/';
|
||||
$fileName = basename($_FILES['new_app_file']['name']);
|
||||
$targetPath = $uploadDir . $fileName;
|
||||
|
||||
if (move_uploaded_file($_FILES['new_app_file']['tmp_name'], $targetPath)) {
|
||||
// 获取旧文件路径
|
||||
$getOldFileSql = "SELECT file_path FROM app_versions WHERE id = ? AND app_id = ?";
|
||||
$stmt = $conn->prepare($getOldFileSql);
|
||||
$stmt->bind_param("ii", $versionId, $appId);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
$oldVersion = $result->fetch_assoc();
|
||||
|
||||
// 删除旧文件
|
||||
if (file_exists($oldVersion['file_path'])) {
|
||||
unlink($oldVersion['file_path']);
|
||||
}
|
||||
|
||||
$fileUpdate = ", file_path = ?";
|
||||
$params[0] = 'sss';
|
||||
$params[] = $targetPath;
|
||||
} else {
|
||||
$error = '文件上传失败';
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($error)) {
|
||||
$updateVersionSql = "UPDATE app_versions SET version = ?, changelog = ?" . $fileUpdate . " WHERE id = ? AND app_id = ?";
|
||||
$stmt = $conn->prepare($updateVersionSql);
|
||||
|
||||
// 动态绑定参数
|
||||
$stmt->bind_param(...$params);
|
||||
|
||||
if ($stmt->execute() === TRUE) {
|
||||
header('Location: manage_versions.php?app_id=' . $appId . '&success=版本更新成功');
|
||||
exit;
|
||||
} else {
|
||||
$error = '版本更新失败: ' . $conn->error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取URL参数中的成功/错误消息
|
||||
if (isset($_GET['success'])) {
|
||||
$success = $_GET['success'];
|
||||
} elseif (isset($_GET['error'])) {
|
||||
$error = $_GET['error'];
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>管理版本 - <?php echo htmlspecialchars($app['name']); ?></title>
|
||||
<!-- Bootstrap CSS -->
|
||||
<link href="../css/bootstrap.min.css" rel="stylesheet">
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="/css/all.min.css">
|
||||
<!-- 自定义CSS -->
|
||||
<link rel="stylesheet" href="../styles.css">
|
||||
<style>
|
||||
.version-card {
|
||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||
}
|
||||
.version-card:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 10px 20px rgba(0,0,0,0.1);
|
||||
}
|
||||
.action-btn {
|
||||
margin: 0 2px;
|
||||
}
|
||||
.modal-backdrop {
|
||||
backdrop-filter: blur(5px);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- 导航栏 -->
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="index.php"><?php echo APP_STORE_NAME; ?></a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="index.php">App列表</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="editapp.php?id=<?php echo $appId; ?>">返回编辑App</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" aria-current="page" href="manage_versions.php?app_id=<?php echo $appId; ?>">管理版本</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="?logout=true">退出登录</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container mt-4">
|
||||
<div class="row mb-4">
|
||||
<div class="col">
|
||||
<h1><i class="fas fa-code-branch me-2"></i>管理版本: <?php echo htmlspecialchars($app['name']); ?></h1>
|
||||
<p class="text-muted">管理该应用的所有版本</p>
|
||||
</div>
|
||||
<div class="col text-end">
|
||||
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addVersionModal">
|
||||
<i class="fas fa-plus-circle me-2"></i>添加新版本
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($success)): ?>
|
||||
<div class="alert alert-success"><?php echo $success; ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($error)): ?>
|
||||
<div class="alert alert-danger"><?php echo $error; ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (empty($versions)): ?>
|
||||
<div class="alert alert-info">
|
||||
暂无版本记录
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="row">
|
||||
<?php foreach ($versions as $version): ?>
|
||||
<div class="col-md-6 col-lg-4 mb-4">
|
||||
<div class="card version-card h-100">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><i class="fas fa-tag me-2"></i>版本 <?php echo htmlspecialchars($version['version']); ?></h5>
|
||||
<h6 class="card-subtitle mb-2 text-muted">发布日期: <?php echo date('Y-m-d H:i', strtotime($version['created_at'])); ?></h6>
|
||||
<p class="card-text"><?php echo nl2br(htmlspecialchars($version['changelog'])); ?></p>
|
||||
</div>
|
||||
<div class="card-footer bg-transparent d-flex justify-content-between align-items-center">
|
||||
<small class="text-muted">文件大小: <?php
|
||||
$filePath = $version['file_path'];
|
||||
if (file_exists($filePath)) {
|
||||
echo filesize($filePath) > 0 ? number_format(filesize($filePath) / 1024 / 1024, 2) . ' MB' : '未知';
|
||||
} else {
|
||||
echo '文件不存在';
|
||||
}
|
||||
?></small>
|
||||
<div> <button type="button" class="btn btn-sm btn-outline-secondary action-btn" data-bs-toggle="modal" data-bs-target="#editVersionModal_<?php echo $version['id']; ?>">
|
||||
<i class="fas fa-edit me-1"></i>编辑
|
||||
</button>
|
||||
<a href="../<?php echo htmlspecialchars($version['file_path']); ?>" class="btn btn-sm btn-primary action-btn" download>
|
||||
<i class="fas fa-download me-1"></i>下载
|
||||
</a>
|
||||
<a href="?app_id=<?php echo $appId; ?>&delete_id=<?php echo $version['id']; ?>" class="btn btn-sm btn-outline-danger action-btn" onclick="return confirm('确定要删除此版本吗?');">
|
||||
<i class="fas fa-trash-alt me-1"></i>删除
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 编辑版本模态框 -->
|
||||
<div class="modal fade" id="editVersionModal_<?php echo $version['id']; ?>" tabindex="-1" aria-labelledby="editVersionModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="editVersionModalLabel"><i class="fas fa-edit me-2"></i>编辑版本 <?php echo htmlspecialchars($version['version']); ?></h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
<div class="modal-body">
|
||||
<input type="hidden" name="version_id" value="<?php echo $version['id']; ?>">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" class="form-control" id="version_<?php echo $version['id']; ?>" name="version" value="<?php echo htmlspecialchars($version['version']); ?>" placeholder="如: 1.0.0" required>
|
||||
<label for="version_<?php echo $version['id']; ?>"><i class="fas fa-hashtag me-2"></i>版本号</label>
|
||||
</div>
|
||||
<div class="form-floating mb-3">
|
||||
<textarea class="form-control" id="changelog_<?php echo $version['id']; ?>" name="changelog" rows="3" placeholder="描述本次更新内容" required><?php echo htmlspecialchars($version['changelog']); ?></textarea>
|
||||
<label for="changelog_<?php echo $version['id']; ?>"><i class="fas fa-history me-2"></i>更新日志</label>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="new_app_file_<?php echo $version['id']; ?>" class="form-label"><i class="fas fa-upload me-2"></i>更新App文件 (可选)</label>
|
||||
<input class="form-control" type="file" id="new_app_file_<?php echo $version['id']; ?>" name="new_app_file">
|
||||
<div class="form-text">当前文件: <?php echo basename($version['file_path']); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
||||
<i class="fas fa-times-circle me-1"></i>取消
|
||||
</button>
|
||||
<button type="submit" class="btn btn-primary" name="edit_version">
|
||||
<i class="fas fa-save me-1"></i>保存更改
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- 添加版本模态框 -->
|
||||
<div class="modal fade" id="addVersionModal" tabindex="-1" aria-labelledby="addVersionModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="addVersionModalLabel"><i class="fas fa-plus-circle me-2"></i>添加新版本</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
<div class="modal-body">
|
||||
<div class="form-floating mb-3">
|
||||
<input type="text" class="form-control" id="version" name="version" placeholder="如: 1.0.0" required>
|
||||
<label for="version"><i class="fas fa-hashtag me-2"></i>版本号</label>
|
||||
</div>
|
||||
<div class="form-floating mb-3">
|
||||
<textarea class="form-control" id="changelog" name="changelog" rows="3" placeholder="描述本次更新内容" required></textarea>
|
||||
<label for="changelog"><i class="fas fa-history me-2"></i>更新日志</label>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="app_file" class="form-label"><i class="fas fa-upload me-2"></i>App文件</label>
|
||||
<input class="form-control" type="file" id="app_file" name="app_file" required>
|
||||
<a href="<?php echo htmlspecialchars($version['file_path']); ?>" class="btn btn-sm btn-primary" download>下载</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
|
||||
<button type="submit" class="btn btn-primary" name="add_version">添加版本</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap JS Bundle with Popper -->
|
||||
<script src="/js/bootstrap.bundle.js"></script>
|
||||
<script>
|
||||
// 导航栏滚动效果
|
||||
window.addEventListener('scroll', function() {
|
||||
const navbar = document.querySelector('.navbar');
|
||||
if (window.scrollY > 10) {
|
||||
navbar.classList.add('scrolled');
|
||||
} else {
|
||||
navbar.classList.remove('scrolled');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
348
admin/review_apps.php
Normal file
348
admin/review_apps.php
Normal file
@@ -0,0 +1,348 @@
|
||||
<?php
|
||||
require_once '../config.php';
|
||||
require_once '../vendor/autoload.php';
|
||||
require_once '../includes/logger.php';
|
||||
use PHPMailer\PHPMailer\PHPMailer;
|
||||
use PHPMailer\PHPMailer\Exception;
|
||||
|
||||
session_start();
|
||||
// 检查是否已登录
|
||||
if (!isset($_SESSION['admin'])) {
|
||||
header('Location: login.php');
|
||||
exit();
|
||||
}
|
||||
|
||||
// 检查权限 - 允许all和review权限
|
||||
if (!in_array($_SESSION['admin']['permission'], ['all', 'review'])) {
|
||||
$redirect = $_SESSION['admin']['permission'] == 'say' ? 'announcements.php' : 'index.php';
|
||||
header("Location: $redirect");
|
||||
exit();
|
||||
}
|
||||
|
||||
$success = '';
|
||||
$error = '';
|
||||
|
||||
// 处理审核操作
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['review_action'])) {
|
||||
$appId = $_POST['app_id'];
|
||||
$action = $_POST['review_action'];
|
||||
$rejectionReason = urldecode($_POST['rejection_reason'] ?? '');
|
||||
|
||||
// 验证应用ID
|
||||
if (!is_numeric($appId)) {
|
||||
$error = '无效的应用ID';
|
||||
} else {
|
||||
// 检查数据库连接
|
||||
if (!($conn instanceof mysqli)) {
|
||||
log_error('数据库连接错误: 连接不是MySQLi实例', __FILE__, __LINE__);
|
||||
$error = '数据库连接错误,请检查配置';
|
||||
} else {
|
||||
// 更新应用状态
|
||||
$status = $action === 'approve' ? 'approved' : 'rejected';
|
||||
$stmt = $conn->prepare("UPDATE apps SET status = ?, rejection_reason = ? WHERE id = ?");
|
||||
if (!$stmt) {
|
||||
$error = "数据库错误: " . $conn->error;
|
||||
} else {
|
||||
$stmt->bind_param("ssi", $status, $rejectionReason, $appId);
|
||||
if ($stmt->execute()) {
|
||||
// 获取应用信息和开发者邮箱
|
||||
$getAppStmt = $conn->prepare("SELECT name, developer_email FROM apps WHERE id = ?");
|
||||
$getAppStmt->bind_param("i", $appId);
|
||||
$getAppStmt->execute();
|
||||
$appResult = $getAppStmt->get_result();
|
||||
$appInfo = $appResult->fetch_assoc();
|
||||
$getAppStmt->close();
|
||||
|
||||
$success = '应用审核已更新';
|
||||
$appName = $appInfo['name'] ?? '未知应用';
|
||||
$devEmail = $appInfo['developer_email'] ?? '';
|
||||
|
||||
// 发送邮件通知
|
||||
if (!empty($devEmail)) {
|
||||
$mail = new PHPMailer(true);
|
||||
try {
|
||||
// 服务器配置
|
||||
$mail->isSMTP();
|
||||
$mail->Host = SMTP_HOST;
|
||||
$mail->Port = SMTP_PORT;
|
||||
$mail->SMTPSecure = SMTP_ENCRYPTION;
|
||||
$mail->SMTPAuth = true;
|
||||
$mail->Username = SMTP_USERNAME;
|
||||
$mail->Password = SMTP_PASSWORD;
|
||||
$mail->CharSet = 'UTF-8';
|
||||
$mail->isHTML(true);
|
||||
$mail->setFrom(SMTP_FROM_EMAIL, SMTP_FROM_NAME);
|
||||
$mail->addAddress($devEmail);
|
||||
|
||||
// 邮件内容
|
||||
if ($status === 'approved') {
|
||||
$mail->Subject = '应用审核通过通知';
|
||||
$mail->Body = "<div style='font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; border: 1px solid #e0e0e0; border-radius: 8px;'>
|
||||
<h2 style='color: #2c3e50;'>应用审核通过通知</h2>
|
||||
<p>您好,</p>
|
||||
<p>您的应用 <strong>{$appName}</strong> 已成功通过审核!</p>
|
||||
<p>现在可以在应用商店中查看您的应用。</p>
|
||||
<p style='margin-top: 20px; color: #666;'>此致<br>应用商店团队</p>
|
||||
</div>";
|
||||
} else {
|
||||
$mail->Subject = '应用审核未通过通知';
|
||||
$mail->Body = "<div style='font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; border: 1px solid #e0e0e0; border-radius: 8px;'>
|
||||
<h2 style='color: #e74c3c;'>应用审核未通过通知</h2>
|
||||
<p>您好,</p>
|
||||
<p>您的应用 <strong>{$appName}</strong> 未通过审核。</p>
|
||||
<p>原因:<br>{$rejectionReason}</p>
|
||||
<p style='margin-top: 20px; color: #666;'>此致<br>应用商店团队</p>
|
||||
</div>";
|
||||
}
|
||||
|
||||
$mail->send();
|
||||
$success .= ',邮件通知已发送';
|
||||
} catch (Exception $e) {
|
||||
log_error("邮件发送失败: {$mail->ErrorInfo}", __FILE__, __LINE__);
|
||||
$error = "审核状态已更新,但邮件发送失败: {$mail->ErrorInfo}";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$error = '更新审核状态失败: ' . $conn->error;
|
||||
}
|
||||
$stmt->close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取待审核应用列表
|
||||
$pendingApps = [];
|
||||
if (!($conn instanceof mysqli)) {
|
||||
log_error('数据库连接错误: 连接不是MySQLi实例', __FILE__, __LINE__);
|
||||
$error = '数据库连接错误,请检查配置';
|
||||
} else {
|
||||
$stmt = $conn->prepare("SELECT a.id, a.name, a.description, a.status, a.created_at, d.username
|
||||
FROM apps a
|
||||
LEFT JOIN developers d ON a.developer_id = d.id
|
||||
WHERE a.status = 'pending'
|
||||
ORDER BY a.created_at DESC");
|
||||
if (!$stmt) {
|
||||
$error = "数据库错误: " . $conn->error;
|
||||
} else {
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
$pendingApps = $result->fetch_all(MYSQLI_ASSOC);
|
||||
$stmt->close();
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>应用审核 - <?php echo APP_STORE_NAME; ?></title>
|
||||
<!-- Bootstrap CSS -->
|
||||
<link href="../css/bootstrap.min.css" rel="stylesheet">
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="/css/all.min.css">
|
||||
<!-- SweetAlert2 CSS -->
|
||||
<link rel="stylesheet" href="/js/sweetalert.js/dist/sweetalert2.min.css">
|
||||
<!-- 自定义CSS -->
|
||||
<link rel="stylesheet" href="../styles.css">
|
||||
<!-- Fluent Design 模糊效果 -->
|
||||
<style>
|
||||
.blur-bg {
|
||||
backdrop-filter: blur(10px);
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.app-card {
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
.app-card:hover {
|
||||
transform: scale(1.02);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- 导航栏 -->
|
||||
<nav class="navbar navbar-expand-lg navbar-light blur-bg">
|
||||
<div class="container">
|
||||
<a href="../index.php"><img src="/favicon.jpeg" alt="Logo" style="height: 30px; margin-right: 10px; border-radius: var(--border-radius);"></a>
|
||||
<a class="navbar-brand" href="../index.php"><?php echo APP_STORE_NAME; ?></a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="index.php">App列表</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="addapp.php">添加App</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" aria-current="page" href="review_apps.php">应用审核</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" onclick="confirmLogout()">退出登录</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container mt-4">
|
||||
<div class="alert alert-info">
|
||||
请遵循应用商店的<a href="/docs/app_review_standards.php" target="_blank"><i class="fas fa-external-link-alt me-1"></i>审核规则</a>,确保应用符合平台要求。
|
||||
</div>
|
||||
<?php if (!empty($success)): ?>
|
||||
<div class="alert alert-success"><?php echo $success; ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($error)): ?>
|
||||
<div class="alert alert-danger"><?php echo $error; ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<h2><i class="fas fa-check-circle me-2"></i>应用审核</h2>
|
||||
<p class="text-muted"><i class="fas fa-clock me-1"></i>待审核应用: <?php echo count($pendingApps); ?></p>
|
||||
|
||||
<?php if (empty($pendingApps)): ?>
|
||||
<div class="alert alert-info">没有待审核的应用</div>
|
||||
<?php else: ?>
|
||||
<div class="row">
|
||||
<?php foreach ($pendingApps as $app): ?>
|
||||
<div class="col-md-6 mb-4">
|
||||
<div class="card app-card shadow-sm">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h5 class="card-title mb-0"><?php echo htmlspecialchars($app['name']); ?></h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="card-text"><?php echo htmlspecialchars($app['description']); ?></p>
|
||||
<?php
|
||||
$appId = $app['id'];
|
||||
// 获取下载链接,假设在 app_versions 表中
|
||||
$getDownloadLinkStmt = $conn->prepare("SELECT file_path FROM app_versions WHERE app_id = ? ORDER BY created_at DESC LIMIT 1");
|
||||
if ($getDownloadLinkStmt) {
|
||||
$getDownloadLinkStmt->bind_param("i", $appId);
|
||||
$getDownloadLinkStmt->execute();
|
||||
$downloadLinkResult = $getDownloadLinkStmt->get_result();
|
||||
$downloadLinkInfo = $downloadLinkResult->fetch_assoc();
|
||||
$downloadLink = $downloadLinkInfo ? $downloadLinkInfo['file_path'] : '';
|
||||
$getDownloadLinkStmt->close();
|
||||
} else {
|
||||
$downloadLink = '';
|
||||
log_error('数据库准备语句错误: ' . $conn->error, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
// 获取应用标签
|
||||
$getTagsStmt = $conn->prepare("SELECT t.name FROM tags t JOIN app_tags at ON t.id = at.tag_id WHERE at.app_id = ?");
|
||||
if ($getTagsStmt) {
|
||||
$getTagsStmt->bind_param("i", $appId);
|
||||
$getTagsStmt->execute();
|
||||
$tagsResult = $getTagsStmt->get_result();
|
||||
$tags = [];
|
||||
while ($tag = $tagsResult->fetch_assoc()) {
|
||||
$tags[] = $tag['name'];
|
||||
}
|
||||
$tagString = implode(', ', $tags);
|
||||
$getTagsStmt->close();
|
||||
} else {
|
||||
$tagString = '';
|
||||
log_error('数据库准备语句错误: ' . $conn->error, __FILE__, __LINE__);
|
||||
}
|
||||
?>
|
||||
<?php if (!empty($downloadLink)): ?>
|
||||
<p class="card-text"><strong>下载链接:</strong> <a href="<?php echo htmlspecialchars('../' . $downloadLink); ?>" target="_blank">点击下载</a></p>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($tagString)): ?>
|
||||
<p class="card-text"><strong>标签:</strong> <?php echo htmlspecialchars($tagString); ?></p>
|
||||
<?php endif; ?>
|
||||
<p class="card-text"><strong>开发者:</strong> <?php echo htmlspecialchars($app['username'] ?? '管理员'); ?></p>
|
||||
<p class="card-text"><strong>提交时间:</strong> <?php echo htmlspecialchars($app['created_at']); ?></p>
|
||||
<p class="card-text"><strong>描述:</strong> <?php echo nl2br(htmlspecialchars($app['description'])); ?></p>
|
||||
|
||||
<!-- 获取应用图片 -->
|
||||
<?php
|
||||
$images = [];
|
||||
$stmt = $conn->prepare("SELECT image_path FROM app_images WHERE app_id = ?");
|
||||
$stmt->bind_param("i", $app['id']);
|
||||
$stmt->execute();
|
||||
$imgResult = $stmt->get_result();
|
||||
while ($img = $imgResult->fetch_assoc()) {
|
||||
$images[] = $img['image_path'];
|
||||
}
|
||||
$stmt->close();
|
||||
?>
|
||||
|
||||
<?php if (!empty($images)): ?>
|
||||
<div class="mb-3">
|
||||
<strong>预览图片:</strong><br>
|
||||
<img src="<?php echo htmlspecialchars($images[0]); ?>" alt="应用截图" class="img-thumbnail" style="max-width: 200px;">
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="post" class="mt-3">
|
||||
<input type="hidden" name="app_id" value="<?php echo $app['id']; ?>">
|
||||
<div class="d-flex gap-2">
|
||||
<button type="submit" name="review_action" value="approve" class="btn btn-success me-2"><i class="fas fa-check me-1"></i>通过</button>
|
||||
<button type="button" class="btn btn-danger" onclick="showRejectReason(<?php echo $app['id']; ?>, '<?php echo addslashes(htmlspecialchars($app['name'])); ?>')"><i class="fas fa-times me-1"></i>拒绝</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function showRejectReason(appId, appName) {
|
||||
Swal.fire({
|
||||
title: '拒绝应用: ' + appName,
|
||||
html: '<textarea id="rejectionReason" class="swal2-textarea" rows="3" placeholder="请详细说明拒绝原因,帮助开发者改进应用"></textarea>',
|
||||
confirmButtonText: '确认拒绝',
|
||||
cancelButtonText: '取消',
|
||||
showCancelButton: true,
|
||||
validationMessage: '请输入拒绝原因',
|
||||
preConfirm: () => {
|
||||
const reason = document.getElementById('rejectionReason').value;
|
||||
if (!reason) {
|
||||
Swal.showValidationMessage('请输入拒绝原因');
|
||||
}
|
||||
return reason;
|
||||
}
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
const form = document.createElement('form');
|
||||
form.method = 'post';
|
||||
form.innerHTML = `
|
||||
<input type="hidden" name="app_id" value="${appId}">
|
||||
<input type="hidden" name="review_action" value="reject">
|
||||
<input type="hidden" name="rejection_reason" value="${encodeURIComponent(result.value)}">
|
||||
`;
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap JS with Popper -->
|
||||
<script src="/js/bootstrap.bundle.js"></script>
|
||||
<!-- SweetAlert2 JS -->
|
||||
<script src="/js/sweetalert.js"></script>
|
||||
<script>
|
||||
function confirmLogout() {
|
||||
Swal.fire({
|
||||
title: '确认退出登录?',
|
||||
icon: 'question',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
reverseButtons: true
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
window.location.href = 'logout.php';
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
205
admin/system_info.php
Normal file
205
admin/system_info.php
Normal file
@@ -0,0 +1,205 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once '../config.php';
|
||||
|
||||
// 删除文件
|
||||
function delete_file($file_path) {
|
||||
if (file_exists($file_path)) {
|
||||
return unlink($file_path);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 处理删除请求
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$upload_dirs = [
|
||||
'../uploads/apps',
|
||||
'../uploads/images'
|
||||
];
|
||||
|
||||
// 全量删除
|
||||
if (isset($_POST['delete_all'])) {
|
||||
foreach ($upload_dirs as $dir) {
|
||||
if (is_dir($dir)) {
|
||||
$files = scandir($dir);
|
||||
foreach ($files as $file) {
|
||||
if ($file !== '.' && $file !== '..') {
|
||||
$file_path = $dir . '/' . $file;
|
||||
if (is_file($file_path)) {
|
||||
delete_file($file_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
header('Location: ' . $_SERVER['PHP_SELF']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// 单个删除
|
||||
if (isset($_POST['delete_files'])) {
|
||||
foreach ($_POST['delete_files'] as $file_info) {
|
||||
list($type, $filename) = explode('|', $file_info);
|
||||
$dir = $type === '图片' ? '../uploads/images' : '../uploads/apps';
|
||||
$file_path = $dir . '/' . $filename;
|
||||
delete_file($file_path);
|
||||
}
|
||||
header('Location: ' . $_SERVER['PHP_SELF']);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
// 验证管理员权限
|
||||
if (!isset($_SESSION['admin'])) {
|
||||
header('Location: login.php');
|
||||
exit();
|
||||
}
|
||||
|
||||
// 非全部权限管理员重定向到对应权限页面
|
||||
if ($_SESSION['admin']['permission'] != 'all') {
|
||||
$redirect = $_SESSION['admin']['permission'] == 'say' ? 'announcements.php' : 'review_apps.php';
|
||||
header("Location: $redirect");
|
||||
exit();
|
||||
}
|
||||
|
||||
// 获取上传文件和图片信息
|
||||
function get_uploaded_files_info() {
|
||||
$uploaded_files = [];
|
||||
|
||||
// 上传目录配置
|
||||
$upload_dirs = [
|
||||
'../uploads/apps',
|
||||
'../uploads/images'
|
||||
];
|
||||
|
||||
foreach ($upload_dirs as $dir) {
|
||||
if (is_dir($dir)) {
|
||||
$files = scandir($dir);
|
||||
foreach ($files as $file) {
|
||||
if ($file !== '.' && $file !== '..') {
|
||||
$file_path = $dir . '/' . $file;
|
||||
if (is_file($file_path)) {
|
||||
$file_size = filesize($file_path);
|
||||
$uploaded_files[] = [
|
||||
'name' => $file,
|
||||
'size' => $file_size,
|
||||
'type' => strpos($dir, 'images') !== false ? '图片' : '文件'
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $uploaded_files;
|
||||
}
|
||||
|
||||
$uploaded_files = get_uploaded_files_info();
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>系统信息 - 上传文件列表</title>
|
||||
<!-- Bootstrap CSS -->
|
||||
<link href="../css/bootstrap.min.css" rel="stylesheet">
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="/css/all.min.css">
|
||||
<link rel="stylesheet" href="../styles.css">
|
||||
<!-- 自定义CSS -->
|
||||
<link rel="stylesheet" href="../styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<!-- 导航栏 -->
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<div class="container">
|
||||
<a href="../index.php"><img src="/favicon.jpeg" alt="Logo" style="height: 30px; margin-right: 10px; border-radius: var(--border-radius);"></a>
|
||||
<a class="navbar-brand" href="index.php">管理员面板</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="index.php">首页</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="system_info.php">系统信息</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container mt-4">
|
||||
<form method="post">
|
||||
<h2><i class="fas fa-file-alt me-2"></i>上传文件信息</h2>
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><input type="checkbox" id="selectAll"></th>
|
||||
<th><i class="fas fa-file-name me-2"></i>文件名</th>
|
||||
<th><i class="fas fa-database me-2"></i>大小</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($uploaded_files as $file): ?>
|
||||
<?php if ($file['type'] === '文件'): ?>
|
||||
<tr>
|
||||
<td><input type="checkbox" name="delete_files[]" value="<?php echo $file['type'] . '|' . $file['name']; ?>"></td>
|
||||
<td><?php echo htmlspecialchars($file['name']); ?></td>
|
||||
<td><?php echo round($file['size'] / 1024, 2); ?> KB</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h2><i class="fas fa-image me-2"></i>上传图片信息</h2>
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><input type="checkbox" id="selectAllImages"></th>
|
||||
<th><i class="fas fa-file-image me-2"></i>文件名</th>
|
||||
<th><i class="fas fa-database me-2"></i>大小</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($uploaded_files as $file): ?>
|
||||
<?php if ($file['type'] === '图片'): ?>
|
||||
<tr>
|
||||
<td><input type="checkbox" name="delete_files[]" value="<?php echo $file['type'] . '|' . $file['name']; ?>"></td>
|
||||
<td><?php echo htmlspecialchars($file['name']); ?></td>
|
||||
<td><?php echo round($file['size'] / 1024, 2); ?> KB</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<button type="submit" name="delete_all" class="btn btn-danger" onclick="return confirm('确定要删除所有文件吗?')"><i class="fas fa-trash-alt me-2"></i>全量删除</button>
|
||||
<button type="submit" class="btn btn-danger ms-2" onclick="return confirm('确定要删除选中的文件吗?')"><i class="fas fa-trash-alt me-2"></i>删除选中</button>
|
||||
</form>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap JS Bundle with Popper -->
|
||||
<script src="/js/bootstrap.bundle.js"></script>
|
||||
<script>
|
||||
document.getElementById('selectAll').addEventListener('change', function() {
|
||||
const checkboxes = document.querySelectorAll('input[name="delete_files[]"]');
|
||||
checkboxes.forEach(checkbox => {
|
||||
checkbox.checked = this.checked;
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById('selectAllImages').addEventListener('change', function() {
|
||||
const checkboxes = document.querySelectorAll('input[name="delete_files[]"]');
|
||||
checkboxes.forEach(checkbox => {
|
||||
checkbox.checked = this.checked;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
62
admin/test_config.php
Normal file
62
admin/test_config.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
require_once '../config.php';
|
||||
session_start();
|
||||
|
||||
// 输出配置和会话信息
|
||||
echo '<!DOCTYPE html><html><head><title>配置测试</title></head><body>';
|
||||
echo '<h1>配置文件测试</h1>';
|
||||
|
||||
echo '<h2>常量配置</h2>';
|
||||
echo 'APP_STORE_NAME: ' . (defined('APP_STORE_NAME') ? APP_STORE_NAME : '未定义') . '<br>';
|
||||
echo 'DB_HOST: ' . (defined('DB_HOST') ? DB_HOST : '未定义') . '<br>';
|
||||
echo 'DB_USER: ' . (defined('DB_USER') ? DB_USER : '未定义') . '<br>';
|
||||
echo 'DB_NAME: ' . (defined('DB_NAME') ? DB_NAME : '未定义') . '<br>';
|
||||
echo 'DEBUG_MODE: ' . (defined('DEBUG_MODE') ? (DEBUG_MODE ? 'true' : 'false') : '未定义') . '<br>';
|
||||
|
||||
echo '<h2>管理员账户</h2>';
|
||||
if (isset($admin_accounts) && is_array($admin_accounts)) {
|
||||
echo '找到 ' . count($admin_accounts) . ' 个管理员账户<br>';
|
||||
foreach ($admin_accounts as $account) {
|
||||
echo '用户名: ' . $account['username'] . ', 权限: ' . $account['permission'] . '<br>';
|
||||
}
|
||||
} else {
|
||||
echo '未找到管理员账户配置<br>';
|
||||
}
|
||||
|
||||
echo '<h2>数据库连接</h2>';
|
||||
if (isset($conn) && $conn instanceof mysqli) {
|
||||
echo '数据库连接对象存在<br>';
|
||||
if ($conn->ping()) {
|
||||
echo '数据库连接成功<br>';
|
||||
} else {
|
||||
echo '数据库连接失败: ' . $conn->error . '<br>';
|
||||
}
|
||||
} else {
|
||||
echo '数据库连接对象不存在<br>';
|
||||
}
|
||||
|
||||
echo '<h2>会话信息</h2>';
|
||||
echo '会话ID: ' . session_id() . '<br>';
|
||||
echo '管理员登录状态: ' . (isset($_SESSION['admin']) ? '已登录' : '未登录') . '<br>';
|
||||
if (isset($_SESSION['admin'])) {
|
||||
echo '管理员ID: ' . $_SESSION['admin']['id'] . '<br>';
|
||||
echo '管理员用户名: ' . $_SESSION['admin']['username'] . '<br>';
|
||||
echo '管理员权限: ' . $_SESSION['admin']['permission'] . '<br>';
|
||||
}
|
||||
|
||||
echo '<h2>权限检查测试</h2>';
|
||||
echo 'index.php访问检查: ';
|
||||
if (isset($_SESSION['admin']) && $_SESSION['admin']['permission'] == 'all') {
|
||||
echo '允许访问<br>';
|
||||
} else {
|
||||
echo '将被重定向<br>';
|
||||
}
|
||||
|
||||
echo 'review_apps.php访问检查: ';
|
||||
if (isset($_SESSION['admin']) && in_array($_SESSION['admin']['permission'], ['all', 'review'])) {
|
||||
echo '允许访问<br>';
|
||||
} else {
|
||||
echo '将被重定向<br>';
|
||||
}
|
||||
|
||||
echo '</body></html>';
|
||||
Reference in New Issue
Block a user