领证纪念日实际关联 2 人;端上只读了老列所以只带出 1 个 (#91d)

用户 2026-11-05:「你去查一下这个领证纪念日到底关联了几个人,数据库里。」

查库结果:
  anniversaries #2 「领证纪念日」
    person_id = 1                    ← **老列**,只能存一个
  anniversary_people(多对多表)
    person_id=1  杨永全
    person_id=3  洪博为
    = **2 人**                        ← 真正的事实

根因链(两处都缺一不可):

① 服务端 `occurrences()` 从来没输出 `person_ids`
   `peopleMap()`(查多对多表)只在 `split()` 里用了 —— 那是**网页端**的路径;
   `occurrences()` 是 API(鸿蒙端)用的,只透传了 `person_id` 这个老列。
   ⇒ 端上永远只拿到 1 个人。
   ⇒ occurrences 开头一次性 `peopleMap(array_column($all,'id'))`,
     输出 `person_ids`(多对多表为准,为空才退回老列)。

② 端上编辑框只读 `dayDetail.personId`(单个数字)
   ⇒ 改用 `personIds.slice()`(完整列表)。
   FbRecentDay 新增 `personIds: number[]`;`parseRecentDays` 里
   "person_ids 非空就用它,否则退回 person_id"。

⚠️ 老列 `anniversaries.person_id` 是升级到多对多之前的遗留字段。
   两边不一致时**以多对多表为准**(用户在新版界面上改的就是那张表)。
⚠️ 部署时踩了一次:第一次 scp 没生效(服务端文件 grep 不到新代码),
   导致验证结果仍是空的。重新部署并 md5 比对后才确认生效。

实测(部署后):
  领证纪念日   person_ids = [1,3]  → 杨永全、洪博为 ✅
  杨永全 的生日 person_ids = [1]    (派生条目单个人)
  其余派生条目同理,各 1 人。

编译通过,已装真机。
This commit is contained in:
2026-11-05 20:57:23 +08:00
parent 5f8de01033
commit 9047fb411d
3 changed files with 30 additions and 1 deletions
+6
View File
@@ -189,6 +189,8 @@ interface RawRecentDay {
day?: number | null; month?: number | null; day?: number | null; month?: number | null;
/* #88:卡片右侧的两种日期写法(服务端给成品文字) */ /* #88:卡片右侧的两种日期写法(服务端给成品文字) */
lunar_label?: string | null; solar_md?: string | null; lunar_label?: string | null; solar_md?: string | null;
/* #91d:完整关联人列表(多对多表为准) */
person_ids?: number[] | null;
} }
interface RawTaskBoard { interface RawTaskBoard {
@@ -925,6 +927,10 @@ export function parseRecentDays(v: Object | null | undefined): FbRecentDay[] {
month: r.month !== null && r.month !== undefined ? n(r.month) : 0, month: r.month !== null && r.month !== undefined ? n(r.month) : 0,
lunarLabel: s(r.lunar_label), lunarLabel: s(r.lunar_label),
solarMd: s(r.solar_md), solarMd: s(r.solar_md),
/* #91d:优先用多对多表的完整列表;为空才退回老列的单个人 */
personIds: (r.person_ids !== null && r.person_ids !== undefined && r.person_ids.length > 0)
? r.person_ids.map((x: number): number => x)
: (n(r.person_id) > 0 ? [n(r.person_id)] : []),
}; };
out.push(it); out.push(it);
} }
+13
View File
@@ -204,6 +204,19 @@ export interface FbRecentDay {
kind: string; kind: string;
/** 关联的人(自建纪念日可能关联多人;0 = 没关联) */ /** 关联的人(自建纪念日可能关联多人;0 = 没关联) */
personId: number; personId: number;
/**
* **完整**关联人 id 列表(#91d)。
*
* 🔴 用户 2026-11-05:「你去查一下这个领证纪念日到底关联了几个人,数据库里。」
* 查库:「领证纪念日」老列 `person_id = 1`,但 `anniversary_people`
* 里有 **2 人**(杨永全 + 洪博为)。
*
* ⚠️ `personId` 是**老列**(`anniversaries.person_id`),只能存一个 ——
* 升级到多对多之后它是遗留字段。编辑框必须用这个数组,
* 否则第二个及以后的人会被静默丢掉(正是用户遇到的问题)。
* ⚠️ 服务端可能给空数组(老数据还没回填多对多表)⇒ `personId` 兜底。
*/
personIds: number[];
/** /**
* 来源:`custom` = 手动填的纪念日;`birthday_solar` / `birthday_lunar` = 派生生日。 * 来源:`custom` = 手动填的纪念日;`birthday_solar` / `birthday_lunar` = 派生生日。
* ⚠️ 端上据此在文案上区分「纪念日 / 生日」(用户两条要求分别就是这两类)。 * ⚠️ 端上据此在文案上区分「纪念日 / 生日」(用户两条要求分别就是这两类)。
+11 -1
View File
@@ -2186,7 +2186,17 @@ export struct FbHomePage {
editingRepeat: 'solar', editingRepeat: 'solar',
editingMonth: 1, editingMonth: 1,
editingDay: 1, editingDay: 1,
editingPersonIds: this.dayDetail.personId > 0 ? [this.dayDetail.personId] : [], /* 🔴🔴 #91d(用户 2026-11-05):「你去查一下这个领证纪念日到底关联了
几个人,数据库里。」
查库:「领证纪念日」关联 **2 人**(杨永全 #1 + 洪博为 #3)。
而这里原来只读 `dayDetail.personId` —— 那是**老列**
`anniversaries.person_id`,只能存一个 ⇒ 洪博为被静默丢掉,
编辑框只带出 1 个人。
⇒ 改用 `personIds`(服务端按多对多表给的完整列表)。
⚠️ `personIds` 为空时才退回老列(老数据还没回填多对多表的情况),
这段兜底已写在 `parseRecentDays` 里,这里直接用即可。 */
editingPersonIds: this.dayDetail.personIds.slice(),
roster: this.dayRoster, roster: this.dayRoster,
onClose: (): void => { onClose: (): void => {
this.closeDayDetail(); this.closeDayDetail();