zhouruizhe
main
本次 PR 主体是「快速规划首站不可达」的错误语义化、定位新鲜度的主动计时器、打卡记录页的异常兜底,以及清理无用枚举/切换 appid。整体逻辑自洽,未发现必须修复的正确性缺陷。下面按严重程度分类。
local-planner.ts
isLocationSnapshotFresh
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/manifest.json:49
project.config.json:27
manifest.config.ts:8,71
manifestEnv.UNI_MP_WEIXIN_APPID || 'touristappid'
.env
.env.development
.env.production
.env.example:2
appid: 'touristappid'
wxda4fb5048b5dc9a1
dev
README.md:10
UNI_MP_WEIXIN_APPID
src/manifest.json
project.config.json
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/domain/travel/local-planner.ts:297-302
selected.length === 0 && remaining.length > 0
remaining
createLocalPlan:543
Error
selectRecommendedPois:588-589
src/pages/check-in/records.vue:142-147 的「重新加载开放点位」按钮直接绑 loadAvailablePois,不会顺带刷新 profile。 这处单独重载点位是合理的(profile 与 POI 目录解耦),功能正确;仅提示:若希望「重载」一并复位整体状态,可考虑绑 loadRecords。当前实现可接受,属产品取舍。
src/pages/check-in/records.vue:142-147
loadAvailablePois
loadRecords
src/services/location/current-location.ts:8-23 的 isLocationSnapshotFresh 默认参数 checkedAt = Date.now() 实际未被 planner 使用(planner 总是显式传 locationFreshnessCheckedAt.value)。默认值作为独立工具函数的兜底是合理的,保留即可;仅提示存在「两套计时来源」的潜在混淆——目前 planner 走显式传参,没问题。
src/services/location/current-location.ts:8-23
checkedAt = Date.now()
locationFreshnessCheckedAt.value
pnpm install && pnpm test
node_modules
npx
vitest@^2.0.5
package.json:136
test/current-location.test.ts
maxAge
+1ms
test/travel-assistant.test.ts
TravelValidationError
code === 'quick_route_unreachable'
pnpm run type-check
TravelValidationError.code
planner/index.vue
setTimeout(refreshLocationFreshness, expiresInMs + 1)
onHide
onUnload
onShow
--
v-if
No dependencies set.
The note is not visible to the blocked user.
🔍 审查结论
本次 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的集成无类型回归。setTimeout(refreshLocationFreshness, expiresInMs + 1)生效;再验证切到后台(onHide)或返回上级(onUnload)时计时器被清除、回到页面(onShow)按剩余时长重新调度,不会出现重复定时器。--、相关分区按v-if正确隐藏。