99 lines
3.0 KiB
Markdown
99 lines
3.0 KiB
Markdown
---
|
||
name: hooks-api
|
||
description: >
|
||
Duooomi 应用 Hooks API 层使用指南。当需要数据获取、API 调用、AIGC 任务提交、模板操作、文件上传、用户认证、余额查询时触发。Hooks 分三层:core(基础能力)、data(数据查询)、actions(写操作)。所有 hooks 基于 @repo/sdk Controller 通过 IoC 容器 root.get() 获取实例,使用 handleError 统一错误处理。
|
||
---
|
||
|
||
# Hooks API 层
|
||
|
||
## 架构
|
||
|
||
```
|
||
hooks/
|
||
├── core/ # 基础能力:useAuth, useLoomartApi, useUserBalance
|
||
├── data/ # 数据查询:useTemplates, useTemplateDetail, useTemplateGenerations,
|
||
│ # useRecommendedTemplates, usePublicTemplates, useLikesTemplates,
|
||
│ # useCategories, useTags, useActivities, useSearchHistory, useError
|
||
├── actions/ # 写操作:useAigcTask, useTemplateActions, useFileUpload, useTemplateInteraction
|
||
└── 独立hooks # useIOSPurchase, useUpdateChecker, useColorScheme, useThemeColor
|
||
```
|
||
|
||
## 核心模式
|
||
|
||
### handleError 统一错误处理
|
||
|
||
```tsx
|
||
import { handleError } from '@/hooks/data/use-error'
|
||
const { data, error } = await handleError(async () => await controller.method(params))
|
||
```
|
||
|
||
### IoC 容器获取 Controller
|
||
|
||
```tsx
|
||
import { root } from '@repo/core'
|
||
import { TemplateController } from '@repo/sdk'
|
||
const controller = root.get(TemplateController)
|
||
```
|
||
|
||
## 通用返回值
|
||
|
||
```tsx
|
||
// 简单列表: { data, loading, error, load }
|
||
// 分页列表: { data, loading, loadingMore, error, execute/load, refetch, loadMore, hasMore }
|
||
// 详情: { data, loading, error, execute/load, refetch }
|
||
```
|
||
|
||
## 使用示例
|
||
|
||
### 模板列表(分页)
|
||
|
||
```tsx
|
||
const { data, loading, loadingMore, execute, loadMore, hasMore } = useTemplates()
|
||
useEffect(() => { execute({ page: 1, limit: 20, categoryId: 'xxx' }) }, [])
|
||
const handleLoadMore = () => { if (hasMore && !loadingMore) loadMore({ categoryId: 'xxx' }) }
|
||
```
|
||
|
||
### AIGC 任务提交 + 轮询
|
||
|
||
```tsx
|
||
const { submitTask, startPolling, stopPolling, isPolling } = useAigcTask()
|
||
const { taskId } = await submitTask({ templateId: 'xxx', params: {...} })
|
||
if (taskId) {
|
||
startPolling(taskId,
|
||
(result) => { /* 完成 */ },
|
||
(error) => { /* 失败 */ }
|
||
)
|
||
}
|
||
useEffect(() => () => stopPolling(), [])
|
||
```
|
||
|
||
### 文件上传
|
||
|
||
```tsx
|
||
const { uploadFile, loading, progress, uploadedUrl } = useFileUpload()
|
||
const { url, error } = await uploadFile(file, 'avatars')
|
||
```
|
||
|
||
### 模板点赞/收藏
|
||
|
||
```tsx
|
||
const { likeTemplate, unlikeTemplate, checkLiked, favoriteTemplate } = useTemplateInteraction()
|
||
const { liked } = await checkLiked(templateId)
|
||
```
|
||
|
||
### 认证
|
||
|
||
```tsx
|
||
const { user, isLogin, signIn, signOut } = useAuth()
|
||
```
|
||
|
||
## 编写新 Hook 规范
|
||
|
||
1. 放在正确的分层目录 (core/data/actions)
|
||
2. 用 `handleError` 包裹所有 SDK 调用
|
||
3. 通过 `root.get(XxxController)` 获取 controller
|
||
4. 返回 `{ data, loading, error, ...methods }`
|
||
5. 操作方法用 `useCallback` 包裹
|
||
6. 在对应 index.ts 中导出
|
||
7. ownerId 从 `process.env.EXPO_PUBLIC_OWNER_ID` 获取
|