feat(web): 5 项 UI 修复 — 统一浅色/登录回跳/logo locale/用户名下拉/Docs 真页
ci-pangolin / Redline Scan — 脱敏 (UI 文案) (pull_request) Successful in 25s
ci-pangolin / Codegen Drift — token 生成物未漂移 (pull_request) Successful in 7s
ci-pangolin / Cleartext Scan — Android 禁明文 (pull_request) Successful in 26s
ci-pangolin / DS-flow — 原型/跨端同源/代码色单源闸 (pull_request) Successful in 11s
ci-pangolin / Go — build + test (pull_request) Successful in 15s
ci-pangolin / Portable SQL — 可移植性 (mysql/sqlite) (pull_request) Successful in 26s
ci-pangolin / E2E Smoke — L4 进程级端到端 (pull_request) Successful in 10s
ci-pangolin / Go — integration (mysql/redis testcontainers) (pull_request) Successful in 4m36s
ci-pangolin / Golden — 视觉回归 (全量:components/auth/desktop/tablet) (pull_request) Successful in 20s
ci-pangolin / Lint — shellcheck (pull_request) Failing after 10m3s
Deploy Site / deploy-site (push) Failing after 13m20s
ci-pangolin / Flutter — analyze + test (pull_request) Failing after 14m42s
ci-pangolin / OpenAPI Sync Check (pull_request) Failing after 14m52s

用户中心:
- 统一浅色:theme.tsx 无偏好时不再跟随系统 prefers-color-scheme:dark(登录页变
  黑真因),恒浅色;保留手动切换。
- 登录回跳:UserCenter 加 safeRedirect 白名单,登录成功按 ?redirect= 回来源页
  (官网带 /,登录后回主页),无则进 overview。
- logo locale:新增 i18n brandName(zh 穿山甲/其余 Pangolin),Login/UserCenter
  /Subscription 三处引用。
- 存 pg_uc_email(getMe 时)/ clearSession 删,供官网读用户名。

官网(全走 CSS class 合 CSP,无内联 style):
- logo locale:i18n nav.brand(zh 穿山甲/其余 Pangolin),Header+Footer。
- 登录态头部显示用户名(读同源 pg_uc_email)+ 下拉菜单(进入用户中心/切换用户/
  退出登录,复用 .langmenu 风格);未登录 Log in 带 ?redirect=/ 回跳。
- Docs 四卡片补真内容页(en+zh:quickstart/faq/protocol/privacy + Doc.astro
  布局),卡片改回 <a href>;Protocol 改正 sing-box+REALITY(去 WireGuard)。

验证:同源闸绿 · 两端 build 过 · redline 0 · Header 零内联 style · 无 WireGuard。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-07-08 09:52:04 +08:00
parent f37f1f3b59
commit 5b89de656e
23 changed files with 516 additions and 24 deletions
+7 -1
View File
@@ -40,6 +40,12 @@ export const STRINGS: Record<string, Record<Lang, string>> = {
'nav.login': { zh: '登录', en: 'Log in', ja: 'ログイン', ko: '로그인', ru: 'Войти', es: 'Iniciar sesión' },
'nav.center': { zh: '用户中心', en: 'Account', ja: 'アカウント', ko: '계정', ru: 'Личный кабинет', es: 'Mi cuenta' },
'nav.get': { zh: '立即下载', en: 'Get the app', ja: 'アプリを入手', ko: '앱 받기', ru: 'Получить приложение', es: 'Obtener la app' },
// 品牌字标:中文显「穿山甲」,其余语言统一显「Pangolin」(英文版 logo 本地化)。
'nav.brand': { zh: '穿山甲', en: 'Pangolin', ja: 'Pangolin', ko: 'Pangolin', ru: 'Pangolin', es: 'Pangolin' },
// 登录态用户下拉菜单项(3 项 × 6 语)。
'menu.center': { zh: '进入用户中心', en: 'Open account center', ja: 'アカウントセンターへ', ko: '계정 센터 열기', ru: 'Личный кабинет', es: 'Ir a mi cuenta' },
'menu.switch': { zh: '切换用户', en: 'Switch account', ja: 'アカウントを切替', ko: '계정 전환', ru: 'Сменить аккаунт', es: 'Cambiar de cuenta' },
'menu.logout': { zh: '退出登录', en: 'Log out', ja: 'ログアウト', ko: '로그아웃', ru: 'Выйти', es: 'Cerrar sesión' },
'hero.eyebrow': { zh: '极速 · 稳定 · 省心', en: 'Fast · Stable · Effortless', ja: '高速 · 安定 · 快適', ko: '빠름 · 안정 · 간편', ru: 'Быстро · Стабильно · Без забот', es: 'Rápido · Estable · Sin complicaciones' },
'hero.h1': { zh: '极速畅连,\n网络如丝顺滑', en: 'Faster, smoother,\neverywhere', ja: 'もっと速く、もっと滑らかに、\nどこでも', ko: '더 빠르고 더 매끄럽게,\n어디서나', ru: 'Быстрее, плавнее,\nвезде', es: 'Más rápido, más fluido,\nen todas partes' },
@@ -140,7 +146,7 @@ export const STRINGS: Record<string, Record<Lang, string>> = {
'docs.2t': { zh: '常见问题', en: 'FAQ', ja: 'よくある質問', ko: '자주 묻는 질문', ru: 'Вопросы и ответы', es: 'Preguntas frecuentes' },
'docs.2d': { zh: '连接、计费、设备与兑换码的常见疑问。', en: 'Connection, billing, devices and redeem codes.', ja: '接続・請求・デバイス・引き換えコードのよくある疑問。', ko: '연결, 결제, 기기, 등록 코드에 대한 궁금증.', ru: 'Подключение, оплата, устройства и коды активации.', es: 'Conexión, facturación, dispositivos y códigos de canje.' },
'docs.3t': { zh: '协议与安全', en: 'Protocol & security', ja: 'プロトコルとセキュリティ', ko: '프로토콜 & 보안', ru: 'Протокол и безопасность', es: 'Protocolo y seguridad' },
'docs.3d': { zh: 'WireGuard、加密方式与无日志架构说明。', en: 'WireGuard, encryption and our no-logs architecture.', ja: 'WireGuard、暗号化方式、ノーログ設計の解説。', ko: 'WireGuard, 암호화 방식, 노로그 아키텍처 설명.', ru: 'WireGuard, шифрование и наша архитектура без логов.', es: 'WireGuard, cifrado y nuestra arquitectura sin registros.' },
'docs.3d': { zh: 'sing-box + REALITY、加密方式与无日志架构说明。', en: 'sing-box + REALITY, encryption and our no-logs architecture.', ja: 'sing-box + REALITY、暗号化方式、ノーログ設計の解説。', ko: 'sing-box + REALITY, 암호화 방식, 노로그 아키텍처 설명.', ru: 'sing-box + REALITY, шифрование и наша архитектура без логов.', es: 'sing-box + REALITY, cifrado y nuestra arquitectura sin registros.' },
'docs.4t': { zh: '隐私政策', en: 'Privacy policy', ja: 'プライバシーポリシー', ko: '개인정보 처리방침', ru: 'Политика конфиденциальности', es: 'Política de privacidad' },
'docs.4d': { zh: '我们收集什么、不收集什么,一目了然。', en: 'Exactly what we collect — and what we never do.', ja: '収集するもの・しないものを明確に。', ko: '무엇을 수집하고 무엇을 수집하지 않는지 한눈에.', ru: 'Что мы собираем — и чего не собираем никогда.', es: 'Exactamente qué recopilamos y qué nunca hacemos.' },
'docs.read': { zh: '阅读', en: 'Read', ja: '読む', ko: '읽기', ru: 'Читать', es: 'Leer' },