巡检人员在地图上长按一个停车位 POI 后,常常想立刻写下“该车位被占用”。但长按只是用户发起了动作;只有 Map Kit 返回 POI 事件,页面才拿到了 POI 名称、标识和坐标。即便草稿按钮变成可确认,也仍要先确认最近事件是不是这一次 POI 长按,而不是此前发生的其他地图事件。

这次工程把 POI 长按次数、最近事件、回调坐标、事件时间线、本地草稿和人工登记分开显示。它要解决的不是替巡检人员判断停车位真实状态,而是让“我正在等回调”“我拿到了 POI 坐标”“我只是写了一份本地说明”不再混成一句“已记录”。

一、停车位长按后,用户以为完成的是什么

1.1 一次手势不等于一个停车位事实

用户在底图上看到 POI 并长按,最多说明他对那个可见地点发起了操作。停车位是否真实存在、是否被占用、占用车辆是否合规,都不由手势或页面草稿直接证明。

页面应先让用户看到“等待真实 Marker 或 POI 长按”“当前坐标为空”这类状态。它们提醒用户:此时还没有来自地图事件的点位来源,不能用屏幕上大概的位置补填停车位记录。

在这里插入图片描述

1.2 POI 事件返回的,是地点线索而不是占用结论

工程在 MapEventManager 上注册 onPoiLongClick(),从回调 POI 中取得名称、标识和坐标:

manager.onPoiLongClick((poi: mapCommon.Poi) => {
  const coordinate = `${poi.position.latitude}, ${poi.position.longitude}`;
  this.poiLongPressCount += 1;
  this.lastEvent = `POI 长按:${poi.name} (${poi.id})`;
  this.eventCoordinates = coordinate;
  this.workOrderState = `已获取真实 POI 坐标,可确认 ${this.taskType} 草稿`;
  this.manualRecordState = '真实坐标已取得,人工登记保持关闭';
  this.recordInspectionEvent('POI 长按', poi.name, coordinate, true);
});

这段代码能证明页面只在真实 POI 长按回调到达后增加 POI 计数、写入回调坐标,并在时间线标为真实记录。它不能证明这个 POI 一定是停车位,也不能证明停车位已经发生占用。

对用户来说,POI 长按:名称(标识)比一句“位置已确认”更有用:前者保留了当前事件来自什么对象,后者会把地点线索扩张成业务结论。

1.3 在长按之前,页面至少要先具备三个可见条件

POI 不会因为页面打开就自动产生回调。用户准备操作前,应依次检查三个条件:

  1. 地图控制器已就绪:页面不再显示“等待 MapComponent 回调”或“地图初始化失败”。这说明当前至少拿到了可用的地图控制器。
  2. 长按监听已注册:页面状态应显示“地图控制器已就绪,长按监听已注册”。没有这条准备状态,用户看见底图也不能确信当前页面会接收 POI 事件。
  3. 目标是可见 POI,而不是空白地图:只有底图识别出的 POI 才可能触发 onPoiLongClick();在空白区域长按不应被当作停车位 POI 操作。

工程把监听注册放在地图回调成功之后:

this.mapController = controller;
this.mapEventManager = controller.getEventManager();
this.registerLongPressEvents(this.mapEventManager);
this.mapState = '地图控制器已就绪,长按监听已注册';

这段代码能证明长按监听依赖真实的 MapComponent 控制器,页面没有在控制器缺失时虚构“可接收 POI”的状态。它不能证明底图上每一个名称看似停车位的对象都会被服务识别为 POI,也不能证明当前设备一定会收到事件。

对用户而言,三个条件的价值是把“地图看得见”与“POI 事件可取证”分开。只有地图可见时,继续长按可能只是无反馈地重复手势;三个条件都满足时,用户才应开始观察 POI 计数、最近事件与坐标的变化。

1.4 地图初始化失败时,先解释“为什么不能操作”,不要把静默等待留给用户

地图区域出现不等于 POI 操作已经具备条件。当前页面在 MapComponent 没有返回控制器,或回调携带非零错误码时,会把地图状态改为“地图初始化失败”,同时标出“未添加测试 Marker”,并保留格式化后的错误信息。它没有继续注册长按事件,也没有把页面写成“等待真实长按”。

这条分支对产品体验很重要:用户此时面对的不是“尚未长按成功”,而是“本页尚未得到可用地图控制器”。如果仍用同一个“再试一次”提示,用户会在无效状态里重复长按,甚至把没有反馈误会成目标 POI 不可用。

页面可按下面的顺序帮助用户判断下一步,而不替他臆测地图服务或网络已经恢复:

  1. 先看地图状态:出现“地图初始化失败”时,停止把任何手势当成 POI 操作,不依据旧坐标确认草稿。
  2. 再看错误文本:错误文本说明本次未取得控制器的原因线索,但不是用户已经完成重连或服务已恢复的证明。
  3. 保留现场任务说明:若现场必须继续巡检,可建立人工登记草稿;文字说明要保留“未获得 MapKit 长按事件”,不填写为系统位置。
  4. 待页面重新就绪后重新取点:只有状态回到“地图已就绪,等待真实长按”,且随后出现新的 POI 长按记录,才能按本文的四项检查重新判断。

这组提示减少的不是一个技术报错,而是一段无效等待。它让用户知道:现在缺的是页面的地图运行条件,不是再换一个 POI 多长按几次;人工记录仍能保留任务,但必须保留它与真实 POI 回调之间的证据差别。

二、页面草稿为什么不能抢在 POI 回调前下结论

2.1 “待落点”是当前草稿最诚实的状态

事件尚未返回时,草稿区显示“尚未取得真实 MapKit 点位”“待确认草稿缺少真实地图点位,无法确认”。这不是让用户无事可做,而是防止他把屏幕上看见的 POI 名称、自己记下的地址或空白长按的位置伪装成系统坐标。

此时用户可以补充现场观察,但应把它保留为人工说明;页面不能给这段说明附上“POI 已返回”的状态。把待落点说清楚,反而能让下一位巡检人员知道还缺哪一类证据。

2.2 可确认按钮使用的是“真实事件存在”门槛

当前工程用 hasRealEvidence() 决定草稿是否可确认:

private hasRealEvidence(): boolean {
  return this.markerLongPressCount + this.poiLongPressCount > 0;
}

Text(this.hasRealEvidence() ? '可确认' : '待落点')
this.buildDraftField('点位来源', this.hasRealEvidence() ? this.lastEvent : '尚未取得真实 MapKit 点位');
this.buildDraftField('坐标', this.eventCoordinates);

这段代码能证明页面要求至少有一次真实地图事件才允许确认本地草稿,并会显示当前的最近事件和坐标。它也带来一个需要用户特别注意的边界:这个门槛同时接受 Marker 和 POI 事件。

所以停车位任务不能只看到按钮变成“可确认”就写“POI 已返回”。还要核对“最近事件”是否是 POI 长按、POI 计数是否增加、坐标是否对应这次停车位操作。否则页面可能只是保留了一次此前的 Marker 回调,而不是当前停车位 POI 的证据。

2.3 把“按钮可用”变成一次可复核的四项检查

停车位巡检不应以按钮从灰色变为绿色作为终点。用户看到“可确认”后,应在点击前完成四项检查:

检查项 页面上应看到什么 不满足时的动作
事件类型 最近事件以 POI 长按: 开头 停止确认,排除此前 Marker 事件。
POI 计数 POI 长按次数在本次操作后增加 不把一次没有回调的手势写成 POI 事件。
坐标 当前坐标不是“坐标为空”,且与当前 POI 操作相邻出现 保留等待状态,不用人工地址替换。
时间线 最新记录来源为“POI 长按”,并标为“真实回调” 先看人工降级或旧事件是否混入。

这四项都来自当前页面已有的证据区和时间线,不要求用户在文章外补造数据。它们共同支持的结论仅是“本地草稿有一条可回看的 POI 事件来源”;不支持“停车位已被占用”“该点位已被业务确认”。

三、真实 POI 回调到本地草稿之间还隔着什么

3.1 时间线让用户回看这条记录从哪里来

回调后的记录不会只留在当前字段,还会写入本次页面时间线:

private recordInspectionEvent(source: string, detail: string, coordinate: string, isReal: boolean): void {
  this.updateOperation(isReal ? 'EVENT' : 'MANUAL');
  const item: InspectionEventItem = {
    sequence: this.operationSequence,
    source: source,
    detail: detail,
    coordinate: coordinate,
    isReal: isReal,
    eventTime: this.lastUpdatedAt
  };
  this.eventRecords = [item, ...this.eventRecords].slice(0, 5);
}

这段代码能证明页面给本次事件保留来源、对象细节、坐标、真实标识和当前会话时间,并只保留最近 5 条。它不能证明这些记录已经同步到停车管理系统,也不能证明历史记录不会因重置页面而消失。

对停车位巡检来说,时间线的意义是区分“真实 POI 回调”与“人工降级”。若现场人员后续发现自己长按的是错误地点,也能根据来源和时间回看当前草稿不应被当作停车位事实。

3.1.1 回调后要核对的是同一条证据链,而不是四个孤立字段

POI 计数、最近事件、当前坐标和时间线由同一次回调更新,但它们在页面上分散显示。用户应把它们当作一条链来读:计数说明回调次数变化,最近事件说明对象名称和标识,坐标说明事件位置,时间线说明来源及真实标记。

如果这四项出现不一致,例如 POI 计数增加但时间线最后一条仍是人工登记,或坐标仍为空,就不要确认草稿。对页面来说,这意味着需要继续观察当前会话状态;对用户来说,意味着不能选择一项“看上去成功”的状态替另外三项下结论。

这种一致性检查不会额外制造业务流程。它只是把页面已经呈现的局部状态重新合在一起,避免用户在多次手势、切换任务类型或人工登记之后,误将不同时间产生的字段拼成一条不存在的 POI 证据。

3.1.2 连续长按多个 POI 时,“最近事件”只代表最后一次,不代表整张停车位清单

页面每收到一条事件,都会把新项放到时间线最前面,并只保留最近 5 条。与此同时,草稿区的“最近事件”和“当前坐标”会被下一次真实回调覆盖。因此,连续长按 A、B 两个停车位后,页面可同时留下两条时间线记录,但草稿区展示的是最后回调的 B;它不会自动维护“当前正在编辑 A”的独立草稿。

这个限制决定了用户不能先长按多处地点、最后再逐一确认。若先长按 A,看到坐标后又长按 B,再点击确认本地草稿,确认状态能证明的只是当前页面已取得某次真实事件;结合最新事件和坐标,实际更接近 B,而不是先前的 A。只看 POI 次数从 1 变成 2,无法恢复草稿究竟引用了哪一处地点。

为了不让“最后一次回调”覆盖用户的判断,可采用一处点位一轮核对的操作节奏:

  1. 长按一个可见 POI 后,先确认最新时间线是 POI 长按,并阅读名称、标识、坐标和时间。
  2. 若要形成当前页面草稿,在再次长按其他地点前完成四项检查;确认后仍标记为“未提交后台”。
  3. 需要继续处理另一处点位时,先把前一处的名称、标识、坐标和草稿层级按已有业务流程留存,再开始下一次长按。
  4. 当页面时间线已经接近 5 条时,不以“屏幕上还看得到”作为交接保证;更早的记录会被新事件顶出,且重置页面会清空全部会话信息。

这不是要求用户为每一次地图手势新增复杂流程,而是承认当前页面的证据容器是“最近会话”,不是停车位台账。把这一点写进状态文案后,用户知道何时应先完成本地判断、何时应暂停操作去补留存,而不会把计数增长理解成多处停车位都已经被系统登记。

3.2 确认本地草稿仍不等于提交停车位记录

真实事件存在时,用户可以点击“确认本地工单草稿”。工程对此的最终状态很明确:

private confirmDraft(): void {
  if (!this.hasRealEvidence()) {
    this.workOrderState = '待确认草稿缺少真实地图点位,无法确认。';
    return;
  }
  this.workOrderState = `本地工单草稿已确认:${this.taskType} · ${this.priority},未提交后台。`;
  this.updateOperation('DRAFT');
}

这段代码能证明页面只会把草稿确认为当前页面的本地状态,并明确写出“未提交后台”。它不能证明占用记录已经入库、执法人员已派遣或停车位状态已更新。

用户确认前应再看一次点位来源、坐标和最近事件;确认后也应把它理解为“可交接的本地草稿”,而不是“停车位案件已完成”。

3.3 草稿确认前后,用户应带走不同的信息

确认前,用户带走的是“候选证据”:POI 名称与标识、当前坐标、最近事件和时间线。确认后,页面额外形成“本地工单草稿已确认”的状态,但它仍没有产生后台编号、提交回执或停车管理系统的状态变化。

因此交接文案应避免写成“已登记停车位占用”。更准确的说法是“本地草稿已确认,待按业务流程补交”。这句话保留了用户已经完成的本地动作,也明确指出尚未发生的系统动作,下一位人员无需猜测是否还要做提交或现场核验。

四、没有 POI 回调时,人工登记如何不断言地图事实

4.1 人工登记保留任务,不补写坐标

若没有任何真实地图事件,工程允许建立人工登记草稿,并明确写入“未写入地图坐标或长按计数”“待补充真实点位”。人工登记可以保存巡检人员当前的文字说明,却不能借用 POI 名称、坐标或事件次数。

这使现场任务不至于因网络、地图加载或 POI 不可见而完全中断,同时让下一步核验知道这是一条人工降级记录,而非系统回调。

4.2 有真实事件后,人工路径必须关闭

工程通过 canCreateManualRecord() 让人工登记只在没有真实事件时可用;一旦已有真实坐标,按钮的文案明确为“人工登记未执行:真实坐标已存在,不可覆盖 MapKit 事件”。

这里应再次注意共享门槛:停车位场景下,不但要确认“人工路径是否关闭”,还要确认关闭它的真实事件是不是 POI。若来源是 Marker,不能把那次事件挪用为停车位 POI 的占用证明。

4.3 重置页面会清掉本次事件,交接不能只靠屏幕还亮着

页面的“重置本地会话”会清空 Marker 与 POI 长按次数、当前坐标、最近事件、草稿状态和事件时间线:

private resetSession(): void {
  this.markerLongPressCount = 0;
  this.poiLongPressCount = 0;
  this.eventCoordinates = '坐标为空';
  this.lastEvent = '等待真实 Marker 或 POI 长按';
  this.workOrderState = '等待真实落点证据';
  this.eventRecords = [];
  this.updateOperation('RESET');
}

这段代码能证明当前页面保存的是一次会话内的本地状态,重置后不会继续保留这次 POI 事件。它不能证明重置前的事件已经自动留在后台,也不能依靠“操作过一次”的印象恢复坐标。

因此需要交接时,用户应在重置前记录本次 POI 名称、标识、坐标、时间线状态和草稿状态;若这些信息未被其他经过确认的业务流程保存,就不能先重置页面再期待从本页找回。这个边界尤其适合停车位巡检:现场人员常在处理多处点位时切换任务,最容易把前一处的会话状态误当成已经持久化的记录。

五、停车位长按这一次,哪些内容可以交接

一次真实 POI 长按可以交接 POI 名称与标识、回调坐标、POI 长按次数、最近事件、时间线中的真实标记和本地草稿状态。交接时应按以下顺序核对:

  1. 来源是否为 POI:最近事件和时间线应明确显示 POI 长按,而非只显示“真实事件”。
  2. 坐标是否属于本次操作:对照长按时间、POI 名称和当前坐标,不用旧事件替代当前停车位。
  3. 草稿处于哪一层:区分待落点、可确认、本地草稿已确认;三者都不是后台记录。
  4. 占用事实是否另有证据:现场观察、业务登记或管理系统回执仍需单独取得,不能由 POI 回调推导。

如果这次记录需要留给另一位人员,推荐按“事件来源 → 坐标与时间 → 草稿层级 → 业务证据缺口”写一行交接摘要。例如可以写“本次页面收到 POI 长按回调,坐标见页面证据区;本地草稿已确认但未提交后台;停车位占用仍待现场或业务系统核验”。这里的每一句都对应页面当前能证明的层次,不会把现场观察和系统回执混写成同一个结果。

这些信息帮助用户把地图事件交接清楚,但不把一个地点对象自动升级为停车位占用结果。

在这里插入图片描述

必要条件|运行门禁

G1:SDK/API门禁

确认 HarmonyOS 6.1.1 API 24 已安装,Hvigor 能构建 entry 模块。

在这里插入图片描述
在这里插入图片描述

G2:Kit门禁

确认本文页面的 Kit import 可解析,并使用 API 24 支持的接口。

G3:模块/页面门禁

确认 Stage 模块、页面路由、设备类型和相关模块配置完整。

G4:权限门禁

确认静态声明存在;Camera/AI字幕等运行时能力在真正调用前完成动态授权。

在这里插入图片描述

G5:系统能力门禁

确认目标设备声明并实际提供所需摄像头、麦克风、地图、视觉或文件能力。任一门禁未通过,停止进入核心操作。

在这里插入图片描述

MapKit文章在 G5 放行前增加服务配置门禁:AppGallery Connect 中已选择正确项目,应用包名和签名证书与工程一致,MapKit 服务已开通且应用服务凭据/授权配置已完成。不得在文章或源码中暴露服务密钥。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐