docs: 补充项目设计与环境文档
- 增加产品功能、技术方案与数据库设计说明 - 增加本地中间件环境与联调说明
This commit is contained in:
479
docs/产品功能文档.md
Normal file
479
docs/产品功能文档.md
Normal file
@@ -0,0 +1,479 @@
|
|||||||
|
# 电子名片系统产品功能文档
|
||||||
|
|
||||||
|
## 1. 文档目的
|
||||||
|
|
||||||
|
本文档用于明确“电子名片 + 多租户后台管理系统”项目的业务目标、角色权限、功能范围、核心流程与交付边界,作为后续产品设计、技术开发、联调测试和验收的统一依据。
|
||||||
|
|
||||||
|
## 2. 项目概述
|
||||||
|
|
||||||
|
### 2.1 项目定位
|
||||||
|
|
||||||
|
本项目面向律师事务所、咨询机构、专业服务组织等“事务所型租户”,提供一套可运营、可配置、可扩展的电子名片系统:
|
||||||
|
|
||||||
|
- 前台:微信小程序,用于展示事务所信息、人员名片信息,并提供分享、拨号、导航、加联系人等能力。
|
||||||
|
- 后台:多租户管理系统,用于平台管理、租户管理、组织管理、用户管理、名片维护、素材管理和数据统计。
|
||||||
|
- 后端:统一提供租户、用户、名片、文件、统计等 API 服务,支撑小程序与后台管理系统。
|
||||||
|
|
||||||
|
### 2.2 业务目标
|
||||||
|
|
||||||
|
- 帮助事务所快速搭建统一品牌形象的电子名片体系。
|
||||||
|
- 帮助租户管理员统一维护事务所、部门、律师/员工信息。
|
||||||
|
- 帮助普通用户便捷维护个人电子名片,提高对外传播效率。
|
||||||
|
- 帮助平台方通过多租户能力统一服务多个事务所,降低交付和运维成本。
|
||||||
|
|
||||||
|
### 2.3 当前仓库现状
|
||||||
|
|
||||||
|
当前仓库已包含微信小程序静态原型,已具备以下页面雏形:
|
||||||
|
|
||||||
|
- 律所主页
|
||||||
|
- 律师列表页
|
||||||
|
- 律师详情页
|
||||||
|
- 浏览历史页
|
||||||
|
|
||||||
|
现阶段页面主要依赖本地 Mock 数据,后续需改造为对接后端接口的动态数据版本。
|
||||||
|
|
||||||
|
## 3. 目标用户与角色定义
|
||||||
|
|
||||||
|
### 3.1 角色划分
|
||||||
|
|
||||||
|
系统包含 3 类后台角色与 1 类前台访问身份:
|
||||||
|
|
||||||
|
| 角色 | 身份说明 | 核心职责 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 超级管理员 | 平台运营方 | 管理租户、平台账号、平台配置、全局字典、全局监控 |
|
||||||
|
| 租户管理员 | 某个事务所的管理员 | 管理本租户的组织、人员、事务所资料、名片内容、素材与数据 |
|
||||||
|
| 普通用户 | 某个事务所下的成员 | 登录后台维护个人名片资料、查看个人数据、预览和分享名片 |
|
||||||
|
| 小程序访客 | 公众用户 | 浏览事务所主页、查看名片、拨号、保存联系人、导航、分享 |
|
||||||
|
|
||||||
|
### 3.2 权限边界
|
||||||
|
|
||||||
|
| 功能模块 | 超级管理员 | 租户管理员 | 普通用户 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| 平台登录 | 支持 | 不支持 | 不支持 |
|
||||||
|
| 租户后台登录 | 可模拟排查 | 支持 | 支持 |
|
||||||
|
| 租户管理 | 全部 | 无 | 无 |
|
||||||
|
| 事务所信息维护 | 可查看 | 全部 | 只读 |
|
||||||
|
| 部门/组织维护 | 可查看 | 全部 | 只读 |
|
||||||
|
| 用户账号管理 | 全部 | 管理本租户用户 | 仅维护本人登录资料 |
|
||||||
|
| 角色授权 | 全部 | 分配本租户角色 | 无 |
|
||||||
|
| 名片信息维护 | 可查看 | 管理本租户全部名片 | 管理本人名片 |
|
||||||
|
| 素材管理 | 可查看 | 管理本租户素材 | 仅上传/替换本人素材 |
|
||||||
|
| 统计分析 | 全局 | 本租户 | 本人 |
|
||||||
|
| 数据隔离 | 平台可见全部 | 仅本租户 | 仅本人/本租户授权范围 |
|
||||||
|
|
||||||
|
## 4. 核心业务对象
|
||||||
|
|
||||||
|
### 4.1 核心对象
|
||||||
|
|
||||||
|
- 租户:一个事务所或公司/组织,是系统中的一级业务单元。
|
||||||
|
- 组织:租户下的部门、分所、业务组。
|
||||||
|
- 用户:租户下的可登录成员。
|
||||||
|
- 名片:用户对外展示的信息载体。
|
||||||
|
- 事务所主页:租户对外展示的机构简介、地址、专业领域、联系方式等信息。
|
||||||
|
- 素材:头像、徽标、封面图、二维码、附件等文件。
|
||||||
|
- 浏览记录:小程序端名片的访问行为数据。
|
||||||
|
|
||||||
|
### 4.2 核心关系
|
||||||
|
|
||||||
|
- 一个平台可管理多个租户。
|
||||||
|
- 一个租户可拥有多个组织节点。
|
||||||
|
- 一个租户可拥有多个用户。
|
||||||
|
- 一个用户默认对应一张电子名片。
|
||||||
|
- 一个租户对应一个对外展示主页,可关联多个办公地点、多个专业领域。
|
||||||
|
|
||||||
|
## 5. 产品功能范围
|
||||||
|
|
||||||
|
## 5.1 微信小程序端
|
||||||
|
|
||||||
|
### 5.1.1 律所主页
|
||||||
|
|
||||||
|
用于展示事务所品牌与入口信息。
|
||||||
|
|
||||||
|
功能点:
|
||||||
|
|
||||||
|
- 展示事务所 Logo、名称、封面图、简介
|
||||||
|
- 展示总部地址、办公地点列表、专业领域标签
|
||||||
|
- 展示一键跳转“人员列表”
|
||||||
|
- 展示咨询电话、导航入口
|
||||||
|
- 支持根据当前小程序绑定的 AppID 加载对应事务所信息
|
||||||
|
|
||||||
|
典型页面映射:
|
||||||
|
|
||||||
|
- 当前已有静态页面:`pages/firm/index`
|
||||||
|
|
||||||
|
### 5.1.2 人员名片列表
|
||||||
|
|
||||||
|
用于浏览某个租户下全部可公开展示的成员名片。
|
||||||
|
|
||||||
|
功能点:
|
||||||
|
|
||||||
|
- 按姓名、办公地点、专业领域搜索
|
||||||
|
- 按办公机构筛选
|
||||||
|
- 按专业领域筛选
|
||||||
|
- 卡片式展示头像、姓名、职务、专业方向
|
||||||
|
- 点击进入名片详情
|
||||||
|
- 一键拨打热线或跳转事务所位置
|
||||||
|
|
||||||
|
典型页面映射:
|
||||||
|
|
||||||
|
- 当前已有静态页面:`pages/lawyer-list/index`
|
||||||
|
|
||||||
|
### 5.1.3 个人名片详情
|
||||||
|
|
||||||
|
用于展示成员完整的对外名片信息。
|
||||||
|
|
||||||
|
功能点:
|
||||||
|
|
||||||
|
- 展示姓名、头像、职务、所属事务所/组织、联系方式、地址
|
||||||
|
- 展示个人简介、专业领域、二维码
|
||||||
|
- 支持拨打电话
|
||||||
|
- 支持保存到系统通讯录
|
||||||
|
- 支持打开地图导航
|
||||||
|
- 支持查看个人简介弹窗
|
||||||
|
- 支持分享小程序名片
|
||||||
|
- 支持记录浏览历史
|
||||||
|
|
||||||
|
典型页面映射:
|
||||||
|
|
||||||
|
- 当前已有静态页面:`pages/lawyer-detail/index`
|
||||||
|
|
||||||
|
### 5.1.4 浏览历史
|
||||||
|
|
||||||
|
用于提升回访效率。
|
||||||
|
|
||||||
|
功能点:
|
||||||
|
|
||||||
|
- 展示最近浏览的名片列表
|
||||||
|
- 展示浏览时间
|
||||||
|
- 支持点击再次进入名片
|
||||||
|
- 支持清空历史
|
||||||
|
|
||||||
|
说明:
|
||||||
|
|
||||||
|
- 当前原型为本地缓存方案,正式版本升级为“本地缓存 + 服务端埋点统计”双轨制。
|
||||||
|
|
||||||
|
典型页面映射:
|
||||||
|
|
||||||
|
- 当前已有静态页面:`pages/history/index`
|
||||||
|
|
||||||
|
### 5.1.5 分享与传播
|
||||||
|
|
||||||
|
功能点:
|
||||||
|
|
||||||
|
- 支持微信好友分享
|
||||||
|
- 支持微信会话卡片传播
|
||||||
|
- 支持通过二维码进入指定租户主页或指定个人名片页
|
||||||
|
- 支持在分享链路中保留租户信息与被分享对象信息
|
||||||
|
|
||||||
|
### 5.1.6 异常与空状态
|
||||||
|
|
||||||
|
功能点:
|
||||||
|
|
||||||
|
- 名片不存在提示
|
||||||
|
- 租户不存在或已停用提示
|
||||||
|
- 网络异常重试
|
||||||
|
- 暂无公开成员提示
|
||||||
|
- 暂无定位/电话/二维码配置提示
|
||||||
|
|
||||||
|
## 5.2 后台管理系统
|
||||||
|
|
||||||
|
后台管理系统为统一的 Web 管理端,登录后根据角色显示不同菜单与权限。
|
||||||
|
|
||||||
|
### 5.2.1 登录与账号体系
|
||||||
|
|
||||||
|
功能点:
|
||||||
|
|
||||||
|
- 账号密码登录
|
||||||
|
- 图形验证码
|
||||||
|
- 登录态续期与退出登录
|
||||||
|
- 角色鉴权、菜单鉴权、按钮鉴权
|
||||||
|
- 超级管理员与租户用户使用不同登录入口或同入口分流
|
||||||
|
- 支持用户首次登录后修改初始密码
|
||||||
|
- 支持重置密码
|
||||||
|
|
||||||
|
扩展项:
|
||||||
|
|
||||||
|
- 手机验证码登录
|
||||||
|
- 微信绑定登录
|
||||||
|
|
||||||
|
### 5.2.2 超级管理员端
|
||||||
|
|
||||||
|
#### 1. 租户管理
|
||||||
|
|
||||||
|
功能点:
|
||||||
|
|
||||||
|
- 新增/编辑/禁用租户
|
||||||
|
- 设置租户名称、编码、联系人、联系电话、状态、到期时间
|
||||||
|
- 设置租户套餐能力与上限
|
||||||
|
- 初始化租户管理员账号
|
||||||
|
- 配置租户对应的小程序 AppID、AppSecret、原始 ID、发布状态
|
||||||
|
- 查看租户使用情况
|
||||||
|
|
||||||
|
#### 2. 平台账号与权限管理
|
||||||
|
|
||||||
|
功能点:
|
||||||
|
|
||||||
|
- 平台管理员账号管理
|
||||||
|
- 平台角色管理
|
||||||
|
- 平台菜单与权限点管理
|
||||||
|
|
||||||
|
#### 3. 平台基础配置
|
||||||
|
|
||||||
|
功能点:
|
||||||
|
|
||||||
|
- 全局字典维护
|
||||||
|
- 系统参数维护
|
||||||
|
- 文件存储配置
|
||||||
|
- 微信小程序基础配置
|
||||||
|
- 小程序服务器域名、上传域名等平台级配置
|
||||||
|
|
||||||
|
#### 4. 租户小程序配置管理
|
||||||
|
|
||||||
|
功能点:
|
||||||
|
|
||||||
|
- 维护租户与微信小程序的绑定关系
|
||||||
|
- 配置并校验小程序 AppID 是否唯一
|
||||||
|
- 维护 AppSecret、原始 ID、名称、版本标记、启用状态
|
||||||
|
- 查看当前租户小程序配置是否完整
|
||||||
|
- 为后端公开接口提供 AppID 到租户的映射基础
|
||||||
|
|
||||||
|
#### 5. 全局监控与审计
|
||||||
|
|
||||||
|
功能点:
|
||||||
|
|
||||||
|
- 登录日志
|
||||||
|
- 操作日志
|
||||||
|
- 租户状态监控
|
||||||
|
- 错误告警概览
|
||||||
|
|
||||||
|
### 5.2.3 租户管理员端
|
||||||
|
|
||||||
|
#### 1. 事务所/公司/组织信息管理
|
||||||
|
|
||||||
|
功能点:
|
||||||
|
|
||||||
|
- 维护事务所名称、Logo、封面图、简介
|
||||||
|
- 维护总部地址、经纬度、联系电话
|
||||||
|
- 维护办公机构列表
|
||||||
|
- 维护专业领域列表
|
||||||
|
- 维护对外展示状态
|
||||||
|
|
||||||
|
#### 2. 组织架构管理
|
||||||
|
|
||||||
|
功能点:
|
||||||
|
|
||||||
|
- 部门/分所树维护
|
||||||
|
- 设置组织负责人
|
||||||
|
- 组织排序与展示控制
|
||||||
|
|
||||||
|
#### 3. 用户管理
|
||||||
|
|
||||||
|
功能点:
|
||||||
|
|
||||||
|
- 新增/导入/编辑/禁用用户
|
||||||
|
- 分配组织与角色
|
||||||
|
- 重置密码
|
||||||
|
- 设置是否公开展示
|
||||||
|
- 设置名片排序与推荐位
|
||||||
|
|
||||||
|
#### 4. 名片管理
|
||||||
|
|
||||||
|
功能点:
|
||||||
|
|
||||||
|
- 维护个人基础信息:姓名、职务、手机、邮箱、地址
|
||||||
|
- 维护个人扩展信息:简介、擅长领域、荣誉、执业证号、社交二维码
|
||||||
|
- 上传头像、二维码、宣传图
|
||||||
|
- 预览小程序展示效果
|
||||||
|
- 控制名片发布状态、上下架状态
|
||||||
|
|
||||||
|
#### 5. 素材与文件管理
|
||||||
|
|
||||||
|
功能点:
|
||||||
|
|
||||||
|
- 上传图片
|
||||||
|
- 查看图片使用情况
|
||||||
|
- 删除未引用素材
|
||||||
|
- 限制文件大小、格式
|
||||||
|
|
||||||
|
#### 6. 数据统计
|
||||||
|
|
||||||
|
功能点:
|
||||||
|
|
||||||
|
- 按用户查看名片浏览量
|
||||||
|
- 按时间查看访问趋势
|
||||||
|
- 查看热门名片排行
|
||||||
|
- 查看分享传播数据
|
||||||
|
|
||||||
|
### 5.2.4 普通用户端
|
||||||
|
|
||||||
|
普通用户登录后台后,仅维护本人相关信息。
|
||||||
|
|
||||||
|
功能点:
|
||||||
|
|
||||||
|
- 查看与编辑本人名片
|
||||||
|
- 上传本人头像、二维码
|
||||||
|
- 预览本人名片
|
||||||
|
- 查看本人浏览数据
|
||||||
|
- 修改密码
|
||||||
|
|
||||||
|
## 5.3 通用支撑能力
|
||||||
|
|
||||||
|
### 5.3.1 文件上传能力
|
||||||
|
|
||||||
|
- 支持头像、Logo、封面、二维码上传
|
||||||
|
- 支持图片压缩与格式校验
|
||||||
|
- 支持生成访问 URL
|
||||||
|
|
||||||
|
### 5.3.2 日志与审计
|
||||||
|
|
||||||
|
- 登录日志
|
||||||
|
- 操作日志
|
||||||
|
- 异常日志
|
||||||
|
- 关键业务日志
|
||||||
|
|
||||||
|
### 5.3.3 数据隔离
|
||||||
|
|
||||||
|
- 以租户为边界进行数据隔离
|
||||||
|
- 所有租户业务数据必须带租户归属
|
||||||
|
- 非平台角色不可跨租户读取和操作数据
|
||||||
|
|
||||||
|
### 5.3.4 可配置展示
|
||||||
|
|
||||||
|
- 支持控制成员是否公开
|
||||||
|
- 支持控制字段是否展示
|
||||||
|
- 支持控制租户主页是否启用
|
||||||
|
|
||||||
|
## 6. 核心业务流程
|
||||||
|
|
||||||
|
### 6.1 租户开通流程
|
||||||
|
|
||||||
|
1. 超级管理员创建租户。
|
||||||
|
2. 系统生成租户编码与初始租户管理员账号。
|
||||||
|
3. 超级管理员配置该租户对应的小程序 AppID 与相关参数。
|
||||||
|
4. 租户管理员首次登录,完善事务所资料。
|
||||||
|
5. 租户管理员创建组织并导入用户。
|
||||||
|
6. 用户补充个人名片信息并发布。
|
||||||
|
7. 小程序开始展示对应租户主页及成员名片。
|
||||||
|
|
||||||
|
### 6.2 普通用户名片维护流程
|
||||||
|
|
||||||
|
1. 普通用户登录后台。
|
||||||
|
2. 编辑个人信息、专业领域、联系方式、头像和二维码。
|
||||||
|
3. 点击保存并预览。
|
||||||
|
4. 若租户策略要求审核,则进入待审核状态。
|
||||||
|
5. 审核通过后在小程序端公开展示。
|
||||||
|
|
||||||
|
### 6.3 小程序访客浏览流程
|
||||||
|
|
||||||
|
1. 用户通过分享链接或二维码进入小程序。
|
||||||
|
2. 系统根据当前小程序 AppID 识别租户,并根据页面参数识别目标名片。
|
||||||
|
3. 加载事务所主页或名片详情。
|
||||||
|
4. 用户执行拨号、加联系人、导航、分享等动作。
|
||||||
|
5. 系统记录浏览、分享等统计数据。
|
||||||
|
|
||||||
|
## 7. 关键数据字段建议
|
||||||
|
|
||||||
|
### 7.1 事务所主页字段
|
||||||
|
|
||||||
|
- 租户名称
|
||||||
|
- 英文名称
|
||||||
|
- Logo
|
||||||
|
- 封面图
|
||||||
|
- 简介
|
||||||
|
- 联系电话
|
||||||
|
- 总部地址
|
||||||
|
- 经纬度
|
||||||
|
- 办公机构列表
|
||||||
|
- 专业领域列表
|
||||||
|
- 官网/公众号链接
|
||||||
|
- 展示状态
|
||||||
|
|
||||||
|
### 7.2 个人名片字段
|
||||||
|
|
||||||
|
- 用户姓名
|
||||||
|
- 性别
|
||||||
|
- 头像
|
||||||
|
- 职务/头衔
|
||||||
|
- 所属部门/分所
|
||||||
|
- 手机号
|
||||||
|
- 座机
|
||||||
|
- 邮箱
|
||||||
|
- 地址
|
||||||
|
- 擅长领域
|
||||||
|
- 个人简介
|
||||||
|
- 执业证号
|
||||||
|
- 教育/荣誉信息
|
||||||
|
- 微信二维码
|
||||||
|
- 名片封面图
|
||||||
|
- 对外展示状态
|
||||||
|
- 排序值
|
||||||
|
|
||||||
|
## 8. 非功能需求
|
||||||
|
|
||||||
|
### 8.1 安全性
|
||||||
|
|
||||||
|
- 后台接口必须鉴权
|
||||||
|
- 密码加密存储
|
||||||
|
- 操作日志可追溯
|
||||||
|
- 文件上传类型和大小受控
|
||||||
|
- 租户数据严格隔离
|
||||||
|
|
||||||
|
### 8.2 可用性
|
||||||
|
|
||||||
|
- 常规操作响应流畅
|
||||||
|
- 关键操作具备失败提示
|
||||||
|
- 网络失败可重试
|
||||||
|
- 页面需适配主流手机尺寸
|
||||||
|
|
||||||
|
### 8.3 可维护性
|
||||||
|
|
||||||
|
- 功能模块边界清晰
|
||||||
|
- 支持租户规模扩展
|
||||||
|
- 支持后续扩展审核、预约咨询、线索收集等能力
|
||||||
|
|
||||||
|
## 9. 版本建议
|
||||||
|
|
||||||
|
### 9.1 第一阶段:MVP
|
||||||
|
|
||||||
|
建议优先落地以下能力:
|
||||||
|
|
||||||
|
- 多租户基础能力
|
||||||
|
- 超级管理员租户管理
|
||||||
|
- 租户管理员维护事务所与用户
|
||||||
|
- 普通用户维护本人名片
|
||||||
|
- 小程序动态化展示事务所主页、列表、详情、历史
|
||||||
|
- 文件上传
|
||||||
|
- 基础统计
|
||||||
|
|
||||||
|
### 9.2 第二阶段:增强版
|
||||||
|
|
||||||
|
- 名片审核流
|
||||||
|
- Excel 批量导入/导出
|
||||||
|
- 分享海报/专属二维码
|
||||||
|
- 数据大屏与更细粒度统计
|
||||||
|
- 微信绑定登录
|
||||||
|
- 消息通知
|
||||||
|
|
||||||
|
## 10. 验收标准
|
||||||
|
|
||||||
|
### 10.1 业务验收
|
||||||
|
|
||||||
|
- 可创建多个租户,且数据互不串扰
|
||||||
|
- 超级管理员可管理租户
|
||||||
|
- 租户管理员可管理本租户事务所信息和用户
|
||||||
|
- 普通用户可编辑本人名片
|
||||||
|
- 小程序可按租户维度展示对应事务所与用户名片
|
||||||
|
- 小程序动作能力可正常使用:拨号、分享、导航、加联系人
|
||||||
|
|
||||||
|
### 10.2 体验验收
|
||||||
|
|
||||||
|
- 页面信息完整、结构清晰
|
||||||
|
- 搜索/筛选结果正确
|
||||||
|
- 空状态、错误状态、无权限状态提示明确
|
||||||
|
- 后台操作路径简洁,表单校验清晰
|
||||||
|
|
||||||
|
## 11. 后续开发原则
|
||||||
|
|
||||||
|
- 先完成“可用且正确”的多租户闭环,再逐步增加高级能力。
|
||||||
|
- 先保证租户、用户、名片、展示四条主链路打通,再扩展统计、审核、营销。
|
||||||
|
- 小程序与后台字段模型保持统一,避免前后端重复定义和语义不一致。
|
||||||
844
docs/技术文档.md
Normal file
844
docs/技术文档.md
Normal file
@@ -0,0 +1,844 @@
|
|||||||
|
# 电子名片系统技术文档
|
||||||
|
|
||||||
|
## 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`
|
||||||
|
|
||||||
|
该方案在复杂度、交付速度、稳定性、私有化友好程度和后续扩展能力之间较为均衡,适合作为本项目第一阶段正式落地方案。后台统一多租户,小程序按租户独立发布,二者职责边界清晰,便于实施和运营。
|
||||||
432
docs/数据库设计文档.md
Normal file
432
docs/数据库设计文档.md
Normal file
@@ -0,0 +1,432 @@
|
|||||||
|
# 电子名片系统数据库设计文档
|
||||||
|
|
||||||
|
## 1. 文档目标
|
||||||
|
|
||||||
|
本文档用于固定电子名片系统第一阶段的数据库模型,覆盖多租户后台、小程序 `AppID` 绑定、组织/用户/名片、素材、统计、审计等核心模块,并与当前产品文档、技术文档保持一致。
|
||||||
|
|
||||||
|
对应初始化脚本:
|
||||||
|
|
||||||
|
- [easycard_init.sql](/Users/slience/postgraduate/easycard/database/mysql/easycard_init.sql)
|
||||||
|
- [V1__create_core_schema.sql](/Users/slience/postgraduate/easycard/backend/easycard-boot/src/main/resources/db/migration/mysql/V1__create_core_schema.sql)
|
||||||
|
- [V2__seed_platform_base_data.sql](/Users/slience/postgraduate/easycard/backend/easycard-boot/src/main/resources/db/migration/mysql/V2__seed_platform_base_data.sql)
|
||||||
|
|
||||||
|
## 2. 设计原则
|
||||||
|
|
||||||
|
### 2.1 总体原则
|
||||||
|
|
||||||
|
- 数据库:MySQL 8.x
|
||||||
|
- 字符集:`utf8mb4`
|
||||||
|
- 排序规则:`utf8mb4_0900_ai_ci`
|
||||||
|
- 架构模式:单库单 Schema,多租户共享表结构
|
||||||
|
- 多租户隔离:业务表统一使用 `tenant_id`
|
||||||
|
- 小程序租户识别:使用 `miniapp_app_id` 映射到 `tenant_id`
|
||||||
|
|
||||||
|
### 2.2 关键约束
|
||||||
|
|
||||||
|
- 平台级数据使用 `tenant_id = 0`
|
||||||
|
- 租户业务数据必须带 `tenant_id > 0`
|
||||||
|
- 小程序 `AppID` 全平台唯一
|
||||||
|
- 一个租户在同一环境仅允许一条小程序配置
|
||||||
|
- 用户、角色、组织编码、专业领域编码等按租户唯一
|
||||||
|
|
||||||
|
### 2.3 删除策略
|
||||||
|
|
||||||
|
- 核心业务表默认使用逻辑删除字段 `deleted`
|
||||||
|
- 日志和统计明细表默认不做逻辑删除
|
||||||
|
- 需要唯一约束的业务表,唯一索引统一带上 `deleted`
|
||||||
|
|
||||||
|
### 2.4 主键策略
|
||||||
|
|
||||||
|
第一阶段采用:
|
||||||
|
|
||||||
|
- `BIGINT UNSIGNED AUTO_INCREMENT`
|
||||||
|
|
||||||
|
原因:
|
||||||
|
|
||||||
|
- 对当前规模足够简单稳定
|
||||||
|
- 便于直接落地和排查问题
|
||||||
|
- 后续如需分布式 ID,可在应用层平滑切换
|
||||||
|
|
||||||
|
### 2.5 外键策略
|
||||||
|
|
||||||
|
第一阶段不强依赖数据库物理外键,采用“应用层维护逻辑关联 + 数据库索引约束”的方式。
|
||||||
|
|
||||||
|
原因:
|
||||||
|
|
||||||
|
- 更适合多租户共享表结构
|
||||||
|
- 更利于后续表结构演进
|
||||||
|
- 避免逻辑删除和历史日志场景下的迁移成本
|
||||||
|
|
||||||
|
## 3. 核心实体关系
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
erDiagram
|
||||||
|
SYS_TENANT ||--o{ TENANT_MINIAPP_CONFIG : has
|
||||||
|
SYS_TENANT ||--o{ SYS_USER : owns
|
||||||
|
SYS_TENANT ||--o{ SYS_ROLE : owns
|
||||||
|
SYS_TENANT ||--o{ ORG_DEPARTMENT : owns
|
||||||
|
SYS_TENANT ||--|| ORG_FIRM_PROFILE : owns
|
||||||
|
SYS_TENANT ||--o{ ORG_FIRM_PRACTICE_AREA : owns
|
||||||
|
SYS_TENANT ||--o{ CARD_PROFILE : owns
|
||||||
|
SYS_TENANT ||--o{ FILE_ASSET : owns
|
||||||
|
SYS_USER ||--o{ SYS_USER_ROLE : has
|
||||||
|
SYS_ROLE ||--o{ SYS_USER_ROLE : assigned
|
||||||
|
SYS_ROLE ||--o{ SYS_ROLE_MENU : grants
|
||||||
|
SYS_MENU ||--o{ SYS_ROLE_MENU : bound
|
||||||
|
ORG_DEPARTMENT ||--o{ SYS_USER : contains
|
||||||
|
SYS_USER ||--|| CARD_PROFILE : owns
|
||||||
|
CARD_PROFILE ||--o{ CARD_PROFILE_SPECIALTY : has
|
||||||
|
ORG_FIRM_PRACTICE_AREA ||--o{ CARD_PROFILE_SPECIALTY : references
|
||||||
|
FILE_ASSET ||--o{ FILE_ASSET_USAGE : used_by
|
||||||
|
CARD_PROFILE ||--o{ CARD_VIEW_LOG : viewed
|
||||||
|
CARD_PROFILE ||--o{ CARD_SHARE_LOG : shared
|
||||||
|
CARD_PROFILE ||--o{ CARD_STAT_DAILY : aggregated
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. 模块划分
|
||||||
|
|
||||||
|
### 4.1 平台与租户
|
||||||
|
|
||||||
|
- `sys_tenant`
|
||||||
|
- `tenant_miniapp_config`
|
||||||
|
- `sys_config`
|
||||||
|
|
||||||
|
### 4.2 账号与权限
|
||||||
|
|
||||||
|
- `sys_user`
|
||||||
|
- `sys_role`
|
||||||
|
- `sys_user_role`
|
||||||
|
- `sys_menu`
|
||||||
|
- `sys_role_menu`
|
||||||
|
|
||||||
|
### 4.3 基础字典
|
||||||
|
|
||||||
|
- `sys_dict_type`
|
||||||
|
- `sys_dict_item`
|
||||||
|
|
||||||
|
### 4.4 组织与事务所信息
|
||||||
|
|
||||||
|
- `org_department`
|
||||||
|
- `org_firm_profile`
|
||||||
|
- `org_firm_practice_area`
|
||||||
|
|
||||||
|
### 4.5 名片与素材
|
||||||
|
|
||||||
|
- `card_profile`
|
||||||
|
- `card_profile_specialty`
|
||||||
|
- `file_asset`
|
||||||
|
- `file_asset_usage`
|
||||||
|
|
||||||
|
### 4.6 统计与审计
|
||||||
|
|
||||||
|
- `card_view_log`
|
||||||
|
- `card_share_log`
|
||||||
|
- `card_stat_daily`
|
||||||
|
- `sys_login_log`
|
||||||
|
- `sys_operation_log`
|
||||||
|
|
||||||
|
## 5. 关键表设计说明
|
||||||
|
|
||||||
|
## 5.1 `sys_tenant`
|
||||||
|
|
||||||
|
用途:
|
||||||
|
|
||||||
|
- 平台租户主表
|
||||||
|
- 管理事务所基础信息、到期时间、资源上限、启停用状态
|
||||||
|
|
||||||
|
关键字段:
|
||||||
|
|
||||||
|
- `tenant_code`:租户编码,平台唯一
|
||||||
|
- `tenant_name`:租户名称
|
||||||
|
- `tenant_status`:`ENABLED / DISABLED / EXPIRED`
|
||||||
|
- `user_limit`:用户上限
|
||||||
|
- `storage_limit_mb`:素材存储空间上限
|
||||||
|
|
||||||
|
## 5.2 `tenant_miniapp_config`
|
||||||
|
|
||||||
|
用途:
|
||||||
|
|
||||||
|
- 维护租户与微信小程序的映射关系
|
||||||
|
- 后端通过 `miniapp_app_id` 识别租户
|
||||||
|
|
||||||
|
关键字段:
|
||||||
|
|
||||||
|
- `tenant_id`
|
||||||
|
- `env_code`:`DEV / TEST / PROD`
|
||||||
|
- `miniapp_app_id`
|
||||||
|
- `miniapp_app_secret`
|
||||||
|
- `miniapp_original_id`
|
||||||
|
- `request_domain`
|
||||||
|
- `publish_status`:`UNCONFIGURED / DRAFT / PUBLISHED / DISABLED`
|
||||||
|
|
||||||
|
关键约束:
|
||||||
|
|
||||||
|
- `miniapp_app_id` 全局唯一
|
||||||
|
- `tenant_id + env_code + deleted` 唯一
|
||||||
|
|
||||||
|
## 5.3 `sys_user`
|
||||||
|
|
||||||
|
用途:
|
||||||
|
|
||||||
|
- 平台用户与租户用户统一账号表
|
||||||
|
|
||||||
|
关键字段:
|
||||||
|
|
||||||
|
- `tenant_id`:平台用户固定为 `0`
|
||||||
|
- `user_type`:`PLATFORM / TENANT`
|
||||||
|
- `username`
|
||||||
|
- `password_hash`
|
||||||
|
- `dept_id`
|
||||||
|
- `user_status`:`ENABLED / DISABLED / LOCKED`
|
||||||
|
- `must_update_password`
|
||||||
|
|
||||||
|
关键约束:
|
||||||
|
|
||||||
|
- `tenant_id + username + deleted` 唯一
|
||||||
|
|
||||||
|
## 5.4 `sys_role`
|
||||||
|
|
||||||
|
用途:
|
||||||
|
|
||||||
|
- 平台角色和租户角色统一管理
|
||||||
|
|
||||||
|
关键字段:
|
||||||
|
|
||||||
|
- `role_scope`:`PLATFORM / TENANT`
|
||||||
|
- `role_code`
|
||||||
|
- `role_name`
|
||||||
|
- `data_scope`:`ALL / TENANT / DEPT / SELF`
|
||||||
|
- `is_builtin`
|
||||||
|
|
||||||
|
关键约束:
|
||||||
|
|
||||||
|
- `tenant_id + role_code + deleted` 唯一
|
||||||
|
|
||||||
|
补充说明:
|
||||||
|
|
||||||
|
- 平台初始化脚本仅预置平台超级管理员角色
|
||||||
|
- `TENANT_ADMIN`、`TENANT_USER` 这类租户内置角色,应在“创建租户”流程中按租户自动生成
|
||||||
|
|
||||||
|
## 5.5 `org_department`
|
||||||
|
|
||||||
|
用途:
|
||||||
|
|
||||||
|
- 表示总部、分所、部门、业务组等组织树
|
||||||
|
|
||||||
|
关键字段:
|
||||||
|
|
||||||
|
- `parent_id`
|
||||||
|
- `dept_type`:`HEADQUARTERS / BRANCH / DEPARTMENT / GROUP`
|
||||||
|
- `dept_code`
|
||||||
|
- `dept_name`
|
||||||
|
- `leader_user_id`
|
||||||
|
- `display_order`
|
||||||
|
|
||||||
|
说明:
|
||||||
|
|
||||||
|
- 小程序前端展示办公机构列表时,可直接读取 `HEADQUARTERS / BRANCH` 类型节点
|
||||||
|
|
||||||
|
## 5.6 `org_firm_profile`
|
||||||
|
|
||||||
|
用途:
|
||||||
|
|
||||||
|
- 事务所对外展示主信息
|
||||||
|
|
||||||
|
关键字段:
|
||||||
|
|
||||||
|
- `firm_name`
|
||||||
|
- `firm_short_name`
|
||||||
|
- `logo_asset_id`
|
||||||
|
- `hero_asset_id`
|
||||||
|
- `intro`
|
||||||
|
- `hotline_phone`
|
||||||
|
- `hq_address`
|
||||||
|
- `hq_latitude`
|
||||||
|
- `hq_longitude`
|
||||||
|
|
||||||
|
关键约束:
|
||||||
|
|
||||||
|
- 一个租户仅允许一条有效事务所主页记录
|
||||||
|
|
||||||
|
## 5.7 `org_firm_practice_area`
|
||||||
|
|
||||||
|
用途:
|
||||||
|
|
||||||
|
- 租户级专业领域字典
|
||||||
|
|
||||||
|
关键字段:
|
||||||
|
|
||||||
|
- `area_code`
|
||||||
|
- `area_name`
|
||||||
|
- `display_order`
|
||||||
|
- `area_status`
|
||||||
|
|
||||||
|
## 5.8 `card_profile`
|
||||||
|
|
||||||
|
用途:
|
||||||
|
|
||||||
|
- 用户电子名片主表
|
||||||
|
|
||||||
|
关键字段:
|
||||||
|
|
||||||
|
- `user_id`
|
||||||
|
- `card_name`
|
||||||
|
- `card_title`
|
||||||
|
- `mobile`
|
||||||
|
- `email`
|
||||||
|
- `avatar_asset_id`
|
||||||
|
- `wechat_qr_asset_id`
|
||||||
|
- `bio`
|
||||||
|
- `certificate_no`
|
||||||
|
- `education_info`
|
||||||
|
- `honor_info`
|
||||||
|
- `is_public`
|
||||||
|
- `publish_status`
|
||||||
|
- `display_order`
|
||||||
|
- `view_count`
|
||||||
|
- `share_count`
|
||||||
|
|
||||||
|
关键约束:
|
||||||
|
|
||||||
|
- 一个用户默认一张名片,`tenant_id + user_id + deleted` 唯一
|
||||||
|
|
||||||
|
## 5.9 `card_profile_specialty`
|
||||||
|
|
||||||
|
用途:
|
||||||
|
|
||||||
|
- 名片与专业领域的关联表
|
||||||
|
|
||||||
|
说明:
|
||||||
|
|
||||||
|
- 保留 `specialty_name` 快照,避免租户修改专业领域名称后历史展示失真
|
||||||
|
|
||||||
|
## 5.10 `file_asset`
|
||||||
|
|
||||||
|
用途:
|
||||||
|
|
||||||
|
- 管理头像、Logo、封面图、二维码等素材
|
||||||
|
|
||||||
|
关键字段:
|
||||||
|
|
||||||
|
- `storage_provider`
|
||||||
|
- `bucket_name`
|
||||||
|
- `object_key`
|
||||||
|
- `original_name`
|
||||||
|
- `file_ext`
|
||||||
|
- `mime_type`
|
||||||
|
- `file_size`
|
||||||
|
- `file_hash`
|
||||||
|
- `access_url`
|
||||||
|
- `asset_status`
|
||||||
|
|
||||||
|
## 5.11 `file_asset_usage`
|
||||||
|
|
||||||
|
用途:
|
||||||
|
|
||||||
|
- 记录素材被哪个业务对象引用
|
||||||
|
- 支持后台查看图片使用情况
|
||||||
|
|
||||||
|
关键字段:
|
||||||
|
|
||||||
|
- `asset_id`
|
||||||
|
- `biz_type`
|
||||||
|
- `biz_id`
|
||||||
|
- `field_name`
|
||||||
|
|
||||||
|
## 5.12 `card_view_log` / `card_share_log` / `card_stat_daily`
|
||||||
|
|
||||||
|
用途:
|
||||||
|
|
||||||
|
- `card_view_log`:原始浏览明细
|
||||||
|
- `card_share_log`:原始分享明细
|
||||||
|
- `card_stat_daily`:按日聚合统计
|
||||||
|
|
||||||
|
说明:
|
||||||
|
|
||||||
|
- 原始明细用于追溯
|
||||||
|
- 聚合表用于后台统计查询
|
||||||
|
|
||||||
|
## 5.13 `sys_login_log` / `sys_operation_log`
|
||||||
|
|
||||||
|
用途:
|
||||||
|
|
||||||
|
- 平台与租户后台的登录审计
|
||||||
|
- 关键业务操作审计
|
||||||
|
|
||||||
|
说明:
|
||||||
|
|
||||||
|
- 这两张表是安全审计与问题排查的基础,不建议省略
|
||||||
|
|
||||||
|
## 6. 状态字段建议值
|
||||||
|
|
||||||
|
### 6.1 租户状态
|
||||||
|
|
||||||
|
- `ENABLED`
|
||||||
|
- `DISABLED`
|
||||||
|
- `EXPIRED`
|
||||||
|
|
||||||
|
### 6.2 用户状态
|
||||||
|
|
||||||
|
- `ENABLED`
|
||||||
|
- `DISABLED`
|
||||||
|
- `LOCKED`
|
||||||
|
|
||||||
|
### 6.3 小程序发布状态
|
||||||
|
|
||||||
|
- `UNCONFIGURED`
|
||||||
|
- `DRAFT`
|
||||||
|
- `PUBLISHED`
|
||||||
|
- `DISABLED`
|
||||||
|
|
||||||
|
### 6.4 名片发布状态
|
||||||
|
|
||||||
|
- `DRAFT`
|
||||||
|
- `PUBLISHED`
|
||||||
|
- `OFFLINE`
|
||||||
|
|
||||||
|
### 6.5 文件状态
|
||||||
|
|
||||||
|
- `UPLOADED`
|
||||||
|
- `ACTIVE`
|
||||||
|
- `ARCHIVED`
|
||||||
|
- `DELETED`
|
||||||
|
|
||||||
|
## 7. 索引设计原则
|
||||||
|
|
||||||
|
- 所有高频业务表统一创建 `tenant_id` 索引
|
||||||
|
- 所有按编码查找的字段创建唯一索引或普通索引
|
||||||
|
- 行为日志按 `tenant_id + card_id + 时间` 建索引
|
||||||
|
- 聚合统计表按 `tenant_id + stat_date`、`tenant_id + card_id + stat_date` 建索引
|
||||||
|
|
||||||
|
## 8. 初始化脚本说明
|
||||||
|
|
||||||
|
初始化脚本文件:
|
||||||
|
|
||||||
|
- [easycard_init.sql](/Users/slience/postgraduate/easycard/database/mysql/easycard_init.sql)
|
||||||
|
- [Flyway 迁移目录](/Users/slience/postgraduate/easycard/backend/easycard-boot/src/main/resources/db/migration/mysql/README.md)
|
||||||
|
|
||||||
|
脚本内容包含:
|
||||||
|
|
||||||
|
- 数据库创建
|
||||||
|
- 全部核心表 DDL
|
||||||
|
- 索引与唯一约束
|
||||||
|
- 默认平台角色初始化
|
||||||
|
- 默认基础菜单初始化
|
||||||
|
- 默认字典类型与字典项初始化
|
||||||
|
|
||||||
|
Flyway 版本化脚本拆分为:
|
||||||
|
|
||||||
|
- `V1__create_core_schema.sql`:只负责建表和索引
|
||||||
|
- `V2__seed_platform_base_data.sql`:只负责平台级基础数据
|
||||||
|
|
||||||
|
## 9. 后续扩展建议
|
||||||
|
|
||||||
|
当项目进入第二阶段,可在当前模型上继续扩展:
|
||||||
|
|
||||||
|
- 名片审核表
|
||||||
|
- 微信用户绑定表
|
||||||
|
- Excel 导入任务表
|
||||||
|
- 消息通知表
|
||||||
|
- 线索与咨询记录表
|
||||||
|
|
||||||
|
第一阶段不建议提前引入过多非核心表,优先保证主链路稳定。
|
||||||
166
docs/本地中间件环境说明.md
Normal file
166
docs/本地中间件环境说明.md
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
# 本地容器环境说明
|
||||||
|
|
||||||
|
## 1. 目标
|
||||||
|
|
||||||
|
本文档说明如何在本机通过 Docker Compose 快速启动电子名片项目所需的完整容器环境。
|
||||||
|
|
||||||
|
当前提供的服务包括:
|
||||||
|
|
||||||
|
- MySQL 8.0
|
||||||
|
- Redis 7
|
||||||
|
- MinIO
|
||||||
|
- Spring Boot 后端
|
||||||
|
- Vue 管理后台(Nginx 托管)
|
||||||
|
|
||||||
|
对应文件:
|
||||||
|
|
||||||
|
- [docker-compose.yml](/Users/slience/postgraduate/easycard/docker-compose.yml)
|
||||||
|
- [MySQL Dockerfile](/Users/slience/postgraduate/easycard/docker/mysql/Dockerfile)
|
||||||
|
- [MySQL 配置](/Users/slience/postgraduate/easycard/docker/mysql/conf.d/my.cnf)
|
||||||
|
- [Redis 配置](/Users/slience/postgraduate/easycard/docker/redis/redis.conf)
|
||||||
|
- [Backend Dockerfile](/Users/slience/postgraduate/easycard/docker/backend/Dockerfile)
|
||||||
|
- [Frontend Dockerfile](/Users/slience/postgraduate/easycard/docker/frontend-admin/Dockerfile)
|
||||||
|
- [Nginx 配置](/Users/slience/postgraduate/easycard/docker/frontend-admin/nginx.conf)
|
||||||
|
|
||||||
|
## 2. 启动方式
|
||||||
|
|
||||||
|
在项目根目录执行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
查看状态:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose ps
|
||||||
|
```
|
||||||
|
|
||||||
|
停止并保留数据卷:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose down
|
||||||
|
```
|
||||||
|
|
||||||
|
停止并删除数据卷:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose down -v
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. 服务说明
|
||||||
|
|
||||||
|
### 3.1 MySQL
|
||||||
|
|
||||||
|
- 容器名:`easycard-mysql`
|
||||||
|
- 数据库:`easycard`
|
||||||
|
- 用户:`root`
|
||||||
|
- 密码:`root`
|
||||||
|
|
||||||
|
说明:
|
||||||
|
|
||||||
|
- 首次启动时会自动执行 [easycard_init.sql](/Users/slience/postgraduate/easycard/database/mysql/easycard_init.sql)
|
||||||
|
- 该脚本当前只负责创建 `easycard` 数据库
|
||||||
|
- 表结构、平台基础数据、演示数据由后端启动后的 Flyway 脚本统一执行
|
||||||
|
- 数据持久化目录:`docker/data/mysql`
|
||||||
|
- 当前不对宿主机暴露端口,仅允许 Docker 内网访问
|
||||||
|
|
||||||
|
### 3.2 Redis
|
||||||
|
|
||||||
|
- 容器名:`easycard-redis`
|
||||||
|
- 默认未设置密码
|
||||||
|
|
||||||
|
说明:
|
||||||
|
|
||||||
|
- 当前为本地开发配置
|
||||||
|
- 后续若进入联调或准生产环境,建议补充访问密码
|
||||||
|
- 数据持久化目录:`docker/data/redis`
|
||||||
|
- 当前不对宿主机暴露端口,仅允许 Docker 内网访问
|
||||||
|
|
||||||
|
### 3.3 MinIO
|
||||||
|
|
||||||
|
- 容器名:`easycard-minio`
|
||||||
|
- 用户名:`minioadmin`
|
||||||
|
- 密码:`minioadmin`
|
||||||
|
|
||||||
|
说明:
|
||||||
|
|
||||||
|
- `minio-init` 会在启动后自动创建 `easycard` bucket
|
||||||
|
- 当前脚本默认给该 bucket 开启下载访问,便于本地联调图片访问
|
||||||
|
- 数据持久化目录:`docker/data/minio`
|
||||||
|
- 当前不对宿主机暴露端口,仅允许 Docker 内网访问
|
||||||
|
|
||||||
|
### 3.4 Backend
|
||||||
|
|
||||||
|
- 容器名:`easycard-backend`
|
||||||
|
- 端口:`8112`
|
||||||
|
|
||||||
|
说明:
|
||||||
|
|
||||||
|
- 使用 [docker/backend/Dockerfile](/Users/slience/postgraduate/easycard/docker/backend/Dockerfile) 进行多阶段构建
|
||||||
|
- 容器启动时使用 `docker` profile
|
||||||
|
- 日志目录挂载到 `docker/data/backend/logs`
|
||||||
|
- 首次启动会等待 MySQL 健康检查通过后再启动
|
||||||
|
|
||||||
|
接口地址:
|
||||||
|
|
||||||
|
- [http://localhost:8112/api/v1/system/ping](http://localhost:8112/api/v1/system/ping)
|
||||||
|
- [http://localhost:8112/swagger-ui/index.html](http://localhost:8112/swagger-ui/index.html)
|
||||||
|
|
||||||
|
### 3.5 Frontend Admin
|
||||||
|
|
||||||
|
- 容器名:`easycard-frontend-admin`
|
||||||
|
- 端口:`8081`
|
||||||
|
|
||||||
|
说明:
|
||||||
|
|
||||||
|
- 使用 [docker/frontend-admin/Dockerfile](/Users/slience/postgraduate/easycard/docker/frontend-admin/Dockerfile) 构建前端产物
|
||||||
|
- 通过 Nginx 托管前端静态资源
|
||||||
|
- Nginx 会将 `/api`、`/swagger-ui`、`/v3/api-docs` 反向代理到 backend 服务
|
||||||
|
- Nginx 日志目录挂载到 `docker/data/nginx/logs`
|
||||||
|
|
||||||
|
访问地址:
|
||||||
|
|
||||||
|
- [http://localhost:8081](http://localhost:8081)
|
||||||
|
|
||||||
|
## 4. 与后端配置的对应关系
|
||||||
|
|
||||||
|
当前后端默认配置位于:
|
||||||
|
|
||||||
|
- [application.yml](/Users/slience/postgraduate/easycard/backend/easycard-boot/src/main/resources/application.yml)
|
||||||
|
|
||||||
|
容器内部联通使用:
|
||||||
|
|
||||||
|
- `DB_HOST=mysql`
|
||||||
|
- `DB_PORT=3306`
|
||||||
|
- `DB_NAME=easycard`
|
||||||
|
- `DB_USERNAME=root`
|
||||||
|
- `DB_PASSWORD=root`
|
||||||
|
- `REDIS_HOST=redis`
|
||||||
|
- `REDIS_PORT=6379`
|
||||||
|
- `REDIS_DATABASE=0`
|
||||||
|
- MinIO 服务名:`minio`
|
||||||
|
|
||||||
|
## 5. 数据挂载目录
|
||||||
|
|
||||||
|
当前容器数据与日志均挂载到宿主机目录:
|
||||||
|
|
||||||
|
- `docker/data/mysql`
|
||||||
|
- `docker/data/redis`
|
||||||
|
- `docker/data/minio`
|
||||||
|
- `docker/data/backend/logs`
|
||||||
|
- `docker/data/nginx/logs`
|
||||||
|
|
||||||
|
这样做的好处:
|
||||||
|
|
||||||
|
- 便于本地排查数据
|
||||||
|
- 重建容器后数据仍保留
|
||||||
|
- 便于备份和手工清理
|
||||||
|
|
||||||
|
## 6. 注意事项
|
||||||
|
|
||||||
|
- `easycard_init.sql` 当前仅适用于手工建库和 Docker 首次建库
|
||||||
|
- 若重新执行初始化脚本,请先删除 MySQL 数据卷,否则 MySQL 不会再次执行 `/docker-entrypoint-initdb.d`
|
||||||
|
- 若需要重建表结构和演示数据,请删除 MySQL 数据后重新启动 backend,由 Flyway 重新执行版本脚本
|
||||||
|
- 若本机已有 8112 或 8081 端口占用,需要同步调整后端和前端端口映射
|
||||||
|
- 当前仅 `frontend-admin(8081)` 和 `backend(8112)` 对宿主机暴露端口
|
||||||
Reference in New Issue
Block a user