Update planner, check-in records, location service and tests #10

Merged
admin merged 1 commits from zhouruizhe into main 2026-08-01 22:01:35 +08:00
Owner
No description provided.
admin added 1 commit 2026-07-31 15:14:06 +08:00
Update planner, check-in records, location service and tests
AI Code Review / review (pull_request) Successful in 6m54s
c0ed0048aa
Author
Owner

🔍 审查结论

本次 PR 主体是「快速规划首站不可达」的错误语义化、定位新鲜度的主动计时器、打卡记录页的异常兜底,以及清理无用枚举/切换 appid。整体逻辑自洽,未发现必须修复的正确性缺陷。下面按严重程度分类。

严重问题(必须修复)

  • 无。核心改动(local-planner.ts 的 throw、isLocationSnapshotFresh、planner 计时器生命周期、records.vue 兜底)经静态核验与现有测试覆盖均成立。

建议改进

  • src/manifest.json:49(及配套 project.config.json:27)——直接改了生成产物里的 appid,存在下次构建即漂移的风险。 manifest.config.ts:8,71 的 appid 来自 manifestEnv.UNI_MP_WEIXIN_APPID || 'touristappid',而仓库内 .env / .env.development / .env.production 均未设置该变量(.env.example:2 为空占位)。也就是说干净构建会生成 appid: 'touristappid',与本次提交的 wxda4fb5048b5dc9a1 不一致——下一次任何人跑 dev 构建都会把这一行改回去或改成别的值,正好是本 PR 自己在 README.md:10 加的「不应单独保留由最后一次构建造成的前缀漂移」要避免的情形。README 也明确「不要直接修改这两个生成文件」。建议:appid 统一由本地 UNI_MP_WEIXIN_APPID 环境变量提供,让 src/manifest.json 由构建生成,而不是手改快照;project.config.json(IDE 工程文件,手维护)保留 appid 没问题。注意两文件若一处走构建、一处手改,后续会无声分裂。

  • src/domain/travel/local-planner.ts:297-302 的 throw 条件可读性可再收紧。 selected.length === 0 && remaining.length > 0 语义正确(首站在时长内放不下才进此分支;候选为空时 remaining 也为空,会落到 createLocalPlan:543 的兜底 Error),但「剩余 > 0」这一判断依赖读者理解 remaining 只会被 splice 掉已选点位。建议加一行注释说明「fitting 为空 → 首站即不可达」,与 selectRecommendedPois:588-589 的等价处理呼应(目前两处错误措辞不同,未来可考虑统一文案)。

  • src/pages/check-in/records.vue:142-147 的「重新加载开放点位」按钮直接绑 loadAvailablePois,不会顺带刷新 profile。 这处单独重载点位是合理的(profile 与 POI 目录解耦),功能正确;仅提示:若希望「重载」一并复位整体状态,可考虑绑 loadRecords。当前实现可接受,属产品取舍。

  • src/services/location/current-location.ts:8-23isLocationSnapshotFresh 默认参数 checkedAt = Date.now() 实际未被 planner 使用(planner 总是显式传 locationFreshnessCheckedAt.value)。默认值作为独立工具函数的兜底是合理的,保留即可;仅提示存在「两套计时来源」的潜在混淆——目前 planner 走显式传参,没问题。

测试与验证建议

  • 跑测试套件pnpm install && pnpm test。本环境无 node_modulesnpx 拉到 vitest 4.x 与项目 vitest@^2.0.5package.json:136)不兼容,无法在此执行(属环境问题,非代码缺陷)。重点确认两个改动过的用例:test/current-location.test.ts(新鲜度边界:恰好 maxAge 为 fresh、+1ms 为 stale、未来时间/非法字符串为 false)与 test/travel-assistant.test.ts(quick 模式首站不可达时抛 TravelValidationErrorcode === 'quick_route_unreachable')。
  • 类型检查pnpm run type-check(vue-tsc),确认 TravelValidationError.code 新字段、isLocationSnapshotFresh 签名与 planner/index.vuerecords.vue 的集成无类型回归。
  • 手动验证(planner 计时器):定位成功后,页面保持可见静止 >5 分钟,确认「当前位置」会自动变为不可用(无需任何点击/提交触发),即新增的 setTimeout(refreshLocationFreshness, expiresInMs + 1) 生效;再验证切到后台(onHide)或返回上级(onUnload)时计时器被清除、回到页面(onShow)按剩余时长重新调度,不会出现重复定时器。
  • 手动验证(快速规划不可达):以远离光明区的起点 + 步行 + 短时长提交,确认弹窗标题为「当前路线无法完成」并给出靠近光明区/延长时长/改用自选点位的引导文案;再用自选/推荐模式触发其它校验错误,确认仍走「暂时无法生成路线」通用分支(未被新分支误吞)。
  • 手动验证(records 兜底):构造 POI 仓库读取异常,确认顶部出现「开放点位暂时无法读取」错误块、「重新加载开放点位」按钮可恢复;并确认 storage 失败时积分/点位/徽章显示 --、相关分区按 v-if 正确隐藏。
## 🔍 审查结论 本次 PR 主体是「快速规划首站不可达」的错误语义化、定位新鲜度的主动计时器、打卡记录页的异常兜底,以及清理无用枚举/切换 appid。整体逻辑自洽,未发现必须修复的正确性缺陷。下面按严重程度分类。 ### 严重问题(必须修复) - 无。核心改动(`local-planner.ts` 的 throw、`isLocationSnapshotFresh`、planner 计时器生命周期、`records.vue` 兜底)经静态核验与现有测试覆盖均成立。 ### 建议改进 - **`src/manifest.json:49`(及配套 `project.config.json:27`)——直接改了生成产物里的 appid,存在下次构建即漂移的风险。** `manifest.config.ts:8,71` 的 appid 来自 `manifestEnv.UNI_MP_WEIXIN_APPID || 'touristappid'`,而仓库内 `.env` / `.env.development` / `.env.production` 均未设置该变量(`.env.example:2` 为空占位)。也就是说干净构建会生成 `appid: 'touristappid'`,与本次提交的 `wxda4fb5048b5dc9a1` 不一致——下一次任何人跑 `dev` 构建都会把这一行改回去或改成别的值,正好是本 PR 自己在 `README.md:10` 加的「不应单独保留由最后一次构建造成的前缀漂移」要避免的情形。README 也明确「不要直接修改这两个生成文件」。建议:appid 统一由本地 `UNI_MP_WEIXIN_APPID` 环境变量提供,让 `src/manifest.json` 由构建生成,而不是手改快照;`project.config.json`(IDE 工程文件,手维护)保留 appid 没问题。注意两文件若一处走构建、一处手改,后续会无声分裂。 - **`src/domain/travel/local-planner.ts:297-302` 的 throw 条件可读性可再收紧。** `selected.length === 0 && remaining.length > 0` 语义正确(首站在时长内放不下才进此分支;候选为空时 `remaining` 也为空,会落到 `createLocalPlan:543` 的兜底 `Error`),但「剩余 > 0」这一判断依赖读者理解 `remaining` 只会被 splice 掉已选点位。建议加一行注释说明「fitting 为空 → 首站即不可达」,与 `selectRecommendedPois:588-589` 的等价处理呼应(目前两处错误措辞不同,未来可考虑统一文案)。 - **`src/pages/check-in/records.vue:142-147` 的「重新加载开放点位」按钮直接绑 `loadAvailablePois`,不会顺带刷新 profile。** 这处单独重载点位是合理的(profile 与 POI 目录解耦),功能正确;仅提示:若希望「重载」一并复位整体状态,可考虑绑 `loadRecords`。当前实现可接受,属产品取舍。 - **`src/services/location/current-location.ts:8-23` 的 `isLocationSnapshotFresh` 默认参数 `checkedAt = Date.now()` 实际未被 planner 使用**(planner 总是显式传 `locationFreshnessCheckedAt.value`)。默认值作为独立工具函数的兜底是合理的,保留即可;仅提示存在「两套计时来源」的潜在混淆——目前 planner 走显式传参,没问题。 ### 测试与验证建议 - **跑测试套件**:`pnpm install && pnpm test`。本环境无 `node_modules`,`npx` 拉到 vitest 4.x 与项目 `vitest@^2.0.5`(`package.json:136`)不兼容,无法在此执行(属环境问题,非代码缺陷)。重点确认两个改动过的用例:`test/current-location.test.ts`(新鲜度边界:恰好 `maxAge` 为 fresh、`+1ms` 为 stale、未来时间/非法字符串为 false)与 `test/travel-assistant.test.ts`(quick 模式首站不可达时抛 `TravelValidationError` 且 `code === 'quick_route_unreachable'`)。 - **类型检查**:`pnpm run type-check`(vue-tsc),确认 `TravelValidationError.code` 新字段、`isLocationSnapshotFresh` 签名与 `planner/index.vue`、`records.vue` 的集成无类型回归。 - **手动验证(planner 计时器)**:定位成功后,页面保持可见静止 >5 分钟,确认「当前位置」会**自动**变为不可用(无需任何点击/提交触发),即新增的 `setTimeout(refreshLocationFreshness, expiresInMs + 1)` 生效;再验证切到后台(`onHide`)或返回上级(`onUnload`)时计时器被清除、回到页面(`onShow`)按剩余时长重新调度,不会出现重复定时器。 - **手动验证(快速规划不可达)**:以远离光明区的起点 + 步行 + 短时长提交,确认弹窗标题为「当前路线无法完成」并给出靠近光明区/延长时长/改用自选点位的引导文案;再用自选/推荐模式触发其它校验错误,确认仍走「暂时无法生成路线」通用分支(未被新分支误吞)。 - **手动验证(records 兜底)**:构造 POI 仓库读取异常,确认顶部出现「开放点位暂时无法读取」错误块、「重新加载开放点位」按钮可恢复;并确认 storage 失败时积分/点位/徽章显示 `--`、相关分区按 `v-if` 正确隐藏。
admin merged commit b1e0cae07a into main 2026-08-01 22:01:35 +08:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: team/gmTouringMiniApp#10