From 157d8133f92e6362c3b01ba495a9cdb4cb43c081 Mon Sep 17 00:00:00 2001 From: Harmon Date: Tue, 30 Jun 2026 18:47:53 +0800 Subject: [PATCH] Redesign login page with feature carousel --- frontend/src/App.css | 186 ++++++++++++++++-- frontend/src/App.jsx | 2 +- frontend/src/LoginPage.jsx | 153 +++++++++----- .../src/assets/login/cluster-delivery.svg | 78 ++++++++ .../assets/login/processing-architecture.svg | 85 ++++++++ frontend/src/assets/login/system-overview.svg | 81 ++++++++ 6 files changed, 526 insertions(+), 59 deletions(-) create mode 100644 frontend/src/assets/login/cluster-delivery.svg create mode 100644 frontend/src/assets/login/processing-architecture.svg create mode 100644 frontend/src/assets/login/system-overview.svg diff --git a/frontend/src/App.css b/frontend/src/App.css index 0c04761..4e7fdca 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -4125,30 +4125,49 @@ input[type="checkbox"] { .login-page-wrapper { min-height: 100vh; - background: radial-gradient(circle at 12% 10%, rgba(37, 99, 235, 0.15) 0%, transparent 42%), - radial-gradient(circle at 90% 0%, rgba(14, 165, 233, 0.14) 0%, transparent 45%), + background: + linear-gradient(135deg, rgba(15, 23, 42, 0.04), rgba(37, 99, 235, 0.07)), linear-gradient(180deg, #f8fafc 0%, #e8eefc 100%); display: flex; align-items: center; justify-content: center; - padding: 24px; + padding: 28px; +} + +.login-shell { + width: min(1180px, 100%); + min-height: min(720px, calc(100vh - 56px)); + display: grid; + grid-template-columns: minmax(340px, 420px) minmax(0, 1fr); + background: #ffffff; + border: 1px solid #dbe4f3; + border-radius: 18px; + box-shadow: 0 18px 38px rgba(15, 23, 42, 0.14); + overflow: hidden; } .login-card { - width: min(420px, 94vw); + width: 100%; background: #ffffff; - border: 1px solid #dbe4f3; - border-radius: 16px; - box-shadow: 0 24px 52px rgba(15, 23, 42, 0.16); - padding: 24px; + border-right: 1px solid #dbe4f3; + padding: 34px; display: flex; flex-direction: column; - gap: 14px; + justify-content: center; + gap: 16px; +} + +.login-card--checking { + width: min(420px, 94vw); + border: 1px solid #dbe4f3; + border-radius: 14px; + box-shadow: var(--shadow-panel); } .login-card h2 { margin: 0; - font-size: 1.4em; + font-size: 1.55em; + line-height: 1.25; color: var(--color-text-primary); } @@ -4166,7 +4185,7 @@ input[type="checkbox"] { color: var(--color-accent-strong); font-weight: 700; font-size: 0.75em; - letter-spacing: 0.4px; + letter-spacing: 0; padding: 4px 10px; } @@ -4196,7 +4215,7 @@ input[type="checkbox"] { .login-card input, .login-card select { width: 100%; - padding: 10px 12px; + padding: 11px 12px; border: 1px solid #cbd5e1; border-radius: 8px; font-size: 0.95em; @@ -4240,6 +4259,149 @@ input[type="checkbox"] { color: #1e3a8a; } +.login-submit-btn { + min-height: 42px; + border-radius: 8px; + font-weight: 700; +} + +.login-visual-panel { + min-width: 0; + display: grid; + grid-template-rows: auto minmax(0, 1fr) auto; + gap: 18px; + padding: 34px; + background: #f8fafc; +} + +.login-slide-copy { + max-width: 680px; +} + +.login-slide-copy span { + color: var(--color-accent-strong); + font-size: 0.82em; + font-weight: 700; +} + +.login-slide-copy h3 { + margin: 8px 0 8px; + color: var(--color-text-primary); + font-size: 1.55em; + line-height: 1.25; +} + +.login-slide-copy p { + margin: 0; + color: var(--color-text-secondary); + line-height: 1.58; +} + +.login-slide-frame { + position: relative; + min-height: 0; + border: 1px solid #cbd5e1; + border-radius: 12px; + overflow: hidden; + background: #0f172a; +} + +.login-slide-image { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + object-fit: cover; + opacity: 0; + transform: scale(1.018); + transition: opacity 0.45s ease, transform 0.7s ease; +} + +.login-slide-image.active { + opacity: 1; + transform: scale(1); +} + +.login-slide-dots { + display: flex; + justify-content: center; + gap: 8px; +} + +.login-slide-dots button { + width: 30px; + height: 8px; + border: 1px solid #93a4bd; + border-radius: 999px; + background: #e2e8f0; + padding: 0; + cursor: pointer; +} + +.login-slide-dots button.active { + width: 42px; + border-color: var(--color-accent); + background: var(--color-accent); +} + +@media (max-width: 920px) { + .login-page-wrapper { + align-items: flex-start; + overflow-y: auto; + } + + .login-shell { + min-height: auto; + grid-template-columns: 1fr; + } + + .login-card { + border-right: none; + border-bottom: 1px solid #dbe4f3; + padding: 24px; + } + + .login-visual-panel { + min-height: 420px; + padding: 24px; + } +} + +@media (max-width: 560px) { + .login-page-wrapper { + padding: 12px; + } + + .login-shell { + border-radius: 12px; + } + + .login-card, + .login-visual-panel { + padding: 18px; + } + + .login-card h2, + .login-slide-copy h3 { + font-size: 1.28em; + } + + .login-visual-panel { + min-height: 360px; + } +} + +@media (prefers-reduced-motion: reduce) { + .login-slide-image { + transition: opacity 0.15s ease; + transform: none; + } + + .login-slide-image.active { + transform: none; + } +} + .user-role-chip { display: inline-flex; align-items: center; diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 8f269f0..5486f21 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -2095,7 +2095,7 @@ function App() { if (!authChecked) { return (
-
+

正在检查登录状态...

请稍候,系统正在验证会话。

diff --git a/frontend/src/LoginPage.jsx b/frontend/src/LoginPage.jsx index e1c42c1..2a9a878 100644 --- a/frontend/src/LoginPage.jsx +++ b/frontend/src/LoginPage.jsx @@ -1,5 +1,26 @@ import React, { useEffect, useState } from 'react'; import apiClient from './api/client'; +import clusterDeliveryUrl from './assets/login/cluster-delivery.svg'; +import processingArchitectureUrl from './assets/login/processing-architecture.svg'; +import systemOverviewUrl from './assets/login/system-overview.svg'; + +const loginSlides = [ + { + title: '统一管理雷达数据生产流程', + description: '覆盖源数据入库、精密轨道匹配、生产编排、成果目录和地图分析,形成可审计的工程闭环。', + image: systemOverviewUrl, + }, + { + title: '面向 D-InSAR / SBAS 的处理链路', + description: '扫描与解析先行,生产任务进入队列,运行结果和失败归因统一登记,便于复查和补跑。', + image: processingArchitectureUrl, + }, + { + title: '支持集群生产与成果交付', + description: '主服务器负责资产、权限和审计,生产节点承担受控处理服务,结果回传后进入交付申请与下载流程。', + image: clusterDeliveryUrl, + }, +]; const LoginPage = ({ onLoginSuccess }) => { const [username, setUsername] = useState(''); @@ -7,6 +28,7 @@ const LoginPage = ({ onLoginSuccess }) => { const [loading, setLoading] = useState(false); const [message, setMessage] = useState(''); const [licenseStatus, setLicenseStatus] = useState(null); + const [activeSlide, setActiveSlide] = useState(0); useEffect(() => { const checkLicense = async () => { @@ -20,6 +42,13 @@ const LoginPage = ({ onLoginSuccess }) => { checkLicense(); }, []); + useEffect(() => { + const timer = window.setInterval(() => { + setActiveSlide((current) => (current + 1) % loginSlides.length); + }, 5200); + return () => window.clearInterval(timer); + }, []); + const handleSubmit = async (event) => { event.preventDefault(); setLoading(true); @@ -48,57 +77,89 @@ const LoginPage = ({ onLoginSuccess }) => { return (
-
-
-
InSAR
-

管理系统登录

-

内网受控访问,请使用管理员分配的账号登录。

-
- - {licenseStatus && !licenseStatus.ok && ( -
- 当前授权状态异常:{licenseStatus.reason || '未授权'} +
+
+
+
InSAR Production
+

雷达数据生产管理系统

+

内网受控访问,请使用管理员分配的账号登录。

- )} -
- - - -
+ {licenseStatus && !licenseStatus.ok && ( +
+ 当前授权状态异常:{licenseStatus.reason || '未授权'} +
+ )} - {message && ( -
- {message} +
+ + + +
+ + {message && ( +
+ {message} +
+ )} + +
+ 提示: + 首次部署请确认已在 `.env` 配置管理员账号与密码。
- )} +
-
- 提示: - 首次部署请确认已在 `.env` 配置管理员账号与密码。 -
+
+
+ 系统能力 +

{loginSlides[activeSlide].title}

+

{loginSlides[activeSlide].description}

+
+
+ {loginSlides.map((slide, index) => ( + {slide.title} + ))} +
+
+ {loginSlides.map((slide, index) => ( +
+
); diff --git a/frontend/src/assets/login/cluster-delivery.svg b/frontend/src/assets/login/cluster-delivery.svg new file mode 100644 index 0000000..167e276 --- /dev/null +++ b/frontend/src/assets/login/cluster-delivery.svg @@ -0,0 +1,78 @@ + + Cluster and Result Delivery Architecture + A cluster processing and result delivery architecture for radar data production. + + + + + + + + + + + + + + + + + + 集群生产与成果交付 + 主服务器统一管理任务,子服务器只承担受控生产服务,成果回传后进入交付流程。 + + + 主服务器 + 资产、任务、用户、审计 + + + 任务队列 + + 成果目录 + + 用户权限 + + + + + 生产节点 + LandSAR / Gamma 执行 + + + 1.6 + + GPU + + 受控 Worker 服务 + + + + + 成果交付 + 申请、打包、下载 + + + + 交付包 + D-InSAR / SBAS + LT-1 / GF3 正射 + + + + + + + + + + + + + + + + + 最小化子服务器代码暴露:仅部署受控执行服务、运行环境和任务数据目录;业务资产与权限仍由主服务器统一管理。 + + + diff --git a/frontend/src/assets/login/processing-architecture.svg b/frontend/src/assets/login/processing-architecture.svg new file mode 100644 index 0000000..7bec2a2 --- /dev/null +++ b/frontend/src/assets/login/processing-architecture.svg @@ -0,0 +1,85 @@ + + Production Pipeline Architecture + A pipeline diagram for SAR data parsing, precise orbit matching, D-InSAR and SBAS production, and catalog registration. + + + + + + + + + + + + + + + + + + 生产处理链路 + 增量扫描优先,解析与预览异步,生产结果统一登记到成果目录。 + + + + 源数据扫描 + 增量过滤 + + + + 元数据解析 + XML / TAR / ZIP + + + + 精轨匹配 + 自动补链 + + + + 生产编排 + 队列 / Worker + + + + 成果 + 登记交付 + + + + + + + + + + + D-InSAR / SBAS 生产 + LandSAR、Gamma、SARscape 按任务类型接入 + + + 配对 + + 处理 + + 登记 + + + 可审计运行记录 + 成功、部分成功、失败原因与日志明细独立记录 + + + + + + + + 任务批次 + 失败归因 + 成果目录 + 交付申请 + + + + diff --git a/frontend/src/assets/login/system-overview.svg b/frontend/src/assets/login/system-overview.svg new file mode 100644 index 0000000..a44450b --- /dev/null +++ b/frontend/src/assets/login/system-overview.svg @@ -0,0 +1,81 @@ + + Radar Data Production System Overview + An engineering-style system overview with satellite acquisition, asset catalog, processing, result management, and map analysis. + + + + + + + + + + + + + + + + + + + + + + + + + + + + 雷达数据生产管理系统 + 数据接入 · 生产编排 · 成果管理 · 地图分析 + + + 源数据接入 + LT-1 / Sentinel-1 / GF3 + + + + + 资产台账 + 解析、精轨匹配、缓存 + + + + + + 生产工作台 + D-InSAR / SBAS / 正射 + + + + + + 成果目录 + 登记、提取、交付包 + + + + + + + + + + + + + + 统一生产态势 + 任务、Worker、成果、日志形成可追溯闭环 + + + 扫描入库 + 配对规划 + 集群生产 + 成果发布 + + + +