"use client" import type React from "react" import { useState, useEffect } from "react" import { Eye, EyeOff, Mail, Phone } from "lucide-react" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Checkbox } from "@/components/ui/checkbox" import { useRouter } from "next/navigation" import { WeChatIcon } from "@/components/icons/wechat-icon" import { AppleIcon } from "@/components/icons/apple-icon" import { useToast } from "@/components/ui/use-toast" // 使用环境变量:不配置则用本地 API(支持 zhiqun@qq.com / Zhiqun1984) const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL ?? "" // 定义登录响应类型 interface LoginResponse { code: number message: string data?: { token: string } } interface LoginForm { account: string // 邮箱或手机号 password: string verificationCode: string agreeToTerms: boolean } export default function LoginPage() { const [showPassword, setShowPassword] = useState(false) const [activeTab, setActiveTab] = useState<"password" | "verification">("password") const [isLoading, setIsLoading] = useState(false) const [form, setForm] = useState({ account: "", password: "", verificationCode: "", agreeToTerms: false, }) const router = useRouter() const { toast } = useToast() const handleInputChange = (e: React.ChangeEvent) => { const { name, value } = e.target setForm((prev) => ({ ...prev, [name]: value })) } const handleCheckboxChange = (checked: boolean) => { setForm((prev) => ({ ...prev, agreeToTerms: checked })) } const validateForm = () => { if (!form.account.trim()) { toast({ variant: "destructive", title: "请输入账号", description: "请输入邮箱或手机号", }) return false } if (!form.agreeToTerms) { toast({ variant: "destructive", title: "请同意用户协议", description: "需要同意用户协议和隐私政策才能继续", }) return false } if (activeTab === "password" && !form.password) { toast({ variant: "destructive", title: "请输入密码", description: "密码不能为空", }) return false } if (activeTab === "verification" && !form.verificationCode) { toast({ variant: "destructive", title: "请输入验证码", description: "验证码不能为空", }) return false } return true } const handleLogin = async (e: React.FormEvent) => { e.preventDefault() if (!validateForm()) return setIsLoading(true) try { const formData = new FormData() const isEmail = form.account.includes("@") formData.append(isEmail ? "email" : "phone", form.account) if (activeTab === "password") { formData.append("password", form.password) } else { formData.append("verificationCode", form.verificationCode) } const apiUrl = API_BASE_URL ? `${API_BASE_URL}/auth/login` : "/api/auth/login" const response = await fetch(apiUrl, { method: "POST", body: formData, // 不需要设置Content-Type,浏览器会自动设置为multipart/form-data并添加boundary }) const result: LoginResponse = await response.json() if (result.code === 10000 && result.data?.token) { // 保存token到localStorage localStorage.setItem("token", result.data.token) // 成功后跳转 router.push("/") toast({ title: "登录成功", description: "欢迎回来!", }) } else { throw new Error(result.message || "登录失败") } } catch (error) { toast({ variant: "destructive", title: "登录失败", description: error instanceof Error ? error.message : "请稍后重试", }) } finally { setIsLoading(false) } } const handleSendVerificationCode = async () => { if (!form.account.trim()) { toast({ variant: "destructive", title: "请输入手机号", description: "发送验证码需要手机号", }) return } setIsLoading(true) try { const formData = new FormData() formData.append("phone", form.account) const apiUrl = API_BASE_URL ? `${API_BASE_URL}/auth/send-code` : "/api/auth/send-code" const response = await fetch(apiUrl, { method: "POST", body: formData, }) const result = await response.json() if (result.code === 10000) { toast({ title: "验证码已发送", description: "请查看手机短信", }) } else { throw new Error(result.message || "发送失败") } } catch (error) { toast({ variant: "destructive", title: "发送失败", description: error instanceof Error ? error.message : "请稍后重试", }) } finally { setIsLoading(false) } } useEffect(() => { // 检查是否已登录 const token = localStorage.getItem("token") if (token) { router.push("/profile") } }, [router]) return (
setActiveTab(v as "password" | "verification")} > 验证码登录 密码登录

支持 邮箱 / 手机号 / 微信 / Apple 登录

{form.account.includes("@") ? ( ) : ( )}
) }