13 KiB
13 KiB
SAAS 架构概览
面向技术决策会议的架构说明文档。本文档聚焦 SAAS 多租户-公司-部门-用户-角色架构设计、当前实现状态与未来发展方向。
1. 项目定位
GVS-DSDK 是一套面向中小企业(SMB)的 SAAS 化企业管理平台,包含:
- 多租户 SAAS 框架:支持租户入驻、审核、隔离
- 企业资源管理(GERP):组织、角色、权限、菜单、工单、资产、文档
- 三大业务引擎:分佣引擎、支付网关、统计引擎
- 分布式通信底座(MSYNC):服务注册、发现、分布式事务
2. 技术栈
| 层 | 技术 |
|---|---|
| 后端框架 | Django 4.2+ / DRF / SimpleJWT |
| 异步任务 | Celery + Redis(可降级同步) |
| 实时通信 | Socket.IO(python-socketio) |
| 数据库 | MySQL 5.7+(7 库分库路由) |
| 缓存 | Redis(可降级 locmem) |
| 安全 | bcrypt / AES-256-GCM / JWT |
| 前端 | 原生 HTML/JS + 自研 NeoUI/GERPUI 组件 |
| 部署 | Gunicorn + Nginx 反向代理 |
3. 双包架构
┌─────────────────────────────────────────────────────┐
│ d:\SMANAGE(项目根) │
│ │
│ ┌──────────────────────┐ ┌──────────────────────┐│
│ │ gvsds │ │ gvsdsdk ││
│ │ 主服务器(业务层) │◄─┤ 分布式 SDK(薄封装)││
│ │ - Django 项目 │ │ - 协议契约层 ││
│ │ - 14 个业务 App │ │ - 惰性加载 ││
│ │ - 完整业务实现 │ │ - PascalCase 协议 ││
│ └──────────────────────┘ └──────────────────────┘│
│ ▲ ▲ │
│ │ │ │
│ ┌──────────────────────┐ ┌──────────────────────┐│
│ │ ATestCServer │ │ TempLate/ ││
│ │ 子服务器示例 │ │ 前端模板资源 ││
│ │ 通过 SDK 接入 │ │ GERP/AKS/MSOC 等 ││
│ └──────────────────────┘ └──────────────────────┘│
└─────────────────────────────────────────────────────┘
3.1 gvsds — 主服务器
- 14 个 Django App:
core / gerp / ugm / crb / invite / ccgo / sve / t4 / mc / doc / api / msync / payment / commission / stats - 7 库分库路由:
Users / GerpCore / Plans / Tasks / T4PC / Document / Minecraft - 6 个自定义中间件:IP 过滤、域名注入、当前角色注入、服务认证、攻击检测、错误日志
3.2 gvsdsdk — 分布式 SDK
- 薄封装层:1:1 包装
gvsds.apps.msync原生层,无运行时开销 - 惰性加载(PEP 562):90+ 符号按需 import
- 双类导出:自有实现(无 Django 依赖,子服务器可用)+ 服务端转发(依赖 Django ORM)
- 三大引擎:
CommissionEngine(分佣)、PaymentManager(支付)、TransactionManager(分布式事务)
3.3 主从通信机制
- 版本校验:启动时
gvsdsdk.check_min_version('1.0.0'),主从必须一致 - Socket.IO 协议:20+ 事件,全程 PascalCase 字段
- 支付网关自动注册:
gvsdsdk/apps.py的ready()钩子
4. SAAS 多租户架构(核心)
4.1 组织四层架构
┌──────────────────────────────────────────────────────────┐
│ 第 4 层:鉴权规则层(运行时) │
│ 操作权限 (RBAC) 数据权限 (ABAC + RoleScope) │
├──────────────────────────────────────────────────────────┤
│ 第 3 层:角色权限载体层 │
│ Role + UserRole + RolePermission │
├──────────────────────────────────────────────────────────┤
│ 第 2 层:岗位模板层(初始化快照) │
│ PositionTemplate + PositionTemplatePermission │
│ CopyToRole 一次性复制,后续独立演进 │
├──────────────────────────────────────────────────────────┤
│ 第 1 层:组织人事层 │
│ Tenant → Company → Department │
│ UserDept(员工-部门多对多) │
│ Position(人事职务标签,与权限解耦) │
│ Workgroup(跨部门工作组) Shop(商铺,归公司) │
└──────────────────────────────────────────────────────────┘
4.2 数据模型核心表(共 17 张 SAAS 表)
| 分类 | 表名 | 职责 |
|---|---|---|
| 租户 | Tenant |
多租户根,含审核状态/到期时间 |
| 组织 | Company / CompanyInfo / Department / Workgroup |
公司树/工商信息/部门树/跨部门组 |
| 用户 | User / UserAvatar / User2FA / UserPending2FA / UserLoginLog / AccountActivation / Password / UserIDCard |
用户身份与认证 |
| 角色权限 | Role / Permission / UserRole / RolePermission |
RBAC 核心 |
| 岗位模板 | PositionTemplate / PositionTemplatePermission |
权限初始化快照 |
| 人事标签 | Position / UserDept |
职务标签(与权限解耦) |
| 商铺 | Shop / RoleShop |
多商铺体系 |
| ABAC | UserABAC |
属性访问控制(补充) |
| 审计 | AuditLog / AbnormalUserLog |
操作审计 + 攻击溯源 |
4.3 关键设计决策
(1) Position 与权限完全解耦
- 人事职务标签(
Position)仅用于人事管理,不直接绑定权限 - 调岗/升职只修改
UserDept.PositionUUID与UserRole,权限只通过UserRole → RolePermission → Permission走 - 规避了业界常见错误:把职务直接绑权限导致调岗时权限树重算
(2) PositionTemplate 的"快照复制"机制
- 模板 → 角色 = 一次性复制(
CopyToRole),复制后两者无运行时绑定 - 模板调整只影响之后新建的角色,已有角色不被动变更
- 避免了"模板改一个字段,全员权限突然变了"的运维灾难
(3) UserRole 作为胖关联表
UserRole 表同时承载三重语义:
- 权限分配:User ↔ Role 多对多
- 组织归属:携带
CompanyUUID / DeptUUID / WorkgroupUUID - 数据范围:
RoleType标识"普通成员/部门负责人"
优势:同一用户在不同公司/部门可绑不同角色,原生支持 SAAS 强需求 代价:UserRole 违反单一职责,未来扩展需谨慎
(4) 角色作用域四档数据权限(RoleScope)
| 类型 | 判定条件 | 可见范围 |
|---|---|---|
admin |
IsSuperuser/IsStaff 或 admin:super 权限 |
全公司 |
dept_manager |
UserRole.RoleType=1 且 DeptUUID 非空 |
本部门成员 |
workgroup_lead |
UserRole.RoleType=1 且 WorkgroupUUID 非空 |
本工作组成员 |
member |
其他 | 仅自己 |
4.4 运行时鉴权流程
HTTP Request
│
├─► JWTAuthentication → User 实例
├─► CurrentRoleMiddleware → request.current_role (Role)
├─► DomainMiddleware → request.current_company_uuid
│
├──► 操作权限校验:PermissionVerifier(permission, attrs, user, request)
│ ├─ ABAC:UserABAC.HierarchicalPermissionIdentifiers ∋ attr?
│ └─ RBAC:RolePermission(角色)→Permission.PermCode ∋ attr?
│ (含请求级缓存,消除 N+1)
│
└──► 数据权限校验:RoleScope.GetUserScope(request)
└─ ApplyScopeToQueryset(qs, scope, table_name)
按 admin/dept_manager/workgroup_lead/member 差异化过滤
4.5 主键设计
- 全程使用
BINARY(16)UUID 主键 - 优势:分布式生成、无 ID 冲突、不暴露顺序信息
- 代价:InnoDB 聚簇索引无序,写入有页分裂开销(可考虑改 UUIDv7)
5. 三大业务引擎
5.1 分佣引擎(CommissionEngine)
| 策略 | Type | 说明 |
|---|---|---|
PercentageStrategy |
percentage |
比例分账,支持保底/封顶 |
FixedStrategy |
fixed |
固定金额 |
TieredStrategy |
tiered |
阶梯分账 |
RemainderStrategy |
remainder |
剩余归平台 |
WithdrawalFeeStrategy |
withdrawal_fee |
提现手续费 |
支持:规则配置 → 触发分佣 → 预结算 → 邀请链分佣 → 查询统计
5.2 支付网关(PaymentManager)
| 渠道 | 支付方式 | 转账 |
|---|---|---|
| 微信支付 | JSAPI/Native/H5/小程序 | 支持 |
| 支付宝 | APP/H5/Native | 支持 |
| 银行卡 | APP/H5/Native | 仅 bank 类型 |
支持:网关配置 → 支付/查询/退款/转账 → 回调处理
5.3 统计引擎(stats)
- Celery 定时任务:每日重置 / 每月重置 / 排行榜构建 / 过期清理
- 按角色差异化仪表盘
6. 当前实现状态
6.1 已完成
- ✅ 14 个业务 App 完整实现
- ✅ 多租户入驻审核工作流
- ✅ RBAC + ABAC 混合鉴权
- ✅ 分佣引擎 + 支付网关 + 统计引擎
- ✅ MSYNC 分布式通信(注册/发现/OGM/Saga 事务)
- ✅ 文件分片上传 + 资产管理
- ✅ 操作审计日志 + 攻击检测
6.2 已知技术债
| 优先级 | 问题 | 影响 |
|---|---|---|
| 高 | Role/Permission 模型在 gvsds 与 gvsdsdk 双份定义 | 字段漂移风险 |
| 高 | 部分表(User/Dept/Workgroup/Shop)无 TenantUUID | 跨租户查询需 JOIN,删除租户困难 |
| 中 | ABAC 实现本质是 RBAC(字符串集合) | 名实不符,扩展受限 |
| 中 | 数据权限硬编码 if table_name == 'X' |
违反开闭原则 |
| 中 | 缺乏软删除机制 | 误删不可恢复 |
| 低 | UUID 主键无序导致索引膨胀 | 大数据量写入性能下降 |
| 低 | 根 README.md 仍为 Flask 时代文档 | 新人易误读 |
7. 未来发展方向(会议讨论建议项)
7.1 短期(1-3 个月)
- 统一 Role/Permission 模型:让 gerp 直接复用 gvsdsdk 的模型定义,消除双份漂移
- 补全 TenantUUID 字段:所有租户语义表直接打
TenantUUID,简化跨租户查询与租户删除 - 数据权限策略化:用策略模式替代
if table_name == 'X',每个模型注册自己的ScopeFilter - 更新根 README.md:反映当前 Django 架构
7.2 中期(3-6 个月)
- 重构 ABAC 为真正的属性访问控制:支持时间/IP/资源所有者/字段级权限
- 引入软删除机制:
DeletedAt+DeletedByUUID,配合审计日志实现数据恢复 - 支付网关扩展:增加 PayPal/Stripe 适配(出海场景)
- 租户配额管理:用户数/数据量/API 调用次数配额
7.3 长期(6+ 个月)
- 拆分协议层:把 gvsdsdk 拆为
gvsds-protocol(纯协议)+gvsds-business(业务能力),主从各自依赖 - 改用 UUIDv7 或 Snowflake:解决主键无序问题
- 多区域部署:基于 MSYNC 实现跨地域多活
- 微服务化拆分:gerp/payment/commission/stats 可独立部署
8. 关键架构原则
- PascalCase 全链路一致:从数据库字段 → Python 类 → Socket.IO 事件 → 前端,无转换层
- 优雅降级:Redis/Celery/网关依赖缺失时自动降级,开发环境零依赖启动
- 配置外置:
app.ini+secrets.ini+ 环境变量三层配置,支持 12-factor 部署 - 薄封装 SDK:协议契约层与业务实现层分离,主从可独立演进
- Position 与权限解耦:人事标签不绑权限,避免调岗重算
9. 联系与维护
- 主仓库:
d:\SMANAGE - SDK 包:
gvsdsdk/(pyproject.toml v1.0.0) - 子服务器示例:
ATestCServer/ - 设计文档:
docs/commission_engine.md/docs/payment_gateway.md/docs/stats_engine.md
本架构文档用于技术决策会议参考,详细 API 与字段定义见 gvsdsdk/API.md 与 gvsdsdk/README.md。