2e40133d8fe596fabc327c0fca04d7730d4bd932
5
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
8d79857f1a |
v54:首页任务标题截断(真根因=两列网格被撑破)/ 名册分组→标签且候选读词表 / 旅程地图视图 / 旅程设置按钮 / 显示方式默认列表或地图
用户 2026-10-16 傍晚五条。 ① 首页「近期任务」标题太长会挤成两行 用户原话:「首页**近期任务**那个地方要注意截断:如果任务标题太长, 会把这个任务**挤成两行**。」 🔴🔴 **真根因是两层,第一版只修了表面**: · 表面:`.dash-what` 只有 `flex:1 1 auto; min-width:0`,**缺** nowrap/hidden/ellipsis ⇒ 收缩后文字在框内换行; · 真身:`.home-duo` 是**两列 grid**,grid 子项默认 `min-width: auto` ("我最小也得装下我的内容")⇒ 一条长标题把那一列顶到 **1763px** (父 `home-duo` 才 1032px)⇒ **整个两列布局被撑破**、页面横向溢出到 **2089px** (视口 1440)。⇒ 行宽 1721px、`scrollWidth === clientWidth`, **`text-overflow: ellipsis` 看起来"没生效"** —— 其实容器自己先爆了。 修法:`.home-duo > * { min-width: 0; }`,且 **整条 flex 链**都补 (`.hd-pane` → `.hd-pane-head` → `.hd-pane-body` → `.dash-list/.tk-list` → `.tk-row`) —— 链上任何一层漏了,收缩就断在那一层、下面的 nowrap 全白写。 配套:任务标题加 `title=` 悬停看全。 ⚠️ 这是本项目**第二次**踩 flex/grid 的 `min-width:auto`(v53 的 `.mv-grid` 是同类)。 **以后"文字截断不生效"先量容器有没有被撑破**。 ② 名册「分组」→「标签」;打标签的候选要**从设置里读** 用户原话:「现在名册里面给人打标签的时候,**这个标签数据是从哪读出来的**呀? 在这个名册的设置页面,有很多分组,现在还叫分组。但是打标签的时候, **却不是从这些分组里读出来的**。……应该叫「名册标签」,是不是? **应该从这里面把所有标签都读出来**吧?……以后就没有分组的概念了, **全部都是标签的概念**。」 🔴 **用户观察得完全正确,这是两套数据源**: · 设置页显示的词表来自 `person_groups`(**分组表**); · 打标签的候选来自 `PersonTag::cloud()`(**你已经打过的词**,现算的); ⇒ 两边根本不是一个数据源 ⇒ "设置里列着一堆、打标签时却只有几个"。 修法:**`PersonTag::choices()` = 设置页词表 ∪ 我用过的词**(并集,词表在前)。 · 词表里的词**还没用过**也能一点就打上(这正是词表的意义); · 用过的词补在后面(历史不丢); · 名册列表 / 新增 / 编辑 / 挑人 / 导入 **五处同一个函数**。 界面口径全面改"标签"(**表名仍是 `person_groups`**:改名要背着 `PersonGroup` 类、 `person_roster.group_id`、以及**另一个会话正在写的 `app/ApiHandler.php`** (它引用了 `PersonGroup::orderFor`)一起动,风险远大于收益): · `_person_groups.php` 标题「名册标签」、按钮「加一个我自己的标签」; · 删除文案改成"只是从候选里去掉这个词,已打在别人身上的不受影响" (**语义真的变了**:标签是各自身上的字符串,不是引用); · `people/_settings_menu.php`、`people/settings.php`、`settings/me.php`、 `settings.php`(「公共分组」→「公共标签」)全部同步。 顺带按"全部都是标签"改另两条入口: · `people/pick.php`「加进哪一组」下拉 → **打标签**; · `people/import.php` 同上;`ContactImporter::run()` 加 `$tags` 参数。 🔴 新增 `PersonTag::addOne()`(**追加**一个标签)—— 这两处**绝不能用 `setFor()`** (它是"先 DELETE 再 INSERT"的整组替换)⇒ 会把人**原有**的标签清光 (症状是"用一次导入,别人原有的标签全没了",极难联想)。 ⚠️ `group_id` 在 pick/import 的**服务端仍收着**(老书签/脚本兼容),只是界面不再展示。 ③ 旅程模块加**地图视图**(读 TripLog 移植) 用户原话:「你去读一下 TripLog 的代码,在旅程这个模块,**可以在地图上显示旅程数据**。 1. 先读一下它之前那个代码是怎么实现的,**在我们的旅程模块也实现一下**。」 读 TripLog(`templates/activities/index.php`)得到的要点: · 用**高德 AMap**(合规白名单内,绝不是境外瓦片); · `position` 必须是 **[lng,lat] 数组**(传 `{lng,lat}` 裸对象会让 AMap 抛错、 整个绘制循环当场中断 —— 它注释里写着"批 11 的光秃秃地图就是它"); · `setFitView()` 后**上限 11 级**(只有一趟时会被放大到街道级,那是导航视角); · `.amap-marker` 整层 `pointer-events:none`(否则包装层挡住别家卡片的点击); · **容器必须有固定高度**(0 高度 → 空白地图)。 它那套"同城环形扇开"是**几百行几何**,本仓数据量没压出这个问题 ⇒ **有意不做**。 本仓数据更规整:`trip_nodes` 早有 `from_lng/from_lat/to_lng/to_lat`(v17 批) + `from_city/to_city` ⇒ 新增 `Trip::attachSpots()`: ① 有坐标取**重心**(不是端点 —— 端点会让"青岛→伊春"偏到某一头); ② 没坐标退到**城市重心**(`Geo::lookup` 离线城市表,**不发网络请求**: 列表页几十趟若逐条打高德逆地理,一次开页就是几十个外部请求); ③ 都没有就不上图(列表里照常有,模板会说清"有几趟没上图")。 🔴 城市那里**必须也取重心**:`cities()` 的顺序是**按时间**(出发地在最前), 取"第一个城市"会让**所有旅程都叠在家上**、地图毫无信息量。 布局:两个视图用**标签页**(`?view=map` 是**链接**不是纯 JS 按钮 —— 书签/前进后退/无 JS 都正确;也**有意不**把地图藏在 `display:none` 里, 高德在 0 尺寸容器里会渲染空白)。 高德 SDK 加载器重构:原来 `fbLoadAddr()` 顺带拉 `addr_suggest.js`, 而地图只用 SDK 自带的 `AMap.Map/Marker` ⇒ 抽出 `window.fbAmapSdk()`(只拉 SDK)、 新增 `fb-amap` meta(不带 plugin),`fb-addr` 那份共用同一加载器。 ④ 旅程列表页「新建旅程」**后面**加「设置」按钮 用户原话:「2. 在旅程的「新建旅程」后面也加一个「设置」按钮。」 ⇒ 补 `_settings_menu.php`(设置恒排最右),菜单**第一条**加「显示方式」。 ⑤ 显示方式:默认列表还是地图(用户自配) 用户原话:「3. 里面的设置让用户自己配置:**到底默认显示旅程列表,还是用地图显示**。」 ⇒ 新增 `trips/display`(设置页 + `?set=` 快速设置)与 `trips/display_save`, 存 **`user_settings.trip_default_view`**(每人一份,**不是**全家设置)。 ⚠️ 访客也能改(只影响自己看到的默认,不是数据变更)。 验证(新增 2 套件 + 更新 e2e/deploy 断言): · _fb_v54_ui.py(**33 条**真机断言) · _b54_falsify.py(**11 注入 / 11 全抓**,基线 33/0) · e2e **1518/0**;familybook_deploy.sh 加「第54批形态」段(**24 条**) · 部署 **0 FAIL**;线上 **20 个文件 md5 逐字节一致**; 线上实测:词表 24 条、`choices()` 24 条、**`cloud` 15 条全部 ⊆ `choices`**、 4 趟旅程全部可上图(样例落在济南·青岛重心);诊断页已删复验 404 ⚠️ 本轮踩坑(已写进 pitfalls.md): · 🔴🔴 **"文字截断不生效"要先量容器有没有被撑破**(第一嫌疑是 flex/grid 子项 `min-width:auto`,不是 `text-overflow` 写错); · **反向断言("不该再出现 X")必须用 `_code_has`(剥注释)** —— 需求原话正当留在注释里,裸 `grep -F` 会命中自己的说明(本轮部署假红一次); · **冗余防线会让反向验证打不红**(两处 `min-width:0` 只去掉一条 ⇒ 探针照旧全绿, 注入必须一起去掉); · **界面多加一个字符就可能打歪既有断言**(我在词表管理页给标签名加了 `#`, 把 e2e 的 `my_group_order()` 读成 `#家人`)。 |
||
|
|
7544fb9f6a |
v41 第 41 批:流水线提速 + 12 项界面/交互开发 + DAV 彻底修复
DAV(用户「务必彻底解决」): - 真根因是 home-set 层级错:CalDav::HOME_PATH 原为 /dav/calendars/、 CardDav 原为 /carddav/addressbooks/,而日历本/通讯录的 href 在 /dav/N.ics/ 与 /carddav/N.vcf/ —— home-set 下面一本都没有。 Thunderbird 按 home-set 前缀认成员,于是「找不到日历本 / 找不到联系人」。 改为 /dav/ 与 /carddav/(所有既有 URL 一字不变,老配置不作废)。 - 又发现并修掉 Depth:0 违反 RFC 4918:原实现无论 depth 都列出全部子集合, 且第一条 response 是日历本(不含 current-user-principal)。改为按 depth 分流, Depth:0 只回资源自身、Depth:1 才列出子集合。 界面与交互: - 观影:新建影院弹窗层级修正 + 详细地址;照片左右按钮悬停不再位移; 弹框底栏改「确定 / 取消」。 - 旅程:新建旅程改弹窗并按观影式排版;详情页四个动作按钮按用户指定顺序与配色; 编辑与新增行程弹窗化(单容器 + AJAX);行程时间控件改 AntD(精确到分); 参与人默认带上自己;车次号/车牌号紧跟交通方式词。 - 资源:新建/编辑改弹窗 + 观影式排版 + 新建时即定共享人。 - 纪念日:新建改弹框 + 观影式排版。 验证: - e2e 1510/0;v41 十二项真机 48/0;DAV 反向验证 8/0; 部署断言空跑 337/0;模板 div 深度三形态穷举 33 组全配平。 - 线上 DAV 终验(--resolve 真实入口 + 真 DAV 口令)12/0; 线上确认 Depth:0 恰好 1 个 response。 |
||
|
|
2e51d3f5e4 |
v24 第 16 批:旅程 / 行程两级(术语固定 · 题图16:9 · 五项统计 · 独立行程页 · 设置三页)
用户十条,逐条落地:
1. 「题图应该按照 16:9 显示,因为添加的时候是按这个比例裁剪的,现在的显示比例不对。」
→ 详情页题图容器从 4:3 改成 16:9,与 ImageSlot 的 cover 槽位同一个数字
(部署断言比对这两处,避免哪天改一处漏一处)。
2. 「题图的右侧,显示的是参与人都有谁、去了几个城市、一共去了几天、一共几段行程,
一共花了多少钱,这些信息,都从该活动下的所有行程统计总结,简介那一段话保留。」
→ 新增 Trip::summary():参与人(各段并集)/ 城市(去重)/ 天数 / 段数 / 总花销,
全部读时算(与"时间城市派生"同一条原则,不存冗余)。
天数按**日历天**含首尾(8/1→8/3 = 3 天,不是 24 小时整除的 2 天)。
城市与时间从标题旁挪进信息区,简介保留。
3. 「活动页面,不需要上传图片,图片视频,都是针对一次具体的行程的。」
→ 删掉旅程页的照片上传板块与照片墙;照片一律挂在**行程**上
(行程表单里有上传,附件 target_type='trip_node')。
4. 「计划行程、未成行的行程,都不要显示……只要是没有就是 0 条,那个类型就不显示了,
现在显示的是 0 条,这样没意义。」
→ 空分组直接跳过不渲染;全空时给一句引导(否则新建旅程页面一片空白)。
有内容的分组照常显示(计划 / 实际 / 未成行三种)。
5. 「行程的编辑功能,点击后会把页面撑破。编辑行程,打开新的页面进行编辑。」
→ 行程的新增与编辑改成**独立页面**(trips/node_new / trips/node_edit)。
原来内联在详情页:N 份表单互相撞元素 id、密码管理器逐个扫描变卡,
正是"把页面撑破"的成因。
6. 「添加计划行程和实际行程的按钮,都放在右上角。点击后打开新的页面进行添加。」
→ 详情页右上角两个按钮(+ 计划行程 / + 实际行程),指向独立新增页。
顺带:标题旁边不再放时间(时间移到题图右侧信息区)。
7. 「添加和编辑行程的内容,你去找 triplog 里面的添加节点功能,跟那个一样。」
→ 字段全量照搬 TripLog 的 nodes/form.php:
类型 / 标题 / 起止时间 / 出行方式 + 车辆 / 线路名 / 承运方 / 车次航班号 /
座位 / 登机口 / 出发地 / 到达地 / 内容 / 参与人(含角色)/ 照片 / 花销。
交通字段不做条件列(先填高铁车次、后来改成自驾,填过的东西不该丢)。
8. 「右上角的按钮,需要增加一个设置按钮,用来设置车辆管理、出行方式、节点类型。
注意,我们在财务中,已经把车辆添加进去了,所以这里不用重复添加那里面的车辆,
直接读取就可以,但是可以添加其他的车辆,比如租的车,借别人的车。」
→ 新增旅程设置菜单(三页):车辆管理 / 出行方式 / 节点类型。
车辆**两个来源刻意不合并**:财务里 kind='car' 的账目(那是资产,没有车牌车型)
由 Vehicle::fromLedger() 只读列出,选车下拉里标「来自财务」;
自家 / 租的 / 借的车录进 vehicles 表。不复制财务的车(避免同一台车两处维护)。
节点类型做成**可自定义**的表(TripLog 同款),内置 5 种不可删;
行程里存类型**名字**,所以改类型名会级联更新已用它的行程。
9. 「活动都改名吧,改成旅程,新建旅程,旅程包含行程,这个名字就固定下来。」
→ 术语固定:**旅程**(容器)包含**行程**(单元)。
顶层按钮「新建旅程」、详情页三组叫「计划的行程 / 实际行程 / 未成行」、
列表「N 段行程」、设置菜单「旅程设置」。上一批的"活动"叫法全部换掉。
10. 「新建旅程里面,怎么还有备注啊,同行的人啊,这些都不要了,这些都是从行程里面
总结出来的。在新建旅程和编辑旅程的时候,都不要了。」
→ 旅程表单只剩:标题 → 题图 → 简介 + 公开开关。
备注与同行的人全部移除(参与人 = 各段行程参与人的合集)。
⚠️ 但**老数据里活动级那份参与人名单不能被清空**(那时还没有行程级参与人),
所以路由"没传这个键就不动",并加了断言钉住这一点。
数据结构(Schema v21,老库自动升级):
· 新表 vehicles(自家/租的/借的)、node_types(可自定义)、trip_expenses(行程级花销)
· trip_nodes 补 9 列:出行方式 / 车辆 / 线路名 / 承运方 / 车次 / 座位 / 登机口 / 起终点
· trip_node_members 补 role_tag(司机 / 摄影担当这类角色)
· 花销金额存**分**,解析走字符串拆小数点(128.55*100 在浮点下会差一分)
验证:e2e 891/0(+46 条本批断言)· 升级 134/0 · 桌面几何 428/0 · 交互 92/0 ·
窄屏溢出 30/0(扩到行程表单 + 设置三页 + 详情页)· 题图点击 4/0 · 静态体检全绿。
**反向验证 6/6**:题图退回 4:3、标题旁加回时间、空分组照旧渲染、编辑退回非独立页、
车辆不读财务、总花销不汇总 —— 六种坏法全部被断言抓住。
部署静态断言新增第 16 批一组(含"空分组不许渲染""行程页不许有照片上传"
"旅程表单不许有备注与同行的人""题图必须 16:9"等反退化防线)。
部署后服务器自检 19/19,六个关键文件 md5 与线上逐一核对一致。
|
||
|
|
7138314dc7 |
v24 第 15 批:活动 / 旅程两级语义(术语 · 派生时间城市 · 表单三项 · 题图可点)
用户原话四条,逐条落地:
1. 「旅程模块,按钮是记一次活动,而不是记一趟旅程。旅程是活动里面的概念。」
→ 顶层一律改称**活动**:按钮「记一次活动」、页标题「活动」、`N 次` / `N 段旅程`;
活动详情三组改叫「计划的旅程 / 走过的旅程 / 没成行的」;
节点表单「这段旅程叫什么」「阶段」;flash 文案 17 处同步。
(导航条仍叫「旅程」——用户就是这么称呼这个模块,列表页加副标题说清两级关系。)
2. 「活动不需要开始和结束时间,是根据活动中的旅程,最早的旅程开始时间,和最晚的
旅程结束时间,计算出来的。目的地也不需要…去的城市,也是根据旅程,得到的。」
→ 活动**不再存**这三样,全部**读时算出来**:
· Trip::derived() 最早开始 / 最晚结束 / 城市去重
· Trip::cities() 按最早出现时间排(先后顺序本身是信息,不是字母序)
· Trip::attachDerived() 列表页批量补(避免 N+1)
· Trip::activitySpan() 没有旅程时说「还没有旅程」,不用「日期待补」
create/update 不再写 events 的起止与地点(老值保留不动,页面不读)。
列表排序/搜索、首页「最近去了」改走子查询。
3. 「题图那里,没有办法上传图片,点击哪里都没反应。」——**真 bug**
「点图 = 开文件框」那句 JS 只写在 people/form.php 的内页脚本里(头像专用);
第 14 批加的旅程题图与图书封面照抄了同一套 DOM 却没有对应的 JS,
于是图块有 cursor:pointer 与 hover 高亮(看着能点),点下去毫无反应。
→ 做成声明式通用绑定:图上写 data-pick-input="#fileInputId",
app.js 统一接管(一个页面多个也各绑各的),并删掉旧的那份专用实现。
三处(头像 / 题图 / 图书封面)全挂上。
4. 「添加活动的页面,顺序是这样的:添加标题,上传并裁剪题图,然后一段简介,就可以了。」
→ 主区就这三项,顺序照原话;时间/城市不做输入项(只留一句说明它们从哪来,
不说清用户会满页找"怎么没地方填时间")。
备注 / 公开 / 同行的人收进「更多设置」折叠区——功能一个没丢。
顺带修掉两处会炸的实现问题:
· ORDER BY 引用聚合别名(first_at)在 MariaDB/MySQL 报 1247,且只在运行时炸、
php -l 看不出 → 改成 ORDER BY MIN(starts_at),否则整个旅程模块 Fatal。
· e2e 里"详情页显示了派生时间"原本写成整页查找,下面每段旅程自己也渲染日期,
于是把派生值塞成 null 也照样绿(借光假绿)→ 判据收进页头那一段。
验证:e2e 845/0(+15 条本批断言)· 升级 134/0 · 桌面几何 428/0 · 移动几何 688/0 ·
交互 92/0 · 题图真机点击 4/0 · 读书窄屏 15/0 · 家谱 34/0 + 10/0 + 反向 3/3 ·
观影按钮 60/0 + 反向 3/3 · 本批反向验证 4/4(题图绑定抽掉→红、派生值不挂→红、
城市退回读 location→红、时间字段加回表单→红)· 部署静态断言新增两组(含"活动不许
再写起止时间/目的地"与"ORDER BY 不许引用聚合别名"的反退化防线)。
部署后服务器自检 19/19,五个关键文件 md5 与线上逐一核对一致。
|
||
|
|
71a7ec35a0 |
v14: 观影/家谱/日程/旅程/资源/任务六模块统一,首页改 dashboard
用户 14 条需求一次交付(1-13 功能 + 14 工作方式)。 观影(1-4) - 返回文案全模块统一为「返回观影」(不再有「返回列表」「返回观影记录」三种叫法) - 观影人一律用彩色人物标签 person_chip:底色由头像主色算出来(上传时存库), 瀑布流卡片也按人显示;五处观影模板全部改用它 - 人员显示统一走 person_name()(shown → 我给他起的称呼 → 姓名) - 影院管理页与年度报告页的上下两块用 .card + .card 统一给间距(原来紧贴成一整块) 家谱(5) - 树根从「我」换成**辈分最高的祖先**:库画的是"树根的祖先链+后代+树根的兄弟姐妹", 根=我 时伯父/堂兄/嫂子/侄子一个都不画(12 人夹具只画出 8 人) - focusMap 按**代数**圈定三代(不再按步数),normalizeLinks 把子女对称挂到父母双方 —— 修掉"母亲登录看不到孩子" - 新增「看全部 / 回到我」两个按钮,放在画布外(画布整块被库接管了手势) 统一事件原语(6-9) - 旅程:TripLog 全量迁入(3 趟旅程 / 21 段行程 / 72 张照片 / 5 个人)。 复用 events(kind='trip') + trip_details + trip_nodes(计划/执行双轨保留) - 日程:每人可建日历本(自定义色)+ 共享只读/可写;观影与旅行是每人默认两本, 内容是**从各模块实时派生**的(不复制,所以改了观影日期日历立刻跟着变); 没有具体时分 = 全天;月视图参照群晖 Calendar - 资源:挂在某人名下的附属信息(标题+正文+多附件),可共享给多人并设只读/读写, 默认折叠、可搜标题与正文 - 任务:看板三列 + 两级子任务 + 评论@人 + 共享 + 循环(完成时按原截止日推下一期) - 统一附件表:四个模块的附件共用一张,下载地址不落库、一律由 media.php 现算 模块化(10-11) - App\Module 是模块的唯一来源(加一行 = 导航条/主题色/个人设置三处自动出现) - 个人设置里可勾选要显示哪些模块、拖动排序(关掉的模块**不会**被兜底补回来) - 每个模块一套主题色(家庭级),只覆盖 --brand 三兄弟,不碰纸墨底色 其他(12-13) - 新增成员表单可选所属分组(编辑表单没有:分组是"我和他的关系",只归我自己) - 首页改 dashboard:接下来的日子 / 未来七天 / 手头在做 / 往年今日。 家人卡片从首页撤走(看人去名册) 验证(全部通过) - e2e 542 条(新增 4 模块端到端 60+ 条) - 桌面几何 368 / 移动端几何 520 / 家谱 12 / 交互 97 / 老库升级 123 - SQL 列名静态校验 0 处可疑(对着真实表结构) - 反向验证 18 条新注入全部抓住 顺带修掉的既有问题 - 老库升级回填 SQL 按实际存在的列动态拼(缺列不再 1054 炸断升级) - 全新安装时 Schema::ensure 跑在"人还没建"之前 → 补建日历本三处齐备 - 窄屏导航横向溢出(模块从 4 个加到 8 个后顶栏撑破视口) |