BUG-004 已按你的要求修好,修改总结如下。 --- ## 根因 - 后端详情接口 **只接受 Long 类型 id**(`ToolController#getFoodDetail(Long id)`)。 - 列表里部分条目没有 `id`,`food-encyclopedia` 用 `item.name` 当 id 传,例如 `id=羊肉(熟)`,后端报 `NumberFormatException`,请求失败,页面只弹出「数据加载失败」且内容空白。 --- ## 修改说明 ### 1. `msh_single_uniapp/pages/tool/food-encyclopedia.vue` - **只传数字 id**:仅在 `item.id` 为有效数字时拼进 `id` 参数;否则不传 `id`,避免把名称当 id 传给后端。 - **始终传 name**:跳转时带上 `name`(有则 `id=xxx&name=xxx`,无 id 则只传 `name=xxx`),详情页在失败或无 id 时用 name 展示。 ### 2. `msh_single_uniapp/pages/tool/food-detail.vue` - **入参与日志** - 使用 `pageParams: { id, name }` 保存入参。 - `onLoad` 里打印:`console.log('[food-detail] onLoad params:', this.pageParams)`。 - `loadFoodData` 里打印:`console.log('[food-detail] getFoodDetail request param:', { id, type: typeof id })`。 - **只对数字 id 调接口** - 仅当 `options.id` 能解析为数字时才调用 `loadFoodData(Number(options.id))`。 - 仅有 `options.name` 时:不请求接口,直接 `loadError = '暂无该食物详情数据,展示参考数据'`,用 `applyDefaultFoodData(false)` 填充,并把 `foodData.name` 设为解码后的 `options.name`。 - **API 失败时(catch)** - **a.** `loadError = errMsg`(具体错误信息,便于调试)。 - **b.** `applyDefaultFoodData(false)`,用 `defaultFoodData` 填满页面,保证有名称、分类、关键营养、营养成分表等。 - **c.** 若有 `pageParams.name`,用其覆盖 `foodData.name`,避免显示默认「五谷香」。 - 再 `showToast('数据加载失败')`。 - `loadError` 有值时,页面顶部已有「当前数据来自缓存,可能不是最新」的提示(原有 `v-if="loadError"` 的 `.cache-notice`)。 - **保证列表能渲染** - `applyDefaultFoodData` 中保证 `name/category/safetyTag/image` 有默认值,`keyNutrients`、`nutritionTable` 用 `defaultFoodData` 的非空数组拷贝,确保 `.food-name-overlay`、`.nutrient-card`、`.nutrition-row` 在默认数据下也能正常渲染。 - 成功拿到 API 数据时,用 `ensureNonEmptyArray(parseKeyNutrients(data), defaultFoodData.keyNutrients)` 等,避免解析出空数组导致列表为空。 --- 效果简述: - 列表点有**数字 id** 的条目:正常请求详情并展示;失败时用默认数据 + 入参 name(若有)+ 缓存提示 + Toast。 - 列表点**无 id、只有 name** 的条目:不请求接口,直接展示默认数据 + 该 name + 缓存提示,不再报错或空白。 - 控制台可看到 `onLoad params` 和 `getFoodDetail request param`,便于确认传参是否正确。