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}
-
- ))}
-
-
-
- {/* 右侧表单 */}
-
-
-
-
- 欢迎回来
-
-
- 使用邮箱登录或注册以继续
-
+
+
+
-
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}
+
+ ))}
+
+
+
+
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;