276 lines
15 KiB
Markdown
276 lines
15 KiB
Markdown
# 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 已知技术债
|
||
|
||
| 优先级 | 问题 | 影响 |
|
||
|---|---|---|
|
||
| ~~高~~ | ~~Role/Permission 模型双份定义~~:✅ 已收敛(2026-08-10)——gvsds 各 app 模型统一 `from gvsdsdk.models import`,SDK 为唯一模型源 | — |
|
||
| 高 | 部分表(User/Dept/Workgroup/Shop)无 TenantUUID | 跨租户查询需 JOIN,删除租户困难(待迁移脚本补列回填) |
|
||
| 中 | ABAC 实现本质是 RBAC(字符串集合) | 已文档更正为"属性标识符补充层",真 ABAC 重构列入中期规划 |
|
||
| 中 | 数据权限硬编码 `if table_name == 'X'` | 违反开闭原则 |
|
||
| 中 | 缺乏软删除机制 | 误删不可恢复 |
|
||
| ~~中~~ | ~~stats 双轨~~:✅ 已统一(2026-08-07)——`StatEngine`(gvsds/apps/stats/manager.py)已删除,编排方法全部并入 gvsdsdk `StatsManager`,视图/Celery 任务统一走 SDK | — |
|
||
| 低 | UUID 主键无序导致索引膨胀 | 大数据量写入性能下降 |
|
||
|
||
---
|
||
|
||
## 7. 未来发展方向(会议讨论建议项)
|
||
|
||
### 7.1 短期(1-3 个月)
|
||
|
||
1. ~~统一 Role/Permission 模型~~:✅ 已收敛(2026-08-10)——视图层统一经 gvsdsdk Manager 访问,模型层 gvsds 统一从 gvsdsdk import,双份定义消除
|
||
2. **补全 TenantUUID 字段**:所有租户语义表直接打 `TenantUUID`,简化跨租户查询与租户删除
|
||
3. **数据权限策略化**:用策略模式替代 `if table_name == 'X'`,每个模型注册自己的 `ScopeFilter`
|
||
4. ~~更新根 README.md~~:✅ 已反映当前 Django 架构
|
||
5. ~~统一 stats 双轨实现~~:✅ 已收敛——`StatEngine` 删除,`StatsManager` 补齐编排方法(DefineMetric/GenerateDailyRanking/QueryRanking/RunScheduledResets/BuildRankings 等),视图与 Celery 任务统一经 gvsdsdk 访问
|
||
|
||
### 7.2 中期(3-6 个月)
|
||
|
||
1. **重构 ABAC 为真正的属性访问控制**:支持时间/IP/资源所有者/字段级权限
|
||
2. **引入软删除机制**:`DeletedAt` + `DeletedByUUID`,配合审计日志实现数据恢复
|
||
3. **支付网关扩展**:增加 PayPal/Stripe 适配(出海场景)
|
||
4. **租户配额管理**:用户数/数据量/API 调用次数配额
|
||
|
||
### 7.3 长期(6+ 个月)
|
||
|
||
1. **拆分协议层**:把 gvsdsdk 拆为 `gvsds-protocol`(纯协议)+ `gvsds-business`(业务能力),主从各自依赖
|
||
2. **改用 UUIDv7 或 Snowflake**:解决主键无序问题
|
||
3. **多区域部署**:基于 MSYNC 实现跨地域多活
|
||
4. **微服务化拆分**:gerp/payment/commission/stats 可独立部署
|
||
|
||
---
|
||
|
||
## 8. 关键架构原则
|
||
|
||
1. **PascalCase 全链路一致**:从数据库字段 → Python 类 → Socket.IO 事件 → 前端,无转换层
|
||
2. **优雅降级**:Redis/Celery/网关依赖缺失时自动降级,开发环境零依赖启动
|
||
3. **配置外置**:`app.ini` + `secrets.ini` + 环境变量三层配置,支持 12-factor 部署
|
||
4. **薄封装 SDK**:协议契约层与业务实现层分离,主从可独立演进
|
||
5. **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](file:///d:/SMANAGE/gvsdsdk/API.md) 与 [gvsdsdk/README.md](file:///d:/SMANAGE/gvsdsdk/README.md)。**
|