845 lines
23 KiB
Markdown
845 lines
23 KiB
Markdown
# 电子名片系统技术文档
|
||
|
||
## 1. 文档目标
|
||
|
||
本文档用于定义本项目的技术架构、技术栈、中间件、数据隔离策略、部署方案与工程结构,目标是在满足 `JDK 21 + Spring Boot + Vue 3 + TypeScript` 约束下,实现一套轻量、稳定、易扩展的多租户电子名片系统。
|
||
|
||
## 2. 技术设计原则
|
||
|
||
- 正确性优先:先保证多租户隔离、权限控制、数据一致性和关键链路稳定。
|
||
- 轻量优先:优先采用单体模块化架构,避免过早拆分微服务。
|
||
- 稳定优先:使用成熟、社区活跃、可持续维护的主流组件。
|
||
- 扩展优先:模块边界清晰,为后续审核流、线索、预约、营销等功能预留能力。
|
||
|
||
## 3. 总体架构
|
||
|
||
系统由 3 个前后端子系统组成:
|
||
|
||
1. 后端服务:统一提供租户、账号、名片、文件、统计等业务接口。
|
||
2. 后台管理端:供超级管理员、租户管理员、普通用户登录管理数据。
|
||
3. 微信小程序:面向公众展示事务所与个人电子名片。
|
||
|
||
说明:
|
||
|
||
- 后台系统为多租户统一平台。
|
||
- 微信小程序按“1 个租户 = 1 个小程序 AppID”设计,每个事务所拥有独立小程序。
|
||
- 多个租户的小程序可复用同一套后端服务与同一套代码模板,通过配置完成租户绑定。
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
A["超级管理员 / 租户管理员 / 普通用户"] --> B["后台管理端 Vue3 + TS"]
|
||
C["微信访客"] --> D["微信小程序"]
|
||
B --> E["Spring Boot API"]
|
||
D --> E
|
||
E --> F["MySQL 8"]
|
||
E --> G["Redis"]
|
||
E --> H["MinIO"]
|
||
E --> I["日志/监控"]
|
||
```
|
||
|
||
## 4. 推荐工程结构
|
||
|
||
建议在当前仓库基础上扩展为如下结构:
|
||
|
||
```text
|
||
easycard/
|
||
├─ docs/ # 产品/技术/接口/部署文档
|
||
├─ backend/ # Spring Boot 后端
|
||
│ ├─ easycard-boot/ # 启动模块
|
||
│ ├─ easycard-common/ # 通用基础能力
|
||
│ ├─ easycard-module-system/ # 系统管理、权限、日志
|
||
│ ├─ easycard-module-tenant/ # 多租户管理
|
||
│ ├─ easycard-module-org/ # 组织/事务所信息
|
||
│ ├─ easycard-module-user/ # 用户与账号
|
||
│ ├─ easycard-module-card/ # 名片管理
|
||
│ ├─ easycard-module-file/ # 文件上传与素材管理
|
||
│ └─ easycard-module-stat/ # 浏览与分享统计
|
||
├─ admin-web/ # Vue3 后台管理端
|
||
└─ frontend_miniprogram/ # 微信小程序
|
||
```
|
||
|
||
说明:
|
||
|
||
- 当前仓库已存在 `frontend_miniprogram/`,后续应保持为独立子项目。
|
||
- 后端采用“单体应用 + 模块化分层”方案,控制复杂度,同时便于后续拆分。
|
||
|
||
## 5. 技术栈选型
|
||
|
||
## 5.1 后端技术栈
|
||
|
||
| 分类 | 选型 | 说明 |
|
||
| --- | --- | --- |
|
||
| JDK | JDK 21 | 满足长期支持版本要求 |
|
||
| 框架 | Spring Boot 3.3.x | 稳定、生态成熟 |
|
||
| Web | Spring MVC | 提供 REST API |
|
||
| 参数校验 | Spring Validation | 请求参数校验 |
|
||
| ORM | MyBatis-Plus | 开发效率高,适合后台管理型系统 |
|
||
| 数据库 | MySQL 8.0 | 成熟稳定,部署简单 |
|
||
| 缓存 | Redis 7 | 缓存、会话、验证码、热点数据 |
|
||
| 鉴权 | Spring Security 6 + JWT | 标准化、安全性强、扩展性好 |
|
||
| 对象存储 | MinIO | 轻量、私有化友好,可替换云 OSS |
|
||
| 数据迁移 | Flyway | 管理数据库版本与初始化脚本 |
|
||
| API 文档 | springdoc-openapi + Knife4j | 自动生成接口文档,方便联调 |
|
||
| 日志 | Logback | 默认稳定方案 |
|
||
| 对象映射 | MapStruct | 降低 DTO/VO 转换样板代码 |
|
||
| 构建 | Maven | Java 生态成熟、稳定 |
|
||
| 测试 | JUnit 5 + Spring Boot Test + Testcontainers | 保证接口与数据库集成质量 |
|
||
|
||
### 5.1.1 为什么不优先使用微服务
|
||
|
||
当前场景的核心复杂度在于:
|
||
|
||
- 多租户隔离
|
||
- 角色权限控制
|
||
- 小程序与后台双端联动
|
||
- 名片内容与文件管理
|
||
|
||
这些问题本质上更适合“模块化单体”优先解决。若过早拆分为微服务,会明显增加:
|
||
|
||
- 部署复杂度
|
||
- 联调成本
|
||
- 配置和监控成本
|
||
- 分布式事务与调用链复杂度
|
||
|
||
因此第一阶段推荐单体架构,待租户数量、访问量和团队规模增长后,再按模块拆分。
|
||
|
||
## 5.2 后台管理端技术栈
|
||
|
||
| 分类 | 选型 | 说明 |
|
||
| --- | --- | --- |
|
||
| 框架 | Vue 3 | 主流稳定 |
|
||
| 语言 | TypeScript | 类型安全 |
|
||
| 构建工具 | Vite | 启动与构建速度快 |
|
||
| 路由 | Vue Router | 标准路由方案 |
|
||
| 状态管理 | Pinia | 轻量清晰 |
|
||
| UI 组件库 | Element Plus | 适合中后台、生态成熟 |
|
||
| 请求库 | Axios | 简洁稳定 |
|
||
| 样式 | SCSS + CSS Variables | 可维护、便于主题化 |
|
||
| 表格/表单增强 | Element Plus 原生能力优先 | 减少额外依赖 |
|
||
| 图表 | ECharts | 用于统计分析页 |
|
||
|
||
## 5.3 微信小程序技术栈
|
||
|
||
| 分类 | 选型 | 说明 |
|
||
| --- | --- | --- |
|
||
| 框架 | 原生微信小程序 | 当前仓库已采用 |
|
||
| 语言 | TypeScript | 已有基础 |
|
||
| 样式 | Less | 当前仓库已采用 |
|
||
| 数据请求 | 封装 `wx.request` | 简洁稳定,避免引入额外运行时 |
|
||
| 本地缓存 | `wx.setStorageSync` / `wx.getStorageSync` | 用于轻量本地状态,如浏览历史 |
|
||
|
||
说明:
|
||
|
||
- 当前小程序已有静态页面和 Mock 数据,后续改造重点是抽离 API 层、租户配置、环境变量管理和错误处理。
|
||
- 本项目按“一个小程序对应一个租户”设计,小程序内不再依赖页面参数动态切换租户。
|
||
- 小程序租户识别以 `AppID` 为主键,后台需维护 `AppID -> tenant_id` 的映射配置。
|
||
|
||
## 6. 核心架构设计
|
||
|
||
## 6.1 多租户模型
|
||
|
||
第一阶段推荐使用:
|
||
|
||
- 共享数据库
|
||
- 共享数据表结构
|
||
- 业务表统一增加 `tenant_id`
|
||
|
||
该方案优点:
|
||
|
||
- 成本低
|
||
- 开发快
|
||
- 部署简单
|
||
- 适合中小规模 SaaS
|
||
|
||
需要重点保证:
|
||
|
||
- 所有租户业务表都必须带 `tenant_id`
|
||
- 查询默认按 `tenant_id` 过滤
|
||
- 非平台角色不可跨租户访问
|
||
- 日志中要记录操作人、租户、操作对象
|
||
|
||
补充说明:
|
||
|
||
- 多租户主要体现在后台管理端和后端数据层。
|
||
- 小程序虽然是“一租户一 AppID”,但后端仍是统一多租户服务,公开接口和管理接口都需要具备租户隔离能力。
|
||
|
||
### 6.1.1 表分类建议
|
||
|
||
平台级表:
|
||
|
||
- `sys_tenant`
|
||
- `sys_platform_user`
|
||
- `sys_platform_role`
|
||
- `sys_menu`
|
||
- `sys_dict`
|
||
- `tenant_miniapp_config`
|
||
|
||
租户级表:
|
||
|
||
- `tenant_user`
|
||
- `tenant_role`
|
||
- `tenant_user_role`
|
||
- `org_department`
|
||
- `org_firm_profile`
|
||
- `card_profile`
|
||
- `file_asset`
|
||
- `card_view_stat`
|
||
- `operation_log`
|
||
|
||
### 6.1.2 未来扩展策略
|
||
|
||
当单租户数据量或安全要求显著上升时,可平滑扩展为:
|
||
|
||
- 大租户独立数据库
|
||
- 普通租户共享数据库
|
||
|
||
为此后端需抽象租户上下文与数据访问入口,不把 `tenant_id` 获取逻辑写死在业务代码中。
|
||
|
||
### 6.1.3 小程序与租户绑定模型
|
||
|
||
本项目推荐采用:
|
||
|
||
- 后台:多租户统一平台
|
||
- 小程序:一个租户对应一个微信小程序 AppID
|
||
- 后端:统一一套服务,按小程序配置映射到具体租户
|
||
|
||
该模式的优点:
|
||
|
||
- 每个事务所有独立品牌入口,体验更清晰
|
||
- 不需要在小程序页面参数中显式传递 `tenantCode`
|
||
- 可直接以小程序 `AppID` 作为租户识别主键
|
||
- 每个租户可独立发布、独立审核、独立配置微信能力
|
||
- 后端仍可复用统一业务代码和统一数据库结构
|
||
|
||
需要接受的代价:
|
||
|
||
- 每增加一个租户,就需要新增一个小程序 AppID
|
||
- 小程序发布、审核、备案、类目维护成本会随租户数量线性增加
|
||
- 构建与配置管理需要支持按租户生成不同发行包
|
||
|
||
## 6.2 权限模型
|
||
|
||
推荐采用 RBAC 模型:
|
||
|
||
- 用户
|
||
- 角色
|
||
- 菜单
|
||
- 按钮权限点
|
||
- 数据范围
|
||
|
||
角色建议:
|
||
|
||
- `PLATFORM_SUPER_ADMIN`
|
||
- `TENANT_ADMIN`
|
||
- `TENANT_USER`
|
||
|
||
权限控制分 3 层:
|
||
|
||
1. 接口层:校验是否登录、是否具备角色/权限。
|
||
2. 服务层:校验数据归属与业务状态。
|
||
3. 数据层:统一追加租户过滤条件。
|
||
|
||
## 6.3 登录认证设计
|
||
|
||
### 6.3.1 后台管理端
|
||
|
||
采用 `JWT Access Token + Redis` 组合:
|
||
|
||
- 登录成功后签发短期 Access Token
|
||
- Redis 记录登录会话、验证码和黑名单
|
||
- 退出登录时清理 Redis 中的会话信息
|
||
|
||
这样做的原因:
|
||
|
||
- 便于水平扩容
|
||
- 比传统服务端 Session 更适合前后端分离
|
||
- Redis 介入后可控制踢下线、单点登录、风控扩展
|
||
|
||
### 6.3.2 微信小程序
|
||
|
||
小程序端建议区分两类访问:
|
||
|
||
- 公开访问:无需登录,可浏览公开名片
|
||
- 成员访问:后续如需在小程序维护本人名片,可通过微信登录绑定用户
|
||
|
||
第一阶段的最简实现:
|
||
|
||
- 小程序仅做公开展示
|
||
- 每个小程序在构建时写入固定 `AppID` 配置
|
||
- 小程序启动后直接读取当前租户配置并调用公开接口
|
||
|
||
若后续要支持小程序内登录:
|
||
|
||
- 前端调用 `wx.login()`
|
||
- 后端调用微信 `code2Session`
|
||
- 将 `openid/unionId` 与系统用户绑定
|
||
|
||
### 6.3.3 小程序如何确定对应租户
|
||
|
||
由于本项目采用“一个小程序对应一个租户”的模式,因此租户识别以微信小程序 `AppID` 为主,不再依赖页面参数中的 `tenantCode`。
|
||
|
||
推荐落地方式如下:
|
||
|
||
#### 1. 租户配置表维护小程序信息
|
||
|
||
建议新增配置表或配置字段:
|
||
|
||
- `tenant_id`
|
||
- `tenant_code`
|
||
- `miniapp_app_id`
|
||
- `miniapp_app_secret`
|
||
- `miniapp_name`
|
||
- `miniapp_original_id`
|
||
- `request_domain`
|
||
- `publish_status`
|
||
|
||
其中:
|
||
|
||
- `miniapp_app_id` 是当前方案中的租户识别主键
|
||
- `miniapp_app_secret` 仅后端保存,必须加密存储
|
||
- `request_domain` 用于约束该小程序实际访问的接口域名,可作为辅助校验项
|
||
|
||
后台管理端需要新增“小程序配置”功能,至少支持:
|
||
|
||
- 为租户录入和修改 `AppID`
|
||
- 配置 `AppSecret`
|
||
- 校验 `AppID` 全平台唯一
|
||
- 启停用小程序配置
|
||
- 查询当前租户是否已完成小程序配置
|
||
|
||
#### 2. 小程序构建时注入固定租户配置
|
||
|
||
每个租户的小程序发行包包含固定配置,例如:
|
||
|
||
```ts
|
||
export const tenantRuntimeConfig = {
|
||
appId: 'wx1234567890xxxxxx',
|
||
apiBaseUrl: 'https://api.example.com',
|
||
}
|
||
```
|
||
|
||
说明:
|
||
|
||
- `appId` 是前端运行时的固定配置
|
||
- 同一个租户的小程序所有页面默认只访问本租户数据
|
||
- 不允许在小程序内切换到其他租户
|
||
|
||
#### 3. 后端接口通过租户上下文处理公开请求
|
||
|
||
公开接口建议改为以下风格:
|
||
|
||
- `/api/open/profile`
|
||
- `/api/open/cards`
|
||
- `/api/open/card/{cardId}`
|
||
- `/api/open/card/{cardId}/view`
|
||
- `/api/open/card/{cardId}/share`
|
||
|
||
即:
|
||
|
||
- 小程序端不需要在路径中传 `tenantCode`
|
||
- 后端通过 `AppID` 识别当前租户
|
||
|
||
#### 4. 请求上下文的识别策略
|
||
|
||
推荐策略如下:
|
||
|
||
1. 小程序请求时显式传递 `X-Miniapp-Appid`
|
||
2. Spring Boot 在过滤器中解析 `X-Miniapp-Appid`
|
||
3. 后端查询 `tenant_miniapp_config` 获取对应 `tenant_id`
|
||
4. 将 `tenant_id` 写入 `TenantContext`
|
||
5. 后续查询统一按 `tenant_id` 过滤
|
||
|
||
请求示例:
|
||
|
||
```http
|
||
GET /api/v1/open/profile
|
||
X-Miniapp-Appid: wx1234567890xxxxxx
|
||
```
|
||
|
||
对应的服务端逻辑:
|
||
|
||
```text
|
||
X-Miniapp-Appid -> tenant_miniapp_config -> tenant_id -> TenantContext
|
||
```
|
||
|
||
说明:
|
||
|
||
- 虽然 `X-Miniapp-Appid` 由前端传入,但其值来自构建时固定配置,不是页面动态参数
|
||
- `request_domain` 可作为辅助白名单校验,避免错误小程序配置访问非目标域名
|
||
- 对登录态接口和管理接口,仍必须叠加 token 与权限校验,不能只依赖 `AppID`
|
||
|
||
这种方式的优点是:
|
||
|
||
- 实现简单,适合当前单租户小程序模式
|
||
- 后端租户识别统一
|
||
- 与微信登录场景天然兼容,便于后续通过 `AppID + AppSecret` 调用 `code2Session`
|
||
|
||
#### 5. 管理端与小程序的数据边界
|
||
|
||
需要明确:
|
||
|
||
- 小程序公开接口只返回“已发布、允许公开”的租户信息和名片信息
|
||
- 即使攻击者伪造请求,也只能尝试访问公开数据,不应接触后台管理数据
|
||
- 后台管理接口仍然必须基于登录态、角色和 `tenant_id` 做严格隔离
|
||
|
||
#### 6. 构建与发布策略
|
||
|
||
一个租户一个小程序,建议采用“同一套源码,多套租户配置”的方式发布:
|
||
|
||
- 公共源码只维护一套
|
||
- 每个租户维护一份环境配置
|
||
- 打包时选择目标租户配置生成对应小程序包
|
||
|
||
建议配置文件结构:
|
||
|
||
```text
|
||
frontend_miniprogram/
|
||
├─ config/
|
||
│ ├─ tenants/
|
||
│ │ ├─ dev.default.ts
|
||
│ │ ├─ prod.nj_xx_law.ts
|
||
│ │ └─ prod.sample.ts
|
||
```
|
||
|
||
这样可以保证:
|
||
|
||
- 代码复用
|
||
- 配置隔离
|
||
- 发版过程可控
|
||
|
||
#### 7. 结论
|
||
|
||
在“一个小程序对应一个租户”的前提下,小程序识别租户的核心是:
|
||
|
||
- 小程序 `AppID`
|
||
- 后台维护的 `AppID -> tenant_id` 映射关系
|
||
- 小程序请求头中的 `X-Miniapp-Appid`
|
||
|
||
后端则通过统一的租户上下文机制,把请求路由到正确的租户数据范围。
|
||
|
||
## 6.4 文件存储设计
|
||
|
||
使用 MinIO 统一管理:
|
||
|
||
- 租户 Logo
|
||
- 用户头像
|
||
- 名片二维码
|
||
- 封面图
|
||
|
||
建议做法:
|
||
|
||
- 按业务分桶或目录管理
|
||
- 保存原始文件名、MIME、大小、哈希值
|
||
- 生成缩略图或压缩图
|
||
- 通过业务表引用文件 ID,而非直接在业务表中散落 URL
|
||
|
||
## 6.5 统计设计
|
||
|
||
统计范围:
|
||
|
||
- 名片浏览次数
|
||
- 名片分享次数
|
||
- 热门名片排行
|
||
- 按日趋势统计
|
||
|
||
第一阶段建议方案:
|
||
|
||
- 实时写入行为日志
|
||
- 定时汇总到统计表
|
||
|
||
这样可以兼顾:
|
||
|
||
- 原始数据可追溯
|
||
- 查询统计页更高效
|
||
|
||
## 7. 分层设计
|
||
|
||
后端建议遵循以下分层:
|
||
|
||
- Controller:参数接收、鉴权注解、响应封装
|
||
- Service:业务编排、事务控制、权限校验
|
||
- Domain/Manager:核心领域规则
|
||
- Mapper:数据库访问
|
||
- DTO/VO:输入输出模型
|
||
|
||
统一规范:
|
||
|
||
- 禁止 Controller 直接编写复杂业务逻辑
|
||
- 禁止 Service 直接暴露数据库实体给前端
|
||
- 输入输出对象分离,避免前端字段误改
|
||
|
||
## 8. API 设计建议
|
||
|
||
## 8.1 接口风格
|
||
|
||
- 统一 RESTful 风格
|
||
- 统一响应结构:`code`、`message`、`data`
|
||
- 列表接口统一支持分页
|
||
- 查询接口统一支持关键字、状态、时间区间筛选
|
||
|
||
## 8.2 接口分组建议
|
||
|
||
平台端:
|
||
|
||
- `/api/platform/auth/*`
|
||
- `/api/platform/tenants/*`
|
||
- `/api/platform/users/*`
|
||
- `/api/platform/config/*`
|
||
|
||
租户后台:
|
||
|
||
- `/api/tenant/auth/*`
|
||
- `/api/tenant/firm/*`
|
||
- `/api/tenant/org/*`
|
||
- `/api/tenant/users/*`
|
||
- `/api/tenant/cards/*`
|
||
- `/api/tenant/files/*`
|
||
- `/api/tenant/stats/*`
|
||
|
||
小程序公开端:
|
||
|
||
- `/api/open/profile`
|
||
- `/api/open/cards`
|
||
- `/api/open/card/{cardId}`
|
||
- `/api/open/card/{cardId}/view`
|
||
- `/api/open/card/{cardId}/share`
|
||
|
||
## 8.3 版本管理
|
||
|
||
建议从一开始就保留版本前缀:
|
||
|
||
- `/api/v1/...`
|
||
|
||
这样便于未来做不兼容升级。
|
||
|
||
## 9. 数据库设计建议
|
||
|
||
## 9.1 核心表
|
||
|
||
建议第一阶段至少包含以下核心表:
|
||
|
||
- `sys_tenant`:租户信息
|
||
- `tenant_miniapp_config`:租户与小程序配置映射
|
||
- `sys_user`:登录用户
|
||
- `sys_role`:角色
|
||
- `sys_user_role`:用户角色关系
|
||
- `org_department`:部门/分所
|
||
- `org_firm_profile`:事务所主页信息
|
||
- `card_profile`:个人名片主表
|
||
- `card_specialty`:名片专业领域
|
||
- `file_asset`:文件素材
|
||
- `card_view_log`:名片浏览日志
|
||
- `card_share_log`:名片分享日志
|
||
- `card_stat_daily`:名片按日统计表
|
||
- `sys_login_log`:登录日志
|
||
- `sys_operation_log`:操作日志
|
||
|
||
## 9.2 通用字段规范
|
||
|
||
每个业务表建议统一包含:
|
||
|
||
- `id`
|
||
- `tenant_id`
|
||
- `created_by`
|
||
- `created_time`
|
||
- `updated_by`
|
||
- `updated_time`
|
||
- `deleted`
|
||
|
||
说明:
|
||
|
||
- 平台级表可不包含 `tenant_id`
|
||
- 删除建议优先逻辑删除,关键日志表使用物理追加
|
||
|
||
### 9.3 小程序配置表建议
|
||
|
||
建议新增 `tenant_miniapp_config` 表,用于描述租户与微信小程序的绑定关系。
|
||
|
||
建议字段:
|
||
|
||
- `id`
|
||
- `tenant_id`
|
||
- `miniapp_app_id`
|
||
- `miniapp_app_secret`
|
||
- `miniapp_name`
|
||
- `miniapp_original_id`
|
||
- `request_domain`
|
||
- `version_tag`
|
||
- `publish_status`
|
||
- `created_time`
|
||
- `updated_time`
|
||
|
||
用途说明:
|
||
|
||
- 后台超级管理员或平台实施人员配置租户对应的小程序信息
|
||
- 后端在微信登录、发布管理、AppID 识别时使用该表
|
||
- 后续若增加多个环境,可在该表中扩展 `env` 字段区分测试和生产配置
|
||
|
||
约束建议:
|
||
|
||
- `miniapp_app_id` 全局唯一
|
||
- `tenant_id` 与 `miniapp_app_id` 建立唯一映射
|
||
- `miniapp_app_secret` 必须加密存储,不向前端返回
|
||
|
||
## 10. 部署方案
|
||
|
||
## 10.1 部署目标
|
||
|
||
目标是“轻量、稳定、可私有化部署”,推荐采用 Docker Compose 作为首期部署方式。
|
||
|
||
## 10.2 推荐中间件
|
||
|
||
| 组件 | 版本建议 | 用途 |
|
||
| --- | --- | --- |
|
||
| Nginx | 1.26+ | 反向代理、静态资源分发 |
|
||
| JDK | 21 | 运行 Spring Boot |
|
||
| MySQL | 8.0 | 主数据库 |
|
||
| Redis | 7 | 缓存与会话 |
|
||
| MinIO | 最新稳定版 | 文件存储 |
|
||
|
||
## 10.2.1 服务器配置建议
|
||
|
||
本项目第一阶段目标是“轻量、稳定、可扩展”,因此不建议一开始就采购过重的集群资源。推荐按环境和业务规模分层配置。
|
||
|
||
### 1. 开发环境
|
||
|
||
适用场景:
|
||
|
||
- 本地开发
|
||
- 单人或小团队联调
|
||
|
||
建议配置:
|
||
|
||
- CPU:4 核
|
||
- 内存:8 GB
|
||
- 系统盘:100 GB SSD
|
||
|
||
部署建议:
|
||
|
||
- MySQL、Redis、MinIO 可通过 Docker Desktop 或本机服务运行
|
||
- 后端、后台前端、小程序开发工具本地启动
|
||
|
||
### 2. 测试环境
|
||
|
||
适用场景:
|
||
|
||
- 功能测试
|
||
- 接口联调
|
||
- UAT 验收
|
||
|
||
建议配置:
|
||
|
||
- CPU:4 核
|
||
- 内存:8 GB 到 16 GB
|
||
- 系统盘:100 GB SSD
|
||
- 数据盘:100 GB SSD
|
||
|
||
部署建议:
|
||
|
||
- 单台 Linux 服务器部署 `Nginx + Spring Boot + MySQL + Redis + MinIO`
|
||
- 使用 Docker Compose 管理服务,便于迁移和重建环境
|
||
|
||
### 3. 生产环境当前推荐
|
||
|
||
适用场景:
|
||
|
||
- 仅服务 1 家事务所
|
||
- 约 20 名后台用户
|
||
- 小程序访问量较低到中等
|
||
- 以名片展示、资料维护、图片上传为主
|
||
|
||
建议配置:
|
||
|
||
- CPU:4 核
|
||
- 内存:8 GB
|
||
- 系统盘:50 GB SSD
|
||
- 数据盘:100 GB SSD
|
||
- 带宽:3 Mbps 到 5 Mbps
|
||
|
||
部署方式:
|
||
|
||
- 单机部署
|
||
- 使用 Docker Compose 部署 `Nginx + Spring Boot + MySQL + Redis + MinIO`
|
||
|
||
说明:
|
||
|
||
- 这是当前项目规模下更匹配的正式生产配置
|
||
- 对于 1 家事务所、20 名用户,该配置已能覆盖日常访问和后台维护需求
|
||
- 若图片、二维码、封面素材不多,`50 GB 系统盘 + 100 GB 数据盘` 基本足够
|
||
- MinIO、MySQL 数据目录建议挂载到数据盘,避免挤占系统盘
|
||
|
||
### 4. 容量规划建议
|
||
|
||
磁盘容量建议重点考虑以下部分:
|
||
|
||
- MySQL 数据量
|
||
- MinIO 文件素材
|
||
- 日志文件
|
||
- 数据库备份
|
||
|
||
经验建议:
|
||
|
||
- 当前项目规模下,初期生产环境总可用磁盘 150 GB 左右即可起步
|
||
- 若头像、二维码、宣传海报较多,可将数据盘扩展到 200 GB
|
||
- 数据库与对象存储应避免共用过小系统盘
|
||
|
||
|
||
### 5. 本项目首期推荐结论
|
||
|
||
按照当前明确范围:
|
||
|
||
- 1 家事务所
|
||
- 约 20 名用户
|
||
- 单租户使用
|
||
|
||
推荐采用以下生产配置:
|
||
|
||
- 1 台 4 核 8 GB Linux 云服务器
|
||
- 1 块 50 GB 系统盘
|
||
- 1 块 100 GB 数据盘
|
||
- 3 Mbps 到 5 Mbps 带宽
|
||
- Docker Compose 部署 `Nginx + Spring Boot + MySQL + Redis + MinIO`
|
||
|
||
如果希望多留一些冗余,可升级为:
|
||
|
||
- 1 台 4 核 16 GB 或 8 核 8 GB Linux 云服务器
|
||
- 数据盘提升到 200 GB
|
||
|
||
当前规模下,不需要一开始就做多机、主从或集群部署。
|
||
|
||
## 10.3 部署拓扑
|
||
|
||
```mermaid
|
||
flowchart TB
|
||
U["浏览器 / 微信小程序"] --> N["Nginx"]
|
||
N --> A["admin-web 静态站点"]
|
||
N --> B["backend API"]
|
||
B --> C["MySQL"]
|
||
B --> D["Redis"]
|
||
B --> E["MinIO"]
|
||
```
|
||
|
||
## 10.4 环境划分
|
||
|
||
建议至少划分 3 套环境:
|
||
|
||
- `dev`:本地开发环境
|
||
- `test`:测试联调环境
|
||
- `prod`:生产环境
|
||
|
||
每套环境均需独立配置:
|
||
|
||
- 数据库连接
|
||
- Redis 地址
|
||
- 对象存储地址
|
||
- JWT 密钥
|
||
- 微信小程序配置
|
||
|
||
补充说明:
|
||
|
||
- 由于采用“一租户一小程序”,生产环境需要为每个租户维护独立的小程序生产配置
|
||
- 测试环境可使用测试小程序 AppID 或体验版配置
|
||
|
||
## 10.5 配置管理
|
||
|
||
建议采用:
|
||
|
||
- Spring Profiles 区分环境
|
||
- 前端使用 `.env.development`、`.env.test`、`.env.production`
|
||
- 敏感配置通过环境变量注入,不写死在仓库
|
||
|
||
## 10.6 发布方式
|
||
|
||
推荐发布步骤:
|
||
|
||
1. 后端 Maven 打包为可执行 Jar。
|
||
2. 后台管理端 Vite 构建后部署到 Nginx 静态目录。
|
||
3. 选择目标租户的小程序配置,构建对应发行包。
|
||
4. 小程序通过微信开发者工具上传发布到该租户对应的小程序账号。
|
||
5. 数据库通过 Flyway 自动迁移到目标版本。
|
||
|
||
小程序发布补充要求:
|
||
|
||
- 每个租户需独立维护小程序 AppID、类目、服务器域名和上传主体信息
|
||
- 发布前需校验当前构建包是否使用了正确的租户配置
|
||
- 建议在后台配置中记录当前租户对应的小程序版本号和发布时间
|
||
- 后端在生产环境中以 `AppID` 作为公开接口租户识别的主键
|
||
|
||
### 10.6.1 Flyway 迁移约定
|
||
|
||
后端建议使用以下目录承载迁移脚本:
|
||
|
||
- [db/migration/mysql](/Users/slience/postgraduate/easycard/backend/easycard-boot/src/main/resources/db/migration/mysql)
|
||
|
||
首批迁移建议:
|
||
|
||
- `V1__create_core_schema.sql`:创建核心表结构
|
||
- `V2__seed_platform_base_data.sql`:初始化平台角色、菜单和字典
|
||
|
||
约束:
|
||
|
||
- 不回改已上线版本脚本
|
||
- 所有字段变更、新表、新索引均追加新版本
|
||
- 租户级默认数据在业务代码的“创建租户”流程中初始化,不直接写入平台基线迁移
|
||
|
||
## 11. 可观测性与运维
|
||
|
||
第一阶段建议最少落地以下能力:
|
||
|
||
- 应用日志滚动归档
|
||
- 登录日志与操作日志
|
||
- API 错误日志
|
||
- 文件上传失败日志
|
||
- 慢 SQL 排查
|
||
|
||
若进入正式商用阶段,建议增加:
|
||
|
||
- Prometheus + Grafana
|
||
- Spring Boot Actuator
|
||
- 异常告警通知
|
||
|
||
## 12. 安全设计
|
||
|
||
必须满足以下安全要求:
|
||
|
||
- 密码使用强哈希算法存储
|
||
- JWT 密钥与数据库密码不得入库明文
|
||
- 所有后台接口进行登录与权限校验
|
||
- 文件上传限制扩展名、大小与 MIME
|
||
- 公开接口做基础限流
|
||
- 防止越权读取其他租户数据
|
||
- 敏感操作写入审计日志
|
||
|
||
## 13. 开发实施建议
|
||
|
||
建议按以下顺序推进开发:
|
||
|
||
1. 先搭建后端基础框架、权限框架、租户框架、数据库脚手架。
|
||
2. 再完成后台管理端登录、租户管理、事务所管理、用户管理、名片管理。
|
||
3. 最后将微信小程序从 Mock 数据切换为真实接口,并补齐统计与异常处理。
|
||
|
||
## 14. 第一阶段交付清单
|
||
|
||
第一阶段建议交付内容如下:
|
||
|
||
- 后端基础框架与数据库脚本
|
||
- 超级管理员租户管理
|
||
- 租户管理员事务所管理、用户管理、名片管理
|
||
- 普通用户个人名片维护
|
||
- 小程序主页、列表、详情、历史动态化
|
||
- 文件上传
|
||
- 浏览统计
|
||
- 接口文档
|
||
- Docker Compose 部署文件
|
||
|
||
## 15. 技术结论
|
||
|
||
结合当前需求与仓库现状,推荐采用:
|
||
|
||
- 后端:`JDK 21 + Spring Boot 3.3 + Spring Security + MyBatis-Plus + MySQL + Redis + MinIO + Flyway`
|
||
- 后台:`Vue 3 + TypeScript + Vite + Pinia + Element Plus`
|
||
- 小程序:`原生微信小程序 + TypeScript + Less + 一租户一 AppID 的租户配置方案`
|
||
- 部署:`Nginx + Docker Compose`
|
||
|
||
该方案在复杂度、交付速度、稳定性、私有化友好程度和后续扩展能力之间较为均衡,适合作为本项目第一阶段正式落地方案。后台统一多租户,小程序按租户独立发布,二者职责边界清晰,便于实施和运营。
|