地点输入:补地址联想,下拉带详细地址好区分同名地点 laoyang/FamilyBook#36

用户 2026-10-30:「在所有调用高德显示详细地址的地方…不能只把地点告诉我,
一定要把详细地址也放在后面。因为同一个地址可能有好几个,
我根本不知道应该选哪一个。」

网页端(addr_suggest.js)已经是这个行为,端上原本**连联想都没有**(纯文本框)。
本次把能力补到端上:

- 新增 FbGeoRepo.ets:调服务端 /api/v1/geo/tips,最少 2 字才查
- 新增 FbAddrInput.ets:候选每行两行字(地名 14px 深色 + 详细地址 12px 灰),
  同名地点靠第二行区分;防抖 260ms(与网页端同节奏);用 seq 丢弃过期响应
- 日程编辑、行程节点两处地点接入

🔴 走服务端代理而不是端上直连高德:高德 Web 服务 key 是服务端密钥,
打进安装包等于公开(反编译/抓包即得,配额会被跑光、key 可能被封)。
网页端用的 JS API key + 安全密钥是域名白名单那套,原生端没有等价机制。

⚠️ 必须是 @ComponentV2 组件而不是 @Builder:@Builder 的值类型参数
不参与状态观察(SDK r/quick-rules/05-state.md),候选列表/展开态写在
@Builder 里会数据变了界面不重建。本项目在 FbEventChip/FbTagChip/
FbCalOptionRow 上各踩过一次。

⚠️ 联想失败一律返回空候选 ⇒ 退化成普通文本框,手敲照常保存
(接口挂/没网/没配 key 都不能拖垮主流程)。

编译通过(33 tasks,17 executed)。
This commit is contained in:
2026-10-30 08:03:13 +08:00
parent f90cae0dcc
commit f4f27cea55
5 changed files with 343 additions and 5 deletions
@@ -44,6 +44,9 @@ import { FB_TOKEN_STORE } from '../data/FbTokenStore';
import { FB_CAL_SETTINGS } from '../data/FbCalSettings';
import { FbEventChip } from './FbEventChip';
import { FbSheetRing } from './FbSheetRing';
/* 🔴 2026-10-30(工单 #36):地点改成带联想的输入框 ——
用户要「输入简单地址 → 下拉里带详细地址,好区分同名地点」。 */
import { FbAddrInput } from './FbAddrInput';
/* 🔴 v64(用户 2026-10-19):「观影的开始/结束时间应该跟**日程里面的是一样的**。」
⇒ 「日期 + 时间」那一套控件抽成了共用组件(见该文件头),日程与观影都用它。
⚠️ 本文件里原来的 `dateTimeRow` / `dateTimePickerSheet` / `cnDate` /
@@ -519,8 +522,21 @@ export struct FbEventEditSheet {
.margin({ top: 2 })
// ---- 地点 / 备注 ----
this.field('地点', this.fPlace, '地点(可选)', (v: string): void => {
this.fPlace = v;
/* 🔴 2026-10-30(工单 #36):地点换成**带联想**的输入框。
用户:「输入一个简单地址、下拉显示详细地址时,不能只把地点告诉我,
一定要把详细地址也放在后面。因为同一个地址可能有好几个,
我根本不知道应该选哪一个。」——与网页端 addr_suggest.js 同一行为。
⚠️ 选中候选后只把**地名**写进 location(与网页端日程那栏一致:
日程没有单独的"详细地址"字段,而带门牌会让后续按名字搜索变难;
详细地址在下拉里已经看到、能区分就够)。 */
FbAddrInput({
label: '地点',
placeholder: '地点(可选,输入后可从下拉选)',
value: this.fPlace,
token: this.token(),
onValue: (v: string): void => {
this.fPlace = v;
}
})
this.area('备注', this.fNote, '备注(可选)', (v: string): void => {
this.fNote = v;