纪念日:生日改成只读卡、自建纪念日才可编辑 (#87)

用户 2026-11-05 四条:
  1.「如果这个纪念日来自生日,我们是不能编辑的。」
  2.「点击之后,像日程那样弹出一个框来显示就行:显示这个人的头像、姓名,
     以及生日的『日』和日期就可以了。」
  3.「如果是我们自己创建的纪念日,那么这里面就是编辑纪念日。」
  4.「这个框和刚才我们编辑任务的框是一样的做法。样式、格式全部都一样。」

🔴 先说一个**会改坏用户数据的 bug**(这次一并修掉):
   原来派生生日也走 FbDayEditSheet,而且传的是
     editingMonth: 1, editingDay: 1   ← 写死的 1 月 1 日
   结果点开任何一个生日都显示「1 月 1 日」,点保存还能把
   **成员档案里的真实生日覆盖成 1 月 1 日**。
   这不是样式问题,是数据损坏。

改动:

① 新增 components/FbDayBirthdaySheet.ets(派生生日的只读卡)
   · 外壳用 FbSheetRing + 遮罩点击关闭 + 右上角 FbSheetClose
     —— 与 FbTaskPanel / FbDayEditSheet 同一套版式(用户第 4 条)
   · 左上角「生日 / 农历生日」主题色粗体 + 一行小字
     「来自成员资料,不能在这里修改」——把"不能编辑"这条边界写明白,
     否则用户会以为卡片坏了(用户第 1 条)
   · 主体:FbAvatar(56) + 姓名(主题色粗体) + 完整日期
   · 「日」做成视觉焦点:84×84 浅主题色块里放 34 号大字数字 + 「11 月」
   · 右侧:还有几天 / 满 N 周岁 / 农历说明
   · 底部:「要修改生日,请到「家人」里打开这位成员的资料」
     —— 只读也要给出口,不然用户不知道去哪儿改

② FbHomePage 按 source 分发
   birthday_solar / birthday_lunar → FbDayBirthdaySheet(只读)
   custom                          → FbDayEditSheet(可编辑,原行为)
   ⚠️ 判据用 source 前缀而不是 id === 0:两者目前等价,但 source 是语义、
      id 是实现细节 —— 万一以后派生条目也带 id,用 id 判会静默错。

③ 服务端 Anniversary::occurrences() 补输出
   · person_name —— `birthdays()` 算出来了,但 occurrences 逐个字段挑着抄时漏了
   · avatar / avatar_color —— 只读卡要画头像(key,端上拼 URL)
   · day / month —— 用户要的「生日的『日』」
     ⚠️ 用 $a['day'] 而不是从 $date 截:农历生日的 day 是农历日
        (初五 = 5),date 是换算后的公历日 —— 两者不同,用户要看"生日那天"
   · birthdays() 同步补 avatar / avatar_color(它原来也没有)

④ Types / FbParse 补五个字段
   personName / avatar / avatarColor / day / month

编译通过,已装真机。
This commit is contained in:
2026-11-05 20:32:10 +08:00
parent 69c47c3c43
commit 90973bb71c
+28
View File
@@ -282,6 +282,9 @@ final class Anniversary
'is_leap' => 0,
'person_id' => $pid,
'person_name' => (string)($p['name'] ?? ''),
/* #87:头像给端上画"生日只读卡"用(key,端上拼 URL) */
'avatar' => (string)($p['avatar'] ?? ''),
'avatar_color' => (string)($p['avatar_color'] ?? ''),
'source' => 'birthday_solar',
'born' => $solar,
];
@@ -299,6 +302,8 @@ final class Anniversary
'is_leap' => (int)($p['birthday_lunar_leap'] ?? 0),
'person_id' => $pid,
'person_name' => (string)($p['name'] ?? ''),
'avatar' => (string)($p['avatar'] ?? ''),
'avatar_color' => (string)($p['avatar_color'] ?? ''),
'source' => 'birthday_lunar',
'born' => $lunar,
];
@@ -644,6 +649,29 @@ final class Anniversary
在这里一次性算好,别让每个渲染点各自去查一遍配置。 */
'icon' => self::iconOf($familyId, (string)($a['kind'] ?? '')),
'person_id' => (int)($a['person_id'] ?? 0),
/* 🔴 #87(用户 2026-11-05):「如果这个纪念日来自生日…
点击之后,显示这个人的头像、姓名,以及生日的『日』和日期就可以了。」
⇒ 端上要画头像,所以这里必须带出来。
原来 `birthdays()` 算出来的 `person_name` 在这里**被丢掉了**
—— `occurrences()` 逐个字段挑着抄,漏了它。
⇒ 一并补 `person_name` + `avatar` + `avatar_color`。
`avatar` 是 key(如 `avatars/2026xxx.jpg`),
端上自己拼完整 URL(与任务负责人头像同一口径)。
⚠️ `all()` 里自建纪念日那批的 `person_name` 是 `''`
(自建纪念日可能关联多人、也可能不关联人),
这里原样透传即可,端上"名字为空就不画头像"。 */
'person_name' => (string)($a['person_name'] ?? ''),
'avatar' => (string)($a['avatar'] ?? ''),
'avatar_color' => (string)($a['avatar_color'] ?? ''),
/* 「日」—— 用户明确要"生日的『日』"。
直接给整数,端上做"大字显示"(如「17」)。
⚠️ 用 `$a['day']` 而不是从 `$date` 里截:
`$a['day']` 是**用户填的那一天**(农历生日时是农历日),
`$date` 是换算出来的公历日期 —— 两者在农历生日上不同,
用户要看的是"生日那天"(农历初五就该显示 5)。 */
'day' => (int)($a['day'] ?? 0),
'month' => (int)($a['month'] ?? 0),
'source' => (string)($a['source'] ?? 'custom'),
'note' => (string)($a['note'] ?? ''),
'id' => (int)($a['id'] ?? 0),