日程详情卡:补齐行程的出发地/目的地 (#69)

用户 2026-11-05:「点击行程里旅行日历本里的信息时,弹出来的那个框是在首页上
弹出的,还是没有出发地和目的地。」

根因链(三段,缺一段都不显示):

1. FbCalEventFull 没有那四个字段
   #67 只给了 FbCalEvent(列表用),详情卡消费的是 FbCalEventFull。

2. shellOf() 只塞了 location: b.place
   行程节点的 place 是空串 —— 它的位置概念是"从哪到哪",没有单一地点。

3. 最关键:行程条目**永远走 shell,压根不请求详情接口**
   openEvent() 里 `if (!isEditableEvent(e)) { shellOf(e); return; }`,
   行程的 kind 是 trip 不是 custom ⇒ 直接短路。
   而且即使去请求也没意义:Calendar::event($id) 查的是 calendar_events,
   行程节点在 trip_nodes 表,那个 id 查不到东西。
   ⇒ 位置信息**只能**靠 shell 带过去。

改动:

- FbCalEventFull 加 fromPlace/toPlace/fromLng/fromLat/toLng/toLat
- FbCalRepo.toFull() 从接口读(接口给就填,普通日程取到空串)
- 首页 FbHomePage.shellOf()、日程页 FbCalendarPage.shellOf() 两处传递
  (两处是独立实现,只改一处会漏)
- FbEventSheet:
  · navRow 改 navRowRaw(label, place, navTarget) —— 标签不再硬编码「地点」
  · onNavigate 从无参改成 onNavigate(navTarget)
    原来宿主只能读 event.location 猜导航目标,无法区分出发地/目的地
  · 渲染三分支:有 fromPlace 画「出发地」、有 toPlace 画「目的地」、
    有 location 画「地点」(三者互斥:行程条目只有前两个,普通日程只有第三个)
  · 新增 navTargetOf(place, lng, lat):有坐标返回 `lat,lng?地名`
    (同名地点不会搜错城市),没有就只给地名让 FbNav 地理编码
- 首页 navigateEvent / 日程页 navigateDetail 改成接受 navTarget,
  非空直接用,为空退回原来那套推导(底部那颗「导航」按钮传空串)
This commit is contained in:
2026-11-05 16:21:16 +08:00
parent f30ea5b1e4
commit ad9b934760
4 changed files with 137 additions and 17 deletions
+36 -5
View File
@@ -513,13 +513,34 @@ export struct FbHomePage {
}
/** 列表那条 → 完整字段的壳(只垫列表**已知**的字段,别编) */
/**
* 把列表条目垫成一份"详情壳"。
*
* 🔴 #69(用户 2026-11-05):「点击行程里旅行日历本里的信息时,弹出来的那个框…
* 还是没有出发地和目的地。」
*
* 为什么这个壳很重要:`openEvent()` 里
* `if (!isEditableEvent(e)) { this.evtFull = this.shellOf(e); return; }`
* —— 行程条目的 `kind` 是 `'trip'` 不是 `'custom'`,
* **永远走这条捷径、压根不请求详情接口**(而且也没有意义:
* 行程节点的数据在 `trip_nodes` 表里,`Calendar::event($id)` 查的是
* `calendar_events`,对节点 id 必然查不到)。
*
* ⇒ 位置信息**只能**靠这个壳带过去。原来只塞了 `location: b.place`,
* 而行程节点的 `place` 是空串(它的位置概念是"从哪到哪"),
* 于是详情卡里一行位置信息都没有。
*/
private shellOf(b: FbCalEvent): FbCalEventFull {
const shell: FbCalEventFull = {
id: b.id, calendar_id: b.calId, title: b.title, location: b.place,
starts_at: b.date + ' ' + (b.allDay ? '00:00:00' : (b.time + ':00')),
ends_at: b.endTime !== '' ? (b.date + ' ' + b.endTime + ':00') : '',
all_day: b.allDay, note: b.note, rrule: '', reminder_minutes: '',
status: 'confirmed', transp: false, created_by: 0
status: 'confirmed', transp: false, created_by: 0,
/* #69:行程条目的「从哪到哪」—— 服务端不给 location,
不给这几个字段的话详情卡里就没有任何位置信息 */
fromPlace: b.fromPlace, toPlace: b.toPlace,
fromLng: b.fromLng, fromLat: b.fromLat, toLng: b.toLng, toLat: b.toLat
};
return shell;
}
@@ -533,10 +554,20 @@ export struct FbHomePage {
}
/** 详情卡上点「导航」/ 点地点行 → 拉起地图 */
private navigateEvent(): void {
/**
* 去导航(#69:改成接受 `navTarget`)。
*
* 原来是无参的 —— 只读 `evtFull.location`。行程条目没有 location,
* 且详情卡里现在有「出发地」「目的地」两行,得知道点的是哪一行。
* ⇒ 详情卡把那一行的地名(带坐标时是 `lat,lng?地名`)直接交进来。
*/
private navigateEvent(navTarget: string): void {
const placeOfFull: string = this.evtFull !== null ? this.evtFull.location : '';
const placeOfBase: string = this.evtBase !== null ? this.evtBase.place : '';
const place: string = placeOfFull !== '' ? placeOfFull : placeOfBase;
/* 优先用详情卡传来的目标;它为空(老路径 / 极少数情况)才退回原来那套推导 */
const place: string = navTarget !== ''
? navTarget
: (placeOfFull !== '' ? placeOfFull : placeOfBase);
const title: string = this.evtFull !== null ? this.evtFull.title
: (this.evtBase !== null ? this.evtBase.title : '');
/* ⚠️ 必须是 `UIAbilityContext`(`startAbility` 只在这个上下文上有;
@@ -1846,8 +1877,8 @@ export struct FbHomePage {
v86 开编辑入口的决定本身没错(编辑就地改、不跳页),
错在没把"没有写权限的本"排除掉 ⇒ 改为按 calWrite 判定。 */
canEdit: this.evtBase !== null && isEventWritable(this.evtBase, this.calBooks),
onNavigate: (): void => {
this.navigateEvent();
onNavigate: (navTarget: string): void => {
this.navigateEvent(navTarget);
},
onClose: (): void => {
this.closeEvent();