import CaptchaBox, { CaptchaRes } from '@/components/captcha-box'; import { site } from '@/config.json'; import { useInterval } from '@/hooks/hooks'; import api, { ApiError } from '@/utils/api'; import { signUp, useAuth } from '@/utils/auth'; import { Button, Toast } from '@ant-design/react-native'; import { Ionicons } from '@expo/vector-icons'; import { Link, router, useLocalSearchParams } from 'expo-router'; import { openBrowserAsync } from 'expo-web-browser'; import React, { useRef, useState } from 'react'; import { KeyboardAvoidingView, Platform, Pressable, ScrollView, StyleSheet, Text, TextInput, View, } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; function FieldLabel({ children }: { children: React.ReactNode }) { return ( {children} ); } export default function SignUpScreen() { const [mobile, setMobile] = useState(''); const [code, setCode] = useState(''); const [password, setPassword] = useState(''); const [rePass, setRepass] = useState(''); const [email, setEmail] = useState(''); const [name, setName] = useState(''); const [organization, setOrganization] = useState(''); const [agreed, setAgreed] = useState(false); const [flushAgree, setFlushAgree] = useState(false); const [loading, setLoading] = useState(false); const scrollView = useRef(null); const [captchaVisible, setCaptchaVisible] = useState(false); const [smsTtl, setSmsTtl] = useState(0); const { setToken } = useAuth(); const { signIn, } = useLocalSearchParams<{ signIn: string; redirectTo?: string }>(); const waitCaptcha = useRef<(res: CaptchaRes) => void | null>(null); const needsCaptchaRef = useRef(false); const handleCaptcha = (res: CaptchaRes) => { let fun = waitCaptcha.current; waitCaptcha.current = null; alert(1) setCaptchaVisible(false); fun?.(res); } const handleSendCode = async () => { if (mobile.trim().length !== 11) { Toast.fail('请先输入 11 位手机号'); return; } let captcha: CaptchaRes = null!; while (true) { if (needsCaptchaRef.current) { setCaptchaVisible(true); captcha = await new Promise((resolve) => { waitCaptcha.current = resolve; }); if (!captcha || !captcha.ok) { return; } } try { const res = await api.post<{ needsCaptcha?: boolean; timerout: number; }>("sms/send?__session_id=" + captcha?.sid || '', { mobile: mobile, event: 'register', captcha_code: captcha?.code, }); if (res.needsCaptcha) { needsCaptchaRef.current = true; setCaptchaVisible(true); captcha = await new Promise((resolve) => { waitCaptcha.current = resolve; }); alert(JSON.stringify(captcha)); if (!captcha || !captcha.ok) { return; } continue; } setSmsTtl(res.timerout); break; } catch (e) { if (ApiError.isApiError(e)) { if (e.code === -1) { Toast.fail("该手机已被注册"); return; } if (e.code === -99) { Toast.fail("图形验证码无效"); return; } } Toast.fail("发送验证码失败"); return; } } }; // useEffect(() => { // let isMount = true; // setTimeout(()=> { // if (!isMount) { // return; // } // setSmsTtl((pre)=> pre --); // }) // return ()=> { // isMount = false; // } // }, []) useInterval(() => { setSmsTtl((pre) => pre - 1) }, smsTtl > 0 ? 1000 : null); const handleRegister = async () => { setFlushAgree(false); if (mobile.trim().length !== 11) { Toast.fail('请输入正确的手机号'); return; } if (code.trim().length !== 6) { Toast.fail('请输入 6 位验证码'); return; } if (password.length < 6) { Toast.fail('请输入不少于 6 位的登录密码'); return; } if (rePass !== password) { Toast.fail("两次密码输入不一至"); return; } if (!email.includes('@')) { Toast.fail('请输入正确的邮箱'); return; } if (!name.trim()) { Toast.fail('请输入姓名'); return; } if (!agreed) { Toast.fail('请先阅读并同意协议'); setFlushAgree(true); scrollView.current?.scrollToEnd({ animated: true }); return; } setLoading(true); const toastKey = Toast.loading('正在创建账号...'); try { const token = await signUp({ mobile, password, captcha: code, name, email, }); setToken(token); Toast.success('登录成功'); if (signIn) { router.dismissTo("/"); } else { router.dismiss(); } } catch (error) { console.error('登录失败:', error); Toast.fail('登录失败,请稍后重试'); } finally { setLoading(false); Toast.remove(toastKey); } }; const insets = useSafeAreaInsets(); return ( 创建账号 完善基础信息,开启您的智能借贷助手工作台 手机号码 +86 验证码 0} hitSlop={8} onPress={handleSendCode} > 0 ? 'text-on-secondary-fixed' : 'text-primary'}`}> {smsTtl > 0 ? `${smsTtl}s` : '发送验证码'} 登录密码 重复密码 邮箱 姓名 所属机构 router.back()}> 返回登录 遇到问题? setAgreed((value) => !value)} hitSlop={8} className="pt-1" > {agreed ? ( ) : null} 注册即代表您已阅读并同意 《用户服务协议》 openBrowserAsync(`${site}`)}>《隐私政策》 ,以及授权该应用获取您的公开信息。 ); }