Files
MovieLog_Server/index.php
T
laoyang d7c6ac2559 feat: 完善电影记录系统源码与项目文档
功能模块:
- 观影记录:列表(瀑布流)/ 添加 / 编辑 / 详情 / 删除,删除时同步清理图片文件
- 首页快捷搜索 + 高级搜索(片名、影院、观影人、日期区间组合筛选)
- 影院管理:三段式信息 + 50 种预设配色,删除已引用影院时二次确认
- 观影人管理:头像裁剪上传 + 专属配色,已引用者禁止删除
- 图片处理:Cropper.js 裁剪票根/海报/观影照片/头像,多图上传,首字母 SVG 头像兜底
- OMDb 自动获取影片信息(fetch_movie.php 代理,返回 JSON)
- CSV 批量导入:UTF-8/GBK 自动识别,影院去重,事务保护,逐行错误报告
- 统计仪表板:总览 + 按影院/观影人/年份/近 12 个月排行
- 年度报告:按账号关联的观影人视角生成,含 Chart.js 月度与星期分布图
- 多用户:账号增删改、账号与观影人绑定、修改自己的用户名与密码
- 登录鉴权:Session + password_hash,全站页面登录校验

文档:
- 重写 README:功能特性、技术栈、目录结构、数据库结构、部署与使用指南、接口说明、CSV 格式、安全注意事项、已知限制
- 新增 .gitignore,排除 db/ 与 uploads/ 等运行时数据
2026-09-21 08:16:25 +08:00

200 lines
7.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
// ============================================
// 文件: index.php (含搜索 + 观影人头像)
// ============================================
require_once 'config.php';
checkLogin();
$admin = getCurrentAdmin();
// 获取搜索关键词
$keyword = isset($_GET['keyword']) ? trim($_GET['keyword']) : '';
if (!empty($keyword)) {
$movies = searchMovies($keyword);
} else {
$movies = getMovies();
}
?>
<!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 rel="stylesheet" href="css/style.css">
<style>
/* 搜索栏样式 */
.search-bar {
display: flex;
gap: 10px;
align-items: center;
background: var(--card-bg);
padding: 8px 16px;
border-radius: 12px;
box-shadow: var(--shadow);
border: 1px solid var(--border-color);
max-width: 500px;
margin-bottom: 20px;
}
.search-bar input[type="text"] {
flex: 1;
border: none;
outline: none;
padding: 10px 12px;
font-size: 15px;
background: transparent;
color: var(--text-primary);
}
.search-bar button {
background: var(--primary);
color: #fff;
border: none;
padding: 8px 20px;
border-radius: 8px;
font-weight: 600;
cursor: pointer;
transition: background 0.2s;
white-space: nowrap;
}
.search-bar button:hover {
background: var(--primary-dark);
}
.search-bar .clear-btn {
background: transparent;
color: var(--text-secondary);
padding: 8px 12px;
font-size: 14px;
}
.search-bar .clear-btn:hover {
background: var(--bg-secondary);
}
.search-info {
color: var(--text-secondary);
font-size: 14px;
margin-bottom: 16px;
}
/* 观影人头像标签 */
.viewer-tag {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: 12px;
padding: 2px 6px;
border-radius: 12px;
background: rgba(0,0,0,0.04);
}
.viewer-tag img {
width: 18px;
height: 18px;
border-radius: 50%;
object-fit: cover;
}
.card-viewers {
margin-top: 6px;
display: flex;
flex-wrap: wrap;
gap: 4px 8px;
}
@media (max-width: 600px) {
.search-bar {
flex-wrap: wrap;
padding: 8px;
}
.search-bar input[type="text"] {
width: 100%;
flex: 0 0 100%;
padding: 8px 12px;
}
.search-bar button {
flex: 1;
}
}
</style>
</head>
<body>
<?php include 'nav.php'; ?>
<main class="main-content">
<div class="page-header">
<div>
<h2><?= empty($keyword) ? '我的电影' : '搜索结果' ?></h2>
<p class="subtitle">
<?php if (empty($keyword)): ?>
共 <?= count($movies) ?> 部 · 按观影日期排序
<?php else: ?>
找到 <?= count($movies) ?> 部匹配“<strong><?= h($keyword) ?></strong>”的电影
<?php endif; ?>
</p>
</div>
</div>
<!-- 搜索栏 -->
<form method="GET" action="" class="search-bar">
<input type="text" name="keyword" placeholder="搜索电影名称、影院、观影人..." value="<?= h($keyword) ?>">
<button type="submit">🔍 搜索</button>
<?php if (!empty($keyword)): ?>
<a href="index.php" class="clear-btn">✕ 清除</a>
<?php endif; ?>
</form>
<?php if (empty($movies)): ?>
<div class="empty-state">
<div class="empty-icon">🎥</div>
<h3><?= empty($keyword) ? '还没有电影记录' : '没有找到匹配的电影' ?></h3>
<p><?= empty($keyword) ? '点击「添加电影」开始记录你的观影之旅吧' : '尝试其他关键词' ?></p>
<?php if (empty($keyword)): ?>
<a href="add.php" class="btn btn-primary"> 添加第一部电影</a>
<?php else: ?>
<a href="index.php" class="btn btn-outline">查看全部电影</a>
<?php endif; ?>
</div>
<?php else: ?>
<div class="waterfall">
<?php foreach ($movies as $movie): ?>
<div class="movie-card" onclick="location.href='detail.php?id=<?= $movie['id'] ?>'">
<div class="card-image">
<?php
$poster = posterUrl($movie['poster_path']);
if (strpos($poster, 'placeholder') !== false):
?>
<div class="placeholder-poster">
<span>🎬</span>
<span class="placeholder-title"><?= h($movie['title']) ?></span>
</div>
<?php else: ?>
<img src="<?= $poster ?>" alt="<?= h($movie['title']) ?>" loading="lazy">
<?php endif; ?>
</div>
<div class="card-body">
<h3 class="card-title"><?= h($movie['title']) ?></h3>
<div class="card-meta">
<span class="meta-date">📅 <?= $movie['watch_date'] ? date('Y年m月d日', strtotime($movie['watch_date'])) : '日期待补' ?></span>
<?php if ($movie['cinema_name']): ?>
<span class="meta-cinema" style="color: <?= h($movie['cinema_color'] ?? '#888888') ?>;">
🏛️ <?= h($movie['cinema_name']) ?>
</span>
<?php endif; ?>
</div>
<!-- 观影人 -->
<?php if (!empty($movie['viewers'])): ?>
<div class="card-viewers">
<?php foreach ($movie['viewers'] as $viewer): ?>
<span class="viewer-tag" style="color: <?= h($viewer['color'] ?: '#888888') ?>;">
<img src="<?= getAvatarUrl($viewer['avatar'] ?? null, $viewer['name']) ?>" alt="<?= h($viewer['name']) ?>">
<?= h($viewer['name']) ?>
</span>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</main>
<script src="js/main.js"></script>
</body>
</html>