---
url: /docs/api-docs/v1/frontend/splash.md
---
# 前端联调 · 开机信息屏（splash.ts）

> 归属：[前端联调 API 手册](./) → `src/api/splash.ts`
> 端点：**2 个** · 路由前缀 `/api/v1/splash-screen`（**模块名是 `ad`，路由名不是**）
> 鉴权：**两个都免登录**（开屏在登录前展示）
> 错误码：本模块**不定义自己的错误码段** —— 异常复用 `user` 域码（`40301xxx`），见下
> 取值语义：**[取值速查 · splash](./values#splash)** —— `mediaType` / `linkType` / `notice.level` 各自的 DB 缺省值与前端表现、`event` 仅两值的约束、`forecast` 降级是 `[]` 不是 `null`

## 本页 curl 变量

```bash
BASE_URL=https://api.qingmulife.cn   # 本地：http://localhost:3000
ENV=Prd                              # Dev | Prd —— 全程必须一致
```

## 端点一览

| # | 方法 | 路径 | 场景 |
|---|---|---|---|
| [1](#getsplashscreen) | GET | `/api/v1/splash-screen` | 冷启动开屏：广告 + 实时天气 + 运营提醒 |
| [2](#tracksplashevent) | POST | `/api/v1/splash-screen/track` | 广告曝光 / 点击埋点（fire-and-forget） |

***

## getSplashScreen

**一句话**：开屏聚合数据 —— 一次拿广告 + 天气 + 提醒三块（**各块独立可 null**）。

### curl

```bash
curl -s "$BASE_URL/api/v1/splash-screen" \
  -H 'X-Env: Prd'
```

### 请求

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| — | — | — | **无入参、免登录** |

### 响应 `data`

顶层三块，**每块都可能是 `null`** —— 前端必须逐块判空：

| 字段 | 类型 | 可空 | 说明 |
|---|---|---|---|
| `ad` | object | **null** | **是** | 广告块 |
| `ad.id` | number | 是 | 广告 id —— `track` 要用 |
| `ad.imageUrl` | string | 是 | 图片 / 视频封面 URL |
| `ad.mediaType` | string | 是 | `'image'` | `'video'`（默认 `'image'`） |
| `ad.linkType` | string | 是 | `'none'` | `'webview'` |
| `ad.linkUrl` | string | null | 是 | `linkType='webview'` 时才有意义 |
| `weather` | object | **null** | **是** | 天气块 |
| `weather.city` / `.text` / `.icon` | string | 是 | 城市 / 天气文案 / 图标 |
| `weather.temperature` / `.feelsLike` / `.humidity` | number | 是 | int |
| `weather.forecast[]` | object\[] | 是 | `[{date, textDay, tempMax, tempMin, icon}]` —— **和风接口失败时降级为 `[]`（空数组，不是 null）** |
| `weather.updatedAt` | string ISO | 是 | 前端 `new Date` 格式化用 |
| `notice` | object | **null** | **是** | 运营提醒块 |
| `notice.title` / `.content` | string | 是 | |
| `notice.level` | string | 是 | `'info'` | `'warn'` |

> 📌 **信封**：本接口**手组信封**（`{"code":"0","msg":"ok","data":…}`）—— 前端类型只声明了 `{code, data}`，`msg` 未声明（不消费，无影响）。
> 📌 **天气 stub**：`.env` 未配 `QWEATHER` key 时走 stub（长沙数据），`forecast` 为空数组 —— 联调期看到长沙天气不是 bug。

### 错误码

**无业务错误码**（公开只读、异常一律降级为 null / 空数组）。服务不可用 → HTTP 5xx。

***

## trackSplashEvent

**一句话**：广告曝光 / 点击埋点 —— **fire-and-forget**，前端 `.catch(() => {})` 静默。

### curl

```bash
# 曝光
curl -s "$BASE_URL/api/v1/splash-screen/track" \
  -H 'Content-Type: application/json' \
  -H 'X-Env: Prd' \
  -d '{"adId":1,"event":"exposure"}'

# 点击
curl -s "$BASE_URL/api/v1/splash-screen/track" \
  -H 'Content-Type: application/json' \
  -H 'X-Env: Prd' \
  -d '{"adId":1,"event":"click"}'
```

### 请求

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `adId` | number | ✔ | 来自 `data.ad.id` |
| `event` | string | ✔ | **值域仅 `'exposure'` | `'click'`** —— 其他值 → 400 |
| `X-Env` | header | ✔ | 埋点也按库落 |

> 无 Authorization（免登录）。服务端另取 IP 与 `user-agent` 记录。

### 响应 `data`

| 字段 | 类型 | 可空 | 说明 |
|---|---|---|---|
| `data` | **`null`** | — | **恒 `null`**（固定信封 `{"code":"0","msg":"ok","data":null}`）—— 前端类型声明 `void`，忽略即可 |

### 错误码

⚠️ **本模块不定义错误码段** —— 业务异常抛的是 **`UserError`**，因此业务码落在 **user 段 `40301xxx`**：

| 业务码 | HTTP | 触发条件 | 前端建议处置 |
|---|---|---|---|
| `40301001` | 400 | `event` 非 `exposure`/`click`，或 body 非法 JSON | **静默**（埋点失败不影响 UI） |
| `40301004` | 404 | `adId` 对应的广告不存在 | **静默** |
