日程详情卡:补齐行程的出发地/目的地 (#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
+55 -6
View File
@@ -56,7 +56,16 @@ export struct FbEventSheet {
* undefined。宿主页本来就有可靠的上下文来源,且"要不要拉地图"属于导航决策
* (跟"当前在哪个模块"有关),不是这张卡的职责。
*/
@Event onNavigate: () => void = (): void => {
/**
* 点某一行位置信息去导航。
*
* 🔴 #69(用户 2026-11-05):原来是**无参**的 —— 宿主只能自己猜"该导航到哪",
* 实际上它读的是 `event.location`。而行程条目根本没有 location
* (服务端 trip 段不输出那个字段),于是详情卡里既没有位置信息,
* 就算硬加一行也没法指定导航到出发地还是目的地。
* ⇒ 改成带 `navTarget`:点哪一行就把那一行的地名/坐标交出去。
*/
@Event onNavigate: (navTarget: string) => void = (navTarget: string): void => {
};
@Event onClose: () => void = (): void => {
};
@@ -234,10 +243,27 @@ export struct FbEventSheet {
* 重建),不存在"数据变了行不刷新"的场景,所以用 Builder 是安全的;
* 但仍保持**单参数**,把风险面压到最小。
*/
/**
* 算出交给 `onNavigate` 的导航目标(#69)。
*
* 有坐标就带坐标:`lat,lng?地名` —— 同名地点不会搜错城市
* (旅程模块踩过:全国搜「珠江路1018号」搜到了江苏南通,差 500 公里)。
* 没有坐标就只给地名,让 `FbNav` 自己走系统地理编码。
*
* ⚠️ 这是个**纯函数**(不读 this),所以放在 Builder 外面,
* 不会引入"@Builder 里调方法导致不刷新"的问题。
*/
private navTargetOf(place: string, lng: string, lat: string): string {
if (lng !== '' && lat !== '') {
return lat + ',' + lng + '?' + place;
}
return place;
}
@Builder
navRow(place: string) {
navRowRaw(label: string, place: string, navTarget: string) {
Row({ space: 10 }) {
Text('地点')
Text(label)
.fontSize(FbMetric.fontTiny)
.fontColor(FbColors.faint)
.width(56)
@@ -271,7 +297,7 @@ export struct FbEventSheet {
.padding({ top: 8, bottom: 8 })
.alignItems(VerticalAlign.Center)
.onClick((): void => {
this.onNavigate();
this.onNavigate(navTarget);
})
}
@@ -359,6 +385,26 @@ export struct FbEventSheet {
if (this.remindText() !== '') {
this.row('提醒', this.remindText())
}
/* 🔴 #69(用户 2026-11-05):「点击行程里旅行日历本里的信息时,
弹出来的那个框…还是没有出发地和目的地。」
⇒ 行程派生条目(kind='trip')服务端**不给 `location`** ——
行程没有单一"地点"概念,有的是"从哪到哪"。
所以这里必须按 fromPlace / toPlace 分开画两行。
三者互斥地覆盖所有情况:
· 行程条目 → 出发地 + 目的地
· 普通日程 → 地点
不会同时出现(行程的 location 恒为空串,
普通日程的 fromPlace/toPlace 恒为空串)。 */
if (this.event.fromPlace !== '') {
this.navRowRaw('出发地', this.event.fromPlace,
this.navTargetOf(this.event.fromPlace, this.event.fromLng, this.event.fromLat))
}
if (this.event.toPlace !== '') {
this.navRowRaw('目的地', this.event.toPlace,
this.navTargetOf(this.event.toPlace, this.event.toLng, this.event.toLat))
}
if (this.event.location !== '') {
/* 🔴 v73(用户 2026-10-21「有地址的还可以直接一键导航」):
地点不再是纯文字 —— **整行可点**,右侧带一颗「导航」小标签。
@@ -368,7 +414,8 @@ export struct FbEventSheet {
⚠️ 但**视觉上**仍要有那颗「导航」标签 —— 只有"整行可点"
而没有任何标记的话,用户根本不知道地点能点
(本项目踩过:卡尾"查看行程"是纯文本,用户以为按钮坏了)。 */
this.navRow(this.event.location)
this.navRowRaw('地点', this.event.location,
this.navTargetOf(this.event.location, '', ''))
}
if (this.event.note !== '') {
this.row('备注', this.event.note)
@@ -421,7 +468,9 @@ export struct FbEventSheet {
.borderRadius(FbMetric.radiusS)
.border({ width: 1, color: this.accentAlpha('33') })
.onClick((): void => {
this.onNavigate();
/* #69:底部这颗按钮不带具体行 —— 交给宿主自己挑一个
(传空串 = "按老规则推导":location 优先) */
this.onNavigate('');
})
}
if (this.canEdit) {