15 KiB
15 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 / 通用 SAAS 服务层
- 服务层:从薄封装演进为通用 SAAS 服务层——
RoleManager / AuthManager / AdminUserManager / TenantManager / CompanyManager / DepartmentManager / MessageManager / MenuManager / WorkOrderManager / InventoryManager / AssetManager / AuditManager / OrderManager / StatsManager / UserService等,gvsds 视图层通过它们访问数据(裸 ORM 已基本消除) - 惰性加载(PEP 562):130+ 符号按需 import
- 双类导出:自有实现(无 Django 依赖,子服务器可用)+ 服务端实现(依赖 Django ORM)
- msync 原生实现(1.1.0):通信底座已从
gvsds.apps.msync整体迁入gvsdsdk/msync(models/registry/ogm/transaction/auth + Django 集成层),可脱离 gvsds 独立部署(屏蔽 gvsds 后全模块独立导入验证通过) - 引擎:
CommissionEngine(分佣)、PaymentManager(支付)、OrderManager(订单状态机)、StatsManager(统计)、TransactionManager(分布式事务)
3.3 主从通信机制
- 版本校验:启动时
gvsdsdk.check_min_version('1.1.0'),主从必须一致(版本兼容矩阵见gvsdsdk/VERSION_MATRIX.md) - 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 |
职务标签(与权限解耦) |
| 商铺 | Shop / RoleShop |
多商铺体系 |
| ABAC | UserABAC |
属性访问控制(补充) |
| 审计 | AuditLog / AbnormalUserLog |
操作审计 + 攻击溯源 |
4.3 关键设计决策
(1) Position 与权限完全解耦
- 人事职务标签(
Position)仅用于人事管理,不直接绑定权限 - 调岗/升职只修改
Position,权限只通过UserRole → RolePermission → Permission走 - 规避了业界常见错误:把职务直接绑权限导致调岗时权限树重算
(2) PositionTemplate 的"快照复制"机制
- 模板 → 角色 = 一次性复制(
CopyToRole),复制后两者无运行时绑定 - 模板调整只影响之后新建的角色,已有角色不被动变更
- 避免了"模板改一个字段,全员权限突然变了"的运维灾难
(3) UserRole 实体化 + 关联表(部门/工作组多对多)
UserRole 是"用户↔角色"的实体化中间表(联合唯一:同一用户+同一角色仅一行):
- 权限分配:User ↔ Role 多对多(
UserRoleUUID作为全局唯一关联实体) - 组织归属:不再放 UserRole 上,改走关联表(多对多):
UserRoleDepartment:(用户-角色对) ↔ 部门(UserRoleUUID + DeptUUID)UserRoleWorkgroup:(用户-角色对) ↔ 工作组(UserRoleUUID + WorkgroupUUID)
- 成员类型:
RoleType(0=成员 / 1=负责人/组长)冗余在关联表,按部门/工作组区分
优势:一个用户-角色对可同时挂多个部门/工作组,且在不同部门可分别标注成员/负责人
注意:UserRole 上的遗留字段(DeptUUID / WorkgroupUUID / RoleType)已废弃删除(见 gvsdsdk 0002 迁移),
全部语义以关联表为准。
(4) 角色作用域四档数据权限(RoleScope)
| 类型 | 判定条件 | 可见范围 |
|---|---|---|
admin |
IsSuperuser/IsStaff 或 admin:super 权限 |
全公司 |
dept_manager |
UserRoleDepartment.RoleType=1(按当前公司过滤,可多部门) |
本部门成员 |
workgroup_lead |
UserRoleWorkgroup.RoleType=1(按当前公司过滤,可多工作组) |
本工作组成员 |
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 事务)
- ✅ 文件分片上传 + 资产管理
- ✅ 操作审计日志 + 攻击检测
- ✅ 服务层化迁移(P0/P1/P2 全部完成,2026-08-07):role_scope 数据权限底座、form_service 角色/用户链路、菜单/工单/消息/物品/背包/文档/文件资产、25 个 ViewSet queryset、form_service 通用增删改落库、doc 视图/统计任务/审计清理等全部收敛到 gvsdsdk(详见项目记忆「服务层化迁移进度」);invite/sve/t4/ccgo 已定性为业务定制留在 gvsds(与 CRB/MC 同边界)
6.2 已知技术债
| 优先级 | 问题 | 影响 |
|---|---|---|
from gvsdsdk.models import,SDK 为唯一模型源 |
— | |
| 高 | 部分表(User/Dept/Workgroup/Shop)无 TenantUUID | 跨租户查询需 JOIN,删除租户困难(待迁移脚本补列回填) |
| 中 | ABAC 实现本质是 RBAC(字符串集合) | 已文档更正为"属性标识符补充层",真 ABAC 重构列入中期规划 |
| 中 | 数据权限硬编码 if table_name == 'X' |
违反开闭原则 |
| 中 | 缺乏软删除机制 | 误删不可恢复 |
StatEngine(gvsds/apps/stats/manager.py)已删除,编排方法全部并入 gvsdsdk StatsManager,视图/Celery 任务统一走 SDK |
— | |
| 低 | UUID 主键无序导致索引膨胀 | 大数据量写入性能下降 |
7. 未来发展方向(会议讨论建议项)
7.1 短期(1-3 个月)
统一 Role/Permission 模型:✅ 已收敛(2026-08-10)——视图层统一经 gvsdsdk Manager 访问,模型层 gvsds 统一从 gvsdsdk import,双份定义消除- 补全 TenantUUID 字段:所有租户语义表直接打
TenantUUID,简化跨租户查询与租户删除 - 数据权限策略化:用策略模式替代
if table_name == 'X',每个模型注册自己的ScopeFilter 更新根 README.md:✅ 已反映当前 Django 架构统一 stats 双轨实现:✅ 已收敛——StatEngine删除,StatsManager补齐编排方法(DefineMetric/GenerateDailyRanking/QueryRanking/RunScheduledResets/BuildRankings 等),视图与 Celery 任务统一经 gvsdsdk 访问
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。