From c827a784ddbafc1617730f5c4b7c0a907e35dd05 Mon Sep 17 00:00:00 2001 From: Snowz <372492339@qq.com> Date: Mon, 14 Apr 2025 16:50:30 +0800 Subject: [PATCH] first commit --- .htaccess | 1 + 404.html | 26 +++++++++ README.md | 24 ++++++++ admin/_log.php | 10 ++++ admin/admin.php | 73 ++++++++++++++++++++++++ admin/categories.php | 81 ++++++++++++++++++++++++++ admin/index.php | 9 +++ admin/login.php | 49 ++++++++++++++++ admin/logout.php | 7 +++ api/api.php | 50 ++++++++++++++++ assets/css/admin.css | 114 +++++++++++++++++++++++++++++++++++++ assets/css/auth.css | 48 ++++++++++++++++ assets/css/main.css | 0 assets/css/style.css | 106 ++++++++++++++++++++++++++++++++++ assets/js/main.js | 0 includes/api_functions.php | 79 +++++++++++++++++++++++++ includes/auth.php | 33 +++++++++++ includes/config.php | 17 ++++++ includes/db.php | 19 +++++++ 19 files changed, 746 insertions(+) create mode 100644 .htaccess create mode 100644 404.html create mode 100644 README.md create mode 100644 admin/_log.php create mode 100644 admin/admin.php create mode 100644 admin/categories.php create mode 100644 admin/index.php create mode 100644 admin/login.php create mode 100644 admin/logout.php create mode 100644 api/api.php create mode 100644 assets/css/admin.css create mode 100644 assets/css/auth.css create mode 100644 assets/css/main.css create mode 100644 assets/css/style.css create mode 100644 assets/js/main.js create mode 100644 includes/api_functions.php create mode 100644 includes/auth.php create mode 100644 includes/config.php create mode 100644 includes/db.php diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/.htaccess @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/404.html b/404.html new file mode 100644 index 0000000..80ca7f5 --- /dev/null +++ b/404.html @@ -0,0 +1,26 @@ + + + + + + +404 + + + + +

啥也没有

+ + diff --git a/README.md b/README.md new file mode 100644 index 0000000..0bf9d96 --- /dev/null +++ b/README.md @@ -0,0 +1,24 @@ +# 🌟 Random Image API Manager + +## 🚀 项目简介 +嘿,欢迎来到 Random Image API Manager!这是一个用 PHP + MySQL 打造的超级有趣的小工具,让你可以轻松管理随机图片的分类和展示。无论是为你的网站添加趣味图片,还是为你的应用提供动态素材,这个程序都能满足你的需求!🎉 + +## 🎨 功能亮点 +- **分类管理**:后台支持自定义分类,你可以根据需要创建不同的分类,让图片更有条理。 +- **图片上传**:通过后台轻松添加图片 URL,瞬间扩充你的图片库。 +- **随机展示**:通过指定分类的 API 接口,每次请求都能随机返回一张图片,让惊喜无处不在! +- **简单易用**:基于 PHP + MySQL,部署简单,操作直观。 + +## 🛠️ 技术栈 +- **后端**:PHP +- **数据库**:MySQL +- **前端**:简单 HTML + CSS(可扩展) + +## 📦 安装与部署 +### 环境要求 +- PHP 7.4+(推荐) +- MySQL 5.7+ +- Web 服务器(Apache/Nginx) + +### 📝 许可证 +本项目采用 MIT License,你可以自由使用和修改代码。 \ No newline at end of file diff --git a/admin/_log.php b/admin/_log.php new file mode 100644 index 0000000..6faffe8 --- /dev/null +++ b/admin/_log.php @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/admin/admin.php b/admin/admin.php new file mode 100644 index 0000000..81152f7 --- /dev/null +++ b/admin/admin.php @@ -0,0 +1,73 @@ +prepare("INSERT INTO images (url, resolution, category) VALUES (?, ?, ?)"); + + $success = 0; + foreach ($urls as $url) { + $url = trim($url); + if (filter_var($url, FILTER_VALIDATE_URL)) { + try { + $stmt->execute([$url, $resolution, $category]); + $success++; + } catch (PDOException $e) {} + } + } + $message = "成功添加 {$success} 条记录"; +} +?> + + + + + 管理后台 + + + +
+
+

欢迎回来,

+ 退出登录 +
+ + +
+ + +
+
+
+ + + +
+ + + + +
+
+
+ + \ No newline at end of file diff --git a/admin/categories.php b/admin/categories.php new file mode 100644 index 0000000..b11553e --- /dev/null +++ b/admin/categories.php @@ -0,0 +1,81 @@ +prepare("INSERT INTO categories (name) VALUES (?)"); + $stmt->execute([$name]); + $msg = "分类添加成功"; + } elseif ($action === 'delete') { + $stmt = $pdo->prepare("DELETE FROM categories WHERE id = ?"); + $stmt->execute([$_POST['id']]); + $msg = "分类删除成功"; + } + } catch (PDOException $e) { + $error = "操作失败:".$e->getMessage(); + } +} + +// 获取现有分类 +$categories = $pdo->query("SELECT * FROM categories ORDER BY name")->fetchAll(); +?> + + + + 分类管理 + + + + + +
+

分类管理

+ + +
+
+ + + +
+
+ + +
+ + + + + + + + + + + + + + + + + +
ID分类名称操作
+
+ + + +
+
+
+
+ + \ No newline at end of file diff --git a/admin/index.php b/admin/index.php new file mode 100644 index 0000000..6734e06 --- /dev/null +++ b/admin/index.php @@ -0,0 +1,9 @@ + + + + + + 后台登录 + + + +
+
+

图片管理系统

+ +
+ + +
+
+ +
+
+ +
+ +
+
+
+ + \ No newline at end of file diff --git a/admin/logout.php b/admin/logout.php new file mode 100644 index 0000000..6218710 --- /dev/null +++ b/admin/logout.php @@ -0,0 +1,7 @@ + $image['url'], + 'resolution' => $params['resolution'], + 'category' => $params['category'] + ]); + } else { + echo jsonError('未找到匹配的图片', 404); + } + +} catch (InvalidArgumentException $e) { + echo jsonError($e->getMessage(), 400); +} catch (PDOException $e) { + error_log("Database Error: " . $e->getMessage()); + echo jsonError('数据库查询失败', 500); +} catch (Exception $e) { + error_log("System Error: " . $e->getMessage()); + echo jsonError('系统繁忙,请稍后再试', 500); +} \ No newline at end of file diff --git a/assets/css/admin.css b/assets/css/admin.css new file mode 100644 index 0000000..d0e624d --- /dev/null +++ b/assets/css/admin.css @@ -0,0 +1,114 @@ +/* 基础样式 */ +.admin-container { + display: grid; + grid-template-columns: 240px 1fr; + min-height: 100vh; + background: #f8f9fa; +} + +.sidebar { + background: #2c3e50; + padding: 20px; + position: fixed; + width: 240px; + height: 100%; +} + +.brand { + color: white; + font-size: 1.5rem; + padding: 20px; + border-bottom: 1px solid #34495e; +} + +.sidebar nav a { + display: block; + color: #bdc3c7; + padding: 12px; + border-radius: 6px; + margin: 8px 0; + transition: all 0.3s; +} + +.sidebar nav a:hover { + background: #34495e; + color: white; + text-decoration: none; +} + +.sidebar nav a.active { + background: #3498db; + color: white; +} + +.main-content { + padding: 30px; +} + +.content-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 30px; +} + +.user-info { + background: white; + padding: 8px 15px; + border-radius: 20px; + box-shadow: 0 2px 5px rgba(0,0,0,0.1); +} + +.card { + background: white; + border-radius: 12px; + padding: 30px; + box-shadow: 0 5px 15px rgba(0,0,0,0.1); +} + +.form-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 20px; + margin-bottom: 25px; +} + +.form-group label { + display: block; + margin-bottom: 8px; + color: #2c3e50; + font-weight: 500; +} + +.form-control { + width: 100%; + padding: 12px; + border: 2px solid #e0e0e0; + border-radius: 8px; + transition: border-color 0.3s; +} + +.form-control:focus { + border-color: #3498db; + outline: none; +} + +.btn-primary { + background: #3498db; + color: white; + padding: 12px 25px; + border: none; + border-radius: 8px; + cursor: pointer; + transition: background 0.3s; +} + +.btn-primary:hover { + background: #2980b9; +} + +.hint { + color: #7f8c8d; + font-size: 0.9em; + margin-top: 8px; +} \ No newline at end of file diff --git a/assets/css/auth.css b/assets/css/auth.css new file mode 100644 index 0000000..32fdd98 --- /dev/null +++ b/assets/css/auth.css @@ -0,0 +1,48 @@ +.auth-container { + background: linear-gradient(135deg, #6366f1 0%, #a855f7 100%); + min-height: 100vh; + display: flex; + align-items: center; + padding: 2rem; +} + +.auth-card { + background: rgba(255, 255, 255, 0.95); + border-radius: 1rem; + box-shadow: 0 10px 30px rgba(0,0,0,0.15); + overflow: hidden; + max-width: 400px; + margin: 0 auto; + transition: transform 0.3s ease; +} + +.auth-card:hover { + transform: translateY(-5px); +} + +.auth-input-group { + position: relative; + margin-bottom: 1.5rem; +} + +.auth-input { + width: 100%; + padding: 1rem 1rem 1rem 3rem; + border: 2px solid #e5e7eb; + border-radius: 0.5rem; + font-size: 1rem; + transition: border-color 0.3s ease; +} + +.auth-input:focus { + border-color: #6366f1; + outline: none; +} + +.auth-icon { + position: absolute; + left: 1rem; + top: 50%; + transform: translateY(-50%); + color: #6b7280; +} \ No newline at end of file diff --git a/assets/css/main.css b/assets/css/main.css new file mode 100644 index 0000000..e69de29 diff --git a/assets/css/style.css b/assets/css/style.css new file mode 100644 index 0000000..484b8cf --- /dev/null +++ b/assets/css/style.css @@ -0,0 +1,106 @@ +/* 通用样式 */ +body { + font-family: 'Segoe UI', sans-serif; + margin: 0; + background: #f0f2f5; +} + +/* 登录页面 */ +.login-container { + display: flex; + justify-content: center; + align-items: center; + min-height: 100vh; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); +} + +.login-box { + background: white; + padding: 2rem; + border-radius: 10px; + box-shadow: 0 5px 20px rgba(0,0,0,0.1); + width: 400px; +} + +.error-msg { + color: #dc3545; + margin: 1rem 0; + padding: 0.5rem; + background: #f8d7da; + border-radius: 5px; +} + +.form-group input { + width: 100%; + padding: 12px; + margin: 8px 0; + border: 2px solid #ddd; + border-radius: 6px; + transition: border-color 0.3s; +} + +.form-group input:focus { + border-color: #667eea; + outline: none; +} + +button { + background: #667eea; + color: white; + padding: 12px 24px; + border: none; + border-radius: 6px; + cursor: pointer; + width: 100%; + margin-top: 1rem; +} + +/* 管理后台 */ +.admin-container { + max-width: 1200px; + margin: 2rem auto; + padding: 2rem; +} + +header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 2rem; +} + +.logout-btn { + background: #dc3545; + padding: 8px 16px; + text-decoration: none; +} + +.form-wrapper { + background: white; + padding: 2rem; + border-radius: 10px; + box-shadow: 0 2px 10px rgba(0,0,0,0.05); +} + +.form-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 1rem; + margin-bottom: 1rem; +} + +select, textarea { + width: 100%; + padding: 12px; + border: 2px solid #ddd; + border-radius: 6px; + margin-bottom: 1rem; +} + +.success-msg { + background: #d4edda; + color: #155724; + padding: 1rem; + margin-bottom: 1rem; + border-radius: 6px; +} \ No newline at end of file diff --git a/assets/js/main.js b/assets/js/main.js new file mode 100644 index 0000000..e69de29 diff --git a/includes/api_functions.php b/includes/api_functions.php new file mode 100644 index 0000000..022dad8 --- /dev/null +++ b/includes/api_functions.php @@ -0,0 +1,79 @@ + isset($_GET['resolution']) + ? strtoupper(trim($_GET['resolution'])) + : null, + 'category' => isset($_GET['category']) + ? urldecode(trim($_GET['category'])) + : null + ]; + + // 验证分辨率参数 + if ($params['resolution'] && !in_array($params['resolution'], $allowedResolutions, true)) { + throw new InvalidArgumentException('无效的分辨率参数'); + } + + // 验证分类参数 + if ($params['category'] && !in_array($params['category'], $allowedCategories, true)) { + throw new InvalidArgumentException('无效的分类参数'); + } + + return $params; +} + +// 构建图片查询语句 +function buildImageQuery(array $params): string { + $query = "SELECT url FROM images WHERE 1=1"; + + if ($params['resolution']) { + $query .= " AND resolution = :resolution"; + } + + if ($params['category']) { + $query .= " AND category = :category"; + } + + $query .= " ORDER BY RAND() LIMIT 1"; + return $query; +} + +// 获取随机图片 +function fetchRandomImage(PDO $pdo, string $query, array $params) { + $stmt = $pdo->prepare($query); + + if ($params['resolution']) { + $stmt->bindValue(':resolution', $params['resolution']); + } + + if ($params['category']) { + $stmt->bindValue(':category', $params['category']); + } + + $stmt->execute(); + return $stmt->fetch(); +} + +// 标准化JSON响应 +function jsonResponse(array $data): string { + return json_encode([ + 'code' => 200, + 'data' => $data + ], JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT); +} + +// 错误响应格式化 +function jsonError(string $message, int $code = 400): string { + http_response_code($code); + return json_encode([ + 'code' => $code, + 'error' => $message + ], JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT); +} \ No newline at end of file diff --git a/includes/auth.php b/includes/auth.php new file mode 100644 index 0000000..47d447b --- /dev/null +++ b/includes/auth.php @@ -0,0 +1,33 @@ +prepare("SELECT * FROM users WHERE username = ?"); + $stmt->execute([$username]); + $user = $stmt->fetch(); + + // SHA256验证 + if ($user && hash('sha256', $password) === $user['password']) { + $_SESSION['user_id'] = $user['id']; + $_SESSION['username'] = $user['username']; + return true; + } + return false; +} + +// 强制登录检查 +function requireLogin() { + if (!isLoggedIn()) { + header("Location: login.php"); + exit; + } +} \ No newline at end of file diff --git a/includes/config.php b/includes/config.php new file mode 100644 index 0000000..ca6cb39 --- /dev/null +++ b/includes/config.php @@ -0,0 +1,17 @@ + PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC + ] + ); +} catch (PDOException $e) { + die("数据库连接失败: " . $e->getMessage()); +} \ No newline at end of file