3862996045
CI/CD Pipeline / Check if frontend-only change (push) Waiting to run
CI/CD Pipeline / Validate - Code Quality (push) Waiting to run
CI/CD Pipeline / Validate - Type Check (mypy) (push) Waiting to run
CI/CD Pipeline / Validate - Migration (alembic) (push) Waiting to run
CI/CD Pipeline / Unit Tests (push) Blocked by required conditions
CI/CD Pipeline / Integration Tests (push) Blocked by required conditions
CI/CD Pipeline / Frontend Lint (push) Waiting to run
CI/CD Pipeline / Frontend Unit Tests (push) Blocked by required conditions
CI/CD Pipeline / PR Build API Image (push) Waiting to run
CI/CD Pipeline / PR Build Web Image (push) Waiting to run
CI/CD Pipeline / PR Build Worker Image (push) Waiting to run
CI/CD Pipeline / Build Staging API Image (push) Waiting to run
CI/CD Pipeline / Build Staging Web Image (push) Waiting to run
CI/CD Pipeline / Build Staging Worker Image (push) Waiting to run
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Blocked by required conditions
CI/CD Pipeline / Staging E2E Tests (push) Blocked by required conditions
CI/CD Pipeline / Staging API Integration Tests (push) Blocked by required conditions
CI/CD Pipeline / Build Production API Image (push) Waiting to run
CI/CD Pipeline / Build Production Web Image (push) Waiting to run
CI/CD Pipeline / Build Production Worker Image (push) Waiting to run
CI/CD Pipeline / Deploy Production (push) Blocked by required conditions
CI/CD Pipeline / Production Browser E2E (push) Blocked by required conditions
CI/CD Pipeline / ACR Image Cleanup (push) Blocked by required conditions
132 lines
4.2 KiB
TypeScript
132 lines
4.2 KiB
TypeScript
/**
|
|
* 注册页面 - V21 完全对标
|
|
*/
|
|
import React from "react"
|
|
import { Form, Input, message } from "antd"
|
|
import { UserOutlined, LockOutlined, MailOutlined } from "@ant-design/icons"
|
|
import { Link } from "react-router-dom"
|
|
import { useRegister } from "@/hooks/useAuth"
|
|
import Button from "@/components/ui/Button"
|
|
import "./Register.css"
|
|
|
|
interface RegisterFormValues {
|
|
email: string
|
|
username: string
|
|
password: string
|
|
confirmPassword: string
|
|
}
|
|
|
|
const Register: React.FC = () => {
|
|
const registerMutation = useRegister()
|
|
const [form] = Form.useForm()
|
|
|
|
const onFinish = async (values: RegisterFormValues) => {
|
|
try {
|
|
await registerMutation.mutateAsync({
|
|
email: values.email,
|
|
username: values.username,
|
|
password: values.password,
|
|
display_name: values.username,
|
|
})
|
|
message.success("注册成功!请查收验证邮件。")
|
|
} catch (error: unknown) {
|
|
if (!(error as { __msgShown?: boolean })?.__msgShown) message.error("注册失败,请重试")
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className="xx-auth-page">
|
|
<div className="xx-auth-card">
|
|
<div className="xx-auth-header">
|
|
<div className="xx-auth-brand">
|
|
<span className="xx-auth-logo">🦐</span>
|
|
<span className="xx-auth-brand-name">小虾智剪</span>
|
|
</div>
|
|
<p>创建账户,开启智能视频创作之旅</p>
|
|
</div>
|
|
|
|
<Form form={form} name="register" onFinish={onFinish} autoComplete="off" layout="vertical">
|
|
<Form.Item
|
|
name="email"
|
|
label="邮箱"
|
|
rules={[
|
|
{ required: true, message: "请输入邮箱" },
|
|
{ type: "email", message: "请输入有效的邮箱地址" },
|
|
]}
|
|
>
|
|
<Input prefix={<MailOutlined />} placeholder="name@example.com" size="large" />
|
|
</Form.Item>
|
|
|
|
<Form.Item
|
|
name="username"
|
|
label="用户名"
|
|
rules={[
|
|
{ required: true, message: "请输入用户名" },
|
|
{ min: 3, message: "用户名至少 3 个字符" },
|
|
{ max: 20, message: "用户名最多 20 个字符" },
|
|
{
|
|
pattern: /^[a-zA-Z0-9_]+$/,
|
|
message: "用户名只能包含字母、数字和下划线",
|
|
},
|
|
]}
|
|
>
|
|
<Input prefix={<UserOutlined />} placeholder="用户名" size="large" />
|
|
</Form.Item>
|
|
|
|
<Form.Item
|
|
name="password"
|
|
label="密码"
|
|
rules={[
|
|
{ required: true, message: "请输入密码" },
|
|
{ min: 8, message: "密码至少 8 个字符" },
|
|
{
|
|
pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/,
|
|
message: "密码必须包含大小写字母和数字",
|
|
},
|
|
]}
|
|
>
|
|
<Input.Password prefix={<LockOutlined />} placeholder="•••••••••" size="large" />
|
|
</Form.Item>
|
|
|
|
<Form.Item
|
|
name="confirmPassword"
|
|
label="确认密码"
|
|
dependencies={["password"]}
|
|
rules={[
|
|
{ required: true, message: "请确认密码" },
|
|
({ getFieldValue }) => ({
|
|
validator(_, value) {
|
|
if (!value || getFieldValue("password") === value) {
|
|
return Promise.resolve()
|
|
}
|
|
return Promise.reject(new Error("两次输入的密码不一致"))
|
|
},
|
|
}),
|
|
]}
|
|
>
|
|
<Input.Password prefix={<LockOutlined />} placeholder="•••••••••" size="large" />
|
|
</Form.Item>
|
|
|
|
<Form.Item>
|
|
<Button
|
|
buttonType="primary"
|
|
buttonSize="lg"
|
|
htmlType="submit"
|
|
loading={registerMutation.isPending}
|
|
style={{ width: "100%" }}
|
|
>
|
|
{registerMutation.isPending ? "注册中..." : "注册"}
|
|
</Button>
|
|
</Form.Item>
|
|
|
|
<div className="xx-auth-footer">
|
|
已有账号? <Link to="/login">立即登录</Link>
|
|
</div>
|
|
</Form>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default Register
|