feat: gh-ost真实集成验证通过 + 登录页全面中文化 + 外观设置跨浏览器同步修复
gh-ost集成: - handler根据instance_id查DB获取连接信息(host/port/user/password) - 修复gh-ost参数: 去掉不存在的--dry-run(默认noop), 加--execute才真执行 - 加--skip-port-validation(端口映射环境必须) - 加--allow-on-master(单机MySQL直接执行) - 加--initially-drop-ghost-table/old-table/socket-file(清理残留) - GhOstTask增加Port字段, buildArgs同步更新 - dry-run真实验证通过: 连接1.94.55.133:9005, 3行表, 3.85s完成 登录页中文化: - 5个登录组件(SplitView/CenteredCard/SidePanel/FullImage/MinimalDark) - 46处英文文案全部替换为中文 - 平台标题统一为'SQL审核平台' 外观设置同步修复: - GetPublicLoginStyle: GORM First()复用主键导致第二次查询失败 - 改用Take()+重置结构体, 修复theme始终返回dark的bug - UpdateUserPreferences: 同步写入SystemSetting表(login_style+default_theme)
This commit is contained in:
1 parent
62a2b383e1
commit
8aaf2271b8
8 files changed
+135
-61
No files matched your search
@@ -23,9 +23,9 @@ export default function CenteredCard() {
|
||||
<div style={{ position: 'relative', zIndex: 10, width: '100%', maxWidth: 400, background: 'var(--dg-bg-primary)', borderRadius: 14, padding: '40px 32px', boxShadow: '0 8px 32px rgba(0,0,0,0.3)' }}>
|
||||
<div style={{ textAlign: 'center', marginBottom: 32 }}>
|
||||
<h1 style={{ fontSize: 24, fontWeight: 700, marginBottom: 6 }}>
|
||||
<span className="dg-gradient-text">SQL Audit Platform</span>
|
||||
<span className="dg-gradient-text">SQL审核平台</span>
|
||||
</h1>
|
||||
<p style={{ color: 'var(--dg-text-muted)', fontSize: 14 }}>Sign in to your account</p>
|
||||
<p style={{ color: 'var(--dg-text-muted)', fontSize: 14 }}>登录您的账号</p>
|
||||
</div>
|
||||
|
||||
<form onSubmit={handleLogin} style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
|
||||
@@ -33,14 +33,14 @@ export default function CenteredCard() {
|
||||
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Username"
|
||||
placeholder="用户名"
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
style={{ padding: '11px 14px', borderRadius: 8, background: 'var(--dg-bg-secondary)', border: '1px solid var(--dg-border)', color: 'var(--dg-text-primary)', fontSize: 14, outline: 'none' }}
|
||||
/>
|
||||
<input
|
||||
type="password"
|
||||
placeholder="Password"
|
||||
placeholder="密码"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
style={{ padding: '11px 14px', borderRadius: 8, background: 'var(--dg-bg-secondary)', border: '1px solid var(--dg-border)', color: 'var(--dg-text-primary)', fontSize: 14, outline: 'none' }}
|
||||
@@ -52,7 +52,7 @@ export default function CenteredCard() {
|
||||
className="dg-gradient-bg"
|
||||
style={{ padding: '11px 14px', borderRadius: 8, border: 'none', color: '#fff', fontWeight: 600, fontSize: 14, cursor: loading || !username || !password ? 'not-allowed' : 'pointer', opacity: loading || !username || !password ? 0.6 : 1, marginTop: 4 }}
|
||||
>
|
||||
{loading ? 'Signing in…' : 'Sign in'}
|
||||
{loading ? '登录中…' : '登录'}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -40,9 +40,9 @@ export default function FullImage() {
|
||||
>
|
||||
<div style={{ textAlign: 'center', marginBottom: 32 }}>
|
||||
<h1 style={{ fontSize: 24, fontWeight: 700, marginBottom: 6 }}>
|
||||
<span className="dg-gradient-text">SQL Audit Platform</span>
|
||||
<span className="dg-gradient-text">SQL审核平台</span>
|
||||
</h1>
|
||||
<p style={{ color: 'rgba(255,255,255,0.6)', fontSize: 14 }}>Sign in to your workspace</p>
|
||||
<p style={{ color: 'rgba(255,255,255,0.6)', fontSize: 14 }}>登录您的工作区</p>
|
||||
</div>
|
||||
|
||||
<form onSubmit={handleLogin} style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
|
||||
@@ -50,14 +50,14 @@ export default function FullImage() {
|
||||
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Username"
|
||||
placeholder="用户名"
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
style={{ padding: '11px 14px', borderRadius: 8, background: 'rgba(255,255,255,0.08)', border: '1px solid rgba(255,255,255,0.12)', color: '#fff', fontSize: 14, outline: 'none' }}
|
||||
/>
|
||||
<input
|
||||
type="password"
|
||||
placeholder="Password"
|
||||
placeholder="密码"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
style={{ padding: '11px 14px', borderRadius: 8, background: 'rgba(255,255,255,0.08)', border: '1px solid rgba(255,255,255,0.12)', color: '#fff', fontSize: 14, outline: 'none' }}
|
||||
@@ -69,7 +69,7 @@ export default function FullImage() {
|
||||
className="dg-gradient-bg"
|
||||
style={{ padding: '11px 14px', borderRadius: 8, border: 'none', color: '#fff', fontWeight: 600, fontSize: 14, cursor: loading || !username || !password ? 'not-allowed' : 'pointer', opacity: loading || !username || !password ? 0.6 : 1, marginTop: 4 }}
|
||||
>
|
||||
{loading ? 'Signing in…' : 'Sign in'}
|
||||
{loading ? '登录中…' : '登录'}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -18,23 +18,23 @@ export default function MinimalDark() {
|
||||
<div style={{ width: '100%', maxWidth: 320, textAlign: 'center' }}>
|
||||
<Database size={36} className="dg-gradient-text" style={{ marginBottom: 16, display: 'inline-block' }} />
|
||||
<h1 style={{ fontSize: 22, fontWeight: 700, marginBottom: 4 }}>
|
||||
<span className="dg-gradient-text">SQL Audit Platform</span>
|
||||
<span className="dg-gradient-text">SQL审核平台</span>
|
||||
</h1>
|
||||
<p style={{ color: 'var(--dg-text-muted)', fontSize: 13, marginBottom: 36 }}>Secure database auditing & compliance</p>
|
||||
<p style={{ color: 'var(--dg-text-muted)', fontSize: 13, marginBottom: 36 }}>安全的数据库审核与合规管理</p>
|
||||
|
||||
<form onSubmit={handleLogin} style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
|
||||
{error && <div style={{ color: '#f87171', fontSize: 13 }}>{error}</div>}
|
||||
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Username"
|
||||
placeholder="用户名"
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
style={{ padding: '10px 14px', borderRadius: 8, background: 'var(--dg-bg-secondary)', border: 'none', color: 'var(--dg-text-primary)', fontSize: 14, outline: 'none' }}
|
||||
/>
|
||||
<input
|
||||
type="password"
|
||||
placeholder="Password"
|
||||
placeholder="密码"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
style={{ padding: '10px 14px', borderRadius: 8, background: 'var(--dg-bg-secondary)', border: 'none', color: 'var(--dg-text-primary)', fontSize: 14, outline: 'none' }}
|
||||
@@ -46,7 +46,7 @@ export default function MinimalDark() {
|
||||
className="dg-gradient-bg"
|
||||
style={{ padding: '10px 14px', borderRadius: 8, border: 'none', color: '#fff', fontWeight: 600, fontSize: 14, cursor: loading || !username || !password ? 'not-allowed' : 'pointer', opacity: loading || !username || !password ? 0.6 : 1, marginTop: 8 }}
|
||||
>
|
||||
{loading ? 'Signing in…' : 'Sign in'}
|
||||
{loading ? '登录中…' : '登录'}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -29,9 +29,9 @@ export default function SidePanel() {
|
||||
|
||||
<div style={{ position: 'relative', zIndex: 2, textAlign: 'center', maxWidth: 320 }}>
|
||||
<Database size={40} style={{ color: '#fff', marginBottom: 20 }} />
|
||||
<h1 style={{ fontSize: 26, fontWeight: 700, color: '#fff', marginBottom: 12 }}>SQL Audit Platform</h1>
|
||||
<h1 style={{ fontSize: 26, fontWeight: 700, color: '#fff', marginBottom: 12 }}>SQL审核平台</h1>
|
||||
<p style={{ color: 'rgba(255,255,255,0.7)', fontSize: 14, lineHeight: 1.6 }}>
|
||||
Empowering teams with intelligent SQL auditing, real-time compliance monitoring, and actionable insights for database security.
|
||||
为团队提供智能 SQL 审核、实时合规监控与数据库安全保障。
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -39,21 +39,21 @@ export default function SidePanel() {
|
||||
{/* Right Panel — Login Form */}
|
||||
<div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 48 }}>
|
||||
<form onSubmit={handleLogin} style={{ width: '100%', maxWidth: 360, display: 'flex', flexDirection: 'column', gap: 20 }}>
|
||||
<h2 style={{ fontSize: 22, fontWeight: 600, marginBottom: 4 }}>Welcome back</h2>
|
||||
<p style={{ color: 'var(--dg-text-muted)', fontSize: 14, marginBottom: 8 }}>Sign in to access your dashboard</p>
|
||||
<h2 style={{ fontSize: 22, fontWeight: 600, marginBottom: 4 }}>欢迎回来</h2>
|
||||
<p style={{ color: 'var(--dg-text-muted)', fontSize: 14, marginBottom: 8 }}>登录以访问控制台</p>
|
||||
|
||||
{error && <div style={{ color: '#f87171', fontSize: 13 }}>{error}</div>}
|
||||
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Username"
|
||||
placeholder="用户名"
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
style={{ padding: '10px 14px', borderRadius: 8, background: 'var(--dg-bg-tertiary)', border: '1px solid var(--dg-border)', color: 'var(--dg-text-primary)', fontSize: 14, outline: 'none' }}
|
||||
/>
|
||||
<input
|
||||
type="password"
|
||||
placeholder="Password"
|
||||
placeholder="密码"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
style={{ padding: '10px 14px', borderRadius: 8, background: 'var(--dg-bg-tertiary)', border: '1px solid var(--dg-border)', color: 'var(--dg-text-primary)', fontSize: 14, outline: 'none' }}
|
||||
@@ -65,7 +65,7 @@ export default function SidePanel() {
|
||||
className="dg-gradient-bg"
|
||||
style={{ padding: '10px 14px', borderRadius: 8, border: 'none', color: '#fff', fontWeight: 600, fontSize: 14, cursor: loading || !username || !password ? 'not-allowed' : 'pointer', opacity: loading || !username || !password ? 0.6 : 1 }}
|
||||
>
|
||||
{loading ? 'Signing in…' : 'Sign in'}
|
||||
{loading ? '登录中…' : '登录'}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -3,12 +3,12 @@ import { useTheme } from '@/hooks/useTheme';
|
||||
import { Sun, Moon, Database, Code, GitBranch, Bell, History, UserCog } from 'lucide-react';
|
||||
|
||||
const features = [
|
||||
{ icon: Database, label: 'SQL Auditing', desc: 'Real-time query analysis' },
|
||||
{ icon: Code, label: 'Smart Rules', desc: 'Custom compliance rules' },
|
||||
{ icon: GitBranch, label: 'Version Control', desc: 'Track schema changes' },
|
||||
{ icon: Bell, label: 'Alerts', desc: 'Instant notifications' },
|
||||
{ icon: History, label: 'History', desc: 'Full audit trail' },
|
||||
{ icon: UserCog, label: 'Access Control', desc: 'Role-based permissions' },
|
||||
{ icon: Database, label: 'SQL审核', desc: '实时查询分析与合规检测' },
|
||||
{ icon: Code, label: '智能规则', desc: '自定义审核规则引擎' },
|
||||
{ icon: GitBranch, label: '变更管理', desc: 'DDL/DML 变更审批流' },
|
||||
{ icon: Bell, label: '即时通知', desc: '多渠道消息推送' },
|
||||
{ icon: History, label: '审计追踪', desc: '完整操作历史记录' },
|
||||
{ icon: UserCog, label: '权限管理', desc: '基于角色的访问控制' },
|
||||
];
|
||||
|
||||
export default function SplitView() {
|
||||
@@ -28,10 +28,10 @@ export default function SplitView() {
|
||||
<div style={{ flex: 1, display: 'flex', flexDirection: 'column', justifyContent: 'center', padding: '48px 40px', background: 'var(--dg-bg-secondary)' }}>
|
||||
<div style={{ maxWidth: 440 }}>
|
||||
<h1 style={{ fontSize: 28, fontWeight: 700, marginBottom: 8 }}>
|
||||
<span className="dg-gradient-text">SQL Audit Platform</span>
|
||||
<span className="dg-gradient-text">SQL审核平台</span>
|
||||
</h1>
|
||||
<p style={{ color: 'var(--dg-text-muted)', fontSize: 15, marginBottom: 36, lineHeight: 1.5 }}>
|
||||
Enterprise-grade SQL auditing and compliance management.
|
||||
企业级 SQL 审核与合规管理平台。
|
||||
</p>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
|
||||
{features.map((f) => (
|
||||
@@ -51,21 +51,21 @@ export default function SplitView() {
|
||||
onSubmit={handleLogin}
|
||||
style={{ width: '100%', maxWidth: 360, display: 'flex', flexDirection: 'column', gap: 20 }}
|
||||
>
|
||||
<h2 style={{ fontSize: 22, fontWeight: 600, marginBottom: 4 }}>Sign in</h2>
|
||||
<p style={{ color: 'var(--dg-text-muted)', fontSize: 14, marginBottom: 8 }}>Enter your credentials to continue</p>
|
||||
<h2 style={{ fontSize: 22, fontWeight: 600, marginBottom: 4 }}>登录</h2>
|
||||
<p style={{ color: 'var(--dg-text-muted)', fontSize: 14, marginBottom: 8 }}>请输入您的账号信息</p>
|
||||
|
||||
{error && <div style={{ color: '#f87171', fontSize: 13 }}>{error}</div>}
|
||||
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Username"
|
||||
placeholder="用户名"
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
style={{ padding: '10px 14px', borderRadius: 8, background: 'var(--dg-bg-tertiary)', border: '1px solid var(--dg-border)', color: 'var(--dg-text-primary)', fontSize: 14, outline: 'none' }}
|
||||
/>
|
||||
<input
|
||||
type="password"
|
||||
placeholder="Password"
|
||||
placeholder="密码"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
style={{ padding: '10px 14px', borderRadius: 8, background: 'var(--dg-bg-tertiary)', border: '1px solid var(--dg-border)', color: 'var(--dg-text-primary)', fontSize: 14, outline: 'none' }}
|
||||
@@ -77,7 +77,7 @@ export default function SplitView() {
|
||||
className="dg-gradient-bg"
|
||||
style={{ padding: '10px 14px', borderRadius: 8, border: 'none', color: '#fff', fontWeight: 600, fontSize: 14, cursor: loading || !username || !password ? 'not-allowed' : 'pointer', opacity: loading || !username || !password ? 0.6 : 1 }}
|
||||
>
|
||||
{loading ? 'Signing in…' : 'Sign in'}
|
||||
{loading ? '登录中…' : '登录'}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user