| import { useState, useEffect } from "react"; |
| import "./style.css"; |
| import { useNavigate } from "react-router-dom"; // 👈 加在顶部 import 区域 |
| import React from 'react'; |
| import md5 from 'md5'; |
| import bcrypt from "bcryptjs"; |
| export default function RegisterPage() { |
| const navigate = useNavigate(); // 👈 初始化导航器 |
| |
| const [email, setEmail] = useState(""); |
| const [password, setPassword] = useState(""); |
| const [code, setCode] = useState(""); |
| const [sent, setSent] = useState(false); |
| const [countdown, setCountdown] = useState(0); |
| const [confirmPassword, setConfirmPassword] = useState(""); |
| |
| const hashPassword = async (password) => { |
| try { |
| // 使用 10 作为盐的工作因子(越大越慢,更安全) |
| const encryptedPassword = await bcrypt.hash(password, 10); |
| console.log('Encrypted password with bcryptjs:', encryptedPassword); |
| return encryptedPassword; |
| } catch (error) { |
| console.error('Error encrypting password:', error); |
| } |
| }; |
| |
| |
| useEffect(() => { |
| let timer; |
| if (countdown > 0) { |
| timer = setInterval(() => { |
| setCountdown((prev) => prev - 1); |
| }, 1000); |
| } else if (countdown === 0 && sent) { |
| setSent(false); |
| } |
| |
| return () => clearInterval(timer); |
| }, [countdown, sent]); |
| |
| const handleSendCode = async () => { |
| if (!email) { |
| alert("请输入邮箱"); |
| return; |
| } |
| |
| try { |
| const res = await fetch("http://localhost:6001/send-code", { |
| method: "POST", |
| headers: { "Content-Type": "application/json" }, |
| body: JSON.stringify({ email }), |
| }); |
| |
| const data = await res.json(); |
| if (data.success) { |
| alert("验证码已发送到邮箱"); |
| setSent(true); |
| setCountdown(60); |
| } else { |
| alert("发送失败:" + data.message); |
| } |
| } catch (error) { |
| console.error(error); |
| alert("网络错误"); |
| } |
| }; |
| |
| const handleGoToPayment = () => { |
| navigate("/payment"); |
| }; |
| |
| const handleSubmit = async (e) => { |
| e.preventDefault(); |
| |
| if (!email || !password || !confirmPassword || !code) { |
| alert("请填写完整信息"); |
| return; |
| } |
| |
| if (password !== confirmPassword) { |
| alert("两次输入的密码不一致"); |
| return; |
| } |
| |
| const hash_Password = await bcrypt.hash(password, 10); |
| |
| try { |
| // 1. 校验是否能注册 |
| const res = await fetch("http://localhost:6001/register", { |
| method: "POST", |
| headers: { "Content-Type": "application/json" }, |
| body: JSON.stringify({ email, password, code }), |
| }); |
| |
| const data = await res.json(); |
| |
| if (!res.ok || !data.success) { |
| alert("注册失败:" + (data.message || "未知错误")); |
| return; |
| } |
| |
| // 2. 获取动态 notifyUrl |
| const ngrokRes = await fetch("http://localhost:6001/ngrok-url"); |
| const ngrokData = await ngrokRes.json(); |
| const notifyUrl = (ngrokData.backUrl ? ngrokData.backUrl.replace(/\/$/, "") : "http://localhost:6001") + "/paySuccess"; |
| console.log("11111111",hash_Password); |
| // 3. 下单 |
| const payId = getPayId(); |
| const orderResponse = await fetch("http://localhost:6001/user/createOrder", { |
| method: "POST", |
| headers: { "Content-Type": "application/json" }, |
| body: JSON.stringify({ |
| orderid: payId, |
| paytype: parseInt(payType), |
| money: price, |
| notifyUrl: notifyUrl, |
| returnUrl: "http://localhost:8000/user/login", |
| user_name: email, |
| password: hash_Password, |
| }), |
| }); |
| |
| const result = await orderResponse.json(); |
| |
| if (result.code === 0 && result.data) { |
| window.open(result.data, "_blank"); |
| } else { |
| alert("创建订单失败:" + (result.msg || "未知错误")); |
| } |
| } catch (error) { |
| console.error("提交失败:", error); |
| alert("网络错误或服务器异常"); |
| } |
| }; |
| |
| const [payType, setPayType] = useState('1'); |
| const [price, setPrice] = useState('0.01'); |
| const username = localStorage.getItem('username') || 'yky'; |
| |
| const getCurrentTimeAs14DigitInteger = () => { |
| const now = new Date(); |
| return now.toISOString().replace(/[-T:.Z]/g, '').slice(0, 14); |
| }; |
| |
| const getPayId = () => { |
| return getCurrentTimeAs14DigitInteger() + username; |
| }; |
| |
| return ( |
| <div className="container"> |
| <div className="form-box"> |
| <h1 className="title">注册 PTStation</h1> |
| <p className="promo"> |
| 限时活动:<span className="highlight">0.01元开通会员,终身享资源免费!</span> |
| </p> |
| <form onSubmit={handleSubmit}> |
| {/* 表单内容 */} |
| <label>邮箱</label> |
| <input |
| type="email" |
| value={email} |
| onChange={(e) => setEmail(e.target.value)} |
| required |
| /> |
| |
| <label>验证码</label> |
| <div className="code-box"> |
| <input |
| type="text" |
| value={code} |
| onChange={(e) => setCode(e.target.value)} |
| required |
| /> |
| <button type="button" onClick={handleSendCode} disabled={sent}> |
| {sent ? `重新发送(${countdown}s)` : "发送验证码"} |
| </button> |
| </div> |
| |
| <label>密码</label> |
| <input |
| type="password" |
| value={password} |
| onChange={(e) => setPassword(e.target.value)} |
| required |
| /> |
| |
| <label>重复密码</label> |
| <input |
| type="password" |
| value={confirmPassword} |
| onChange={(e) => setConfirmPassword(e.target.value)} |
| required |
| /> |
| |
| <button type="submit" className="submit-btn"> |
| 立即支付0.01,注册并开通会员 |
| </button> |
| </form> |
| |
| </div> |
| </div> |
| ); |
| } |