From 80bda8c021e006888213f489946e101d3b7134e2 Mon Sep 17 00:00:00 2001 From: xiamuceer-j Date: Fri, 6 Mar 2026 14:14:09 +0800 Subject: [PATCH] =?UTF-8?q?feature:=20=E6=96=B0=E5=A2=9E=E5=85=A8=E6=96=B0?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E9=A1=B5=E5=B8=83=E5=B1=80=E4=B8=8E=E4=B8=BB?= =?UTF-8?q?=E9=A2=98=E5=88=87=E6=8D=A2=E5=85=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/Login.tsx | 461 ++++++++++++++++++++++------------- 1 file changed, 290 insertions(+), 171 deletions(-) diff --git a/frontend/src/pages/Login.tsx b/frontend/src/pages/Login.tsx index 08ce433..d6573e5 100644 --- a/frontend/src/pages/Login.tsx +++ b/frontend/src/pages/Login.tsx @@ -1,10 +1,12 @@ import { useEffect, useState } from 'react'; -import { Button, Card, Space, Typography, message, Spin, Form, Input, Tabs } from 'antd'; -import { UserOutlined, LockOutlined } from '@ant-design/icons'; +import { Alert, Button, Card, Col, Divider, Form, Input, Layout, Row, Space, Spin, Tag, Typography, message, theme } from 'antd'; +import { BookOutlined, LockOutlined, RobotOutlined, SafetyCertificateOutlined, TeamOutlined, ThunderboltOutlined, UserOutlined } from '@ant-design/icons'; import { authApi } from '../services/api'; import { useNavigate, useSearchParams } from 'react-router-dom'; import AnnouncementModal from '../components/AnnouncementModal'; +import ThemeSwitch from '../components/ThemeSwitch'; + const { Title, Paragraph } = Typography; export default function Login() { @@ -15,8 +17,11 @@ export default function Login() { const [localAuthEnabled, setLocalAuthEnabled] = useState(false); const [linuxdoEnabled, setLinuxdoEnabled] = useState(false); const [form] = Form.useForm(); + const { token } = theme.useToken(); + const alphaColor = (color: string, alpha: number) => `color-mix(in srgb, ${color} ${(alpha * 100).toFixed(0)}%, transparent)`; + const primaryButtonShadow = `0 8px 20px ${alphaColor(token.colorPrimary, 0.28)}`; + const hoverButtonShadow = `0 12px 28px ${alphaColor(token.colorPrimary, 0.36)}`; const [showAnnouncement, setShowAnnouncement] = useState(false); - const [activeLoginMethod, setActiveLoginMethod] = useState<'local' | 'linuxdo'>('local'); // 检查是否已登录和获取认证配置 useEffect(() => { @@ -97,9 +102,9 @@ export default function Login() { justifyContent: 'center', alignItems: 'center', minHeight: '100vh', - background: 'var(--color-bg-base)', + background: token.colorBgLayout, }}> - + ); } @@ -108,47 +113,52 @@ export default function Login() { const renderLocalLogin = () => (
} - placeholder="用户名" + prefix={} + placeholder="请输入管理账号" autoComplete="username" + style={{ height: 46, borderRadius: 12 }} /> } - placeholder="密码" + prefix={} + placeholder="请输入访问密钥" autoComplete="current-password" + style={{ height: 46, borderRadius: 12 }} /> - + @@ -156,7 +166,7 @@ export default function Login() { // 渲染LinuxDO登录 const renderLinuxDOLogin = () => ( -
+
); @@ -216,11 +226,34 @@ export default function Login() { localStorage.setItem('announcement_hide_forever', 'true'); }; - const currentLoginMethod = localAuthEnabled && linuxdoEnabled - ? activeLoginMethod - : localAuthEnabled - ? 'local' - : 'linuxdo'; + const loginTips = [ + '本地登录默认账号:admin / admin123', + '首次 LinuxDO 登录会自动创建账号', + '系统采用多用户数据隔离机制,每位用户拥有独立的创作空间与配置。', + ]; + + const featureItems = [ + { + icon: , + title: '多 AI 模型协同', + description: '支持 OpenAI、Gemini、Claude 等主流模型,按场景灵活切换。', + }, + { + icon: , + title: '智能向导驱动', + description: '自动生成大纲、角色与世界观,快速搭建完整故事骨架。', + }, + { + icon: , + title: '角色组织管理', + description: '人物关系、组织架构可视化管理,复杂设定也能清晰掌控。', + }, + { + icon: , + title: '章节创作闭环', + description: '支持章节生成、编辑、重写与润色,持续提升内容质量。', + }, + ]; return ( <> @@ -230,155 +263,241 @@ export default function Login() { onDoNotShowToday={handleDoNotShowToday} onNeverShow={handleNeverShow} /> -
- {/* 装饰性背景元素 */} -
-
- - +
- - {/* Logo区域 */} -
-
+
+ + +
+
+ +
+ +
+ MuMuAINovel +
+ + MuMuAINovel + +
+ + +
+ + 基于 AI 的 + <br /> + <span + style={{ + backgroundImage: `linear-gradient(90deg, ${token.colorPrimary} 0%, #d946ef 100%)`, + WebkitBackgroundClip: 'text', + backgroundClip: 'text', + WebkitTextFillColor: 'transparent', + color: token.colorPrimary, + }} + > + 智能小说创作助手 + </span> + + + 从灵感到成稿,围绕「多模型协同、创作流程自动化、角色关系管理、章节精修」构建一体化创作工作台。 + +
+ + + {featureItems.map((item) => ( + + + + + {item.icon} + {item.title} + + + {item.description} + + + + + ))} + +
+ + + OpenAI + Gemini + Claude + LinuxDO OAuth + Docker Compose + PostgreSQL + +
+ + + © 2026 MuMuAINovel · GPLv3 License + +
+ + + +
- Logo + padding: '48px min(7vw, 72px)', + background: token.colorBgLayout, + }} + > +
+ + + 欢迎回来 + + + 登录 MuMuAINovel,继续你的小说创作项目。 + + + +
+ {localAuthEnabled ? renderLocalLogin() : null} + + {linuxdoEnabled && localAuthEnabled ? ( + <> + + {renderLinuxDOLogin()} + + ) : null} + + {!localAuthEnabled && linuxdoEnabled ? renderLinuxDOLogin() : null} + + {!localAuthEnabled && !linuxdoEnabled ? ( + + ) : null} + + + } + style={{ background: alphaColor(token.colorPrimary, 0.06), borderRadius: 12 }} + message="登录说明" + description={( +
    + {loginTips.map((tip) => ( +
  • + {tip} +
  • + ))} +
+ )} + /> +
- - AI小说创作助手 - - - {localAuthEnabled && linuxdoEnabled ? '选择登录方式' : - localAuthEnabled ? '使用账户密码登录' : - '使用 LinuxDO 账号登录'} - -
- - {/* 登录方式 */} - {localAuthEnabled && linuxdoEnabled ? ( - setActiveLoginMethod(key as 'local' | 'linuxdo')} - centered - items={[ - { - key: 'local', - label: '账户密码', - children: renderLocalLogin(), - }, - { - key: 'linuxdo', - label: 'LinuxDO', - children: renderLinuxDOLogin(), - }, - ]} - /> - ) : localAuthEnabled ? ( - renderLocalLogin() - ) : ( - renderLinuxDOLogin() - )} - - {/* 提示信息 */} -
- - {currentLoginMethod === 'linuxdo' ? ( - <> - 🎉 首次登录将自动创建账号 -
- 🔒 每个用户拥有独立的数据空间 - - ) : ( - <> - 🧪 默认账号:admin / admin123 -
- 🔒 每个用户拥有独立的数据空间 - - )} -
-
-
- -
+ + + + ); } \ No newline at end of file