|
@@ -1,177 +1,177 @@
|
|
|
-import { CirclePlay, Send } from "lucide-react";
|
|
|
|
|
-import { useState } from "react";
|
|
|
|
|
-import { getRandomAccountApi, registerAccountApi } from "../../api/register";
|
|
|
|
|
-import { loginAccountApi } from "../../api/login";
|
|
|
|
|
-import { useAtomValue, useSetAtom } from "jotai";
|
|
|
|
|
-import { modalStackAtom, openModalAction } from "../../store";
|
|
|
|
|
-import { pmBridge } from "../../lib/PostMessageBridge";
|
|
|
|
|
-
|
|
|
|
|
-export interface AccountRegisterProps {
|
|
|
|
|
- switchPhoneRegister: () => void;
|
|
|
|
|
- switchLogin: () => void;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-export const AccountRegister = ({ switchPhoneRegister, switchLogin }: AccountRegisterProps) => {
|
|
|
|
|
- const [userName, setUserName] = useState('');
|
|
|
|
|
- const [userPwd, setUserPwd] = useState('');
|
|
|
|
|
- const [loading, setLoading] = useState(false);
|
|
|
|
|
- const [agreed, setAgreed] = useState(false);
|
|
|
|
|
-
|
|
|
|
|
- const modalState = useAtomValue(modalStackAtom);
|
|
|
|
|
- const openModal = useSetAtom(openModalAction);
|
|
|
|
|
-
|
|
|
|
|
- const handleRandomAccount = async () => {
|
|
|
|
|
- setLoading(true);
|
|
|
|
|
- try {
|
|
|
|
|
- const res = await getRandomAccountApi({ is_activate: 1 });
|
|
|
|
|
- if (res.user_name && res.user_pwd) {
|
|
|
|
|
- setUserName(res.user_name);
|
|
|
|
|
- setUserPwd(res.user_pwd);
|
|
|
|
|
- }
|
|
|
|
|
- } catch (error: any) {
|
|
|
|
|
- console.error('获取随机账号失败:', error);
|
|
|
|
|
- alert(error.message || '获取随机账号失败');
|
|
|
|
|
- } finally {
|
|
|
|
|
- setLoading(false);
|
|
|
|
|
- }
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- const handleRegister = async () => {
|
|
|
|
|
- if (!userName) {
|
|
|
|
|
- alert('请输入账号');
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- if (!userPwd) {
|
|
|
|
|
- alert('请输入密码');
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- if (!agreed) {
|
|
|
|
|
- alert('请先同意服务协议与隐私权政策');
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- setLoading(true);
|
|
|
|
|
- try {
|
|
|
|
|
- // 首先执行注册
|
|
|
|
|
- await registerAccountApi({
|
|
|
|
|
- user_name: userName,
|
|
|
|
|
- user_pwd: userPwd
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 注册成功后立即执行登录
|
|
|
|
|
- const loginRes = await loginAccountApi({
|
|
|
|
|
- user_name: userName,
|
|
|
|
|
- user_pwd: userPwd
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- if (loginRes.token) {
|
|
|
|
|
- // 存储 token
|
|
|
|
|
- localStorage.setItem('token', loginRes.token);
|
|
|
|
|
-
|
|
|
|
|
- // 使用 pmBridge 回传给父 iframe
|
|
|
|
|
- const requestId = modalState.login.requestId;
|
|
|
|
|
- pmBridge.sendToIframe("LOGIN SUCCESS", loginRes, requestId);
|
|
|
|
|
-
|
|
|
|
|
- // 关闭登录弹窗
|
|
|
|
|
- openModal({ name: 'login', item: { isOpen: false } });
|
|
|
|
|
- } else {
|
|
|
|
|
- alert('登录失败:未返回 token');
|
|
|
|
|
- }
|
|
|
|
|
- } catch (error: any) {
|
|
|
|
|
- console.error('流程失败:', error);
|
|
|
|
|
- alert(error.message || '操作失败');
|
|
|
|
|
- } finally {
|
|
|
|
|
- setLoading(false);
|
|
|
|
|
- }
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- return (
|
|
|
|
|
- <div className="fixed inset-0 z-[100] flex items-center justify-center bg-black/60 backdrop-blur-sm">
|
|
|
|
|
-
|
|
|
|
|
- <div className="w-full max-w-[320px] mx-5 bg-[#f5f7f8] rounded-2xl shadow-2xl overflow-hidden flex flex-col scale-100">
|
|
|
|
|
-
|
|
|
|
|
- <div className="flex flex-col items-center pt-4 pb-6 px-6">
|
|
|
|
|
-
|
|
|
|
|
- <h1 className="text-xl font-bold text-slate-900 dark:text-slate-100">创建账号</h1>
|
|
|
|
|
- </div>
|
|
|
|
|
-
|
|
|
|
|
- {/* Tabs */}
|
|
|
|
|
- <div className="flex border-b border-slate-200 dark:border-slate-800 px-6 gap-8">
|
|
|
|
|
- <button onClick={switchPhoneRegister} className="flex flex-col items-center justify-center border-b-[3px] border-transparent text-[#64748b] pb-3 pt-2 hover:text-primary transition-colors">
|
|
|
|
|
- <p className="text-sm font-bold leading-normal tracking-wide">手机号注册</p>
|
|
|
|
|
- </button>
|
|
|
|
|
- <button className="flex flex-col items-center justify-center border-b-[3px] border-primary text-primary pb-3 pt-2">
|
|
|
|
|
- <p className="text-sm font-bold leading-normal tracking-wide">账号注册</p>
|
|
|
|
|
- </button>
|
|
|
|
|
- </div>
|
|
|
|
|
-
|
|
|
|
|
- {/* Form Content */}
|
|
|
|
|
- <div className="p-6 space-y-4">
|
|
|
|
|
- {/* Account Input */}
|
|
|
|
|
- <label className="text-xs font-semibold uppercase tracking-wider text-slate-400 ml-1">账号</label>
|
|
|
|
|
- <div className="flex gap-2">
|
|
|
|
|
-
|
|
|
|
|
- <div className="flex-1">
|
|
|
|
|
- <input
|
|
|
|
|
- className="p-2 form-input input-field w-full rounded-lg border-slate-200 bg-white text-slate-900 h-12 text-sm"
|
|
|
|
|
- placeholder="请输入账号"
|
|
|
|
|
- type="text"
|
|
|
|
|
- value={userName}
|
|
|
|
|
- onChange={(e) => setUserName(e.target.value)}
|
|
|
|
|
- />
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
-
|
|
|
|
|
- {/* Password Input */}
|
|
|
|
|
- <label className="text-xs font-semibold uppercase tracking-wider text-slate-400 ml-1">密码</label>
|
|
|
|
|
- <div className="flex gap-2">
|
|
|
|
|
- <div className="flex-1">
|
|
|
|
|
- <input
|
|
|
|
|
- className="p-2 form-input input-field w-full rounded-lg border-slate-200 bg-white text-slate-900 h-12 text-sm"
|
|
|
|
|
- placeholder="请输入密码"
|
|
|
|
|
- type="text"
|
|
|
|
|
- value={userPwd}
|
|
|
|
|
- onChange={(e) => setUserPwd(e.target.value)}
|
|
|
|
|
- />
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- <div className="flex justify-between items-center px-1">
|
|
|
|
|
- <a className="text-xs text-slate-500 dark:text-slate-400 hover:text-primary transition-colors cursor-pointer" onClick={switchLogin}>已有账号</a>
|
|
|
|
|
- <a className="text-xs text-slate-500 dark:text-slate-400 hover:text-primary transition-colors" href="#">遇到问题?</a>
|
|
|
|
|
- </div>
|
|
|
|
|
-
|
|
|
|
|
- {/* Action Button */}
|
|
|
|
|
- <button
|
|
|
|
|
- onClick={handleRegister}
|
|
|
|
|
- disabled={loading}
|
|
|
|
|
- className={`w-full bg-primary hover:bg-primary/90 text-white font-bold h-12 rounded-lg shadow-lg transition-all flex items-center justify-center gap-2 ${loading ? 'opacity-70 cursor-not-allowed' : ''}`}
|
|
|
|
|
- >
|
|
|
|
|
- {loading ? '注册中...' : '立即注册并进入游戏'} <CirclePlay size={18} />
|
|
|
|
|
- </button>
|
|
|
|
|
- <button
|
|
|
|
|
- onClick={handleRandomAccount}
|
|
|
|
|
- disabled={loading}
|
|
|
|
|
- className="w-full text-primary font-bold h-12 rounded-lg shadow-lg transition-all flex items-center justify-center gap-2 border border-primary/20 hover:bg-primary/5"
|
|
|
|
|
- >
|
|
|
|
|
- <Send size={18} />一键生成账号密码
|
|
|
|
|
- </button>
|
|
|
|
|
- {/* Secondary Links */}
|
|
|
|
|
-
|
|
|
|
|
- <div className="flex items-center gap-2 px-1 pt-2">
|
|
|
|
|
- <input
|
|
|
|
|
- className="h-4 w-4 rounded border-slate-300 text-primary focus:ring-primary cursor-pointer"
|
|
|
|
|
- id="tos"
|
|
|
|
|
- type="checkbox"
|
|
|
|
|
- checked={agreed}
|
|
|
|
|
- onChange={(e) => setAgreed(e.target.checked)}
|
|
|
|
|
- />
|
|
|
|
|
- <label htmlFor="tos" className="text-xs leading-relaxed text-slate-500 cursor-pointer select-none">
|
|
|
|
|
- 我已阅读并同意 <a className="text-primary hover:underline" href="#">服务协议</a> 与 <a className="text-primary hover:underline" href="#">隐私权政策</a>
|
|
|
|
|
- </label>
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
-
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- );
|
|
|
|
|
-}
|
|
|
|
|
|
|
+import { CirclePlay, Send } from "lucide-react";
|
|
|
|
|
+import { useState } from "react";
|
|
|
|
|
+import { getRandomAccountApi, registerAccountApi } from "../../api/register";
|
|
|
|
|
+import { loginAccountApi } from "../../api/login";
|
|
|
|
|
+import { useAtomValue, useSetAtom } from "jotai";
|
|
|
|
|
+import { modalStackAtom, openModalAction } from "../../store";
|
|
|
|
|
+import { pmBridge } from "../../lib/PostMessageBridge";
|
|
|
|
|
+
|
|
|
|
|
+export interface AccountRegisterProps {
|
|
|
|
|
+ switchPhoneRegister: () => void;
|
|
|
|
|
+ switchLogin: () => void;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export const AccountRegister = ({ switchPhoneRegister, switchLogin }: AccountRegisterProps) => {
|
|
|
|
|
+ const [userName, setUserName] = useState('');
|
|
|
|
|
+ const [userPwd, setUserPwd] = useState('');
|
|
|
|
|
+ const [loading, setLoading] = useState(false);
|
|
|
|
|
+ const [agreed, setAgreed] = useState(false);
|
|
|
|
|
+
|
|
|
|
|
+ const modalState = useAtomValue(modalStackAtom);
|
|
|
|
|
+ const openModal = useSetAtom(openModalAction);
|
|
|
|
|
+
|
|
|
|
|
+ const handleRandomAccount = async () => {
|
|
|
|
|
+ setLoading(true);
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await getRandomAccountApi({ is_activate: 1 });
|
|
|
|
|
+ if (res.user_name && res.user_pwd) {
|
|
|
|
|
+ setUserName(res.user_name);
|
|
|
|
|
+ setUserPwd(res.user_pwd);
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error: any) {
|
|
|
|
|
+ console.error('获取随机账号失败:', error);
|
|
|
|
|
+ alert(error.message || '获取随机账号失败');
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ setLoading(false);
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const handleRegister = async () => {
|
|
|
|
|
+ if (!userName) {
|
|
|
|
|
+ alert('请输入账号');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!userPwd) {
|
|
|
|
|
+ alert('请输入密码');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!agreed) {
|
|
|
|
|
+ alert('请先同意服务协议与隐私权政策');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ setLoading(true);
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 首先执行注册
|
|
|
|
|
+ await registerAccountApi({
|
|
|
|
|
+ user_name: userName,
|
|
|
|
|
+ user_pwd: userPwd
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 注册成功后立即执行登录
|
|
|
|
|
+ const loginRes = await loginAccountApi({
|
|
|
|
|
+ user_name: userName,
|
|
|
|
|
+ user_pwd: userPwd
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ if (loginRes.token) {
|
|
|
|
|
+ // 存储 token
|
|
|
|
|
+ localStorage.setItem('token', loginRes.token);
|
|
|
|
|
+
|
|
|
|
|
+ // 使用 pmBridge 回传给父 iframe
|
|
|
|
|
+ const requestId = modalState.login.requestId;
|
|
|
|
|
+ pmBridge.sendToIframe("LOGIN_REQUEST", {success:true, data: loginRes}, requestId);
|
|
|
|
|
+
|
|
|
|
|
+ // 关闭登录弹窗
|
|
|
|
|
+ openModal({ name: 'login', item: { isOpen: false } });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ alert('登录失败:未返回 token');
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error: any) {
|
|
|
|
|
+ console.error('流程失败:', error);
|
|
|
|
|
+ alert(error.message || '操作失败');
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ setLoading(false);
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ return (
|
|
|
|
|
+ <div className="fixed inset-0 z-[100] flex items-center justify-center bg-black/60 backdrop-blur-sm">
|
|
|
|
|
+
|
|
|
|
|
+ <div className="w-full max-w-[320px] mx-5 bg-[#f5f7f8] rounded-2xl shadow-2xl overflow-hidden flex flex-col scale-100">
|
|
|
|
|
+
|
|
|
|
|
+ <div className="flex flex-col items-center pt-4 pb-6 px-6">
|
|
|
|
|
+
|
|
|
|
|
+ <h1 className="text-xl font-bold text-slate-900 dark:text-slate-100">创建账号</h1>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ {/* Tabs */}
|
|
|
|
|
+ <div className="flex border-b border-slate-200 dark:border-slate-800 px-6 gap-8">
|
|
|
|
|
+ <button onClick={switchPhoneRegister} className="flex flex-col items-center justify-center border-b-[3px] border-transparent text-[#64748b] pb-3 pt-2 hover:text-primary transition-colors">
|
|
|
|
|
+ <p className="text-sm font-bold leading-normal tracking-wide">手机号注册</p>
|
|
|
|
|
+ </button>
|
|
|
|
|
+ <button className="flex flex-col items-center justify-center border-b-[3px] border-primary text-primary pb-3 pt-2">
|
|
|
|
|
+ <p className="text-sm font-bold leading-normal tracking-wide">账号注册</p>
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ {/* Form Content */}
|
|
|
|
|
+ <div className="p-6 space-y-4">
|
|
|
|
|
+ {/* Account Input */}
|
|
|
|
|
+ <label className="text-xs font-semibold uppercase tracking-wider text-slate-400 ml-1">账号</label>
|
|
|
|
|
+ <div className="flex gap-2">
|
|
|
|
|
+
|
|
|
|
|
+ <div className="flex-1">
|
|
|
|
|
+ <input
|
|
|
|
|
+ className="p-2 form-input input-field w-full rounded-lg border-slate-200 bg-white text-slate-900 h-12 text-sm"
|
|
|
|
|
+ placeholder="请输入账号"
|
|
|
|
|
+ type="text"
|
|
|
|
|
+ value={userName}
|
|
|
|
|
+ onChange={(e) => setUserName(e.target.value)}
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ {/* Password Input */}
|
|
|
|
|
+ <label className="text-xs font-semibold uppercase tracking-wider text-slate-400 ml-1">密码</label>
|
|
|
|
|
+ <div className="flex gap-2">
|
|
|
|
|
+ <div className="flex-1">
|
|
|
|
|
+ <input
|
|
|
|
|
+ className="p-2 form-input input-field w-full rounded-lg border-slate-200 bg-white text-slate-900 h-12 text-sm"
|
|
|
|
|
+ placeholder="请输入密码"
|
|
|
|
|
+ type="text"
|
|
|
|
|
+ value={userPwd}
|
|
|
|
|
+ onChange={(e) => setUserPwd(e.target.value)}
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div className="flex justify-between items-center px-1">
|
|
|
|
|
+ <a className="text-xs text-slate-500 dark:text-slate-400 hover:text-primary transition-colors cursor-pointer" onClick={switchLogin}>已有账号</a>
|
|
|
|
|
+ <a className="text-xs text-slate-500 dark:text-slate-400 hover:text-primary transition-colors" href="#">遇到问题?</a>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ {/* Action Button */}
|
|
|
|
|
+ <button
|
|
|
|
|
+ onClick={handleRegister}
|
|
|
|
|
+ disabled={loading}
|
|
|
|
|
+ className={`w-full bg-primary hover:bg-primary/90 text-white font-bold h-12 rounded-lg shadow-lg transition-all flex items-center justify-center gap-2 ${loading ? 'opacity-70 cursor-not-allowed' : ''}`}
|
|
|
|
|
+ >
|
|
|
|
|
+ {loading ? '注册中...' : '立即注册并进入游戏'} <CirclePlay size={18} />
|
|
|
|
|
+ </button>
|
|
|
|
|
+ <button
|
|
|
|
|
+ onClick={handleRandomAccount}
|
|
|
|
|
+ disabled={loading}
|
|
|
|
|
+ className="w-full text-primary font-bold h-12 rounded-lg shadow-lg transition-all flex items-center justify-center gap-2 border border-primary/20 hover:bg-primary/5"
|
|
|
|
|
+ >
|
|
|
|
|
+ <Send size={18} />一键生成账号密码
|
|
|
|
|
+ </button>
|
|
|
|
|
+ {/* Secondary Links */}
|
|
|
|
|
+
|
|
|
|
|
+ <div className="flex items-center gap-2 px-1 pt-2">
|
|
|
|
|
+ <input
|
|
|
|
|
+ className="h-4 w-4 rounded border-slate-300 text-primary focus:ring-primary cursor-pointer"
|
|
|
|
|
+ id="tos"
|
|
|
|
|
+ type="checkbox"
|
|
|
|
|
+ checked={agreed}
|
|
|
|
|
+ onChange={(e) => setAgreed(e.target.checked)}
|
|
|
|
|
+ />
|
|
|
|
|
+ <label htmlFor="tos" className="text-xs leading-relaxed text-slate-500 cursor-pointer select-none">
|
|
|
|
|
+ 我已阅读并同意 <a className="text-primary hover:underline" href="#">服务协议</a> 与 <a className="text-primary hover:underline" href="#">隐私权政策</a>
|
|
|
|
|
+ </label>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ );
|
|
|
|
|
+}
|