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:
@@ -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,
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user