Skip to content

开机信息屏(前端调用视角 · 2 端点) ​

本文只回答「哪个页面在什么时机调、响应从哪一层读、失败时前端做什么」。 字段类型 / 可空 / 错误码码值 / curl 一律见 前端联调 API 手册 · splash —— 本文零复述(分工边界见 总览)。 封装:src/api/splash.ts · 消费:页面直调(无 api 层收敛)src/pages/splash/index.vue —— 应用启动页(pages.json 第一项)。 两个端点都免登录(auth: 'none'):无 token 不会被拦(生产实测:聚合端点 200;上报端点缺 body 时是 400 参数校验,不是鉴权拦截)—— 开机屏因此先于登录态渲染。

调用链总览 ​

App 启动 → pages/splash/index(启动页)
   onMounted ──► getSplashScreen(GET,免登录,一次拿全:广告 + 天气 + 提醒)
        ├─ ad 为空 / 无 imageUrl ──► 直接 goNext()(不展示开机屏)
        └─ 有广告 ──► 渲染背景 + 天气卡 + 提醒条 → trackSplashEvent(adId,'exposure') 曝光一次
                    → 5s 倒计时 / 点「跳过」→ goNext()(有 token → 首页 tab,无 → 登录页)
   点广告(仅 linkType==='webview' 且有 linkUrl)──► trackSplashEvent(adId,'click') → navigateTo webview

一、getSplashScreen(页面直调 · 启动页) ​

端点:GET /api/v1/splash-screen(聚合,一次返回三块)

一句话:启动页 onMounted 拉一次聚合数据 —— 决定「展示开机屏」还是「立刻进主流程」。

前端函数签名

项值
封装src/api/splash.ts:46-47 → getSplashScreen();实际消费在 src/pages/splash/index.vue:102-125
触发时机启动页 onMounted —— 每次冷启动一次,页面内不刷新
鉴权none(公开)

必需 payload 键

键从哪来必填
(无)该端点是 GET,无 body;request 层会自动补一个时间戳参数防缓存✔ 自动

响应读法(⚠️ 三块各自独立可空 —— 缺哪块只是那块 UI 不渲染,不是"整体失败")

ts
const res: any = await getSplashScreen();
const d = res?.data ?? {};              // 中文注解:request 不解包 —— 三块都在 res.data 之下
if (!d.ad || !d.ad.imageUrl) return goNext();   // 中文注解:没有可展示的广告 = 不显示开机屏,直接进主流程
ad.value       = d.ad;
weather.value  = d.weather;             // 中文注解:可能为 null → 天气卡整块 v-if 不渲染
notice.value   = d.notice;              // 中文注解:可能为 null → 提醒条整块不渲染
forecast.value = Array.isArray(d.weather?.forecast) ? d.weather.forecast : [];   // 中文注解:预报失败时后端给 [],前端再兜一层
路径(以上代码里 d 的位置)含义
ad.id广告 id —— 曝光/点击上报要用它
ad.imageUrl素材地址(图片直显;视频时是视频源,见坑位)
ad.mediaType'image' / 'video' —— 页面按它分支渲染(index.vue:5)
ad.linkType / ad.linkUrl'none' / 'webview' + 落地页;仅 webview 且 URL 非空才可点
weather.city / .text / .icon / .temperature天气卡主信息(.icon 是字符图标,直接 渲染)
weather.feelsLike / .humidity体感 / 湿度(当前页面未展示,可扩展)
weather.forecast[]逐日预报(date / textDay / tempMin / tempMax / icon)—— 可能为空数组
weather.updatedAt「HH:mm 更新」的取数源(ISO;页面本地格式化,解析失败则不显示)
notice.title / .content / .level提醒条文案 + 级别('info' / 'warn' → 页面按级别换配色)

失败时的前端动作

情形前端动作
任意失败(网络 / 5xx / 无广告)catch 内 静默 goNext() —— 启动页绝不因接口失败卡住用户

⚠️ 坑位

  • forecast 的日期标签是"错位"的:页面把数组第 0 项标成「明天」、第 1 项「后天」(fcLabel(date, i)),所以不要假设 forecast[0] 是今天。
  • 视频广告走视图层,不是逻辑层:mediaType === 'video' 时用 renderjs 在视图层 webview 播 H5 <video>(逻辑层无 DOM)—— 见 index.vue:12-17。改这段前先读该文件注释,别用普通 <video> 组件替换。
  • weather 块的 stub 口径:和风 key 未配置时后端给长沙 stub 数据 + 空 forecast;联调看到"天气永远是长沙"先查 key,不是前端问题。
  • 页面「跳过」按钮 5 秒倒计时;goNext() 的落点由 storage.token 有无决定(有 → 首页 tab,无 → 登录页)—— 这是启动页唯一的登录态判断点,别在别处再判一次。

二、trackSplashEvent(页面直调 · 埋点) ​

端点:POST /api/v1/splash-screen/track(裸 body,不是 {action, payload} 协议)

一句话:广告曝光/点击上报 —— fire-and-forget,失败静默,绝不影响主流程。

前端函数签名

项值
封装src/api/splash.ts:49-57 → trackSplashEvent(adId, event);返回 void,内部 .catch(() => {})
触发时机① 曝光:开机屏渲染完广告后一次(reported 标志位防重)② 点击:用户点带 webview 链接的广告时
鉴权none(公开)

必需 payload 键

键从哪来必填
adIdad.id(曝光/点击都用同一个)✔
event字面量 'exposure' / 'click'(值域外会被后端拒)✔

响应读法

ts
trackSplashEvent(ad.value.id, 'exposure');
// 中文注解:不 await、不读 data(该端点 data 恒为 null);失败也无人处理 —— 埋点丢了就丢了

失败时的前端动作

情形前端动作
任意失败(含 400 / 404)无动作(.catch(() => {}) 吞掉)—— 埋点不影响广告展示与跳转

⚠️ 坑位

  • 点击上报与跳转的顺序:先上报再 navigateTo(同一次点击里同步发出,不等响应)。
  • 曝光只在"真的有广告要展示"时上报:reportExposure() 先判 ad.value 非空 —— 无广告直接进主流程时没有曝光事件,统计口径要按此理解。

后端链接 ​

  • 契约(权威):手册 · splash —— 该端点是「页面直调」而非 api 层封装,字段与错误码一律以手册为准
  • 相邻的免登录端点:用户协议· 登录链(同为启动后第一批调用)api/oauth