feat: AI Worker 平台 MVP v1.0.0 - 多租户/项目管理/AI Worker/任务编排/HITL审核/成本治理
This commit is contained in:
@@ -0,0 +1,210 @@
|
||||
import { useState } from 'react';
|
||||
import { Card, Form, Input, Button, Tabs, Select, Typography, Space, message } from 'antd';
|
||||
import { RobotOutlined } from '@ant-design/icons';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
import type { UserRole } from '@/types';
|
||||
|
||||
const { Title, Text, Link } = Typography;
|
||||
|
||||
const roles: { value: UserRole; label: string }[] = [
|
||||
{ value: 'tenant_admin', label: '租户管理员' },
|
||||
{ value: 'project_manager', label: '项目经理' },
|
||||
{ value: 'reviewer', label: '审核员' },
|
||||
{ value: 'worker', label: '执行者' },
|
||||
];
|
||||
|
||||
export default function Login() {
|
||||
const navigate = useNavigate();
|
||||
const { login, register } = useAuthStore();
|
||||
const [activeTab, setActiveTab] = useState('login');
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
// Login form
|
||||
const [loginForm] = Form.useForm();
|
||||
// Register form
|
||||
const [regForm] = Form.useForm();
|
||||
|
||||
const handleLogin = async (values: { email: string; password: string }) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
await login(values);
|
||||
message.success('登录成功');
|
||||
navigate('/dashboard');
|
||||
} catch (err) {
|
||||
message.error(err instanceof Error ? err.message : '登录失败');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleRegister = async (values: {
|
||||
email: string;
|
||||
username: string;
|
||||
password: string;
|
||||
role: UserRole;
|
||||
tenant_slug: string;
|
||||
tenant_name: string;
|
||||
}) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
await register(values);
|
||||
message.success('注册成功,欢迎使用!');
|
||||
navigate('/dashboard');
|
||||
} catch (err) {
|
||||
message.error(err instanceof Error ? err.message : '注册失败');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="login-bg">
|
||||
<Card
|
||||
style={{
|
||||
width: 460,
|
||||
boxShadow: '0 8px 32px rgba(0,0,0,0.2)',
|
||||
borderRadius: 12,
|
||||
}}
|
||||
>
|
||||
<div style={{ textAlign: 'center', marginBottom: 24 }}>
|
||||
<Space direction="vertical" size={4}>
|
||||
<RobotOutlined style={{ fontSize: 48, color: '#1677ff' }} />
|
||||
<Title level={3} style={{ margin: 0 }}>
|
||||
AI Worker 平台
|
||||
</Title>
|
||||
<Text type="secondary">AI 工作者项目管理平台</Text>
|
||||
</Space>
|
||||
</div>
|
||||
|
||||
<Tabs
|
||||
activeKey={activeTab}
|
||||
onChange={setActiveTab}
|
||||
centered
|
||||
items={[
|
||||
{
|
||||
key: 'login',
|
||||
label: '登录',
|
||||
children: (
|
||||
<Form
|
||||
form={loginForm}
|
||||
layout="vertical"
|
||||
onFinish={handleLogin}
|
||||
size="large"
|
||||
>
|
||||
<Form.Item
|
||||
name="email"
|
||||
label="邮箱"
|
||||
rules={[
|
||||
{ required: true, message: '请输入邮箱' },
|
||||
{ type: 'email', message: '请输入有效邮箱' },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入邮箱" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="password"
|
||||
label="密码"
|
||||
rules={[{ required: true, message: '请输入密码' }]}
|
||||
>
|
||||
<Input.Password placeholder="请输入密码" />
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
<Button
|
||||
type="primary"
|
||||
htmlType="submit"
|
||||
loading={loading}
|
||||
block
|
||||
>
|
||||
登录
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'register',
|
||||
label: '注册',
|
||||
children: (
|
||||
<Form
|
||||
form={regForm}
|
||||
layout="vertical"
|
||||
onFinish={handleRegister}
|
||||
size="middle"
|
||||
>
|
||||
<Form.Item
|
||||
name="email"
|
||||
label="邮箱"
|
||||
rules={[
|
||||
{ required: true, message: '请输入邮箱' },
|
||||
{ type: 'email', message: '请输入有效邮箱' },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入邮箱" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="username"
|
||||
label="用户名"
|
||||
rules={[{ required: true, message: '请输入用户名' }]}
|
||||
>
|
||||
<Input placeholder="请输入用户名" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="password"
|
||||
label="密码"
|
||||
rules={[
|
||||
{ required: true, message: '请输入密码' },
|
||||
{ min: 6, message: '密码至少6位' },
|
||||
]}
|
||||
>
|
||||
<Input.Password placeholder="至少6位" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="role"
|
||||
label="角色"
|
||||
rules={[{ required: true, message: '请选择角色' }]}
|
||||
>
|
||||
<Select options={roles} placeholder="选择角色" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="tenant_name"
|
||||
label="组织名称"
|
||||
rules={[{ required: true, message: '请输入组织名称' }]}
|
||||
>
|
||||
<Input placeholder="例如:我的团队" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="tenant_slug"
|
||||
label="组织标识"
|
||||
rules={[
|
||||
{ required: true, message: '请输入组织标识' },
|
||||
{ pattern: /^[a-z0-9-]+$/, message: '仅限小写字母、数字和连字符' },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="例如:my-team" />
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
<Button
|
||||
type="primary"
|
||||
htmlType="submit"
|
||||
loading={loading}
|
||||
block
|
||||
>
|
||||
注册
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<Text type="secondary" style={{ fontSize: 12 }}>
|
||||
登录即表示您同意我们的服务条款和隐私政策
|
||||
</Text>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user