Files
sub2api/docs/superpowers/work-logs/2026-04-23-portal-frontend-revamp.md
mini 92ffcb81e4
Some checks failed
continuous-integration/drone/push Build is passing
CI / test (push) Has been cancelled
CI / golangci-lint (push) Has been cancelled
Security Scan / backend-security (push) Has been cancelled
Security Scan / frontend-security (push) Has been cancelled
docs(work-log): 门户前端调整工作记录(多语言 + Pricing + Nav 重构 + 内容清理)
2026-05-03 00:00:36 +08:00

8.8 KiB
Raw Permalink Blame History

门户前端调整工作记录

时间窗口2026-04-19 2026-04-23 范围sub2api 项目前端门户页(公开访问的 5 页Landing / Docs / Login / Register / Pricing 目标:完成多语言切换、新增 Pricing 页、消除导航栏抖动、清理对外不应展示的技术细节


阶段一:门户多语言 + Pricing 页

问题:门户 4 页Landing / Docs / Login-narrative / Register-narrative当时是 fidelity-port 自 Claude Design zip 的,约 100+ 处中文硬编码在 template 里。Pricing 页未实现。i18n 框架(vue-i18n)虽然到位,但门户页基本没用上。

做了什么

  1. 新建 components/puro/PuroLocaleSwitcher.vue —— 深色科技风的语言切换器,复用 setLocale() 核心,与 puro.css 设计 token 对齐(区别于 admin 用的 LocaleSwitcher.vue
  2. 抽取 4 页所有中文到 i18n keylanding.*docs.*auth.narrative.* 命名空间),同步生成英文翻译;总计约 130 个 leaf key
  3. 新增 /pricing 路由 + views/pricing/PricingView.vue(约 500 行)+ components/puro/PricingCalculator.vue 子组件
  4. Pricing 页从一开始就 i18n-native约 100 个 key含 4 档定价 tier、cost calculator、12 工具 grid、10 FAQ、final CTA
  5. 关键决策(写进 spec 锁定):
    • 定价数字使用 zip 的 $9.9 / $29.9 / $99 作为占位,配 // preview · 最终定价以开售为准 标签
    • 未实现的功能priority scheduling、zero-log modeSOON 灰标签,不删除展示
    • Binding 卡片暂指 /register;联系商务用 mailto:contact@puro.im
    • Cost calculator 算法照搬 zip JSpuro = official × 0.3),配 // estimated · 以实际计费为准 标签
    • 移除 zip 中的 注册送 $5 测试积分 文案Stage 1 决策)

执行方式subagent-driven-developmentPlan 文件 docs/superpowers/plans/2026-04-20-portal-i18n-pricing.md10 个任务3 个 subagent 实现 + 1 次回归修复)

已合并 PR#2 → main 77bb69b2


阶段二Nav 抖动修复

问题:用户报告点击导航栏「产品/定价/文档」切换时元素位置发生轻微抖动。

根因分析

第一直觉是 active class 引起的字体 weight 变化。grep CSS 后发现并非如此 —— .active 只改 color 不影响布局。

真正原因是:当前 Landing/Docs/Pricing 三个 View 各自在 template 里写了一份完整的 nav包括按钮文案。Vue Router 切换路由时销毁整棵 view 组件树(含 nav重新挂载下一个。虽然视觉上"看似同一个 nav",实际是三份独立拷贝被替换。

进一步发现两份拷贝间有差异:

  • Docs 的注册 CTA 文案是 注册2 字符Landing/Pricing 是 免费试用 →5+1 字符)—— 按钮宽度不同
  • Docs 的英文 Product单数vs 其他两页的 Products(复数)
  • Pricing 的「定价」用 <a href="#" class="active"> —— 点击会 scroll to top 且 URL 改成 /pricing#

做了什么(分两步):

步骤 1短期 —— 文案统一:把三份 nav 的内容对齐到完全一致

  • docs.nav.signup: 注册免费试用 →
  • docs.nav.products (en): ProductProducts
  • PricingView 的 <a href="#"><router-link to="/pricing">
  • commit 779005e1

步骤 2结构性修复 —— 抽 PortalLayout

  • 新建 components/layout/PortalLayout.vue —— 包含 nav + <router-view /> + footer
  • 路由改为嵌套结构://docs/pricing 作为 PortalLayout 的子路由
  • 三个 View 删掉各自的 nav / footer / bg-glow / .puro-page 包装
  • 新增 portal.nav.* i18n 命名空间,删除原来的 landing.nav.* / docs.nav.* / pricing.nav.* 三份重复
  • router-linkactive-class="active" prop 替代硬编码 class
  • scrollBehavior 加上 hash 锚点跳转(offset 80px 绕 sticky nav
  • commit e7f3fe5b

结果:路由切换时 Nav 不再卸载重挂真·SPA 行为。

已合并 PR#3 → main 291e3bfe


阶段三:对外内容清理

Pass 1删除 iShare 引用

  • 用户要求:项目目前定位是独立运营,不要在前端展示 iShare 相关字样
  • 影响:docs.sections.getKey.note 一个 key"未来通过 iShare 入口开放订阅购买"+ DocsView 对应的 <p class="note">
  • commit 623a7518PR #4 → main 5c4b2980

Pass 2移除 footer 技术细节

  • 用户要求:不要透露项目技术开发细节
  • 删除:更新日志 链接(指向 Gitea commitsgit.puro.im 链接、GitHub ↗ 链接、fork of Wei-Shaw/sub2api 字样
  • footer-meta 简化为 © 2026 puro.im
  • 同步删除 linkChangelog i18n key
  • commit 2b6b5fc6PR #5 → main 8be87883

关键文件清单

新增:

  • frontend/src/components/puro/PuroLocaleSwitcher.vue
  • frontend/src/components/puro/PricingCalculator.vue
  • frontend/src/components/layout/PortalLayout.vue
  • frontend/src/views/pricing/PricingView.vue

修改(重点):

  • frontend/src/router/index.ts —— 加 /pricing、嵌套路由、scrollBehavior
  • frontend/src/i18n/locales/{zh,en}.ts —— 新增 portal/landing/docs/pricing/auth.narrative 命名空间
  • frontend/src/views/{landing,docs,pricing}/*View.vue —— 全量 i18n 化 + 移除各自 nav/footer
  • frontend/src/views/auth/{Login,Register}View.vue —— narrative slot i18n 化
  • frontend/src/components/layout/AuthLayout.vue —— 添加右上角语言切换器槽位

commit / PR 索引

阶段 commit 描述
e711a203 feat(i18n): add PuroLocaleSwitcher
63288818 mount switcher in Landing/Docs/AuthLayout
fc7e2767 landing i18n keys + EN
73b39807 docs + auth narrative i18n
13bdd8f8 restore dashboard link in models.note
b989c503 PricingView + calculator
77bb69b2 Merge PR #2 → main
779005e1 unify signup CTA
e7f3fe5b extract PortalLayout
291e3bfe Merge PR #3 → main
623a7518 remove iShare mention
5c4b2980 Merge PR #4 → main
2b6b5fc6 footer remove tech details
8be87883 Merge PR #5 → main

部署链路

每次 merge 到 main 后:

  1. Gitea webhook 触发 Drone CI
  2. Drone 运行 docker build + 推镜像
  3. VPS 上 docker compose 拉取新镜像 + 重启
  4. 总耗时约 35 分钟

每次部署完成的验证手段curl

  1. https://ai.puro.im/ 主 HTML对比 /assets/index-*.js 文件名 hash 是否变化Vite 内容寻址)
  2. fetch 新 chunk grep 关键字符串确认新代码上线
  3. 5 个门户路由全部 200

遗留事项 / 下次可继续

门户层面

  1. 浏览器实测 nav 持久化无抖动(用户已确认部署,肉眼验证待做)
  2. 翻译效果打磨(用户浏览后发现的不自然处随时改)
  3. Pricing 数字 / 功能列表定稿(从 preview 转正式)
  4. 后端 SOON 标记的功能落地zero-log mode、priority scheduling
  5. Pricing FAQ 中的 24 小时上线新模型 等承诺类文案核实

Admin / User 页面(之前搁置的两个决策)

  • 决策 1Admin reskin 深度A 全局换肤 / B 深度 port 两页 / C 全量重写)
  • 决策 2User-facing 页面 vs Admin 页面优先级
  • 推荐路径Phase 2.1 全局换肤 → 2.2 user pages → 2.3 admin pages

仓库卫生

  • backend/config.prod.yamlbackend/sub2api-linuxLOCAL_SETUP_NOTES.md 在某次意外的 git add -A 中被提交到 main。
  • 用户判断:因 Gitea 是私有的,先不处理;仅要求前端层面不展示敏感信息(已通过 footer 清理实现)。
  • 建议:下次添加配置 / 二进制类文件前,往 .gitignore 补规则(backend/config.*.yamlbackend/sub2api-* 等),避免再次误提。

经验教训

  1. 不要 git add -A —— 主 worktree 里有累积的本地文件(生产配置、二进制、笔记),一次性 stage 会把这些都带进 commit。后续都用 git add <具体文件>
  2. 设计稿里的 nav = 3 份独立 HTML ≠ Vue 应该 3 份独立 template —— port 设计稿到 SPA 时要把跨页共享的部分nav、footer、layout shell一开始就抽到 layout 组件。
  3. Subagent 报告"我做完了"≠ 真的做对了 —— 73b39807 提交里 subagent 静默删掉了 <router-link> 退化成纯文本。事后 grep 读 commit diff 才发现。下次 subagent 处理 i18n 抽取时prompt 里要明确"原始 HTML 标签如 <a>/<code>/<router-link> 必须保留,使用 <i18n-t> 命名 slot"。
  4. fidelity port 优先靠 <i18n-t> + 命名 slot不要把带行内标签的句子拍平成纯文本 —— 这点已经写进下次的 i18n 提示模板中。