mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-20 20:39:55 +00:00
refactor(database): 重构系统表命名及数据隔离逻辑
- 将系统表前缀从'system_'统一改为'sys_',包括用户、角色、部门等核心表 - 优化数据权限检查逻辑,支持初始化场景跳过权限验证 - 更新初始化脚本和模型模板,确保与新的表结构兼容 - 修复字典服务中is_default字段类型定义问题 - 调整控制台显示的数据库类型描述 - 添加业务逻辑文档,详细说明系统架构和核心功能 docs: 添加系统业务逻辑文档和多租户设计参考
This commit is contained in:
@@ -280,7 +280,8 @@ class SchedulerUtil:
|
||||
scheduler.start()
|
||||
async with async_db_session() as session:
|
||||
async with session.begin():
|
||||
auth = AuthSchema(db=session)
|
||||
# 在初始化过程中,不需要检查数据权限
|
||||
auth = AuthSchema(db=session, check_data_scope=False)
|
||||
job_list = await JobCRUD(auth).get_obj_list_crud()
|
||||
for item in job_list:
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ class GenTableModel(ModelMixin):
|
||||
return class_name.strip()
|
||||
|
||||
|
||||
class GenTableColumnModel(ModelMixin, UserMixin, TenantMixin):
|
||||
class GenTableColumnModel(ModelMixin):
|
||||
"""
|
||||
代码生成表字段
|
||||
|
||||
|
||||
@@ -9,16 +9,16 @@ from sqlalchemy.orm import relationship
|
||||
from typing import Optional
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
|
||||
from app.core.base_model import CreatorMixin
|
||||
from app.core.base_model import ModelMixin, UserMixin, TenantMixin, CustomerMixin
|
||||
|
||||
|
||||
class {{ class_name }}Model(CreatorMixin):
|
||||
class {{ class_name }}Model(ModelMixin, UserMixin, TenantMixin, CustomerMixin):
|
||||
"""
|
||||
{{ function_name }}表
|
||||
"""
|
||||
__tablename__ = '{{ table_name }}'
|
||||
__table_args__ = {'comment': '{{ function_name }}'}
|
||||
__loader_options__ = ["creator"]
|
||||
__loader_options__: list[str] = ["created_by", "updated_by", "tenant", "customer"]
|
||||
|
||||
{% for column in columns %}
|
||||
{% if column.column_name not in ['id', 'created_id', 'description', 'created_time', 'updated_time'] %}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from typing import Optional
|
||||
from fastapi import Query
|
||||
|
||||
from app.core.validator import DateTimeStr
|
||||
|
||||
class {{ class_name }}QueryParam:
|
||||
"""{{ function_name }}查询参数"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
{% for column in columns %}
|
||||
{% if column.query_type == 'LIKE' %}
|
||||
{{ column.column_name }}: Optional[{{ column.python_type }}] = Query(None, description="{{ column.column_comment }}"),
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% for column in columns %}
|
||||
{% if column.query_type == 'EQ' %}
|
||||
{{ column.column_name }}: Optional[{{ column.python_type }}] = Query(None, description="{{ column.column_comment }}"),
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
creator: Optional[int] = Query(None, description="创建人"),
|
||||
start_time: Optional[DateTimeStr] = Query(None, description="开始时间", example="2025-01-01 00:00:00"),
|
||||
end_time: Optional[DateTimeStr] = Query(None, description="结束时间", example="2025-12-31 23:59:59"),
|
||||
) -> None:
|
||||
|
||||
# 模糊查询字段
|
||||
{% for column in columns %}
|
||||
{% if column.query_type == 'LIKE' %}
|
||||
self.{{ column.column_name }} = ("like", {{ column.column_name }})
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
# 精确查询字段
|
||||
{% for column in columns %}
|
||||
{% if column.query_type == 'EQ' %}
|
||||
self.{{ column.column_name }} = {{ column.column_name }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
self.created_id = creator
|
||||
|
||||
# 时间范围查询
|
||||
if start_time and end_time:
|
||||
self.created_time = ("between", (start_time, end_time))
|
||||
@@ -7,7 +7,9 @@ from typing import Optional
|
||||
{% endif %}
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
from app.core.base_schema import BaseSchema
|
||||
from fastapi import Query
|
||||
from app.core.validator import DateTimeStr
|
||||
from app.core.base_schema import BaseSchema, UserBySchema, TenantSchema, CustomerSchema
|
||||
|
||||
class {{ class_name }}CreateSchema(BaseModel):
|
||||
"""
|
||||
@@ -32,3 +34,42 @@ class {{ class_name }}OutSchema({{ class_name }}CreateSchema, BaseSchema):
|
||||
{{ function_name }}响应模型
|
||||
"""
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class {{ class_name }}QueryParam:
|
||||
"""{{ function_name }}查询参数"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
{% for column in columns %}
|
||||
{% if column.query_type == 'LIKE' %}
|
||||
{{ column.column_name }}: Optional[{{ column.python_type }}] = Query(None, description="{{ column.column_comment }}"),
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% for column in columns %}
|
||||
{% if column.query_type == 'EQ' %}
|
||||
{{ column.column_name }}: Optional[{{ column.python_type }}] = Query(None, description="{{ column.column_comment }}"),
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
created_id: Optional[int] = Query(None, description="创建人"),
|
||||
created_time: Optional[list[DateTimeStr]] = Query(None, description="创建时间范围", example=["2025-01-01 00:00:00", "2025-12-31 23:59:59"]),
|
||||
) -> None:
|
||||
|
||||
# 模糊查询字段
|
||||
{% for column in columns %}
|
||||
{% if column.query_type == 'LIKE' %}
|
||||
self.{{ column.column_name }} = ("like", {{ column.column_name }})
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
# 精确查询字段
|
||||
{% for column in columns %}
|
||||
{% if column.query_type == 'EQ' %}
|
||||
self.{{ column.column_name }} = {{ column.column_name }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
self.created_id = created_id
|
||||
|
||||
# 时间范围查询
|
||||
if created_time and len(created_time) == 2:
|
||||
self.created_time = ("between", (created_time[0], created_time[1]))
|
||||
@@ -5,8 +5,6 @@ from sqlalchemy import String
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship, validates
|
||||
|
||||
from app.core.base_model import ModelMixin, UserMixin, TenantMixin
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from app.api.v1.module_system.user.model import UserModel
|
||||
|
||||
@@ -25,7 +23,7 @@ class CustomerModel(ModelMixin, UserMixin, TenantMixin):
|
||||
- 代理商系统: 租户=总公司, 客户=各地代理商
|
||||
- SaaS平台: 租户=企业, 客户=企业下的子公司/部门
|
||||
"""
|
||||
__tablename__: str = 'system_customer'
|
||||
__tablename__: str = 'sys_customer'
|
||||
__table_args__: dict[str, str] = ({'comment': '客户表'})
|
||||
__loader_options__: list[str] = ["created_by", "updated_by", "tenant"]
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ class DeptModel(ModelMixin, TenantMixin):
|
||||
- 部门不属于客户(customer_id不需要)
|
||||
- 支持无限层级嵌套的树形结构
|
||||
"""
|
||||
__tablename__: str = "system_dept"
|
||||
__tablename__: str = "sys_dept"
|
||||
__table_args__: dict[str, str] = ({'comment': '部门表'})
|
||||
__loader_options__: list[str] = ["tenant"]
|
||||
|
||||
@@ -34,7 +34,7 @@ class DeptModel(ModelMixin, TenantMixin):
|
||||
# 树形结构字段
|
||||
parent_id: Mapped[int | None] = mapped_column(
|
||||
Integer,
|
||||
ForeignKey("system_dept.id", ondelete="SET NULL", onupdate="CASCADE"),
|
||||
ForeignKey("sys_dept.id", ondelete="SET NULL", onupdate="CASCADE"),
|
||||
default=None,
|
||||
index=True,
|
||||
comment="父级部门ID"
|
||||
@@ -52,7 +52,7 @@ class DeptModel(ModelMixin, TenantMixin):
|
||||
lazy="selectin"
|
||||
)
|
||||
roles: Mapped[list["RoleModel"]] = relationship(
|
||||
secondary="system_role_depts",
|
||||
secondary="sys_role_depts",
|
||||
back_populates="depts",
|
||||
lazy="selectin"
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from sqlalchemy import String, Integer, Boolean, ForeignKey, Index
|
||||
from sqlalchemy import String, Integer, Boolean, ForeignKey
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from app.core.base_model import ModelMixin
|
||||
@@ -10,7 +10,7 @@ class DictTypeModel(ModelMixin):
|
||||
"""
|
||||
字典类型表
|
||||
"""
|
||||
__tablename__: str = "system_dict_type"
|
||||
__tablename__: str = "sys_dict_type"
|
||||
__table_args__: dict[str, str] = ({'comment': '字典类型表'})
|
||||
|
||||
dict_name: Mapped[str] = mapped_column(String(255), nullable=False, comment='字典名称')
|
||||
@@ -24,7 +24,7 @@ class DictDataModel(ModelMixin):
|
||||
"""
|
||||
字典数据表
|
||||
"""
|
||||
__tablename__: str = "system_dict_data"
|
||||
__tablename__: str = "sys_dict_data"
|
||||
__table_args__: dict[str, str] = ({'comment': '字典数据表'})
|
||||
|
||||
dict_sort: Mapped[int] = mapped_column(Integer, nullable=False, default=0, comment='字典排序')
|
||||
@@ -38,7 +38,7 @@ class DictDataModel(ModelMixin):
|
||||
# 添加外键关系,同时保留dict_type字段用于业务查询
|
||||
dict_type_id: Mapped[int] = mapped_column(
|
||||
Integer,
|
||||
ForeignKey('system_dict_type.id', ondelete='CASCADE'),
|
||||
ForeignKey('sys_dict_type.id', ondelete='CASCADE'),
|
||||
nullable=False,
|
||||
comment='字典类型ID'
|
||||
)
|
||||
|
||||
@@ -80,7 +80,7 @@ class DictDataCreateSchema(BaseModel):
|
||||
dict_type_id: int = Field(..., description='字典类型ID')
|
||||
css_class: Optional[str] = Field(default=None, max_length=100, description='样式属性(其他样式扩展)')
|
||||
list_class: Optional[str] = Field(default=None, description='表格回显样式')
|
||||
is_default: Optional[str] = Field(default=None, description='是否默认(Y是 N否)')
|
||||
is_default: Optional[bool] = Field(default=None, description='是否默认(Y是 N否)')
|
||||
status: Optional[str] = Field(default=None, description='状态(1正常 0停用)')
|
||||
description: Optional[str] = Field(default=None, max_length=255, description="描述")
|
||||
|
||||
|
||||
@@ -129,6 +129,7 @@ class DictTypeService:
|
||||
dict_label=item.dict_label,
|
||||
dict_value=item.dict_value,
|
||||
dict_type=data.dict_type,
|
||||
dict_type_id=item.dict_type_id,
|
||||
css_class=item.css_class,
|
||||
list_class=item.list_class,
|
||||
is_default=item.is_default,
|
||||
@@ -291,7 +292,8 @@ class DictDataService:
|
||||
try:
|
||||
async with async_db_session() as session:
|
||||
async with session.begin():
|
||||
auth = AuthSchema(db=session)
|
||||
# 在初始化过程中,不需要检查数据权限
|
||||
auth = AuthSchema(db=session, check_data_scope=False)
|
||||
obj_list = await DictTypeCRUD(auth).get_obj_list_crud()
|
||||
if not obj_list:
|
||||
log.warning("未找到任何字典类型数据")
|
||||
|
||||
@@ -25,7 +25,7 @@ class OperationLogModel(ModelMixin, UserMixin, TenantMixin, CustomerMixin):
|
||||
- 1: 登录日志
|
||||
- 2: 操作日志
|
||||
"""
|
||||
__tablename__: str = "system_log"
|
||||
__tablename__: str = "sys_log"
|
||||
__table_args__: dict[str, str] = ({'comment': '系统日志表'})
|
||||
__loader_options__: list[str] = ["created_by", "updated_by", "tenant", "customer"]
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ class MenuModel(ModelMixin):
|
||||
|
||||
支持树形结构(通过parent_id自关联)
|
||||
"""
|
||||
__tablename__: str = "system_menu"
|
||||
__tablename__: str = "sys_menu"
|
||||
__table_args__: dict[str, str] = ({'comment': '菜单表'})
|
||||
__loader_options__: list[str] = ["roles"]
|
||||
|
||||
@@ -60,7 +60,7 @@ class MenuModel(ModelMixin):
|
||||
# 树形结构
|
||||
parent_id: Mapped[int | None] = mapped_column(
|
||||
Integer,
|
||||
ForeignKey('system_menu.id', ondelete='SET NULL'),
|
||||
ForeignKey('sys_menu.id', ondelete='SET NULL'),
|
||||
default=None,
|
||||
index=True,
|
||||
comment='父菜单ID'
|
||||
@@ -79,7 +79,7 @@ class MenuModel(ModelMixin):
|
||||
order_by="MenuModel.order"
|
||||
)
|
||||
roles: Mapped[list["RoleModel"]] = relationship(
|
||||
secondary="system_role_menus",
|
||||
secondary="sys_role_menus",
|
||||
back_populates="menus",
|
||||
lazy="selectin"
|
||||
)
|
||||
|
||||
@@ -29,7 +29,7 @@ class NoticeModel(ModelMixin, UserMixin, TenantMixin, CustomerMixin):
|
||||
- 创建人和创建时间
|
||||
- 通知的可见范围和发布状态
|
||||
"""
|
||||
__tablename__: str = "system_notice"
|
||||
__tablename__: str = "sys_notice"
|
||||
__table_args__: dict[str, str] = ({'comment': '通知公告表'})
|
||||
__loader_options__: list[str] = ["created_by", "updated_by", "tenant", "customer"]
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ class ParamsModel(ModelMixin):
|
||||
- 租户级别参数
|
||||
- 配置项的名称、键、值和类型等信息
|
||||
"""
|
||||
__tablename__: str = "system_param"
|
||||
__tablename__: str = "sys_param"
|
||||
__table_args__: dict[str, str] = ({'comment': '系统参数表'})
|
||||
|
||||
config_name: Mapped[str] = mapped_column(String(500), nullable=False, comment='参数名称')
|
||||
|
||||
@@ -278,7 +278,8 @@ class ParamsService:
|
||||
"""
|
||||
async with async_db_session() as session:
|
||||
async with session.begin():
|
||||
auth = AuthSchema(db=session)
|
||||
# 在初始化过程中,不需要检查数据权限
|
||||
auth = AuthSchema(db=session, check_data_scope=False)
|
||||
config_obj = await ParamsCRUD(auth).get_obj_list_crud()
|
||||
if not config_obj:
|
||||
raise CustomException(msg="系统配置不存在")
|
||||
|
||||
@@ -25,7 +25,7 @@ class PositionModel(ModelMixin, UserMixin, TenantMixin):
|
||||
- 权限控制: 可以根据岗位分配特定权限
|
||||
- 业务流程: 某些审批流可以指定特定岗位处理
|
||||
"""
|
||||
__tablename__: str = "system_position"
|
||||
__tablename__: str = "sys_position"
|
||||
__table_args__: dict[str, str] = ({'comment': '岗位表'})
|
||||
__loader_options__: list[str] = ["users", "created_by", "updated_by", "tenant"]
|
||||
|
||||
@@ -34,7 +34,7 @@ class PositionModel(ModelMixin, UserMixin, TenantMixin):
|
||||
|
||||
# 关联关系 (继承自UserMixin和TenantMixin)
|
||||
users: Mapped[list["UserModel"]] = relationship(
|
||||
secondary="system_user_positions",
|
||||
secondary="sys_user_positions",
|
||||
back_populates="positions",
|
||||
lazy="selectin"
|
||||
)
|
||||
|
||||
@@ -18,18 +18,18 @@ class RoleMenusModel(MappedBase):
|
||||
|
||||
定义角色与菜单的多对多关系,用于权限控制
|
||||
"""
|
||||
__tablename__: str = "system_role_menus"
|
||||
__tablename__: str = "sys_role_menus"
|
||||
__table_args__: dict[str, str] = ({'comment': '角色菜单关联表'})
|
||||
|
||||
role_id: Mapped[int] = mapped_column(
|
||||
Integer,
|
||||
ForeignKey("system_role.id", ondelete="CASCADE", onupdate="CASCADE"),
|
||||
ForeignKey("sys_role.id", ondelete="CASCADE", onupdate="CASCADE"),
|
||||
primary_key=True,
|
||||
comment="角色ID"
|
||||
)
|
||||
menu_id: Mapped[int] = mapped_column(
|
||||
Integer,
|
||||
ForeignKey("system_menu.id", ondelete="CASCADE", onupdate="CASCADE"),
|
||||
ForeignKey("sys_menu.id", ondelete="CASCADE", onupdate="CASCADE"),
|
||||
primary_key=True,
|
||||
comment="菜单ID"
|
||||
)
|
||||
@@ -42,18 +42,18 @@ class RoleDeptsModel(MappedBase):
|
||||
定义角色与部门的多对多关系,用于数据权限控制
|
||||
仅当角色的data_scope=5(自定义数据权限)时使用此表
|
||||
"""
|
||||
__tablename__: str = "system_role_depts"
|
||||
__tablename__: str = "sys_role_depts"
|
||||
__table_args__: dict[str, str] = ({'comment': '角色部门关联表'})
|
||||
|
||||
role_id: Mapped[int] = mapped_column(
|
||||
Integer,
|
||||
ForeignKey("system_role.id", ondelete="CASCADE", onupdate="CASCADE"),
|
||||
ForeignKey("sys_role.id", ondelete="CASCADE", onupdate="CASCADE"),
|
||||
primary_key=True,
|
||||
comment="角色ID"
|
||||
)
|
||||
dept_id: Mapped[int] = mapped_column(
|
||||
Integer,
|
||||
ForeignKey("system_dept.id", ondelete="CASCADE", onupdate="CASCADE"),
|
||||
ForeignKey("sys_dept.id", ondelete="CASCADE", onupdate="CASCADE"),
|
||||
primary_key=True,
|
||||
comment="部门ID"
|
||||
)
|
||||
@@ -88,7 +88,7 @@ class RoleModel(ModelMixin, UserMixin, TenantMixin):
|
||||
* 注意: 客户用户即使有此权限也只能看本客户数据
|
||||
|
||||
- 5: 自定义数据权限
|
||||
* 实现: WHERE dept_id IN (SELECT dept_id FROM system_role_depts WHERE role_id IN current_user.role_ids)
|
||||
* 实现: WHERE dept_id IN (SELECT dept_id FROM sys_role_depts WHERE role_id IN current_user.role_ids)
|
||||
* 场景: 跨部门权限,如人事可以看多个指定部门
|
||||
* 使用: 通过role_depts关联表指定可访问的部门列表
|
||||
|
||||
@@ -97,7 +97,7 @@ class RoleModel(ModelMixin, UserMixin, TenantMixin):
|
||||
- 取所有角色data_scope的最大值(4>3>2>5>1)
|
||||
- 5(自定义)需要合并所有角色关联的部门
|
||||
"""
|
||||
__tablename__: str = "system_role"
|
||||
__tablename__: str = "sys_role"
|
||||
__table_args__: dict[str, str] = ({'comment': '角色表'})
|
||||
__loader_options__: list[str] = ["menus", "depts", "created_by", "updated_by", "tenant"]
|
||||
|
||||
@@ -113,18 +113,18 @@ class RoleModel(ModelMixin, UserMixin, TenantMixin):
|
||||
|
||||
# 关联关系 (继承自UserMixin和TenantMixin)
|
||||
menus: Mapped[list["MenuModel"]] = relationship(
|
||||
secondary="system_role_menus",
|
||||
secondary="sys_role_menus",
|
||||
back_populates="roles",
|
||||
lazy="selectin",
|
||||
order_by="MenuModel.order"
|
||||
)
|
||||
depts: Mapped[list["DeptModel"]] = relationship(
|
||||
secondary="system_role_depts",
|
||||
secondary="sys_role_depts",
|
||||
back_populates="roles",
|
||||
lazy="selectin"
|
||||
)
|
||||
users: Mapped[list["UserModel"]] = relationship(
|
||||
secondary="system_user_roles",
|
||||
secondary="sys_user_roles",
|
||||
back_populates="roles",
|
||||
lazy="selectin"
|
||||
)
|
||||
|
||||
@@ -21,7 +21,7 @@ class TenantModel(ModelMixin):
|
||||
- 租户表不需要customer_id字段(租户不属于客户)
|
||||
- 但需要created_id/updated_id用于审计追踪
|
||||
"""
|
||||
__tablename__: str = 'system_tenant'
|
||||
__tablename__: str = 'sys_tenant'
|
||||
__table_args__: dict[str, str] = {'comment': '租户表'}
|
||||
|
||||
name: Mapped[str] = mapped_column(String(100), nullable=False, unique=True, comment='租户名称')
|
||||
|
||||
@@ -19,18 +19,18 @@ class UserRolesModel(MappedBase):
|
||||
|
||||
定义用户与角色的多对多关系
|
||||
"""
|
||||
__tablename__: str = "system_user_roles"
|
||||
__tablename__: str = "sys_user_roles"
|
||||
__table_args__: dict[str, str] = ({'comment': '用户角色关联表'})
|
||||
|
||||
user_id: Mapped[int] = mapped_column(
|
||||
Integer,
|
||||
ForeignKey("system_user.id", ondelete="CASCADE", onupdate="CASCADE"),
|
||||
ForeignKey("sys_user.id", ondelete="CASCADE", onupdate="CASCADE"),
|
||||
primary_key=True,
|
||||
comment="用户ID"
|
||||
)
|
||||
role_id: Mapped[int] = mapped_column(
|
||||
Integer,
|
||||
ForeignKey("system_role.id", ondelete="CASCADE", onupdate="CASCADE"),
|
||||
ForeignKey("sys_role.id", ondelete="CASCADE", onupdate="CASCADE"),
|
||||
primary_key=True,
|
||||
comment="角色ID"
|
||||
)
|
||||
@@ -42,18 +42,18 @@ class UserPositionsModel(MappedBase):
|
||||
|
||||
定义用户与岗位的多对多关系
|
||||
"""
|
||||
__tablename__: str = "system_user_positions"
|
||||
__tablename__: str = "sys_user_positions"
|
||||
__table_args__: dict[str, str] = ({'comment': '用户岗位关联表'})
|
||||
|
||||
user_id: Mapped[int] = mapped_column(
|
||||
Integer,
|
||||
ForeignKey("system_user.id", ondelete="CASCADE", onupdate="CASCADE"),
|
||||
ForeignKey("sys_user.id", ondelete="CASCADE", onupdate="CASCADE"),
|
||||
primary_key=True,
|
||||
comment="用户ID"
|
||||
)
|
||||
position_id: Mapped[int] = mapped_column(
|
||||
Integer,
|
||||
ForeignKey("system_position.id", ondelete="CASCADE", onupdate="CASCADE"),
|
||||
ForeignKey("sys_position.id", ondelete="CASCADE", onupdate="CASCADE"),
|
||||
primary_key=True,
|
||||
comment="岗位ID"
|
||||
)
|
||||
@@ -97,7 +97,7 @@ class UserModel(ModelMixin, UserMixin, TenantMixin, CustomerMixin):
|
||||
客户用户额外限制:
|
||||
- 无论data_scope如何,都必须加上: AND customer_id = current_user.customer_id
|
||||
"""
|
||||
__tablename__: str = "system_user"
|
||||
__tablename__: str = "sys_user"
|
||||
__table_args__: dict[str, str] = ({'comment': '用户表'})
|
||||
__loader_options__: list[str] = ["dept", "roles", "positions", "created_by", "updated_by", "tenant", "customer"]
|
||||
|
||||
@@ -120,7 +120,7 @@ class UserModel(ModelMixin, UserMixin, TenantMixin, CustomerMixin):
|
||||
|
||||
dept_id: Mapped[int | None] = mapped_column(
|
||||
Integer,
|
||||
ForeignKey('system_dept.id', ondelete="SET NULL", onupdate="CASCADE"),
|
||||
ForeignKey('sys_dept.id', ondelete="SET NULL", onupdate="CASCADE"),
|
||||
nullable=True,
|
||||
index=True,
|
||||
comment="部门ID"
|
||||
@@ -131,12 +131,12 @@ class UserModel(ModelMixin, UserMixin, TenantMixin, CustomerMixin):
|
||||
lazy="selectin"
|
||||
)
|
||||
roles: Mapped[list["RoleModel"]] = relationship(
|
||||
secondary="system_user_roles",
|
||||
secondary="sys_user_roles",
|
||||
back_populates="users",
|
||||
lazy="selectin"
|
||||
)
|
||||
positions: Mapped[list["PositionModel"]] = relationship(
|
||||
secondary="system_user_positions",
|
||||
secondary="sys_user_positions",
|
||||
back_populates="users",
|
||||
lazy="selectin"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user