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:
imeepos
2026-01-23 19:15:24 +08:00
parent 4c01d8e9e7
commit e1340fa101
19 changed files with 2273 additions and 299 deletions

View File

@@ -16,16 +16,22 @@ import { StatusBar as RNStatusBar } from 'react-native'
import { useTranslation } from 'react-i18next'
import { LeftArrowIcon } from '@/components/icon'
import { LinearGradient } from 'expo-linear-gradient'
import { useChangePassword } from '@/hooks/use-change-password'
export default function ChangePasswordScreen() {
const router = useRouter()
const { t } = useTranslation()
// 使用新的 hook
const { changePassword, loading, error: apiError } = useChangePassword()
const [currentPassword, setCurrentPassword] = useState('')
const [newPassword, setNewPassword] = useState('')
const [confirmPassword, setConfirmPassword] = useState('')
const [currentPasswordError, setCurrentPasswordError] = useState('')
const [newPasswordError, setNewPasswordError] = useState('')
const [confirmPasswordError, setConfirmPasswordError] = useState('')
const [successMessage, setSuccessMessage] = useState('')
const validateCurrentPassword = (value: string) => {
if (!value) {
@@ -66,9 +72,12 @@ export default function ChangePasswordScreen() {
return true
}
const handleSubmit = () => {
const handleSubmit = async () => {
Keyboard.dismiss()
// 清除之前的成功消息
setSuccessMessage('')
// 按顺序验证每个字段
if (!validateCurrentPassword(currentPassword)) {
return
@@ -82,12 +91,32 @@ export default function ChangePasswordScreen() {
return
}
// TODO: 调用修改密码的API
// 这里应该调用实际的API来修改密码
console.log('修改密码:', { currentPassword, newPassword })
// 成功后返回
router.back()
// 调用修改密码的API
await changePassword({
oldPassword: currentPassword,
newPassword: newPassword,
confirmPassword: confirmPassword,
})
// 处理结果
if (apiError) {
// 显示错误提示
if (apiError.message) {
// 根据 API 返回的错误消息显示相应的错误
if (apiError.message.includes('旧密码') || apiError.message.includes('当前密码')) {
setCurrentPasswordError(apiError.message)
} else {
setCurrentPasswordError(t('changePassword.apiError'))
}
}
return
}
// 成功后显示提示并返回
setSuccessMessage(t('changePassword.success'))
setTimeout(() => {
router.back()
}, 1500)
}
return (
@@ -205,9 +234,15 @@ export default function ChangePasswordScreen() {
) : null}
</View>
<Pressable
style={styles.submitButtonContainer}
{/* 成功提示 */}
{successMessage ? (
<Text style={styles.successText}>{successMessage}</Text>
) : null}
<Pressable
style={styles.submitButtonContainer}
onPress={handleSubmit}
disabled={loading}
android_ripple={{ color: 'rgba(255, 255, 255, 0.1)' }}
>
<LinearGradient
@@ -216,7 +251,9 @@ export default function ChangePasswordScreen() {
end={{ x: 1, y: 0 }}
style={styles.submitButton}
>
<Text style={styles.submitButtonText}>{t('changePassword.submit')}</Text>
<Text style={styles.submitButtonText}>
{loading ? t('changePassword.submitting') : t('changePassword.submit')}
</Text>
</LinearGradient>
</Pressable>
</View>
@@ -312,5 +349,15 @@ const styles = StyleSheet.create({
fontSize: 16,
fontWeight: '600',
},
successText: {
color: '#4ADE80',
fontSize: 14,
textAlign: 'center',
marginTop: 16,
marginBottom: 8,
},
submitButtonDisabled: {
opacity: 0.6,
},
})