Commit Graph
4 Commits
Author SHA1 Message Date
laoyang 99c22d17bd feat: 片名输入加下拉联想,不必把片名打全就能选片
输入片名时实时下拉候选(海报缩略图 + 片名 + 原名 + 年份 + 电影/剧集标注),
选中即自动填充影片信息,省去「打全片名再点按钮」这一步。

fetch_movie.php
- 新增 action=suggest:只回候选列表,不取详情、不下载海报、不写任何文件,
  可随输入安全地频繁调用;会过滤「影人」类条目、按豆瓣条目 id 去重、默认限 8 条。
- 新增 action=thumb:服务端代取豆瓣缩略图。豆瓣图片有防盗链(只有 Referer 为
  豆瓣域名才返回 200,其它一律 403),浏览器直连必然被拒,只能由服务端带
  Referer 代取;并加 Cache-Control 让浏览器缓存,重复展开不重复回源。
- 新增 ?id=豆瓣条目id:跳过搜索直接取详情。下拉选中后走这条路,既省一次搜索,
  也避免「再按片名搜一次、结果选错条目」。
- 安全:新增 validateDoubanImageUrl() 严格白名单(只允许
  https://img*.doubanio.com/view/photo/…),否则 thumb 就成了 SSRF 跳板;
  接口地址的测试用覆盖项一并写进注释。

add.php
- 片名输入框改为「输入即联想」:320ms 防抖、会话内结果缓存、用 AbortController
  丢弃过期在途请求、↑↓ 选择 / Enter 确认 / Esc 关闭、点击外部关闭、
  中文输入法组字期间不发请求也不劫持 Enter(此时 Enter 是选字)。
- 候选里的豆瓣文本一律转义后再插入,避免把对方内容当 HTML 执行。
- 「📡 自动获取」按钮保留:候选里没有想要的条目时仍可按回车或点按钮,由服务端
  挑最匹配的条目;按钮与下拉选中复用同一套获取逻辑(runFetch)。

README.md
- 接口文档改为四种模式(q / id / suggest / thumb),补上参数、响应样例、
  防盗链原因与白名单说明;使用说明与安全注意事项同步更新。

验证
- fetch_movie_test.py 端到端 79 项全通过(新增 suggest / thumb / id 三组用例,
  含「suggest 与 thumb 不写任何文件」「非白名单地址一律 400」)。
- storage_test.py 回归 196 项全通过。
- A/B 渲染比对 47 个响应:仅 add.php 的两个页面有差异,且差异全部落在下拉联想
  相关代码上,其余响应逐字节一致。
- 已部署到线上,双 PHP 版本(7.4 / 8.1)真实抓取通过:suggest 返回候选、
  thumb 代取回 27KB JPEG、非白名单地址被拒、id= 直连取详情成功。
2026-09-22 07:36:05 +08:00
laoyang ddf2eeafaa feat: 「自动获取」改用豆瓣数据源,海报自动下载入库
此前的 OMDb 数据源必须用英文片名,国产片覆盖极差。改用豆瓣公开接口后
中文片名直接可搜,冷门片/老片/剧集也能命中。

fetch_movie.php(全量重写)
- 搜索走 movie.douban.com/j/subject_suggest;详情走移动端
  m.douban.com/rexxar/api/v2/movie/<id>(PC 详情页有反爬 302,故用移动端接口)
- 海报下载后写入 uploads/posters/,文件名沿用内容指纹规则
- 新增登录鉴权:未登录返回 401(此前该接口完全公开)
- 启用 TLS 证书校验(原为 CURLOPT_SSL_VERIFYPEER=false)
- 魔数兜底 + 12MB 上限:挡掉反爬返回的 HTML 页面与异常大响应
- old_poster 残留清理:重复点击时删掉上一张,且仅删「未被数据库引用」的文件
- 接口地址支持环境变量覆盖,便于用 mock 做端到端测试

lib/helpers.php
- 新增 isValidStoredKey():校验表单回传的存储键,防目录穿越与越权引用

add.php
- 前端改用新字段(豆瓣评分 / 地区 / 又名),并把 poster_key 放进隐藏域回传
- 提交时「手动上传的海报优先」,没有才采用自动获取已入库的海报

README.md
- 同步为豆瓣数据源说明,移除已过时的 OMDb API Key 与 SSL 校验两条安全提示

验证
- 本地 mock 豆瓣端到端:33/33 通过
- 既有存储回归套件:196/196 通过
- A/B 归一化比对:除 add.php 按预期变化外,其余 45 个响应完全一致
- 线上实测:流浪地球 / 哪吒之魔童闹海 均抓取成功,海报落盘为合法 JPEG
2026-09-21 23:05:40 +08:00
laoyang dd957d45bd refactor: 拆分 config.php 为 lib/ 模块,消除页面层重复代码
纯结构性重构,不改变任何功能。

- config.php 由 739 行缩减为 42 行,改为纯引导入口;新增 ROOT_DIR 常量
  统一拼接绝对路径(lib/ 内模块的 __DIR__ 会指向 lib/,必须替换)
- 新增 lib/ 五个模块 db.php / helpers.php / auth.php / movies.php / stats.php,
  由 config.php 按 db → helpers → auth → movies → stats 顺序加载
- add.php、edit.php 各自约 80 行重复的 POST 处理改为调用
  resolveCinemaId / resolvePersonIds / linkViewers / uploadImageFile /
  saveBase64Image / uploadMultiplePhotos / deleteStoredFile
- cinemas.php、persons.php 中重复 4 次的颜色校验改用 normalizeHexColor()
- toggleNewViewer / removeViewerRow / toggleNewCinema 下沉至 js/main.js,
  add.php 中的 removeViewer 统一更名为 removeViewerRow
- 删除死代码:imageUrl()(全项目无调用);cinemas.php 配色数组中本就会被
  array_slice 丢弃的 extra 颜色逻辑,简化为单条扁平 50 元素数组
- README 目录结构补充 lib/ 说明

验证方式:以便携 PHP 8.4 搭建 A/B 回归环境,播种固定数据后遍历 47 个
GET/POST 端点录制「状态码 + 响应体」。重构前后 42 个逐字节相同、2 个仅
上传文件名时间戳不同、3 个差异均为内联脚本下沉(已单独校验函数体逐字符
等价,剥离脚本后 HTML 标记完全一致)。24 个 PHP 文件语法检查全部通过。
2026-09-21 12:56:30 +08:00
laoyang 40e1bc5e56 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:20:56 +08:00