体系架构问题
ERP 的组织模型现状已经非常接近你的设计了!现在有了完整信息,来给出最终评估。 ✅ 好消息:架构主体已完成 80% 扫描完现有模型,发现你的设计基本已经落地,只是有几处细节需要补齐: code复制a...
ERP 的组织模型现状已经非常接近你的设计了!现在有了完整信息,来给出最终评估。 ✅ 好消息:架构主体已完成 80% 扫描完现有模型,发现你的设计基本已经落地,只是有几处细节需要补齐: code复制accounts.Tenant └── organization.Company ✅ 已有,company FK → Company │ └── accounts.Store ✅ 已有,company FK(可空)→ Company └── accounts.Store ✅ 直属租户(company=NULL)→ 直接归属租户 └── organization.Department ⚠️ 缺失 store FK(Department 现在挂在 Company 下) 现状对比你要的设计
模型 你的设计 ERP 现状 状态
Tenant(租户) ✅ ✅ accounts.Tenant 完成
Company(公司) ✅ ✅ organization.Company(继承 TenantBaseModel) 完成
Store.company FK 可空 ✅ ✅ accounts.Store.company(null=True, blank=True) 完成
Store.is_company_owned() ✅ ✅ 已有实现 完成
Store.is_tenant_owned() ✅ ✅ 已有实现 完成
Department ✅ ⚠️ 有,但挂在 Company 下,无 store FK 需补
User → Company/Store/Department ✅ ⚠️ 只有 default_tenant,无 store_id 需补
UserRole 绑定租户/公司 ✅ ✅ 已有 完成
🔴 需要补齐的设计
- Department → 新增 store FK(最关键的改动) 当前 Department 的归属只有 Company 层级,缺少 Store 层级: python复制# organization/models/department.py
class Department(TenantBaseModel): # … 现有字段 …
# 归属层级:二选一
company = models.ForeignKey(
'organization.Company',
on_delete=models.CASCADE,
null=True, blank=True,
related_name='departments',
verbose_name='所属公司'
)
# ← 新增:门店级部门(门店是公司的子级,所以 Dept 的 store 必须属于 company)
store = models.ForeignKey(
'accounts.Store',
on_delete=models.CASCADE,
null=True, blank=True,
related_name='departments',
verbose_name='所属门店'
)
def clean(self):
super().clean()
# 验证:若选了 store,则 store 必须属于同一个 company
if self.store and self.store.company:
if self.company and self.store.company_id != self.company_id:
raise ValidationError("门店必须属于所选公司")
# 自动用 store 的 company
self.company = self.store.company
# 若选了 company 但 store 为空 → 公司级部门
# 若 store 不为空 → 门店级部门
- User 模型 → 新增 store FK 和 default_company python复制# users/models/user.py
class User(AbstractBaseUser): # … 现有字段 …
# 归属字段
default_tenant = models.ForeignKey(...) # 已有
default_company = models.ForeignKey(...) # ← 新增
default_store = models.ForeignKey(...) # ← 新增(关键)
# 当前上下文(切换时用)
current_company_id = models.IntegerField(null=True) # ← 新增
# data_scope 已有
- UserRole 绑定扩展 当前 UserRole 只绑定 tenant_id,需要扩展支持 company_id / store_id: python复制# users/models/user_role.py
class UserRole(models.Model): user = ForeignKey(User) role = ForeignKey(Role)
# 绑定层级:三选一
tenant_id = ForeignKey('accounts.Tenant', ...) # 已有
company_id = ForeignKey('organization.Company', null=True, ...) # ← 新增
store_id = ForeignKey('accounts.Store', null=True, ...) # ← 新增
class Meta:
constraints = [
# 确保只有一个层级被填充
models.CheckConstraint(
check=(
Q(tenant_id__isnull=False, company_id__isnull=True, store_id__isnull=True) |
Q(tenant_id__isnull=True, company_id__isnull=False, store_id__isnull=True) |
Q(tenant_id__isnull=True, company_id__isnull=True, store_id__isnull=False)
),
name='userrole_single_level'
)
]
⚠️ 一个需要决策的设计点 Department 的双层归属如何保证一致性? 你希望 Department 有两个归属路径:
公司级部门(company=某公司, store=NULL) 门店级部门(store=某门店,company 自动推导)
这在业务上是合理的,但在数据模型上有歧义风险: code复制门店A 属于 公司B 门店A 下有"前台组"(department)
→ 前台组的 company 字段是填"公司B"还是空?
方案 做法 优点 缺点
A(推荐) store FK 非空时 company 自动推导(写 clean()),前台不展示 company 字段 数据一致,无歧义 需前端配合,store 级部门不能脱离 store 存在
B 两者都填,显式维护 查询快 容易不一致
C 去掉 company FK,只保留 store FK 最简洁 无法表达"公司级部门"
建议采用方案A,但需要确认:你们是否有"公司级部门"这个概念(比如"集团行政部"不属于任何门店)?如果有,则需要额外考虑。 ✅ 架构整体评价 你的设计与 ERP 现状匹配度:★★★★☆(4/5)
评估维度 评分 说明
多层级完整性 ⭐⭐⭐⭐ 四级(系统/租户/公司/门店)已有,部门归属需补
可空设计合理性 ⭐⭐⭐⭐⭐ Store.company 可空已完美实现
权限粒度 ⭐⭐⭐⭐ UserRole 已有租户绑定,补公司/门店绑定即可
模型一致性 ⭐⭐⭐⭐ 主要模型已继承 TenantBaseModel
业务贴合度 ⭐⭐⭐⭐⭐ 完全贴合"集团连锁 ERP"场景
核心结论:这个架构设计是 Best Practice,ERP 现状已经落地了大部分。 剩余的主要工作:
给 Department 加 store FK(核心改动) 给 User 加 store_id + default_company 扩展 UserRole 支持公司/门店级绑定