feat: add customer travel records and browse history

This commit is contained in:
duanshuwen
2026-08-27 14:19:03 +08:00
parent 0139fe6382
commit 6d9a546918
79 changed files with 12362 additions and 112 deletions

View File

@@ -91,6 +91,11 @@ MiniAPP 重点检查:
- Public API 失败时显示错误、重试或空态,并按现有本地 fallback 规则处理。
- 首页、玩法、路线详情、管家、团队共创和客片案例都由公共 API 层解包 `data`,页面不重复解包。
- `POST /api/public/leads` 的用车需求携带客户 JWT;后端从 JWT 写入 `customerId`,客户端不提交该字段。
- 登录后从“我的”进入“用车提交记录”和“历史浏览记录”两个入口;两个列表均使用 `z-paging` 的 `@query` 分页模式,并传递 `pageNum`、`pageSize`。
- 用车记录列表只显示当前客户数据,点击列表项进入只读详情;确认详情中的联系电话是脱敏值,点击“提交新的用车需求”仍进入 `/pages/vehicle-demand`。
- 历史记录列表点击 `wanfa-route`、`team-building`、`wild-archive` 分别进入既有路线、团队共创和客片案例详情;详情成功后检查浏览历史服务端去重更新,接口失败时检查本地缓存兜底。
- 客户记录接口返回 `401` 时清除本地客户会话并跳转登录;列表还需检查空态、网络错误重试、下拉刷新和加载更多。
- Admin UI 不新增浏览历史菜单;在“需求线索”中以 `leadType=vehicle` 查询刚提交的用车记录,确认详情弹窗、状态更新和车型快照仍可用。
## 接口变更流程
@@ -126,6 +131,8 @@ yarn build:h5
yarn build:mp-weixin
```
涉及客户记录接口时,先确认数据库已执行最新迁移 `0036_customer_browse_history`,再按“登录 → 我的 → 两个入口 → 分页 → 详情 → 返回刷新”的顺序联调。微信开发者工具中需分别验证 H5 和小程序不支持的图片格式不会被记录接口重新引入。
## 安全边界
- 不读取、展示或提交 `.env`、`.env.local` 和生产环境变量值。

View File

@@ -1,6 +1,6 @@
# WonderQ MiniAPP Public API
本文档是 `WonderQ-MiniAPP` 当前使用的 Public API 契约。接口提供站点内容、首页卡片、玩法展示、管家展示、登录和出行需求提交能力。
本文档是 `WonderQ-MiniAPP` 当前使用的 Public API 契约。接口提供站点内容、首页卡片、玩法展示、管家展示、登录、出行需求提交和客户记录查询能力。
## 基础约定
@@ -27,6 +27,10 @@
| `POST` | `/api/public/auth/phone-login` | 否 | 微信手机号登录 |
| `GET` | `/api/public/auth/me` | Customer JWT | 获取当前客户 |
| `POST` | `/api/public/leads` | 否 | 提交出行需求 |
| `GET` | `/api/public/customer/vehicle-demands` | Customer JWT | 查询当前客户的用车提交记录 |
| `GET` | `/api/public/customer/vehicle-demands/{leadId}` | Customer JWT | 查询当前客户的用车提交详情 |
| `POST` | `/api/public/customer/browse-history` | Customer JWT | 新增或更新浏览历史 |
| `GET` | `/api/public/customer/browse-history` | Customer JWT | 分页查询当前客户的浏览历史 |
## 站点配置
@@ -69,6 +73,67 @@ Public 响应只返回 `heroSlides` 和 `vehicleOptions` 的启用内容,其
服务端从 `vehicleDemand` 归一化 `destination`、`travelDate` 和 `peopleCount` 摘要字段。未登录、参数不完整或服务异常分别返回 `401`、`422`、`500`,失败时 `data` 为 `null`。
### 客户用车记录
用车记录接口只返回当前客户自己的 `leadType=vehicle` 记录,必须携带 `Authorization: Bearer <customer-jwt>`。`customerId` 由服务端从 JWT 获取,客户端不能传入或用查询参数覆盖。
列表接口使用 `pageNum` 和 `pageSize` 分页,`pageSize` 最大为 50,成功响应统一为:
```ts
type PageResult<T> = {
items: T[];
total: number;
pageNum: number;
pageSize: number;
};
```
`GET /api/public/customer/vehicle-demands` 的列表项和 `GET /api/public/customer/vehicle-demands/{leadId}` 的详情项使用以下展示字段:
```ts
type CustomerVehicleDemandRecord = {
id: string;
status: "new" | "assigned" | "contacted" | "planning" | "won" | "invalid";
contactName: string | null;
phoneMasked: string;
destination: string | null;
travelDate: string | null;
peopleCount: number | null;
note: string | null;
vehicleDemand: VehicleDemandPayload;
createdAt: string;
updatedAt: string;
};
```
手机号只返回 `phoneMasked`,不返回原始手机号。详情接口对不属于当前客户的 `leadId` 统一返回 `404`。
### 客户浏览历史
`POST /api/public/customer/browse-history` 只接收内容类型和内容 ID,服务端根据内容读取当前标题和图片并保存:
```json
{
"itemType": "wanfa-route",
"itemId": "route-uuid"
}
```
`itemType` 目前支持 `wanfa-route`、`team-building` 和 `wild-archive`。同一客户重复浏览同一内容时,服务端更新 `visitedAt`、标题和图片,不创建重复记录。成功响应为单条 `CustomerBrowseHistoryItem`;列表接口返回 `PageResult<CustomerBrowseHistoryItem>`:
```ts
type CustomerBrowseHistoryItem = {
id: string;
itemType: "wanfa-route" | "team-building" | "wild-archive";
itemId: string;
title: string;
image: string;
visitedAt: string;
};
```
详情页成功读取后由 MiniAPP 异步写入浏览历史;接口失败时继续保留本地历史缓存,浏览历史列表可以展示本地兜底内容。
## 玩法展示
### `GET /api/public/wanfa/categories`