feat: 实现 API 接口对接功能 (删除作品、作品搜索、修改密码)
按照 TDD 规范完成三个核心功能的接口对接: ## 新增功能 ### 1. 删除作品功能 (app/generationRecord.tsx) - 新增 use-template-generation-actions.ts hook - 支持单个删除和批量删除作品 - 删除确认对话框 - 删除成功后自动刷新列表 - 完整的错误处理和加载状态 ### 2. 作品搜索功能 (app/searchWorksResults.tsx) - 新增 use-works-search.ts hook - 替换模拟数据为真实 SDK 接口 - 支持关键词搜索和分类筛选 - 支持分页加载 - 完整的加载、错误、空结果状态处理 ### 3. 修改密码功能 (app/changePassword.tsx) - 新增 use-change-password.ts hook - 使用 Better Auth 的 changePassword API - 客户端表单验证(密码长度、确认密码匹配等) - 成功后自动返回并提示 ## 技术实现 - 严格遵循 TDD 规范(先写测试,后写实现) - 新增 3 个 hooks 和对应的单元测试 - 更新中英文翻译文件 - 更新 jest.setup.js 添加必要的 mock ## 文档 - 新增 api_integration_report.md - API 对接分析报告 - 新增 api_integration_development_plan.md - 开发计划和完成汇总 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@ import {
|
||||
Dimensions,
|
||||
Pressable,
|
||||
StatusBar as RNStatusBar,
|
||||
Alert,
|
||||
} from 'react-native'
|
||||
import { StatusBar } from 'expo-status-bar'
|
||||
import { SafeAreaView } from 'react-native-safe-area-context'
|
||||
@@ -19,7 +20,11 @@ import { DeleteConfirmDialog } from '@/components/ui/delete-confirm-dialog'
|
||||
import LoadingState from '@/components/LoadingState'
|
||||
import ErrorState from '@/components/ErrorState'
|
||||
import PaginationLoader from '@/components/PaginationLoader'
|
||||
import { useTemplateGenerations, type TemplateGeneration } from '@/hooks'
|
||||
import {
|
||||
useTemplateGenerations,
|
||||
useDeleteGeneration,
|
||||
type TemplateGeneration,
|
||||
} from '@/hooks'
|
||||
|
||||
const { width: screenWidth } = Dimensions.get('window')
|
||||
|
||||
@@ -30,14 +35,27 @@ export default function GenerationRecordScreen() {
|
||||
const [selectedId, setSelectedId] = useState<string | null>(null)
|
||||
|
||||
const { generations, loading, loadingMore, error, execute, refetch, loadMore, hasMore } = useTemplateGenerations()
|
||||
const { deleteGeneration, loading: deleting } = useDeleteGeneration()
|
||||
|
||||
useEffect(() => {
|
||||
execute({ page: 1, limit: 20 })
|
||||
}, [execute])
|
||||
|
||||
const handleDelete = () => {
|
||||
console.log('删除记录:', selectedId)
|
||||
const handleDelete = async () => {
|
||||
if (!selectedId) return
|
||||
|
||||
const { data, error } = await deleteGeneration(selectedId)
|
||||
|
||||
if (error) {
|
||||
Alert.alert(t('common.error'), error.message || t('generationRecord.deleteError'))
|
||||
} else {
|
||||
Alert.alert(t('common.success'), data?.message || t('generationRecord.deleteSuccess'))
|
||||
// 刷新列表
|
||||
refetch({ page: 1, limit: 20 })
|
||||
}
|
||||
|
||||
setDeleteDialogOpen(false)
|
||||
setSelectedId(null)
|
||||
}
|
||||
|
||||
const handleRefresh = () => {
|
||||
@@ -122,11 +140,14 @@ export default function GenerationRecordScreen() {
|
||||
<Text style={styles.actionButtonText}>{t('generationRecord.regenerate')}</Text>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
style={styles.deleteButton}
|
||||
style={[styles.deleteButton, deleting && selectedId === item.id && styles.deleteButtonDisabled]}
|
||||
onPress={() => {
|
||||
setSelectedId(item.id)
|
||||
setDeleteDialogOpen(true)
|
||||
if (!deleting) {
|
||||
setSelectedId(item.id)
|
||||
setDeleteDialogOpen(true)
|
||||
}
|
||||
}}
|
||||
disabled={deleting && selectedId === item.id}
|
||||
>
|
||||
<DeleteIcon />
|
||||
</Pressable>
|
||||
@@ -285,5 +306,8 @@ const styles = StyleSheet.create({
|
||||
justifyContent: 'center',
|
||||
marginLeft: 'auto',
|
||||
},
|
||||
deleteButtonDisabled: {
|
||||
opacity: 0.5,
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user