'use client' import {useEffect, useRef, useState} from 'react' import Cap from '@cap.js/widget' import {sendSMS} from '@/actions/verify' import {toast} from 'sonner' import {Button} from '@/components/ui/button' export default function SendMsg(props: { phone: string }) { const [countdown, setCountdown] = useState(0) const [progress, setProgress] = useState(0) const cap = useRef(new Cap({apiEndpoint: '/'})) cap.current.addEventListener('solve', (event) => { console.log('captcha solve', event) }) cap.current.addEventListener('error', (event) => { console.error('captcha error', event) }) cap.current.addEventListener('reset', (event) => { console.log('captcha reset', event) }) cap.current.addEventListener('progress', (event) => { setProgress(event.detail.progress) }) // 计时 useEffect(() => { const interval = setInterval(() => { if (countdown > 0) { setCountdown(countdown - 1) } }, 1000) return () => clearInterval(interval) }, [countdown]) // 发送验证码 const sendCode = async () => { try { // 检查手机号 const valid = /^1\d{10}$/.test(props.phone) if (!valid) { throw new Error('请输入正确的手机号') } // 完成挑战 const result = await cap.current.solve() if (!result.success || !cap.current.token) { throw new Error('人机验证失败') } // 发送验证码 const resp = await sendSMS({ phone: props.phone, captcha: cap.current.token, }) if (!resp.success) { throw new Error(`验证码发送失败: ${resp.message}`) } setCountdown(60) toast.success('验证码已发送') } catch (e) { toast.error('验证码发送失败', { description: (e as Error).message, }) } } return ( ) }