feat: DevTools调试工具 + 前端样式修复 + 管理员登录系统
DevTools (新增): - 进程管理器: 启动/停止/重启/编译 + 端口自动释放 - 服务接管 (tryAdopt): 检测已运行服务,健康检查通过则直接接管 - 一键启动 (startAllSequential): 按 ai-core→gateway→frontend 顺序启动 - 日志布局切换: 标签页模式 ↔ 三栏并列模式 - 性能监控: CPU/内存采样 + SVG 折线图 - Web UI + WebSocket 实时推送 前端修复: - tailwind.config.ts: 修复空配置导致 CSS 不加载 (增加 content/colors/fontFamily) - postcss.config.js: 新建缺失的 PostCSS 配置 - App.tsx: 移除注册功能,仅保留管理员登录 (admin / cyrene-dev-admin) 后端新增: - config.go: AdminUsername/AdminPassword/RegistrationEnabled 环境变量 - auth_handler.go: 管理员登录 + 注册邮箱验证码 + 注册开关控制 - 管理员凭据: admin / cyrene-dev-admin (默认) 其他: - .gitignore: 新增 devtools/node_modules/ devtools/logs/ devtools/package-lock.json - devtools.sh: DevTools 一键启动脚本
This commit is contained in:
Generated
+1
-2746
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>昔涟 - Cyrene AI</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
Generated
+2815
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,6 @@
|
||||
export default {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
||||
+15
-32
@@ -6,24 +6,22 @@ import { useAuth } from '@/hooks/useAuth';
|
||||
import { useChat } from '@/hooks/useChat';
|
||||
|
||||
export default function App() {
|
||||
const { isLoggedIn, login, register, loading: authLoading } = useAuth();
|
||||
const { isLoggedIn, login, loading: authLoading } = useAuth();
|
||||
const { send } = useChat();
|
||||
|
||||
const [authMode, setAuthMode] = useState<'login' | 'register'>('login');
|
||||
const [username, setUsername] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [error, setError] = useState('');
|
||||
|
||||
const handleAuth = async () => {
|
||||
const handleLogin = async () => {
|
||||
setError('');
|
||||
const fn = authMode === 'login' ? login : register;
|
||||
const result = await fn(username, password);
|
||||
const result = await login(username, password);
|
||||
if (!result.success) {
|
||||
setError(result.error || '操作失败');
|
||||
setError(result.error || '登录失败');
|
||||
}
|
||||
};
|
||||
|
||||
// 登录页面
|
||||
// 登录页面 (开发阶段禁用注册)
|
||||
if (!isLoggedIn) {
|
||||
return (
|
||||
<div className="min-h-screen bg-[#FFFAF5] dark:bg-[#1a1a2e] flex items-center justify-center p-4">
|
||||
@@ -39,27 +37,8 @@ export default function App() {
|
||||
|
||||
{/* 表单 */}
|
||||
<div className="bg-white dark:bg-gray-900 rounded-2xl shadow-lg p-6 space-y-4 border border-pink-100 dark:border-pink-900">
|
||||
<div className="flex rounded-lg bg-gray-100 dark:bg-gray-800 p-1">
|
||||
<button
|
||||
onClick={() => setAuthMode('login')}
|
||||
className={`flex-1 py-2 text-sm rounded-md transition-colors ${
|
||||
authMode === 'login'
|
||||
? 'bg-white dark:bg-gray-700 text-pink-500 font-medium shadow-sm'
|
||||
: 'text-gray-400'
|
||||
}`}
|
||||
>
|
||||
登录
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setAuthMode('register')}
|
||||
className={`flex-1 py-2 text-sm rounded-md transition-colors ${
|
||||
authMode === 'register'
|
||||
? 'bg-white dark:bg-gray-700 text-pink-500 font-medium shadow-sm'
|
||||
: 'text-gray-400'
|
||||
}`}
|
||||
>
|
||||
注册
|
||||
</button>
|
||||
<div className="text-center mb-2">
|
||||
<span className="text-sm font-medium text-pink-500">管理员登录</span>
|
||||
</div>
|
||||
|
||||
<input
|
||||
@@ -67,7 +46,7 @@ export default function App() {
|
||||
placeholder="用户名"
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
onKeyDown={(e) => e.key === 'Enter' && handleAuth()}
|
||||
onKeyDown={(e) => e.key === 'Enter' && handleLogin()}
|
||||
className="w-full px-4 py-2.5 rounded-xl border border-pink-200 dark:border-pink-800 bg-white dark:bg-gray-800 text-sm text-gray-700 dark:text-gray-200 placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-pink-400"
|
||||
/>
|
||||
|
||||
@@ -76,7 +55,7 @@ export default function App() {
|
||||
placeholder="密码"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
onKeyDown={(e) => e.key === 'Enter' && handleAuth()}
|
||||
onKeyDown={(e) => e.key === 'Enter' && handleLogin()}
|
||||
className="w-full px-4 py-2.5 rounded-xl border border-pink-200 dark:border-pink-800 bg-white dark:bg-gray-800 text-sm text-gray-700 dark:text-gray-200 placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-pink-400"
|
||||
/>
|
||||
|
||||
@@ -85,12 +64,16 @@ export default function App() {
|
||||
)}
|
||||
|
||||
<button
|
||||
onClick={handleAuth}
|
||||
onClick={handleLogin}
|
||||
disabled={authLoading || !username || !password}
|
||||
className="w-full py-2.5 rounded-xl bg-pink-400 hover:bg-pink-500 disabled:bg-pink-300 text-white font-medium text-sm transition-colors"
|
||||
>
|
||||
{authLoading ? '请稍候...' : authMode === 'login' ? '进入昔涟的世界 ♪' : '注册并开始'}
|
||||
{authLoading ? '请稍候...' : '进入昔涟的世界 ♪'}
|
||||
</button>
|
||||
|
||||
<p className="text-xs text-gray-400 text-center">
|
||||
开发阶段 · 管理员: admin / cyrene-dev-admin
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { CyreneAvatar } from '@/components/persona/CyreneAvatar';
|
||||
|
||||
interface MessageBubbleProps {
|
||||
role: 'user' | 'assistant';
|
||||
role: 'user' | 'assistant' | 'system';
|
||||
content: string;
|
||||
timestamp: number;
|
||||
isStreaming?: boolean;
|
||||
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
/// <reference types="vite/client" />
|
||||
@@ -0,0 +1,31 @@
|
||||
import type { Config } from 'tailwindcss';
|
||||
|
||||
export default {
|
||||
content: [
|
||||
'./index.html',
|
||||
'./src/**/*.{js,ts,jsx,tsx}',
|
||||
],
|
||||
darkMode: 'media',
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
pink: {
|
||||
50: '#fdf2f8',
|
||||
100: '#fce7f3',
|
||||
200: '#fbcfe8',
|
||||
300: '#f9a8d4',
|
||||
400: '#f472b6',
|
||||
500: '#ec4899',
|
||||
600: '#db2777',
|
||||
700: '#be185d',
|
||||
800: '#9d174d',
|
||||
900: '#831843',
|
||||
},
|
||||
},
|
||||
fontFamily: {
|
||||
sans: ['"Noto Sans SC"', '-apple-system', 'BlinkMacSystemFont', '"Segoe UI"', 'Roboto', 'sans-serif'],
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
} satisfies Config;
|
||||
|
||||
Reference in New Issue
Block a user