完成用户红框指定的 4 个「入住运营」报表页面(参考同级菜单页 + 自设计后端接口):
occupancy/moveout-reason/index.vue(上一轮已完成)
occupancy/trial-conversion/index.vue
occupancy/waiting-analysis/index.vue
occupancy/contract-expiry/index.vue
days[]);KPI(30/60/90天内到期 + 已逾期) + 到期分布饼 + 未来月度趋势线 + 合同到期明细(分页, 剩余天数彩色 tag) + 导出occupancy/occupancy-api.ts:新增 4 个接口函数 fetchMoveoutAnalysis/fetchTrialConversion/fetchWaitingAnalysis/fetchContractExpiry + 全部 TS 接口 + mock 数据兜底(catch 返回演示数据并 console.warn,后端上线后删除)。统一 buildQuery 手动拼重复键(tenantIds=1&tenantIds=2),因后端 List 不接受 qs indices。occupancy/入住运营二期-设计与后端接口需求.md(4 个接口契约 + 权限建议)。utils/routerHelper.ts 用 import.meta.glob('../views/**/*.{vue,tsx}') 自动加载,后端菜单配组件路径即可。vue-tsc --noEmit 在本沙箱因 OOM(退出134/崩溃) 跑不完(项目大);改用 esbuild transform 对 5 个文件逐一对 <script> 做 TS 语法校验,发现并修复 1 个真实 bug:
moveout-reason/index.vue:156 fmtDate 模板字符串缺少闭合反引号(上一轮创建时漏写),导致该反引号一路吞掉后续代码直到 line 299 的下一个反引号、整段脚本解析失败。已补上 \}`。ALL SYNTAX OK。新页面其余沿用已验证的同款 KPI/图表/导出模式。本地可用 npm run ts:check 做完整类型复核。用户 09-29 截图反馈「退住原因与平均入住周期」「轮候长者分析」仍显示占位组件。经排查:
component 字段仍指向 operation-analysis/components/ReportPlaceholder,未切换到新页面组件。src/utils/routerHelper.ts 的 import.meta.glob('../views/**/*.{vue,tsx}') 自动扫描;只要后端菜单更新 component 为新页面路径即可渲染。建议后端菜单更新:
operation-analysis/occupancy/moveout-reason/indexoperation-analysis/occupancy/trial-conversion/indexoperation-analysis/occupancy/waiting-analysis/indexoperation-analysis/occupancy/contract-expiry/index若后端菜单不填 component,前端会按 route.path 自动匹配文件路径。
用户反馈 4 个新页面中另外 2 个已能正常展示,但退住/轮候仍显示占位图。结合 generateRoute 逻辑,原因大概率是:
component 为空,URL path 恰好与文件目录同名,前端自动通过 path 找到组件。component 被显式填成了 operation-analysis/components/ReportPlaceholder(或其他不匹配路径),导致强制渲染占位组件。最稳做法:把 4 个页面的 component 统一改成文件对应路径(见上方表格),不依赖 path 自动匹配,避免命名不一致导致部分失败。