feat(template-07): 首页轮播图按后台配置的跳转类型跳转
轮播图原先只读 linkUrl 渲染 <a>,而后台「轮播图管理」的跳转是
linkType + linkUrl/linkTargetId 三元组:配「文章详情 / 产品详情」时
linkUrl 为空,前端拿不到地址,图片就渲染成不可点的纯 <img>,
运营配了也点不动。
- utils 新增 getBannerTarget():linkType 2 → /article/{id}、
3 → /product/{id}、1 → linkUrl;类型缺省但地址非空时按外链兜底
(兼容只存了地址的老数据);字段名兼容 link / linkUrl / link_url
- 新增 isExternalUrl():http(s)、//host、mailto 等视为站外
- getBannerLink() 保留为 getBannerTarget() 的薄封装,对外行为不变
- HeroSection:图片按目标渲染 NuxtLink(站内目标当前页跳转)/
<a target="_blank">(外链)/ 纯 <img>(未配置跳转,保持不可点)
- CmsBanner 补 linkType / linkUrl / linkTargetId 字段声明
首页 4 张图(政府采购代理 / 投融资服务 / AI数智化 / 工程代理)
已在后台配置为「产品详情」跳转。
This commit is contained in:
+55
-13
@@ -166,25 +166,67 @@ export function getNavLink(nav?: CmsNavigation | null): string {
|
||||
}
|
||||
|
||||
/**
|
||||
* 取轮播图(banner)点击跳转链接。
|
||||
* 判断链接是否需要「站外」打开(新标签页)。
|
||||
*
|
||||
* 兼容上游多种字段命名,避免「后台配了 link_url 但前端读不到」这类错位:
|
||||
* - link:本仓库 server/api/banner.get.ts 映射出的标准字段;
|
||||
* - linkUrl:CMS 原始返回字段(Java 把数据库列 link_url 序列化为驼峰 linkUrl);
|
||||
* - link_url:个别上游/老接口可能直接透传的蛇形字段名。
|
||||
* 仅当为非空字符串时才返回,否则返回 ''(调用方据此不渲染 <a>,避免空白可点区域)。
|
||||
* 站外判定:绝对地址(http://、https://)、协议相对地址(//host)
|
||||
* 以及 mailto: / tel: 等非路由协议;其余(含以 / 开头的站内路由)视为站内。
|
||||
*/
|
||||
export function isExternalUrl(url?: string | null): boolean {
|
||||
if (!url) return false
|
||||
const v = url.trim()
|
||||
if (!v) return false
|
||||
return /^([a-z][a-z0-9+.-]*:|\/\/)/i.test(v)
|
||||
}
|
||||
|
||||
/** 轮播图点击目标 */
|
||||
export interface BannerTarget {
|
||||
/** 跳转地址 */
|
||||
href: string
|
||||
/** true=站外(新标签页打开);false=站内路由(当前页跳转) */
|
||||
external: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析轮播图(banner)点击目标。
|
||||
*
|
||||
* 对齐后台「轮播图管理」的跳转配置(linkType + linkTargetId/linkUrl),
|
||||
* 同时兼容上游多种字段命名,避免「后台配了却点不动」:
|
||||
* - linkType=1(外链):取 linkUrl;
|
||||
* - linkType=2(文章详情):/article/{linkTargetId};
|
||||
* - linkType=3(产品详情):/product/{linkTargetId};
|
||||
* - linkType 缺省或为 0 但 linkUrl 非空:按外链兜底(兼容只存了地址的老数据)。
|
||||
*
|
||||
* 字段名兼容:link(本仓库 server/api/banner.get.ts 映射出的标准字段)、
|
||||
* linkUrl(Java 把 link_url 序列化为驼峰)、link_url(个别上游透传的蛇形字段)。
|
||||
*
|
||||
* @returns 跳转目标;返回 null 表示未配置跳转(调用方据此不渲染可点区域,避免空白可点)
|
||||
*/
|
||||
export function getBannerTarget(banner?: Partial<CmsBanner> | null): BannerTarget | null {
|
||||
if (!banner) return null
|
||||
|
||||
const type = Number(banner.linkType ?? 0) || 0
|
||||
const targetId = Number(banner.linkTargetId ?? 0) || 0
|
||||
if (type === 2 && targetId > 0) return { href: `/article/${targetId}`, external: false }
|
||||
if (type === 3 && targetId > 0) return { href: `/product/${targetId}`, external: false }
|
||||
|
||||
const raw = banner.link
|
||||
?? banner.linkUrl
|
||||
?? (banner as Record<string, unknown>).link_url
|
||||
?? ''
|
||||
const href = typeof raw === 'string' ? raw.trim() : ''
|
||||
if (!href) return null
|
||||
return { href, external: isExternalUrl(href) }
|
||||
}
|
||||
|
||||
/**
|
||||
* 取轮播图(banner)点击跳转链接(需要字符串地址的场景使用)。
|
||||
* 仅当后台配置了有效跳转(外链 / 文章 / 产品)时才返回非空字符串。
|
||||
*
|
||||
* @param banner 轮播图数据
|
||||
* @returns 跳转链接字符串;无效时返回 ''
|
||||
*/
|
||||
export function getBannerLink(banner?: Partial<CmsBanner> | null): string {
|
||||
if (!banner) return ''
|
||||
const raw =
|
||||
(banner as Record<string, unknown>).link
|
||||
?? (banner as Record<string, unknown>).linkUrl
|
||||
?? (banner as Record<string, unknown>).link_url
|
||||
?? ''
|
||||
return typeof raw === 'string' && raw.trim() ? raw.trim() : ''
|
||||
return getBannerTarget(banner)?.href ?? ''
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user