Commit Graph
2 Commits
Author SHA1 Message Date
laoyang a43dd06d1f 修版心双重内缩与预览图溢出:宽屏整页错位、头像盖住表单
线上反馈「界面更乱了、全都错位、导航条头像非常大、下拉菜单乱七八糟」。
用无头浏览器实测出三处硬伤,都不是样式文件坏了,是布局算式写错。

一、版心被推两次 → 宽屏正文列塌陷(「全都错位」的根)

  .topbar 与 .container 各自用了同一份「把内容推到居中」的 padding,
  而 .container 本来就已经有 max-width + margin:auto。于是内容被推两次:

    1280px  顶栏品牌 x=89   正文 x=178     差 89px
    1920px  顶栏品牌 x=409  正文 x=818     差 409px,正文列只剩 262px
    2560px  正文列宽度 = 0                内容完全挤没

  改法:抽一个 --shell-pad(= max(--gutter, (100% - --container) / 2)),
  顶栏与正文共用它,并且 .container 不再设 max-width —— 正文列宽度由 padding
  反推,宽屏下正好等于 --container,两边用的是同一个公式,左边缘必然对齐。
  用 100% 而非 100vw,避免滚动条让两者差半格。

二、预览容器把图片尺寸写在了外层 div 上 → 400×400 头像盖住整个表单

  .avatar-preview / .cover-preview 把 width/height/object-fit 写在**容器**上,
  里面的 <img> 完全不受约束,按原始尺寸铺出来:
  头像 400×400、封面 1920×1080,直接把下面的表单项盖住。
  (对照:.card-cover img / .activity-cover img 是写对的。)

  改法:容器只负责「框」(定尺寸、overflow:hidden 裁圆角),
  尺寸与 object-fit 一律落到 > img 上,且用绝对定位铺满 ——
  不用 `display:grid + width:100%`,那种写法列宽会反过来依赖元素自身宽度,
  形成循环,浏览器只能把图算成 0 宽(实测踩到过)。

三、上传区被当成小圆框 → 按钮和提示文字压进头像里

  .avatar-upload 被套上 84×84 圆形尺寸,而模板把预览、按钮、提示文字都放在
  它内部,三样东西全挤在那个小圆里互相重叠。改法:上传容器只做排列
  (头像横排、封面竖排),虚线圆框与圆角归预览块,按钮自成一行。

顺带
  · 下拉面板加 max-height + overflow,13 个菜单项在矮屏不再顶出屏幕底部;
    宽度 max-content 且不换行,并限制不超过视口。
  · 头像地址一律先过 media_avatar() 再判断:外站地址(https://…)会被拒,
    以前按原始值判断非空 → 渲染出 <img src="">,用户管理列表里两个用户
    就是破图。现在退回首字母色块。头像隐藏域仍保留原始值,避免单纯保存就抹掉数据。
  · CSS 结构体检报告不再写在被检查文件旁边(assets/style.css.syntax.txt
    曾被当成站点文件打进部署包);打包排除规则改为「根目录 _ 开头 +
    任意层级的工具报告/日志」,并且不再误伤 templates/ 下 _ 前缀的局部模板。

配套的检查能力(本次之前的检查全绿、页面却视觉上是坏的,所以补这一层)
  · _tooling/_snapshot3.py   按登录态渲染线上页面 + 抓静态资源到本地
  · _tooling/_layout_check.py  无头浏览器测量真实几何并断言:顶栏/正文左右边缘
    对齐、正文列宽度、无横向溢出、头像恒 26px、预览图不溢出且铺满、预览图
    确实加载成功、下拉面板不出屏。6 个页面 × 7 档宽度 = 392 项。
    先用线上那份坏样式跑证明它抓得到(89 项失败),再用修复后的跑(0 失败)。
  · _tooling/css_syntax_check.py  词法级 CSS 结构体检(跳过注释与字符串后数括号),
    比 grep 数大括号可靠 —— 配平不等于合法。
  · 部署脚本新增 7 条静态哨兵,锁住上面三个根因。

验证
  本地:php -l 55 文件 0 失败;模板渲染 234 项;SQL 15 表无未知列;PDO 0 问题;
        CSS 202 类全有定义;CSS 结构体检通过;Mime 27 项;内联 JS 9 个文件;
        布局几何 392 项全通过。
  线上:部署 10 步 EXIT=0(80 项静态断言全 OK / 0 FAIL,含 7 条新哨兵),
        双 PHP 渲染 14 条路由字节数完全一致,26 项内容断言全通过
        (含照片代理 69/69 字节逐字节一致);
        对已部署状态重抓渲染再测布局几何 392 项 0 失败;
        端到端 239 项通过 / 0 项失败。
        用户管理列表里 example.com 外链出现次数由 2 降为 0。
2026-09-23 00:01:05 +08:00
laoyang a79956758b 补齐未接入代码的功能域:参与人 / 评论 / 花销与分摊
数据库里早就建好了 comments、node_members + role_tags、expenses +
expense_splits 三组表,但一直没有代码接入。本次把这三块连上业务,
并新增「节点详情页」作为聚合入口。

新增
- src/Access.php          统一归属校验。此前每个控制器各写各的 family_id
                          条件,容易漏;现在 activity()/node()/target() 一处收敛,
                          requireAdmin() 统一管理员判断。
- src/Comments.php        两级平铺:parent_id 只允许指向顶层,写「回复的回复」
                          时规范化回顶层;删顶层会连同回复一起删。
- src/Members.php         参与人 + 角色标签 + 情绪 + 签到。情绪目录 17 项,
                          全部选用 Emoji 11.0(2018)及以前的码位,避免旧系统
                          字体缺字形显示成空白方块。
- src/Expenses.php        花销与分摊。分摊按「分」为单位 intdiv 平均,
                          余数归最后一人,保证 SUM(share_amount) = total_amount。
- templates/nodes/show.php 节点详情页:基本信息 + 参与人 + 花销 + 讨论 + 附件入口。
- 角色标签管理、评论区、参与人区、花销区各自的模板与控制器。

修复
- 越权:往别人活动的节点上插节点、把别家用户加成参与人,都只校验了
  「节点存在」,没校验「用户与节点同家庭」。现统一走 Access。
- 删活动时节点附件文件删不掉:附件在 /uploads/attachments/ 下,却调了
  只认 /uploads/covers/ 的删除函数,判定不通过 → 文件永久残留。改为
  统一的 deleteUploadFile(),两个目录都认。
- 删有引用记录的用户会 500(activities.created_by / attachments.uploader_id /
  comments.author_id / expenses.payer_user_id 这几处没有级联,也没做前置检查)。

其他
- 活动/节点列表补上附件、评论、参与人、花销四个计数(一次 GROUP BY 查完)。
- 首页布局新增一条迁移易踩的规避:新列上的索引必须排在 ALTER TABLE 之后。
- 新增 .gitignore:config.php(含数据库口令)与 uploads/ 下用户上传的
  头像封面不入库,只保留 uploads/.htaccess 那条禁止执行脚本的规则。
- 新增 config.example.php 作为新环境的配置模板。

本批不改数据库结构,不需要任何数据迁移。

本地与线上验证
- php -l 全绿(PHP 8.4 本地 / 线上 7.4.30 与 8.1.7 双版本)。
- 模板渲染检查 180 项全通过。
- 线上端到端 153 项全通过:登录、活动增删改查、节点流转、
  参与人/角色标签/情绪/签到、评论、花销与分摊、权限、级联清理、
  全站页面无 PHP 报错泄漏、跑完基线逐表核对且既有 id 集合逐字未变。
- 顺带写了 trip_sql_column_check.py:拿真实库表结构静态校验全项目 SQL 的
  列名引用。本次就是靠它之外的 e2e 抓到 travel_modes 并没有 line_name
  (该列属于 trip_nodes),一个列名写错导致节点详情页整页 Fatal。
2026-09-22 22:03:08 +08:00