diff --git a/SAAS_ARCHITECTURE.md b/SAAS_ARCHITECTURE.md new file mode 100644 index 00000000..b2a83ea3 --- /dev/null +++ b/SAAS_ARCHITECTURE.md @@ -0,0 +1,269 @@ +# 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 个月) + +1. **统一 Role/Permission 模型**:让 gerp 直接复用 gvsdsdk 的模型定义,消除双份漂移 +2. **补全 TenantUUID 字段**:所有租户语义表直接打 `TenantUUID`,简化跨租户查询与租户删除 +3. **数据权限策略化**:用策略模式替代 `if table_name == 'X'`,每个模型注册自己的 `ScopeFilter` +4. **更新根 README.md**:反映当前 Django 架构 + +### 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)。** diff --git a/TempLate/GERP/_base b/TempLate/GERP/_base index e10ca79a..bb8a7481 100644 --- a/TempLate/GERP/_base +++ b/TempLate/GERP/_base @@ -6,12 +6,9 @@