expo-duooomi-app/.claude/skills/hooks-api/SKILL.md

99 lines
3.0 KiB
Markdown
Raw 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.

---
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` 获取