Files
john 4e21ca937a
Deploy Documentation / deploy (push) Has been cancelled
Canary / Prepare Version (push) Has been cancelled
Canary / build-cli (push) Has been cancelled
Canary / Upload Install Script (push) Has been cancelled
Canary / bundle-desktop (push) Has been cancelled
Canary / bundle-desktop-intel (push) Has been cancelled
Canary / bundle-desktop-linux (push) Has been cancelled
Canary / bundle-desktop-windows (push) Has been cancelled
Canary / bundle-desktop-windows-cuda (push) Has been cancelled
Canary / Release (push) Has been cancelled
Unused Dependencies / machete (push) Has been cancelled
CI / changes (push) Has been cancelled
CI / Check Rust Code Format (push) Has been cancelled
CI / Build and Test Rust Project (push) Has been cancelled
CI / Build Rust Project on Windows (push) Has been cancelled
CI / Check MSRV (push) Has been cancelled
CI / Lint Rust Code (push) Has been cancelled
CI / Check Generated Schemas are Up-to-Date (push) Has been cancelled
CI / Test and Lint Electron Desktop App (push) Has been cancelled
CI / H5 Plaza Tests and Build (push) Has been cancelled
Live Provider Tests / check-fork (push) Has been cancelled
Live Provider Tests / changes (push) Has been cancelled
Live Provider Tests / Build Binary (push) Has been cancelled
Live Provider Tests / Smoke Tests (push) Has been cancelled
Live Provider Tests / Smoke Tests (Code Execution) (push) Has been cancelled
Live Provider Tests / Compaction Tests (push) Has been cancelled
Live Provider Tests / goose server HTTP integration tests (push) Has been cancelled
Publish Ask AI Bot Docker Image / docker (push) Has been cancelled
Publish Docker Image / docker (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
Add TKMind platform extensions, H5/MindSpace stack, and deployment tooling.
Fork goose with custom MCP widgets, platform extensions (aider, git, web, search),
MindSpace H5 backend/frontend, Plaza/Ops UIs, and deploy scripts for tkmind.cn.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-14 21:30:20 +08:00

216 lines
9.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
sidebar_position: 2
title: 系统架构
sidebar_label: 系统架构
description: Plaza 的整体架构、技术选型、部署结构和服务边界
---
# 系统架构
## 总体架构
```text
┌─────────────────────────────────────────────────────────────────┐
│ 用户访问层 │
│ │
│ 游客/浏览者 登录用户 运营人员 │
│ /plaza, /u/:slug /space, /chat /ops │
└───────────┬────────────────────┬──────────────────┬────────────┘
│ │ │
▼ ▼ ▼
┌───────────────────────────────────────────────────────────────┐
│ Nginx 统一入口(go.tkmind.cn
│ │
│ /plaza, /u/ → Next.js :3001 /ops → Ops SPA :3002 │
│ /api → Node.js :18006 / → H5 SPA :8080 │
└───────────────────────────┬───────────────────────────────────┘
┌───────────────┼───────────────┐
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Plaza 前端 │ │ MindSpace H5 │ │ 运营后台 │
│ Next.js SSR │ │ Vite CSR │ │ Vite CSR │
│ ui/plaza/ │ │ ui/h5/ │ │ ui/ops/ │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
└────────────────┼────────────────┘
│ HTTP /api/*
┌───────────────────────────────┐
│ Node.js 后端服务 │
│ │
│ /api/mindspace/v1/* │
│ /api/plaza/v1/* (新增,plaza-*.mjs)│
│ /api/ops/v1/* (新增,ops-*.mjs
│ /auth/* │
└───────────────┬───────────────┘
┌───────────────┼───────────────┐
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ MySQL │ │ 文件存储 │ │ Redis │
│ 共用数据库 │ │ 本地/OSS │ │ 热度计数 │
│ + plaza_*表 │ │ + 缩略图 │ │ + feed缓存 │
└──────────────┘ └──────────────┘ └──────────────┘
```
## 技术选型
### Plaza 前端(ui/plaza/
| 技术 | 选型 | 原因 |
| --- | --- | --- |
| 框架 | Next.js 14+ App Router | 原生 SSR/SSGSEO 最佳实践 |
| 语言 | TypeScript | 与现有 H5 保持一致 |
| 样式 | Tailwind CSS | 快速开发,与 H5 互不干扰 |
| 状态管理 | React Server Components + SWR | 服务端数据优先,客户端增量更新 |
| 图片优化 | next/image | 自动 WebP、懒加载、尺寸优化 |
| 分析 | 自建埋点(复用后端 analytics API | 不依赖第三方 |
### 运营后台(ui/ops/
| 技术 | 选型 | 原因 |
| --- | --- | --- |
| 框架 | Vite + React | 与 H5 工具链一致,快速启动 |
| UI 组件库 | 复用现有组件风格 | 不引入新依赖 |
| 权限 | 独立 ops_role 中间件 | 与普通 admin 权限隔离 |
### 后端扩展
| 模块 | 实现方式 |
| --- | --- |
| Plaza API | 在现有 Node 服务中新增 `/api/plaza/v1/` 路由模块 |
| 热度计数 | Redis INCR + 定时回写 MySQL |
| 缩略图生成 | 发布时异步截图任务(Puppeteer worker |
| 内容审核队列 | MySQL 任务表(与现有 upload scan 模式一致) |
## 服务边界原则
### Plaza 可以做的
- 读取 `h5_publish_records` 表(逻辑名 *publications*)判断帖子来源是否 `online`
- 读取 `h5_users` 表(逻辑名 *users*)获取创作者基础信息(id、slug、display_name、avatar_url)。
- 在**同一 MySQL 实例**内,通过定时任务将广场计数回写到 `h5_publish_records.plaza_view_count` / `plaza_like_count`(不调用 MindSpace service 函数,但字段由 MindSpace 侧迁移脚本统一定义)。
### Plaza 不能做的
- 直接 JOIN `h5_user_spaces``h5_page_records``h5_assets` 等 MindSpace 核心表。
- 调用 MindSpace 的内部 service 函数(如 `mindspace_service.getPage()`)。
- 绕过 MindSpace 发布流程直接操作 `publications` 状态。
### 跨模块通信方式
```text
Plaza 需要 MindSpace 数据时:
① 读 plaza_posts 中的冗余快照字段(title, cover_url, user_slug 等)
② 调用 /api/mindspace/v1/ 公开接口(只读场景)
③ 通过共用数据库字段或异步任务表传递事件(不 import MindSpace service 模块)
MindSpace 下线 publication 时:
→ 在 mindspace-publications 的同一数据库事务内 UPDATE plaza_posts SET status = 'hidden'
Plaza 回写 publication 广场统计时:
→ 独立定时任务 UPDATE h5_publish_records(见 04-backend-api「互动数据回写」)
```
## 部署结构
### 进程列表
| 进程 | 端口 | 启动命令 | 说明 |
| --- | --- | --- | --- |
| Nginx | 443 | systemd | 统一入口,SSL 终止 |
| Node.js 后端 | 18006 | `node server.mjs` | 现有服务,扩展新路由 |
| MindSpace H5 | 8080 | `pnpm preview` | 现有 Vite SPA |
| Plaza Next.js | 3001 | `pnpm start` | 新建,SSR |
| 运营后台 | 3002 | `pnpm preview` | 新建,CSR SPA,仅内网 |
| Redis | 6379 | systemd | 新增 |
### Nginx 配置核心
```nginx
server {
server_name go.tkmind.cn;
# 广场和用户主页 → Next.js SSR
location ~ ^/(plaza|u/) {
proxy_pass http://127.0.0.1:3001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 运营后台 → 内网限制
location /ops {
allow 10.0.0.0/8; # 内网 IP 段
deny all;
proxy_pass http://127.0.0.1:3002;
}
# 所有 API → 共用后端
location /api {
proxy_pass http://127.0.0.1:18006;
}
# 其余 → MindSpace H5
location / {
proxy_pass http://127.0.0.1:8080;
}
}
```
### Cookie 共享策略
三个前端应用同 host`go.tkmind.cn`),Nginx 按路径转发到不同端口。**Session Cookie 使用 host-only**(不设置 `Domain` 属性),则 `/``/plaza``/ops` 天然共享登录态,无需 SSO。
```
Set-Cookie: session_id=xxx; Path=/; HttpOnly; Secure; SameSite=Lax
```
若未来拆到子域(如 `plaza.go.tkmind.cn`),再改为 `Domain=.go.tkmind.cn` 并统一调整各前端 API 基址。
## 目录结构
```text
ui/
├── h5/ # 现有 MindSpace,不动
├── plaza/ # 新建 Next.js 广场
│ ├── app/
│ │ ├── plaza/ # 广场首页和分类
│ │ │ ├── page.tsx # /plaza SSR
│ │ │ └── cat/[slug]/page.tsx
│ │ ├── plaza/p/[id]/ # 帖子详情
│ │ │ └── page.tsx
│ │ └── u/[slug]/ # 用户主页
│ │ └── page.tsx
│ ├── components/
│ │ ├── PostCard.tsx # 卡片组件
│ │ ├── PostGrid.tsx # 瀑布流
│ │ ├── CategoryNav.tsx # 分类导航
│ │ └── UserProfile.tsx # 用户主页
│ ├── lib/
│ │ └── api.ts # 调用 /api/plaza/v1/
│ └── types/
│ └── plaza.ts
└── ops/ # 新建运营后台
└── src/
├── pages/
│ ├── ReviewQueue.tsx
│ ├── FeaturedManager.tsx
│ └── Analytics.tsx
└── api/
└── client.ts # 调用 /api/ops/v1/
```
## 扩展路径
当以下信号出现时,将 Plaza 拆出为独立后端服务:
| 信号 | 行动 |
| --- | --- |
| 广场流量是 MindSpace 的 10 倍+ | 将 plaza_* 表迁移到独立数据库,后端服务拆分 |
| 推荐算法需要 Python ML 服务 | 新建推荐微服务,后端调用其接口 |
| 内容审核需要独立合规团队 | 运营后台独立部署,API 拆分 |
| 广场开放第三方内容(非 MindSpace) | 数据模型不再依赖 publications 外键,彻底解耦 |
拆分时要搬走的只有:`plaza_*` 表、`/api/plaza/v1/` 路由、`ui/plaza/`,其他不动。