diff --git a/README.md b/README.md index 9f14512..37741c4 100644 --- a/README.md +++ b/README.md @@ -47,9 +47,27 @@ - **Session 登录**:`password_hash` / `password_verify` 加盐哈希存储口令,全站页面均需登录。 - **用户管理**:可新增、编辑、删除管理员账号,可修改用户名与密码。 - **账号 ↔ 观影人绑定**:每个管理员账号可关联一个观影人,绑定后即可查看个人年度报告。 +- **界面主题**:每个账号可以给自己挑一套配色(详见「界面主题」一节),别人登录看到的还是他们各自选的那套。 - **安全约束**:不允许删除最后一个管理员,也不允许删除自己。 - **个人资料**:修改自己的用户名与密码(需验证旧密码)。 +### 界面主题 +- **5 套经典配色**,在「系统设置 → 🎨 我的界面主题」里选,点卡片即时预览、点「保存主题」后全站生效(**不用重新登录**): + +| key | 名称 | 风格 | +| --- | --- | --- | +| `ticket` | 复古票根 | 暖橙 `#e67e22` + 浅灰白,**默认主题** | +| `indigo` | 靛蓝 | 经典蓝 `#2563eb` + 冷调浅灰 | +| `forest` | 松林 | 墨绿 `#2f855a` + 米灰白 | +| `wine` | 绛红 | 酒红 `#b03a5b` + 暖白 | +| `midnight` | 暗夜 | 深灰蓝底 + 靛紫 `#7c5cf5`(**深色主题**) | + +- **主题是每个账号自己的偏好**:存在 `admins.theme`(空 = 用默认主题),只影响自己;切换不需要重新登录。 +- **实现方式**:页面在 `` 上声明用哪套,色值全部集中在 `css/themes.css` 的 `[data-theme=""]` 规则块里;`css/style.css` 的 `:root` 只作为**兜底**(放着默认主题「复古票根」的那一份)。因此 `themes.css` 必须排在 `style.css` **之后**(两者优先级相同,靠后出现者胜)。 +- **页面里一律不写死颜色**:淡色底 / 光晕统一用 `rgba(var(--primary-rgb), α)` 取色,所以新增一套主题**只需要动 CSS**,页面与 JS 一行都不用改。年度报告的 Chart.js 图表读不到 CSS 变量,改为运行时从 `` 的计算样式里取色。 +- `--primary-rgb` 必须与 `--primary` 同色(写成 `"R, G, B"`);每套主题都要声明 `color-scheme`(`light` / `dark`),否则暗色主题下日期选择器、下拉框、滚动条仍是刺眼的白底。 +- **加一套主题**:在 `lib/theme.php` 的 `themeCatalog()` 里加一项,并在 `css/themes.css` 里补一个同 key 的规则块(那一组变量一个都不能少)。 + ### 评价与评论 - **谁可以评价**:**只要有登录账号就能评价**,与「是不是观影人」无关——没一起去看过的人也能打分、写评价、参与讨论。评价的归属是账号(`admins`),不是观影人(`persons`)。 - **页面上默认不出现任何输入框**:详情页「💬 评价与评论」区块上来只展示已有内容;要写什么就点对应那个按钮——「📝 写评价」「✏️ 修改我的评价」「💬 评论」「↩ 回复」,点开才当场展开表单,提交后页面刷新、表单自动收起。折叠用的是原生 `
/`,**不依赖 JS**,键盘也能操作。 @@ -71,7 +89,8 @@ - **观影人管理**:增删改查,支持头像裁剪上传与专属配色;已被电影引用的观影人不允许直接删除。 ### 界面与体验 -- 复古票根色系(主色 `#e67e22` 橙)的响应式设计,移动端断点适配(600 / 768px)。 +- **5 套配色主题可选**(详见下面的「界面主题」),主色、底色、卡片、边框、阴影、滚动条全部跟随主题。 +- 响应式设计,移动端断点适配(600 / 768px)。 - 导航为下拉菜单,自动高亮当前页;顶部始终显示当前用户头像与用户名。 - **点导航栏左上角的「🎬 电影日志」即可回到首页**(右键 / Ctrl+点击还能在新标签页打开),不必再展开右侧折叠菜单去找「首页」。 - 登录页为深色渐变 + 毛玻璃风格。 @@ -101,6 +120,7 @@ MovieLog_Server/ ├── lib/ # 功能模块(被 config.php 统一引入,页面无需单独 require) │ ├── db.php # DB 连接、建表、字段与历史数据迁移、默认管理员 │ ├── helpers.php # 输出转义、文件名、颜色校验、上传/删除文件、图片 URL +│ ├── theme.php # 界面主题注册表(5 套配色)、当前主题、页面上怎么声明 │ ├── settings.php # 系统设置读写;云厂商密钥以 enc:v1:gcm 密文落库 │ ├── storage.php # 存储门面:本地优先读取、URL 生成、上传/删除、迁移、代理读取 │ ├── storage/ # 各存储后端驱动 @@ -135,7 +155,8 @@ MovieLog_Server/ ├── media.php # 服务端图片代理:鉴权后由服务器读取对象并同源回吐 ├── fetch_movie.php # 豆瓣接口(片名候选 / 详情 + 海报入库 / 缩略图代理),返回 JSON ├── test_crop.php # 开发调试页:验证 Base64 图片落盘是否正常 -├── css/style.css # 全局样式 +├── css/style.css # 全局样式(:root 里是默认主题的兜底色值) +├── css/themes.css # 5 套主题的调色板(必须在 style.css 之后加载) ├── js/main.js # 公共脚本(含各页面共用的表单联动函数、破图兜底) ├── assets/ # 静态资源 │ └── default-avatar.png # 默认头像(未上传头像时统一使用) @@ -147,7 +168,7 @@ MovieLog_Server/ └── avatars/ # 观影人头像 ``` -> 页面只需 `require_once 'config.php'`,`lib/` 下的模块会由引导文件统一加载,并保证依赖顺序(db → settings → storage → helpers → auth → movies → reviews → stats)。 +> 页面只需 `require_once 'config.php'`,`lib/` 下的模块会由引导文件统一加载,并保证依赖顺序(db → settings → storage → helpers → theme → auth → movies → reviews → stats)。 --- @@ -157,7 +178,7 @@ MovieLog_Server/ | 表 | 作用 | 关键字段 | | --- | --- | --- | -| `admins` | 管理员账号 | `username`(唯一)、`password`(哈希)、`avatar`、`person_id`(关联观影人) | +| `admins` | 管理员账号 | `username`(唯一)、`password`(哈希)、`avatar`、`person_id`(关联观影人)、`theme`(该账号选的界面主题 key,空 = 用默认主题;见 `lib/theme.php`) | | `cinemas` | 电影院 | `place`(所在地方)、`name`、`address`、`color`(专属配色) | | `movies` | 电影记录 | `title`、`info`、`remark`、`poster_path`、`ticket_path`、`photo_path`(历史遗留单图)、`cinema_id`、`watch_date`、`created_at` | | `persons` | 观影人 | `name`(唯一)、`color`、`avatar` | @@ -284,6 +305,13 @@ server { > 评价人是**登录账号**。家里几个人各有一个账号时,同一部电影可以各自打分,标题栏会显示「N 条评价 · 均分 X」。 +### 换一套界面配色 + +1. 右上角展开菜单 → 「系统设置」,找到最上面的「🎨 我的界面主题」。 +2. 点任意一张主题卡片,**整页立刻换成那套配色**(包括导航、卡片、按钮、表单控件,以及年度报告的图表)——这一步只是预览。 +3. 满意就点「保存主题」。保存后**全站页面都用这套配色,并且不用重新登录**;不满意就再点别的卡片。 +4. 主题是**你自己的偏好**,别人登录看到的仍是他们各自选的那套。默认是「复古票根」。 + ### CSV 批量导入 CSV **共 9 列,顺序固定**: @@ -684,6 +712,8 @@ curl -sk -H "Host: 你的域名" -H "Cookie: PHPSESSID=xxxx" -o /dev/null \ - 迁移到云端后**本地文件不会自动删除**,需要自行确认后再清理;本地优先策略意味着本地文件存在时始终读本地,云端副本仅作备份。 - **下拉联想会随输入向豆瓣实时发请求**(已做 320 ms 防抖 + 会话内结果缓存 + 丢弃过期请求,同一关键词只查一次),但**服务端本身没有做接口级限流**。若担心被豆瓣限流,可把 `add.php` 里的 `DEBOUNCE` 调大,或让下拉只在按下「📡 自动获取」时才工作。 - **缩略图代理(`action=thumb`)每张图都要经服务器回源一次**。已加 `Cache-Control: max-age=86400`,同一张图在浏览器侧一天内只回源一次,正常使用量很小;若把下拉列表做得很大、或候选很多,建议改成在服务端落小图缓存。 +- **主题只做到「换色」这一层**:本项目自己的界面全部跟随主题,但第三方组件里只有 Chart.js 的图表跟着换(运行时从计算样式取色);Cropper.js 的裁剪遮罩、拖拽框是它自带的固定样式,不随主题变化。 +- **加一套主题要改两处**:`lib/theme.php` 的 `themeCatalog()`(有哪些主题)与 `css/themes.css` 的同 key 规则块(色值)。两边不一致时页面会静默退回默认值,所以 `theme_e2e.py` 会断言「每套主题的变量都齐全」以及「`:root` 与 `[data-theme=ticket]` 完全一致」。 --- diff --git a/add.php b/add.php index 7273be3..ba72f5f 100644 --- a/add.php +++ b/add.php @@ -88,12 +88,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { ?> - +> 添加电影 - 电影日志 + @@ -223,6 +290,47 @@ $localStat = localImageStat(); +
+

🎨 我的界面主题

+
+ 挑一套配色,只作用于你自己的账号——别人登录看到的还是他们各自选的那套。
+ 想先看看效果就点一下主题卡片,整页会立刻换色(只是预览,按「保存主题」才真正记住)。 + 按钮、链接、卡片边框、评分徽标与年度报告的图表颜色都会一起换。 +
+ +
+ +
+ $t): ?> + + +
+
+ + 保存后立刻生效,全站页面都用这套配色;不用重新登录。 +
+
+
+

图片存储方式

@@ -656,6 +764,19 @@ $localStat = localImageStat();