🚨 2026-11-10 托管变更:
*.autional.cn已迁出 Vercel —— 改为 mf01 构建(node:24-alpine + 钉版 pnpm)→ 香港自建托管。.cn的构建 env 由 workspaceshared/infra-ops/sites/sites.manifest.json注入;push 后由 mf01 cron(约 10 分钟)构建发布,不经 Vercel。*.autional.com仍在 Vercel —— 本文中涉及 Vercel 的构建/部署描述对.com仍然成立。 现行口径:workspacedocs/AUTIONAL-CN-SITES-SELF-HOST.md。
域名:brand.autional.cn(cn)· brand.autional.com(com) 技术栈:Vite + React 19 + TypeScript + Tailwind CSS
租户品牌选择入口站。
受租户隔离的门户(user / security / admin / authenticator / auth)必须有租户段:<门户>.<域>/<tenantSlug>/。
裸根无会话时统一落到本站,选定品牌后再进入目标门户的登录页:
<门户>.<域>/ 裸根,无会话
└─> brand.<域>/?redirect=https://<门户>.<域>/
└─(选品牌 acme)
└─> auth.<域>/acme/login?redirect=https://<门户>.<域>/acme/
└─(登录)
└─> <门户>.<域>/acme/
三条旁路(避免多余摩擦):
| 场景 | 行为 |
|---|---|
| 门户裸根,已有会话 | 解析出 slug → /<slug>/ 直达,不经过本站 |
深链已带 slug(<门户>/acme/)无会话 |
租户已知 → 直接 auth.<域>/acme/login |
auth.<域>/ 裸根 |
有会话 → /<slug>/dashboard;无会话 → 本站 |
- 骨架(
packages/{shared,tailwind-preset,tsconfig,ui})与各门户同构,逐字同源。 - 品牌数据源 =
GET /bff/tenant/api/v1/tenant/public/tenants(?featured=true精选 /keyword搜索分页 / 无参 legacy 全量)+ 逐租户GET .../tenants/{slug},均为公开端点。首页默认只展示精选组织(服务端featured标记 +featured_sort排序,上限 24 个,由 service-tenant 管理端维护),其余组织通过搜索访问;「最近访问」chips 仅存本机localStorage。 - 本站自身 chrome 用 Autional 品牌令牌(
D:\autional\ui);卡片内部呈现的是租户自己的品牌(logo_url/primary_color)。两层不混。
pnpm install
pnpm dev # http://localhost:13120(构建前自动生成 env.js/robots.txt)
pnpm build # 构建产物:apps/brand-portal/dist/
pnpm test # Vitest 单元测试本地接口代理指向 localhost:11080(网关)与 localhost:11001(tenant-service),见 apps/brand-portal/vite.config.ts。
main → brand(com)自动部署(Vercel);main → cn-brand(cn)由 mf01 cron 构建发布(约 10 分钟,不经 Vercel)。两区同一份源,
区域差异全部由构建期环境变量注入(.com 来自 Vercel 项目 env;.cn 来自 shared/infra-ops/sites/sites.manifest.json)(见 docs/positioning/24):
| 变量 | com | cn |
|---|---|---|
REGION |
com |
cn |
SITE_URL |
https://brand.autional.com |
https://brand.autional.cn |
DEFAULT_LANG / FALLBACK_LANG |
en |
zh |
API_ORIGIN |
https://api.autional.com |
https://api.autional.cn |
CDN_HOST |
https://cdn.autional.com |
https://cdn.autional.cn |
- 路由/重写:
vercel.ts(fail-closed:API_ORIGIN缺失即构建失败)。 - 生成物(勿手改、勿入库):
apps/brand-portal/public/{env.js,robots.txt}←scripts/gen-env.mjs;区域文案在scripts/region-copy.mjs。 - 本地无 env 时兜底 cn 值(与迁移前基线一致)。
- 外壳缓存:
vite-plugin-pwainjectManifest + Workbox precache;manifest 按区域在构建期生成,图标来自站点自身。 - 数据面永不缓存:
/bff、/api/v1、/tenant、/oauth走NetworkOnly;在线导航先网络(4s 超时),离线才回退预缓存index.html。 - 更新:新 SW
skipWaiting+clients.claim立即接管;src/lib/pwa-lifecycle.ts在接管后整页重载一次。首访、未提交输入、60 秒防循环不重载;vite:preloadError最多重载一次。 - 部署注意:
vercel.ts对/sw.js、/index.html、/manifest.webmanifest、/registerSW.js设max-age=0;/assets/*、/workbox-*.js长缓存。SPA 兜底只在Accept: text/html时生效,缺失的静态资源返回 404。 - 验收:SW 受控、Cache Storage 只有 Workbox precache、租户接口不在缓存、离线可开壳但不展示缓存的租户数据。