diff --git a/README.md b/README.md
index ee910a7..ab45263 100644
--- a/README.md
+++ b/README.md
@@ -68,7 +68,13 @@
```
MovieLog_Server/
-├── config.php # 核心:常量、DB 连接、建表与迁移、公共函数、统计与年度报告查询
+├── config.php # 引导入口:错误报告、会话、路径常量、上传目录,并加载 lib/ 各模块
+├── lib/ # 功能模块(被 config.php 统一引入,页面无需单独 require)
+│ ├── db.php # DB 连接、建表、字段与历史数据迁移、默认管理员
+│ ├── helpers.php # 输出转义、文件名、颜色校验、上传/删除文件、图片 URL
+│ ├── auth.php # 登录校验、管理员账号增删改
+│ ├── movies.php # 电影/影院读取、搜索,以及表单关联数据的解析
+│ └── stats.php # 统计仪表板与年度报告查询
├── index.php # 首页:观影列表(瀑布流)+ 快捷搜索
├── add.php # 添加电影
├── edit.php # 编辑电影
@@ -88,7 +94,7 @@ MovieLog_Server/
├── fetch_movie.php # OMDb 代理接口,返回 JSON
├── test_crop.php # 开发调试页:验证 Base64 图片落盘是否正常
├── css/style.css # 全局样式
-├── js/main.js # 少量公共脚本
+├── js/main.js # 公共脚本(含各页面共用的表单联动函数)
├── assets/.gitkeep # 静态占位资源目录
├── db/movies.db # SQLite 数据库(运行时自动生成,不纳入版本控制)
└── uploads/ # 上传图片(运行时自动生成,不纳入版本控制)
@@ -98,6 +104,8 @@ MovieLog_Server/
└── avatars/ # 观影人头像
```
+> 页面只需 `require_once 'config.php'`,`lib/` 下的模块会由引导文件统一加载,并保证依赖顺序(db → helpers → auth → movies → stats)。
+
---
## 数据库结构
diff --git a/add.php b/add.php
index b02d102..32b0539 100644
--- a/add.php
+++ b/add.php
@@ -23,46 +23,27 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$cinema_id = $_POST['cinema_id'] ?? '';
$viewer_selects = $_POST['viewer_select'] ?? [];
$viewer_news = $_POST['viewers_new'] ?? [];
-
+
// 票根裁剪数据
$ticket_crop = $_POST['ticket_crop'] ?? '';
-
- // 新建电影院
- $new_cinema_place = trim($_POST['new_cinema_place'] ?? '');
- $new_cinema_name = trim($_POST['new_cinema_name'] ?? '');
- $new_cinema_address = trim($_POST['new_cinema_address'] ?? '');
-
- if ($cinema_id === 'new' && !empty($new_cinema_name)) {
- $stmt = $db->prepare("INSERT INTO cinemas (place, name, address) VALUES (?, ?, ?)");
- $stmt->execute([$new_cinema_place, $new_cinema_name, $new_cinema_address]);
- $cinema_id = $db->lastInsertId();
- } elseif ($cinema_id === 'new') {
- $cinema_id = null;
- } elseif (!empty($cinema_id) && is_numeric($cinema_id)) {
- $cinema_id = (int)$cinema_id;
- } else {
- $cinema_id = null;
- }
-
+
+ // 电影院:选择已有影院、新建影院或留空
+ $cinema_id = resolveCinemaId(
+ $cinema_id,
+ trim($_POST['new_cinema_place'] ?? ''),
+ trim($_POST['new_cinema_name'] ?? ''),
+ trim($_POST['new_cinema_address'] ?? '')
+ );
+
if (empty($title)) {
$error = '请输入电影名称';
} elseif (empty($watch_date)) {
$error = '请选择观影日期';
} else {
- // ----- 处理海报(直接上传) -----
- $poster_path = '';
- if (isset($_FILES['poster']) && $_FILES['poster']['error'] === UPLOAD_ERR_OK) {
- $ext = strtolower(pathinfo($_FILES['poster']['name'], PATHINFO_EXTENSION));
- if (in_array($ext, ['jpg', 'jpeg', 'png', 'gif', 'webp'])) {
- $filename = uniqueFilename($_FILES['poster']['name']);
- $target = POSTER_DIR . $filename;
- if (move_uploaded_file($_FILES['poster']['tmp_name'], $target)) {
- $poster_path = 'uploads/posters/' . $filename;
- }
- }
- }
-
- // ----- 处理票根(裁剪优先) -----
+ // ----- 海报:直接上传 -----
+ $poster_path = uploadImageFile('poster', POSTER_DIR, 'uploads/posters/') ?? '';
+
+ // ----- 票根:裁剪结果优先,其次原始上传 -----
$ticket_path = '';
if (!empty($ticket_crop)) {
$new_path = saveBase64Image($ticket_crop, TICKET_DIR, 'ticket');
@@ -71,18 +52,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
} else {
$error = '票根裁剪保存失败,请重试';
}
- } elseif (isset($_FILES['ticket']) && $_FILES['ticket']['error'] === UPLOAD_ERR_OK) {
- $ext = strtolower(pathinfo($_FILES['ticket']['name'], PATHINFO_EXTENSION));
- if (in_array($ext, ['jpg', 'jpeg', 'png', 'gif', 'webp'])) {
- $filename = uniqueFilename($_FILES['ticket']['name']);
- $target = TICKET_DIR . $filename;
- if (move_uploaded_file($_FILES['ticket']['tmp_name'], $target)) {
- $ticket_path = 'uploads/tickets/' . $filename;
- }
- }
+ } else {
+ $ticket_path = uploadImageFile('ticket', TICKET_DIR, 'uploads/tickets/') ?? '';
}
-
- // 如果没有错误,继续
+
+ // 没有错误才继续
if (empty($error)) {
// 插入电影
$stmt = $db->prepare("
@@ -91,60 +65,19 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
");
$stmt->execute([$title, $info, $poster_path, $ticket_path, $cinema_id, $watch_date]);
$movie_id = $db->lastInsertId();
-
- // ---- 处理合影照片(多张) ----
- if (isset($_FILES['photos']) && is_array($_FILES['photos']['tmp_name'])) {
- $photo_files = $_FILES['photos'];
- for ($i = 0; $i < count($photo_files['tmp_name']); $i++) {
- if ($photo_files['error'][$i] === UPLOAD_ERR_OK) {
- $ext = strtolower(pathinfo($photo_files['name'][$i], PATHINFO_EXTENSION));
- if (in_array($ext, ['jpg', 'jpeg', 'png', 'gif', 'webp'])) {
- $filename = uniqueFilename($photo_files['name'][$i]);
- $target = PHOTO_DIR . $filename;
- if (move_uploaded_file($photo_files['tmp_name'][$i], $target)) {
- $photo_path = 'uploads/photos/' . $filename;
- $stmt2 = $db->prepare("INSERT INTO movie_photos (movie_id, photo_path) VALUES (?, ?)");
- $stmt2->execute([$movie_id, $photo_path]);
- }
- }
- }
- }
- }
-
- // ---- 处理观影人 ----
- $person_ids = [];
- foreach ($viewer_selects as $idx => $val) {
- if ($val === 'new') {
- $new_name = trim($viewer_news[$idx] ?? '');
- if (!empty($new_name)) {
- $chk = $db->prepare("SELECT id FROM persons WHERE name = ?");
- $chk->execute([$new_name]);
- $existing = $chk->fetch();
- if ($existing) {
- $person_ids[] = $existing['id'];
- } else {
- $ins = $db->prepare("INSERT INTO persons (name) VALUES (?)");
- $ins->execute([$new_name]);
- $person_ids[] = $db->lastInsertId();
- }
- }
- } elseif (is_numeric($val) && $val > 0) {
- $person_ids[] = (int)$val;
- }
- }
- $person_ids = array_unique($person_ids);
- if (!empty($person_ids)) {
- $stmt = $db->prepare("INSERT INTO viewers (movie_id, person_id, name) VALUES (?, ?, ?)");
- foreach ($person_ids as $pid) {
- $stmt->execute([$movie_id, $pid, '']);
- }
- }
-
+
+ // ---- 观影照片(多张)----
+ uploadMultiplePhotos('photos', $movie_id);
+
+ // ---- 一起看的人 ----
+ linkViewers($movie_id, resolvePersonIds($viewer_selects, $viewer_news));
+
header('Location: detail.php?id=' . $movie_id);
exit;
}
}
}
+
?>
@@ -470,7 +403,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
0): ?>
-
+
@@ -533,22 +466,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
+