import { useRouter } from 'expo-router'; import React, { useEffect, useRef, useState } from 'react'; import { Alert, ImageBackground, KeyboardAvoidingView, Platform, ScrollView, StatusBar, StyleSheet, Text, TextInput, TouchableOpacity, View, } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { Images } from '@/constants/images'; import { login, sendVerifyCode } from '@/services/user'; export default function LoginScreen() { const router = useRouter(); const insets = useSafeAreaInsets(); const [phone, setPhone] = useState(''); const [verifyCode, setVerifyCode] = useState(''); const [agreeFlag, setAgreeFlag] = useState(false); const [countdown, setCountdown] = useState(0); const [disabled, setDisabled] = useState(false); const [loading, setLoading] = useState(false); const [tips, setTips] = useState('获取验证码'); const timerRef = useRef | null>(null); useEffect(() => { return () => { if (timerRef.current) { clearInterval(timerRef.current); } }; }, []); // 验证手机号 const isChinesePhoneNumber = (phoneNumber: string) => { const phoneNumberPattern = /^1[3-9]\d{9}$/; return phoneNumberPattern.test(phoneNumber); }; // 开始倒计时 const startCountdown = () => { setDisabled(true); let count = 60; setTips(`${count}s后重新获取`); timerRef.current = setInterval(() => { count--; if (count > 0) { setTips(`${count}s后重新获取`); } else { resetCountdown(); } }, 1000); }; // 重置倒计时 const resetCountdown = () => { setDisabled(false); setTips('获取验证码'); if (timerRef.current) { clearInterval(timerRef.current); timerRef.current = null; } }; // 获取验证码 const handleGetVerifyCode = async () => { if (disabled) return; if (phone && isChinesePhoneNumber(phone)) { try { const res = await sendVerifyCode(phone, 'LOGIN'); if (res) { Alert.alert('提示', '验证码已发送'); startCountdown(); } } catch (error) { Alert.alert('错误', '获取验证码失败,请重试'); } } else { Alert.alert('提示', '请输入正确的手机号'); } }; // 登录 const handleLogin = async () => { if (!agreeFlag) { Alert.alert('提示', '请您先阅读并同意用户协议和隐私政策'); return; } if (phone && isChinesePhoneNumber(phone) && verifyCode) { setLoading(true); try { const result = await login({ loginWay: 'MOBILE', mobile: phone, verifycode: verifyCode, }); if (result.success) { // TODO: 如果 needInfo 为 true,跳转到完善信息页面 // if (result.needInfo) { // router.replace('/user-info'); // return; // } router.back(); } else { Alert.alert('错误', '登录失败,请检查验证码'); } } catch (error) { Alert.alert('错误', '登录失败'); } setLoading(false); } else { Alert.alert('提示', '请输入手机号和验证码'); } }; const goBack = () => { router.back(); }; return ( {/* 底部表单区域 */} {/* 表单 */} {/* 手机号输入 */} 手机号 {/* 验证码输入 */} 验证码 {tips} {/* 协议勾选 */} setAgreeFlag(!agreeFlag)} > {agreeFlag && } 我已阅读并同意 《用户协议》《隐私政策》 {/* 按钮区域 */} {loading ? '登录中...' : '登录'} 返回 ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#1a1a2e', }, background: { flex: 1, }, keyboardView: { flex: 1, }, scrollContent: { flexGrow: 1, justifyContent: 'flex-end', }, bottom: { width: '100%', }, form: { paddingHorizontal: 25, }, formItem: { flexDirection: 'row', alignItems: 'center', paddingVertical: 12, }, label: { color: '#fff', fontSize: 14, width: 50, }, input: { flex: 1, color: '#fff', fontSize: 14, paddingVertical: 8, outlineStyle: 'none', } as any, codeInput: { flex: 1, }, divider: { height: 1, backgroundColor: 'rgba(255,255,255,0.2)', }, verifyBtn: { backgroundColor: '#000', borderRadius: 4, paddingHorizontal: 10, paddingVertical: 5, minWidth: 80, alignItems: 'center', }, verifyBtnDisabled: { backgroundColor: '#ccc', }, verifyBtnText: { color: '#fff', fontSize: 12, }, verifyBtnTextDisabled: { color: '#666', }, agree: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', marginTop: 25, paddingHorizontal: 25, }, radio: { width: 16, height: 16, borderRadius: 8, borderWidth: 1, borderColor: 'rgba(255,255,255,0.5)', marginRight: 6, justifyContent: 'center', alignItems: 'center', }, radioChecked: { borderColor: '#8b3dff', backgroundColor: '#8b3dff', }, radioInner: { width: 6, height: 6, borderRadius: 3, backgroundColor: '#fff', }, agreeText: { color: '#fff', fontSize: 12, }, linkText: { color: '#8b3dff', }, btnArea: { paddingTop: 15, alignItems: 'center', }, btn: { width: 234, height: 45, overflow: 'hidden', }, loginBtnBg: { width: '100%', height: '100%', justifyContent: 'center', alignItems: 'center', }, btnDisabled: { opacity: 0.6, }, btnText: { color: '#fff', fontSize: 14, fontWeight: '600', }, btnBack: { width: 234, height: 35, backgroundColor: '#fff', borderRadius: 25, justifyContent: 'center', alignItems: 'center', marginTop: 10, borderWidth: 1, borderColor: '#fff', }, btnBackText: { color: '#888', fontSize: 12, }, });