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} 条记录";
+}
+?>
+
+
+
+
+ 管理后台
+
+
+
+
+
+ 欢迎回来,= htmlspecialchars($_SESSION['username']) ?>
+ 退出登录
+
+
+
+
= $message ?>
+
+
+
+
+
+
\ 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 |
+ 分类名称 |
+ 操作 |
+
+
+
+
+
+ = $cat['id'] ?> |
+ = htmlspecialchars($cat['name']) ?> |
+
+
+ |
+
+
+
+
+
+
+
+
\ 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 @@
+
+
+
+
+
+ 后台登录
+
+
+
+
+
+
图片管理系统
+
+
= $error ?>
+
+
+
+
+
+
+
\ 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