topfans/docs/API_CALLS_SUMMARY.md
2026-04-07 22:28:50 +08:00

367 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# TopFans Frontend 接口调用总览
> 范围:`frontend` 源码(排除 `unpackage/dist` 编译产物)。
## 1. 请求基础设施
- **统一入口**`frontend/utils/api.js` 的 `request(options)`,底层使用 `uni.request`
- **Base URL**`http://101.132.250.62:8080`(硬编码)。
- **鉴权注入**
- 登录/注册接口(`/api/v1/auth/login`、`/api/v1/auth/register`)不注入 token。
- 其余接口自动从 `uni.getStorageSync('access_token')` 注入 `Authorization: Bearer <token>`
- **统一响应解析**
- HTTP `401`:清理 `access_token`/`user``reLaunch` 到登录页,`reject(Error('登录已过期,请重新登录'))`。
- HTTP `200` 且有 `res.data.code`
- `code === 200``resolve(res.data)`。
- `code === 401/400/403`:同样清会话并跳登录。
- 其他业务码:`reject(Error(res.data.message || '请求失败'))`。
- 其他 HTTP 状态:`reject(Error(res.data?.message || 请求失败(statusCode)))`。
- **超时/重试**:未设置统一 `timeout`,无自动重试机制。
---
## 2. API 清单(函数名 / 参数 / 响应解析 / 用途)
### 2.1 认证与账号
#### `loginApi(mobile, password)`
- **Method/Path**`POST /api/v1/auth/login`
- **参数**`{ mobile, password }`
- **调用位置**
- `store/modules/user.js` -> `actions.login`
- `pages/login/login.vue` -> `handleLogin`(触发 `store.dispatch('user/login')`
- **响应解析**
- `res.code === 200 && res.data` 成功。
- 读取 `res.data.access_token`、`res.data.user` 写入本地缓存与 store。
-`user.avatar_url` 存在,继续调用 `getOssPresignedUrlApi``res.data.url` 并本地缓存头像。
- **用途**登录并初始化会话token、用户信息、头像缓存
#### `registerApi(mobile, password, star_id, nickname)`
- **Method/Path**`POST /api/v1/auth/register`
- **参数**`{ mobile, password, star_id, nickname }`
- **调用位置**
- `store/modules/user.js` -> `actions.register`
- `pages/profile/selectRole.vue` -> `handleNext`(触发 `store.dispatch('user/register')`
- **响应解析**
- 成功同登录流程:读取 `access_token``user`,并尝试头像预缓存。
-`409`(昵称冲突)做显式分支,向上抛 `{ code: 409, message }`
- **用途**:注册并建立登录态。
#### `getUserProfileApi()`
- **Method/Path**`GET /api/v1/auth/me`
- **参数**:无
- **调用位置**
- `pages/profile/profile.vue` -> `fetchUserInfo`
- **响应解析**
- 读取 `res.data` 字段:`uid`、`nickname`、`avatar_url`、`current_identity`、`assets_num`、`slot_limit`、`starbook_limit`、`blockchain_address` 等。
- 页面侧将 `current_identity` 转换为缓存结构 `fan_identity`,并回写本地 `user`
- **用途**:个人中心刷新用户主数据(以服务端为准)。
#### `updateNicknameApi(nickname)`
- **Method/Path**`PUT /api/v1/me/nickname`
- **参数**`{ nickname }`
- **调用位置**
- `pages/profile/profile.vue` -> `confirmChangeNickname`
- **响应解析**:检查 `res.code === 200` 后触发 `fetchUserInfo(true)` 全量刷新。
- **用途**:修改当前身份昵称。
#### `updatePasswordApi(oldPassword, newPassword)`
- **Method/Path**`POST /api/v1/account/password`
- **参数**`{ old_password, new_password }`
- **调用位置**
- `pages/profile/profile.vue` -> `confirmChangePassword`
- **响应解析**`res.code === 200` 后提示成功并强制登出、清缓存、跳登录页。
- **用途**:密码修改与会话重置。
#### `deleteAccountApi()`
- **Method/Path**`POST /api/user/delete-account`
- **参数**:无
- **调用位置**
- `pages/profile/profile.vue` -> `confirmDeleteAccount`
- **响应解析**`result.code === 200` 后执行登出流程并跳登录页。
- **用途**:注销账号。
#### `updateUserInfoApi(nickname)`
- **Method/Path**`POST /api/user/update`
- **参数**`{ nickname }`
- **调用位置**:当前源码未发现调用。
- **用途**:历史/预留接口(当前未接入)。
---
### 2.2 社交(好友关系)
#### `friendListApi(page = 1, pageSize = 10)`
- **Method/Path**`GET /api/v1/social/friends?page={page}&page_size={pageSize}`
- **参数**:分页参数
- **调用位置**
- `pages/components/FriendsContent.vue` -> `loadFriendList`
- **响应解析**
- 读取 `res.data.items`、`res.data.total`。
- 字段映射:`friend_id -> user_id``friend_nickname -> nickname``friend_fan_level -> fan_level``friend_avatar -> avatar_url`。
- 头像会再经 `getFriendAvatarRealUrl()``getOssPresignedUrlApi` 转真实 URL。
- **用途**:好友列表页及分页加载。
#### `searchUserApi(friendUserId)`
- **Method/Path**`GET /api/v1/social/search-user?friend_user_id={friendUserId}`
- **参数**:目标用户 IDUID
- **调用位置**
- `pages/components/FriendsContent.vue` -> `watch(searchUid, ...)` 防抖回调
- **响应解析**
- 成功读取 `res.data` 并解析 `res.data.avatar_url` 为预签名 URL。
- 失败时对 `404` 走“用户不存在”分支。
- **用途**:按 UID 搜索可添加的用户。
#### `sendFriendRequestApi(friendUserId)`
- **Method/Path**`POST /api/v1/social/friend-requests`
- **参数**`{ friend_user_id }`
- **调用位置**
- `pages/components/FriendsContent.vue` -> `confirmAddFriend`
- **响应解析**:调用成功后刷新“已发送请求”列表。
- **用途**:发送好友申请。
#### `getSentFriendRequestsApi(page = 1, pageSize = 10)`
- **Method/Path**`GET /api/v1/social/friend-requests?type=sent&status=pending&page={page}&page_size={pageSize}`
- **参数**:分页参数
- **调用位置**
- `pages/components/FriendsContent.vue` -> `fetchSentRequests`
- **响应解析**
- 读取 `res.data.items`
- 解析 `to_user_avatar_url` 为预签名 URL 后渲染。
- **用途**:我的已发送申请列表。
#### `getReceivedFriendRequestsApi(page = 1, pageSize = 10)`
- **Method/Path**`GET /api/v1/social/friend-requests?type=received&status=pending&page={page}&page_size={pageSize}`
- **参数**:分页参数
- **调用位置**
- `pages/components/FriendsContent.vue` -> `loadReceivedRequests`
- **响应解析**
- 读取 `res.data.items` 分页追加。
- 解析 `from_user_avatar_url` 为预签名 URL。
- **用途**:收到的好友请求列表。
#### `handleFriendRequestApi(requestId, action)`
- **Method/Path**`POST /api/v1/social/friend-requests/handle`
- **参数**`{ request_id, action }``action ∈ {accept, reject}`
- **调用位置**
- `pages/components/FriendsContent.vue` -> `handleAcceptRequest`
- `pages/components/FriendsContent.vue` -> `handleRejectRequest`
- **响应解析**:成功后本地移除对应请求项。
- **用途**:接受/拒绝好友请求。
#### `deleteFriendApi(friendUserId)`
- **Method/Path**`DELETE /api/v1/social/friends`
- **参数**`{ friend_user_id }`
- **调用位置**
- `pages/components/FriendsContent.vue` -> `confirmDeleteFriend`
- **响应解析**:成功后本地删除好友项并更新计数。
- **用途**:解除好友关系。
---
### 2.3 身份(粉丝身份)
#### `getFanIdentitiesApi()`
- **Method/Path**`GET /api/v1/fan-identities`
- **参数**:无
- **调用位置**
- `pages/profile/profile.vue` -> `handleSwitchRole`
- **响应解析**:读取 `res.data.items` 作为可选明星列表。
- **用途**:拉取可新增的粉丝身份候选。
#### `addFanIdentityApi(starId, nickname)`
- **Method/Path**`POST /api/v1/my/fan-identities`
- **参数**`{ star_id, nickname }`
- **调用位置**
- `pages/profile/profile.vue` -> `confirmAddIdentity`
- **响应解析**`res.code === 200` 后刷新用户信息。
- **用途**:新增某明星身份。
#### `getMyFanIdentitiesApi()`
- **Method/Path**`GET /api/v1/my/fan-identities`
- **参数**:无
- **调用位置**
- `pages/profile/profile.vue` -> `handleFanTagClick`
- **响应解析**:读取 `res.data.items``res.data.current_star_id`
- **用途**:身份切换前加载身份列表与当前身份。
#### `switchFanIdentityApi(newStarId)`
- **Method/Path**`POST /api/v1/my/fan-identities/switch`
- **参数**`{ new_star_id }`
- **调用位置**
- `pages/profile/profile.vue` -> `handleSwitchIdentity`
- **响应解析**
- 读取 `res.data.access_token` 覆盖本地 token。
- 读取 `res.data.current_identity``identity_id`、`identity_name`、`tag`、`level`)刷新 UI 与缓存。
- **用途**:切换当前生效身份并刷新会话上下文。
---
### 2.4 资产/NFT星册、详情、点赞
#### `getMyAssetsApi(page = 1, pageSize = 20)`
- **Method/Path**`GET /api/v1/assets/me/items?page={page}&page_size={pageSize}`
- **参数**:分页参数
- **调用位置**
- `pages/components/StarbookContent.vue` -> `loadAssetsList`
- `pages/exhibition/exhibition.vue` -> `handleAddAssetClick`
- **响应解析**
- 读取 `response.data.items`
- 常用字段:`asset_id`、`name`、`cover_url`、`tx_hash`、`like_count`、`status`。
- `cover_url` 会通过 `getAssetCoverRealUrl()` -> `getOssPresignedUrlApi(type=asset)` 转真实访问 URL。
- **用途**:我的藏品列表(星册页、展馆上架弹窗)。
#### `getAssetDetailApi(assetId)`
- **Method/Path**`GET /api/v1/assets/{assetId}`
- **参数**`assetId`
- **调用位置**
- `pages/components/StarbookContent.vue` -> `handleCardClick`
- `pages/exhibition/exhibition.vue` -> `handleNftClick`
- **响应解析**
- 读取 `response.data.asset` 作为详情对象。
- 点赞态兼容读取:`asset.is_liked`,部分调用还兜底 `response.data.is_liked`
- **用途**:点击藏品卡片时拉取完整详情。
#### `likeAssetApi(assetId)`
- **Method/Path**`POST /api/v1/social/assets/{assetId}/like`
- **参数**`assetId`
- **调用位置**
- `pages/components/NftDetailModal.vue` -> `handleLike`(点赞分支)
- **响应解析**`response.code === 200` 后本地 `isLiked=true`、`likeCount+1`。
- **用途**:点赞藏品。
#### `unlikeAssetApi(assetId)`
- **Method/Path**`DELETE /api/v1/social/assets/{assetId}/like`
- **参数**`assetId`
- **调用位置**
- `pages/components/NftDetailModal.vue` -> `handleLike`(取消点赞分支)
- **响应解析**`response.code === 200` 后本地 `isLiked=false`、`likeCount-1`。
- **用途**:取消点赞。
---
### 2.5 展馆(槽位、上架、下架)
#### `getMyGalleriesApi()`
- **Method/Path**`GET /api/v1/mygalleries`
- **参数**:无
- **调用位置**
- `pages/exhibition/exhibition.vue` -> `loadGallerySlots``isMyGallery === true` 分支)
- **响应解析**
- 读取 `response.data.gallery_owner_id`、`response.data.slots`。
- `slots``visibility(public/private)` 分板,并读取 `slot.asset``asset_id`、`cover_url`、`like_count`、`remain_time` 等)。
- **用途**:加载当前用户展馆槽位状态。
#### `getUserGalleriesApi(targetUid)`
- **Method/Path**`GET /api/v1/galleries/{targetUid}`
- **参数**:目标用户 UID
- **调用位置**
- `pages/exhibition/exhibition.vue` -> `loadGallerySlots``isMyGallery === false` 分支)
- **响应解析**:与 `getMyGalleriesApi` 同结构解析。
- **用途**:加载目标用户展馆。
#### `placeAssetToGalleryApi(assetId, galleryOwnerId, slotId)`
- **Method/Path**`POST /api/v1/galleries/place`
- **参数**`{ asset_id, gallery_owner_id, slot_id }`
- **调用位置**
- `pages/exhibition/exhibition.vue` -> `confirmPlaceAsset`
- **响应解析**`response.code === 200` 后关闭弹窗并重新拉取槽位数据。
- **用途**:上架藏品到指定展位槽位。
#### `removeAssetFromGalleryApi(slotId)`
- **Method/Path**`DELETE /api/v1/galleries/slots/{slotId}/asset`
- **参数**`slotId`
- **调用位置**
- `pages/exhibition/exhibition.vue` -> `confirmRemoveAsset`
- **响应解析**`response.code === 200` 后刷新展馆槽位。
- **用途**:下架槽位中的藏品。
---
### 2.6 OSS上传签名 / 预签名读取 / 头像更新)
#### `getOssSignatureApi(type)`
- **Method/Path**`GET /api/v1/assets/oss/signature?type={type}`
- **参数**`type`(实际使用:`avatar`、`asset`
- **调用位置**
- `pages/profile/profile.vue` -> `uploadAvatarToOss``type='avatar'`
- `pages/components/CastloveContent.vue` -> `uploadImageToOss``type='asset'`
- **响应解析**
- 头像上传与素材上传都会读取:
- `host`, `dir`, `policy`, `x_oss_credential`, `x_oss_date`, `security_token`, `signature`, `x_oss_signature_version`
- `type=asset` 时额外读取 `signRes.data.order_id`(铸造订单草稿 ID
- **用途**:向 OSS 直传前获取签名凭证。
#### `getOssPresignedUrlApi(fileName, expires = 3600, type = 'avatar')`
- **Method/Path**`GET /api/v1/assets/oss/presigned-url?file_name={encodeURIComponent(fileName)}&expires={expires}&type={type}`
- **参数**:文件名/路径、有效期、类型
- **调用位置**
- `store/modules/user.js` -> `actions.login`、`actions.register`
- `pages/profile/profile.vue` -> `handleAvatarUpdateSuccess`
- `pages/components/Avatar.vue` -> `fetchOwnAvatarWithCache`
- `utils/assetImageHelper.js` -> `getAssetCoverRealUrl`、`getFriendAvatarRealUrl`
- **响应解析**:通用读取 `res.data.url`;失败时回退默认图或空值。
- **用途**:将 OSS 对象标识转换为可读 URL头像、藏品封面
#### `updateAvatarApi(avatarUrl)`
- **Method/Path**`PUT /api/v1/me/avatar`
- **参数**`{ avatar_url }`
- **调用位置**
- `pages/profile/profile.vue` -> `uploadAvatarToOss`OSS 上传成功后)
- **响应解析**`updateRes.code === 200` 后更新本地 user 缓存、触发 `avatarUpdated` 事件并刷新组件。
- **用途**:头像上传成功后回写用户头像地址。
---
### 2.7 铸造Castlove
#### `createMintOrderApi(orderData)`
- **Method/Path**`POST /api/v1/assets/mints`
- **参数**`orderData`(页面构造字段)
- `name`, `event`, `description`, `material_type`, `material_url`, `rarity`, `tags`, `order_id`
- **调用位置**
- `pages/components/CastloveContent.vue` -> `handleConfirm`
- **响应解析**`response.code === 200` 后视为铸造成功,保存临时展示数据并跳转成功页。
- **用途**:提交铸造订单。
#### `deleteMintOrderApi(orderId)`
- **Method/Path**`DELETE /api/v1/assets/mints/{orderId}`
- **参数**`orderId`
- **调用位置**
- `pages/components/CastloveContent.vue` -> `handleBack`(用户确认返回时清理未完成订单)
- **响应解析**:仅调用,不依赖返回体字段(失败仅记录日志,不阻断返回流程)。
- **用途**:清理中断铸造产生的草稿订单。
---
## 3. 非封装直连网络调用(不经过 `request()`
### `uni.uploadFile`OSS 直传)
- **位置**
- `pages/profile/profile.vue` -> `uploadAvatarToOss`
- `pages/components/CastloveContent.vue` -> `uploadImageToOss`
- **前置**:先调 `getOssSignatureApi` 获取签名字段。
- **成功判定**`uploadRes.statusCode === 200 || 204`。
- **后续动作**
- 头像上传:调用 `updateAvatarApi` 回写业务系统头像地址。
- 藏品素材上传:生成 `uploadedImageUrl`,用于 `createMintOrderApi`
- **说明**:不走 `request()`,因此不受其统一鉴权/错误码分流逻辑约束。
### `uni.downloadFile`(头像文件缓存)
- **位置**
- `utils/avatarCache.js` -> `downloadAndCacheAvatar`
- **调用链**`getOssPresignedUrlApi -> downloadAndCacheAvatar(avatarUrl, realUrl) -> uni.downloadFile`
- **成功判定**`res.statusCode === 200`
- **用途**:将头像下载到本地并 `saveFile`,提升后续展示性能与稳定性。
---
## 4. 调用覆盖与观察
- `utils/api.js` 共导出 **31** 个 API 函数。
- 其中 **30 个已在源码业务层使用**`updateUserInfoApi` 当前未发现调用。
- 响应处理范式基本统一:
- 成功分支:`res.code === 200` + 按需读取 `res.data.*`
- 失败分支:依赖 `throw Error(message)`,页面显示 `error.message`