Skip to content

架构设计 ​

Nexus 是单一的 Nuxt 4 全栈应用:前端(Vue)、服务端(Nitro)、数据层(Drizzle + PostgreSQL)同仓一体,再通过 modules/ 实现业务模块化。本章讲清整体分层与几个关键子系统的设计。

整体分层 ​

text
┌──────────────────────────────────────────────────────────┐
│  应用层  Nuxt Vue(app/)                                  │
│  pages / layouts / components / composables / locales      │
│  i18n 引擎 · 主题换肤 · 路由中间件(auth / admin / locale) │
└───────────────────────┬──────────────────────────────────┘
                         │  fetch → /api/*(JWT in HttpOnly Cookie)
┌───────────────────────┴──────────────────────────────────┐
│  服务层  Nitro(server/)                                   │
│  api/(业务路由)· utils/(auth/credits/payments/modules)  │
│  plugins/(db-migrate / seed-admin / module-migrations)   │
├──────────────┬───────────────┬───────────────┬────────────┤
│  AI 层       │  模块层        │  支付层        │  OAuth 层   │
│  Provider    │  modules/*     │  微信/支付宝   │  authorize  │
│  工厂+适配器 │  聚合加载      │  / Mock        │  /token/    │
│  任务轮询    │  菜单自治      │               │  userinfo   │
├──────────────┴───────────────┴───────────────┴────────────┤
│  数据层  Drizzle ORM + PostgreSQL(schema.ts + migrations) │
└──────────────────────────────────────────────────────────┘

设计要点:

  • 同仓全栈:前端与服务端共享 TypeScript 类型与工具,部署形态简单(一个 Nuxt 应用)。
  • 能力内聚于模块:业务功能以 modules/<name>/ 为单元,页面、API、迁移、菜单随模块一起加载,互不污染。
  • 配置驱动扩展:通过 config/modules.ts 与 nexus-module.json 声明式启用能力,避免散落的注册代码。

模块机制 ​

模块机制是 Nexus 的扩展骨架,详见 模块机制。核心流程:

text
config/modules.ts 声明启用 ['example','wechat-creator']
        │
        ↓  构建期(nexus.module.ts Nuxt 模块扫描)
modules/<name>/pages  → 自动注册到 /modules/<name>/*
modules/<name>/api    → 自动注册到 /api/...
modules/<name>/migrations → 由 module-migration-runner 执行
modules/<name>/menu.json → 注入 Admin 后台菜单
  • 构建期聚合:server/utils/modules/nexus.module.ts 在 Nuxt 构建时扫描启用模块的 pages/、api/、migrations/、menu.json,把它们并入主应用。
  • 运行期加载:模块页面挂到 /modules/<name>/*,菜单按 menu.json 注入后台,无需手改主应用代码。
  • 迁移自治:模块的 Drizzle 迁移由 server/plugins/module-migrations.ts 在启动时执行,与主库迁移隔离管理。

认证体系 ​

text
浏览器                      服务端
  │  RSA-OAEP 加密密码提交    │
  │ ───────────────────────→ │  bcrypt 校验
  │                          │  签发 JWT(HS256,NUXT_AUTH_SECRET)
  │  Set-Cookie: token=...   │  (HttpOnly,随请求自动带上)
  │ ←─────────────────────── │
  │  后续请求带 Cookie         │  中间件校验 JWT → 注入用户上下文
  • 传输安全:登录密码在客户端用 RSA-OAEP 加密后再提交,服务端用私钥解密;存储用 bcrypt 哈希。
  • 会话方式:JWT 无状态令牌写入 HttpOnly Cookie,天然防 XSS 窃取、随请求自动携带。
  • 登录防护:支持失败次数锁定(NUXT_LOGIN_MAX_ATTEMPTS / NUXT_LOGIN_LOCK_WINDOW)。
  • 社交登录与 OAuth 服务:内置 GitHub / Google 登录;同时自身也是一个 OAuth 2.0 / OIDC 提供方(/oauth/authorize、/oauth/token、/oauth/userinfo、.well-known/openid-configuration、/oauth/jwks),可对外签发令牌。

详见 用户认证体系。

AI 基础设施 ​

AI 能力通过 Provider 适配器抽象 统一,屏蔽不同厂商协议差异:

text
调用方(server/api/ai/*)
   │  getProvider(key)
   ↓
Provider 工厂(factory.ts)
   ├─ protocol === 'anthropic' → AnthropicProvider
   └─ protocol !== 'anthropic' → OpenAIProvider(兼容 OpenAI 协议者统一归此类)
   ↓
Provider 接口:chat / chatStream / image / video
   + 可选 submitImageTask / queryImageTask / submitVideoTask(异步轮询)
   ↓
异步生成任务由 ai-task-poller 轮询,结果写回(result-urls)
  • 统一接口:Provider 接口声明 chat / chatStream / image / video 及可选异步任务方法;调用方先查 capabilities 再调用,不支持的能力返回明确错误。
  • 工厂 + 缓存:getProvider(key) 按配置签名缓存实例,配置变化自动重建;未启用或未配置 API Key 时明确报错。
  • 模型解析:model-resolver.ts 负责将请求路由到正确的 Provider 与模型。
  • 任务编排:图像 / 视频等耗时生成走「提交任务 → 轮询 → 写回结果 URL」的异步模式(server/plugins/ai-task-poller.ts)。

详见 AI 基础设施。

多语言与 SEO ​

  • 语言包:app/locales/(zh.ts / en.ts)存放文案,useI18n / useLocale 组合式函数驱动切换。
  • URL 前缀:构建期 localeUrlPrefix(默认开启)使英文带 /en 前缀、中文无前缀(prefix_except_default),便于 SEO 双语言索引。
  • 双语 SEO:自动生成 sitemap.xml、<link rel="hreflang">、canonical,域名来源为 NUXT_APP_URL。
  • 运行期语言:默认语言与「显示语言切换」由系统配置页「语言」Tab 管理,即时生效。

详见 多语言。

主题换肤 ​

  • 目录即主题:每套预设位于 app/themes/<name>/,由构建期扫描器自动生成 CSS 入口和主题注册表。
  • 设计 Token:主题包用 CSS 变量沉淀颜色、字体、圆角和阴影,组件只消费语义 Token。
  • 双维度切换:data-theme 选择主题预设,@nuxtjs/color-mode 管理 light / dark / system 明暗模式。

详见 主题机制。

API 文档(Scalar) ​

  • 服务端在 server/utils/api-docs/ 维护 OpenAPI 定义,/api/docs/openapi.json 输出 JSON。
  • @scalar/nuxt 在 /api_docs 渲染交互式 API 文档(注意 /docs 已被重定向到 /api_docs)。

详见 API 文档。