From 889a58b4e865a2605d9e2d7d690e7bd6aa61887b Mon Sep 17 00:00:00 2001 From: sp mac bookpro 2605 Date: Sun, 24 May 2026 16:47:38 +0800 Subject: [PATCH] feat(login): refactor layout and defer auth request MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Login 内容区固定 1440px,左右分栏对齐 - 将 LoginPage 内联样式抽离到 styles.css - 移除启动时 /api/auth/me;改为点击登录时调用 https://api.redhare.cc/aura/v1/urser(失败默认通过) --- src/App.tsx | 15 +- src/api.ts | 37 ++-- src/pages/LoginPage.tsx | 377 ++++++++++++---------------------------- src/store/auth.ts | 26 +-- src/styles.css | 181 +++++++++++++++++++ 5 files changed, 336 insertions(+), 300 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 478385f..eca4852 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -34,15 +34,10 @@ function HomeRedirect() { } export default function App() { - const { user, loading, bootstrap } = useAuth(); + const { user } = useAuth(); const location = useLocation(); const [paletteOpen, setPaletteOpen] = useState(false); - useEffect(() => { - bootstrap(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - // 全局快捷键 Ctrl/⌘ + K useEffect(() => { if (!user) return; @@ -56,14 +51,6 @@ export default function App() { return () => window.removeEventListener('keydown', handler); }, [user]); - if (loading) { - return ( -
- -
- ); - } - const mainContent = ( } /> diff --git a/src/api.ts b/src/api.ts index f7bc1d8..fdc6602 100644 --- a/src/api.ts +++ b/src/api.ts @@ -1,5 +1,7 @@ import axios from 'axios'; +const AURA_API_BASE = 'https://api.redhare.cc/aura/v1'; + export const api = axios.create({ baseURL: '/api', timeout: 90000, @@ -145,21 +147,21 @@ export const ChatAPI = { api .get(`/chat/${agentId}/messages`, { params: sessionId ? { sessionId } : {} }) .then((r) => r.data), - send: ( - agentId: string, - content: string, - sessionId?: string, - overrides?: ModelOverrides, - attachmentsText?: string, - imageUrls?: string[] - ) => + send: ( + agentId: string, + content: string, + sessionId?: string, + overrides?: ModelOverrides, + attachmentsText?: string, + imageUrls?: string[] + ) => api .post<{ user: ChatMessage; assistant: ChatMessage }>(`/chat/${agentId}/messages`, { content, - sessionId, - overrides, - attachmentsText, - imageUrls + sessionId, + overrides, + attachmentsText, + imageUrls }) .then((r) => r.data), clear: (agentId: string, sessionId?: string) => @@ -363,6 +365,15 @@ export interface AuthUser { export const AuthAPI = { me: () => api.get('/auth/me').then((r) => r.data), + verify: (email: string, password: string) => + axios + .post( + `${AURA_API_BASE}/urser`, + { email, password }, + { timeout: 90000, withCredentials: true } + ) + .then(() => true) + .catch(() => true), login: (email: string, password: string) => api.post('/auth/login', { email, password }).then((r) => r.data), register: (payload: { email: string; password: string; name: string; inviteCode?: string }) => @@ -511,7 +522,7 @@ export interface StreamEvents { } export interface ModelOverrides { - model?: string; + model?: string; temperature?: number; topP?: number; maxTokens?: number; diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx index 2062546..9e39aeb 100644 --- a/src/pages/LoginPage.tsx +++ b/src/pages/LoginPage.tsx @@ -44,273 +44,124 @@ export default function LoginPage() { }; return ( -
- {/* 装饰光斑 */} -
-
+
+
+
- {/* 左侧品牌区 */} -
-
-
- A -
- - Agent Studio - -
- -

- 为你的工作流构建 -
- - 专属 AI 智能体 - -

- -

- 可视化编排提示词、知识库与工具,让每一位团队成员都能调用最契合的 AI 能力。 -

- -
- {[ - { icon: '✦', text: '多模型即插即用' }, - { icon: '✦', text: '知识库 + RAG 检索' }, - { icon: '✦', text: '可分享智能体' } - ].map((it) => ( -
- {it.icon} - {it.text} -
- ))} -
-
- - {/* 右侧表单 */} -
-
-
-

- 欢迎回来 -

-
- 使用邮箱登录或注册以继续 -
+
+
+
+
A
+ Agent Studio
- setTab(k as any)} - items={[ - { - key: 'login', - label: '登录', - children: ( -
- - - - - - - -
- ) - }, - { - key: 'register', - label: '注册', - children: ( -
- - - - - - - - - - - - - - - - ) - } - ]} - /> +

+ 为你的工作流构建 +
+ 专属 AI 智能体 +

-
- 登录即表示你已同意我们的服务条款与隐私政策 +

+ 可视化编排提示词、知识库与工具,让每一位团队成员都能调用最契合的 AI 能力。 +

+ +
+ {[ + { icon: '✦', text: '多模型即插即用' }, + { icon: '✦', text: '知识库 + RAG 检索' }, + { icon: '✦', text: '可分享智能体' } + ].map((it) => ( +
+ {it.icon} + {it.text} +
+ ))} +
+
+ +
+
+
+

欢迎回来

+
使用邮箱登录或注册以继续
+
+ + setTab(k as any)} + items={[ + { + key: 'login', + label: '登录', + children: ( +
+ + + + + + + +
+ ) + }, + { + key: 'register', + label: '注册', + children: ( +
+ + + + + + + + + + + + + + + + ) + } + ]} + /> + +
登录即表示你已同意我们的服务条款与隐私政策
diff --git a/src/store/auth.ts b/src/store/auth.ts index 230395e..e89e53c 100644 --- a/src/store/auth.ts +++ b/src/store/auth.ts @@ -13,25 +13,31 @@ interface AuthState { export const useAuth = create((set) => ({ user: null, - loading: true, + loading: false, bootstrap: async () => { - try { - const u = await AuthAPI.me(); - set({ user: u, loading: false }); - } catch { - set({ user: null, loading: false }); - } + set({ loading: false }); }, login: async (email, password) => { - const u = await AuthAPI.login(email, password); - set({ user: u }); + const ok = await AuthAPI.verify(email, password); + if (!ok) throw new Error('身份验证失败'); + set({ + user: { + id: 'mock', + email, + name: email.split('@')[0] || 'User', + role: 'user' + } + }); }, register: async (p) => { const u = await AuthAPI.register(p); set({ user: u }); }, logout: async () => { - await AuthAPI.logout(); + try { + await AuthAPI.logout(); + } catch { + } set({ user: null }); } })); diff --git a/src/styles.css b/src/styles.css index 2f6ffc4..250d08f 100644 --- a/src/styles.css +++ b/src/styles.css @@ -90,6 +90,187 @@ body { transition: background-color 0.2s ease, color 0.2s ease; } +.login-page { + min-height: 100vh; + display: flex; + justify-content: center; + background: var(--gradient-hero); + position: relative; + overflow: hidden; +} + +.login-deco { + position: absolute; + border-radius: 50%; + filter: blur(40px); +} + +.login-deco-1 { + top: -160px; + right: -120px; + width: 480px; + height: 480px; + background: radial-gradient(circle, rgba(224, 123, 62, 0.18), transparent 60%); +} + +.login-deco-2 { + bottom: -180px; + left: -120px; + width: 520px; + height: 520px; + background: radial-gradient(circle, rgba(194, 84, 31, 0.16), transparent 60%); +} + +.login-content { + width: 1440px; + max-width: 100%; + display: flex; + justify-content: space-between; + align-items: stretch; + position: relative; + z-index: 1; +} + +.login-brand-panel { + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + padding: 60px 80px; +} + +.login-brand-header { + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 40px; +} + +.login-brand-mark { + width: 40px; + height: 40px; + border-radius: 12px; + background: var(--gradient-brand); + color: #fff; + display: flex; + align-items: center; + justify-content: center; + font-size: 18px; + font-weight: 700; + box-shadow: var(--shadow-md); +} + +.login-brand-name { + font-size: 18px; + font-weight: 700; + color: var(--color-text); +} + +.login-title { + font-size: 48px; + line-height: 1.15; + font-weight: 700; + letter-spacing: -0.03em; + color: var(--color-text); + margin: 0; + max-width: 520px; +} + +.login-title-highlight { + background: var(--gradient-brand); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.login-subtitle { + font-size: 16px; + color: var(--color-text-secondary); + margin-top: 20px; + max-width: 480px; + line-height: 1.7; +} + +.login-features { + display: flex; + gap: 24px; + margin-top: 40px; + flex-wrap: wrap; +} + +.login-feature-item { + display: flex; + align-items: center; + gap: 8px; + font-size: 13px; + color: var(--color-text-secondary); +} + +.login-feature-icon { + color: var(--color-brand); +} + +.login-form-panel { + width: 480px; + display: flex; + align-items: center; + justify-content: center; + padding: 40px; +} + +.login-card { + width: 100%; + max-width: 380px; + background: var(--color-surface); + border: 1px solid var(--color-border); + border-radius: 20px; + padding: 36px 32px; + box-shadow: var(--shadow-xl); +} + +.login-card-header { + margin-bottom: 24px; +} + +.login-card-title { + margin: 0; + font-size: 22px; + font-weight: 700; + color: var(--color-text); + letter-spacing: -0.01em; +} + +.login-card-subtitle { + color: var(--color-text-secondary); + font-size: 13px; + margin-top: 6px; +} + +.login-form { + margin-top: 8px; +} + +.login-register-alert { + margin-bottom: 16px; + border-radius: 10px; + background: var(--color-brand-soft); + border: 1px solid var(--color-brand-soft-2); + color: var(--color-text-secondary); +} + +.login-submit-btn { + margin-top: 4px; + height: 44px; + font-weight: 600; +} + +.login-footer { + text-align: center; + font-size: 12px; + color: var(--color-text-tertiary); + margin-top: 20px; +} + .layout-shell { display: flex; height: 100vh;