From 87cf7dfbaab24df89c26ee743000a2370a56b350 Mon Sep 17 00:00:00 2001 From: zoujing Date: Thu, 17 Sep 2026 11:37:49 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BF=AE=E5=A4=8D=E4=BA=8C=E7=BA=A7?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E5=A4=B4=E5=9B=BE=E5=B1=95=E7=A4=BA=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/content.js | 33 +++++---- src/components/BenefitCard/index.vue | 42 ++++------- src/components/ContentCard/index.vue | 20 ++---- src/pages-sub/detail/index.vue | 102 +++++++-------------------- 4 files changed, 67 insertions(+), 130 deletions(-) diff --git a/src/api/content.js b/src/api/content.js index fc58229..93b6b48 100644 --- a/src/api/content.js +++ b/src/api/content.js @@ -34,27 +34,34 @@ const buildGroups = (section) => { }); }; -/** 板块列表(4 个);coverImage 缺失时用该板块首个条目的主图(只读字段,不拼路径) */ -export const getSections = async () => { - if (!USE_MOCK_CONTENT) return contentApi.fetchSections(); - return clone( - sectionsMock.map((section) => { - if (section.coverImage) return section; - const firstGroup = (catalogMock[section.collections[0]] || [])[0]; - const firstId = firstGroup?.item_ids?.[0]; - return { ...section, coverImage: itemsMock[firstId]?.main_image_url || "" }; - }) - ); +/** + * 板块封面兜底:`coverImage` 缺失时取该板块**首个分组首个条目**的主图(只读字段,不拼路径)。 + * + * ⚠️ 兜底必须抽出来给 `getSections` 与 `getSection` **共用**:两处口径一旦不一致,就会出现 + * 「首页板块卡有图、点进板块列表页头图空白」—— `sections.json` 里只有 `tourism` 自带 + * `coverImage`,`lodging` / `food` / `specialties` 三个都没这个字段。 + */ +const withCoverFallback = (section) => { + if (!section || section.coverImage) return section; + const firstGroup = (catalogMock[section.collections[0]] || [])[0]; + const firstId = firstGroup?.item_ids?.[0]; + return { ...section, coverImage: itemsMock[firstId]?.main_image_url || "" }; }; -/** 板块详情:定义 + 分组(含条目)+ 素材 */ +/** 板块列表(4 个) */ +export const getSections = async () => { + if (!USE_MOCK_CONTENT) return contentApi.fetchSections(); + return clone(sectionsMock.map(withCoverFallback)); +}; + +/** 板块详情:定义 + 分组(含条目)+ 素材;封面同样走兜底,供列表页头图使用 */ export const getSection = async (sectionKey) => { if (!USE_MOCK_CONTENT) return contentApi.fetchSection(sectionKey); const section = sectionsMock.find((s) => s.key === sectionKey); if (!section) return null; const groups = buildGroups(section); const supportAssets = (assetsMock || []).filter((a) => section.supportAssetIds.includes(a.entity_id)); - return clone({ ...section, groups, supportAssets }); + return clone({ ...withCoverFallback(section), groups, supportAssets }); }; /** 条目详情 */ diff --git a/src/components/BenefitCard/index.vue b/src/components/BenefitCard/index.vue index 463047b..ece8e48 100644 --- a/src/components/BenefitCard/index.vue +++ b/src/components/BenefitCard/index.vue @@ -105,12 +105,8 @@ const onTap = () => {