Files
EasyCard/docs/技术文档.md
陈子默 74543cb9bf docs: 补充项目设计与环境文档
- 增加产品功能、技术方案与数据库设计说明

- 增加本地中间件环境与联调说明
2026-03-20 12:45:23 +08:00

23 KiB
Raw Permalink Blame History

电子名片系统技术文档

1. 文档目标

本文档用于定义本项目的技术架构、技术栈、中间件、数据隔离策略、部署方案与工程结构,目标是在满足 JDK 21 + Spring Boot + Vue 3 + TypeScript 约束下,实现一套轻量、稳定、易扩展的多租户电子名片系统。

2. 技术设计原则

  • 正确性优先:先保证多租户隔离、权限控制、数据一致性和关键链路稳定。
  • 轻量优先:优先采用单体模块化架构,避免过早拆分微服务。
  • 稳定优先:使用成熟、社区活跃、可持续维护的主流组件。
  • 扩展优先:模块边界清晰,为后续审核流、线索、预约、营销等功能预留能力。

3. 总体架构

系统由 3 个前后端子系统组成:

  1. 后端服务:统一提供租户、账号、名片、文件、统计等业务接口。
  2. 后台管理端:供超级管理员、租户管理员、普通用户登录管理数据。
  3. 微信小程序:面向公众展示事务所与个人电子名片。

说明:

  • 后台系统为多租户统一平台。
  • 微信小程序按“1 个租户 = 1 个小程序 AppID”设计每个事务所拥有独立小程序。
  • 多个租户的小程序可复用同一套后端服务与同一套代码模板,通过配置完成租户绑定。
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. 推荐工程结构

建议在当前仓库基础上扩展为如下结构:

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. 小程序构建时注入固定租户配置

每个租户的小程序发行包包含固定配置,例如:

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 过滤

请求示例:

GET /api/v1/open/profile
X-Miniapp-Appid: wx1234567890xxxxxx

对应的服务端逻辑:

X-Miniapp-Appid -> tenant_miniapp_config -> tenant_id -> TenantContext

说明:

  • 虽然 X-Miniapp-Appid 由前端传入,但其值来自构建时固定配置,不是页面动态参数
  • request_domain 可作为辅助白名单校验,避免错误小程序配置访问非目标域名
  • 对登录态接口和管理接口,仍必须叠加 token 与权限校验,不能只依赖 AppID

这种方式的优点是:

  • 实现简单,适合当前单租户小程序模式
  • 后端租户识别统一
  • 与微信登录场景天然兼容,便于后续通过 AppID + AppSecret 调用 code2Session

5. 管理端与小程序的数据边界

需要明确:

  • 小程序公开接口只返回“已发布、允许公开”的租户信息和名片信息
  • 即使攻击者伪造请求,也只能尝试访问公开数据,不应接触后台管理数据
  • 后台管理接口仍然必须基于登录态、角色和 tenant_id 做严格隔离

6. 构建与发布策略

一个租户一个小程序,建议采用“同一套源码,多套租户配置”的方式发布:

  • 公共源码只维护一套
  • 每个租户维护一份环境配置
  • 打包时选择目标租户配置生成对应小程序包

建议配置文件结构:

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 风格
  • 统一响应结构:codemessagedata
  • 列表接口统一支持分页
  • 查询接口统一支持关键字、状态、时间区间筛选

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_idminiapp_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. 开发环境

适用场景:

  • 本地开发
  • 单人或小团队联调

建议配置:

  • CPU4 核
  • 内存8 GB
  • 系统盘100 GB SSD

部署建议:

  • MySQL、Redis、MinIO 可通过 Docker Desktop 或本机服务运行
  • 后端、后台前端、小程序开发工具本地启动

2. 测试环境

适用场景:

  • 功能测试
  • 接口联调
  • UAT 验收

建议配置:

  • CPU4 核
  • 内存8 GB 到 16 GB
  • 系统盘100 GB SSD
  • 数据盘100 GB SSD

部署建议:

  • 单台 Linux 服务器部署 Nginx + Spring Boot + MySQL + Redis + MinIO
  • 使用 Docker Compose 管理服务,便于迁移和重建环境

3. 生产环境当前推荐

适用场景:

  • 仅服务 1 家事务所
  • 约 20 名后台用户
  • 小程序访问量较低到中等
  • 以名片展示、资料维护、图片上传为主

建议配置:

  • CPU4 核
  • 内存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 部署拓扑

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 迁移约定

后端建议使用以下目录承载迁移脚本:

首批迁移建议:

  • 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

该方案在复杂度、交付速度、稳定性、私有化友好程度和后续扩展能力之间较为均衡,适合作为本项目第一阶段正式落地方案。后台统一多租户,小程序按租户独立发布,二者职责边界清晰,便于实施和运营。