refactor: 移除多租户和客户相关代码及功能

refactor: 统一状态字段为字符串类型并更新相关组件
refactor: 更新模型基类移除租户和客户相关字段
refactor: 简化数据权限控制逻辑
refactor: 优化类型注解使用Python 3.10+语法
refactor: 清理无用导入和注释
docs: 更新文档移除多租户相关内容
This commit is contained in:
zhangtao
2025-12-01 00:36:05 +08:00
parent 463e2fca23
commit 3c12fa56eb
173 changed files with 3143 additions and 7672 deletions
@@ -1,13 +1,13 @@
# -*- coding: utf-8 -*-
from fastapi import APIRouter, Body, Depends, Path, Query
from fastapi import APIRouter, Body, Depends, Path
from fastapi.responses import JSONResponse, StreamingResponse
from app.common.response import StreamResponse, SuccessResponse
from app.common.request import PaginationService
from app.core.router_class import OperationLogRoute
from app.utils.common_util import bytes2file_response
from app.core.base_params import PaginationQueryParam
from app.core.router_class import OperationLogRoute
from app.core.dependencies import AuthPermission
from app.core.base_schema import BatchSetAvailable
from app.core.logger import log
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
from typing import Dict, List, Optional, Sequence, Union, Any
from typing import Sequence, Any
from app.core.base_crud import CRUDBase
from ..auth.schema import AuthSchema
@@ -21,39 +21,39 @@ class PositionCRUD(CRUDBase[PositionModel, PositionCreateSchema, PositionUpdateS
self.auth = auth
super().__init__(model=PositionModel, auth=auth)
async def get_by_id_crud(self, id: int, preload: Optional[List[Union[str, Any]]] = None) -> Optional[PositionModel]:
async def get_by_id_crud(self, id: int, preload: list[str] | None = None) -> PositionModel | None:
"""
根据 id 获取岗位信息。
参数:
- id (int): 岗位 ID。
- preload (Optional[List[Union[str, Any]]]): 预加载关系,未提供时使用模型默认项
- preload (list[str] | None): 预加载关系,未提供时使用模型默认项
返回:
- PositionModel | None: 岗位信息,未找到返回 None。
"""
return await self.get(id=id, preload=preload)
async def get_list_crud(self, search: Optional[Dict] = None, order_by: Optional[List[Dict[str, str]]] = None, preload: Optional[List[Union[str, Any]]] = None) -> Sequence[PositionModel]:
async def get_list_crud(self, search: dict | None = None, order_by: list[dict[str, Any]] | None = None, preload: list[str] | None = None) -> Sequence[PositionModel]:
"""
获取岗位列表。
参数:
- search (Dict | None): 搜索条件。
- order_by (List[Dict[str, str]] | None): 排序字段列表。
- preload (Optional[List[Union[str, Any]]]): 预加载关系,未提供时使用模型默认项
- search (dict | None): 搜索条件。
- order_by (list[dict[str, Any]] | None): 排序字段列表。
- preload (list[str] | None): 预加载关系,未提供时使用模型默认项
返回:
- Sequence[PositionModel]: 岗位列表。
"""
return await self.list(search=search, order_by=order_by, preload=preload)
async def set_available_crud(self, ids: List[int], status: str) -> None:
async def set_available_crud(self, ids: list[int], status: str) -> None:
"""
批量设置岗位可用状态。
参数:
- ids (List[int]): 岗位 ID 列表。
- ids (list[int]): 岗位 ID 列表。
- status (bool): 可用状态。
返回:
@@ -61,15 +61,15 @@ class PositionCRUD(CRUDBase[PositionModel, PositionCreateSchema, PositionUpdateS
"""
await self.set(ids=ids, status=status)
async def get_name_crud(self, ids: List[int]) -> List[str]:
async def get_name_crud(self, ids: list[int]) -> list[str]:
"""
根据 id 列表获取岗位名称。
参数:
- ids (List[int]): 岗位 ID 列表。
- ids (list[int]): 岗位 ID 列表。
返回:
- List[str]: 岗位名称列表。
- list[str]: 岗位名称列表。
"""
position_names = []
for id in ids:
@@ -4,35 +4,25 @@ from typing import TYPE_CHECKING
from sqlalchemy import String, Integer
from sqlalchemy.orm import relationship, Mapped, mapped_column
from app.core.base_model import ModelMixin, UserMixin, TenantMixin
from app.core.base_model import ModelMixin, UserMixin
if TYPE_CHECKING:
from app.api.v1.module_system.user.model import UserModel
class PositionModel(ModelMixin, UserMixin, TenantMixin):
class PositionModel(ModelMixin, UserMixin):
"""
岗位模型
岗位是租户级别的职位定义:
- 岗位属于租户(tenant_id必填)
- 岗位不属于客户(customer_id不需要)
- 用于定义租户内的各种职位(如:总监、经理、专员等)
- 用户可以同时拥有多个岗位
使用场景:
- 职位管理: 定义公司组织架构中的各类职位
- 权限控制: 可以根据岗位分配特定权限
- 业务流程: 某些审批流可以指定特定岗位处理
"""
__tablename__: str = "sys_position"
__table_args__: dict[str, str] = ({'comment': '岗位表'})
__loader_options__: list[str] = ["users", "created_by", "updated_by", "tenant"]
__loader_options__: list[str] = ["users", "created_by", "updated_by"]
name: Mapped[str] = mapped_column(String(40), nullable=False, comment="岗位名称")
order: Mapped[int] = mapped_column(Integer, nullable=False, default=1, comment="显示排序")
# 关联关系 (继承自UserMixin和TenantMixin)
# 关联关系
users: Mapped[list["UserModel"]] = relationship(
secondary="sys_user_positions",
back_populates="positions",
@@ -5,15 +5,15 @@ from pydantic import BaseModel, ConfigDict, Field, field_validator
from fastapi import Query
from app.core.validator import DateTimeStr
from app.core.base_schema import BaseSchema, UserBySchema, TenantSchema
from app.core.base_schema import BaseSchema, UserBySchema
class PositionCreateSchema(BaseModel):
"""岗位创建模型"""
name: str = Field(..., max_length=40, description="岗位名称")
order: Optional[int] = Field(default=1, ge=1, description='显示排序')
name: str = Field(..., max_length=64, description="岗位名称")
order: int = Field(default=1, ge=1, description='显示排序')
status: str = Field(default="0", description="是否启用(0:启用 1:禁用)")
description: Optional[str] = Field(default=None, max_length=255, description="描述")
description: str | None = Field(default=None, max_length=255, description="描述")
@field_validator('name')
@classmethod
@@ -29,7 +29,7 @@ class PositionUpdateSchema(PositionCreateSchema):
...
class PositionOutSchema(PositionCreateSchema, BaseSchema, UserBySchema, TenantSchema):
class PositionOutSchema(PositionCreateSchema, BaseSchema, UserBySchema):
"""岗位信息响应模型"""
model_config = ConfigDict(from_attributes=True)
...
@@ -42,8 +42,10 @@ class PositionQueryParam:
self,
name: Optional[str] = Query(None, description="岗位名称"),
status: Optional[str] = Query(None, description="是否可用"),
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"]),
created_time: list[DateTimeStr] | None = Query(None, description="创建时间范围", example=["2025-01-01 00:00:00", "2025-12-31 23:59:59"]),
updated_time: list[DateTimeStr] | None = Query(None, description="更新时间范围", example=["2025-01-01 00:00:00", "2025-12-31 23:59:59"]),
created_id: int | None = Query(None, description="创建人"),
updated_id: int | None = Query(None, description="更新人"),
) -> None:
# 模糊查询字段
@@ -51,8 +53,12 @@ class PositionQueryParam:
# 精确查询字段
self.created_id = created_id
self.updated_id = updated_id
self.status = status
# 时间范围查询
if created_time and len(created_time) == 2:
self.created_time = ("between", (created_time[0], created_time[1]))
if updated_time and len(updated_time) == 2:
self.updated_time = ("between", (updated_time[0], updated_time[1]))
@@ -1,7 +1,5 @@
# -*- coding: utf-8 -*-
from typing import Any, Dict, List, Optional
from app.core.base_schema import BatchSetAvailable
from app.core.exceptions import CustomException
from app.utils.excel_util import ExcelUtil
@@ -20,7 +18,7 @@ class PositionService:
"""岗位模块服务层"""
@classmethod
async def get_position_detail_service(cls, auth: AuthSchema, id: int) -> Dict:
async def get_position_detail_service(cls, auth: AuthSchema, id: int) -> dict:
"""
获取岗位详情
@@ -35,23 +33,23 @@ class PositionService:
return PositionOutSchema.model_validate(position).model_dump()
@classmethod
async def get_position_list_service(cls, auth: AuthSchema, search: Optional[PositionQueryParam] = None, order_by: Optional[List[Dict[str, str]]] = None) -> List[Dict]:
async def get_position_list_service(cls, auth: AuthSchema, search: PositionQueryParam | None = None, order_by: list[dict] | None = None) -> list[dict]:
"""
获取岗位列表
参数:
- auth (AuthSchema): 认证信息模型
- search (PositionQueryParam | None): 查询参数对象
- order_by (List[Dict[str, str]] | None): 排序参数列表
- order_by (list[dict] | None): 排序参数列表
返回:
- List[Dict]: 岗位列表对象
- list[dict]: 岗位列表对象
"""
position_list = await PositionCRUD(auth).get_list_crud(search=search.__dict__, order_by=order_by)
return [PositionOutSchema.model_validate(position).model_dump() for position in position_list]
@classmethod
async def create_position_service(cls, auth: AuthSchema, data: PositionCreateSchema) -> Dict:
async def create_position_service(cls, auth: AuthSchema, data: PositionCreateSchema) -> dict:
"""
创建岗位
@@ -69,7 +67,7 @@ class PositionService:
return PositionOutSchema.model_validate(new_position).model_dump()
@classmethod
async def update_position_service(cls, auth: AuthSchema, id:int, data: PositionUpdateSchema) -> Dict:
async def update_position_service(cls, auth: AuthSchema, id:int, data: PositionUpdateSchema) -> dict:
"""
更新岗位
@@ -79,7 +77,7 @@ class PositionService:
- data (PositionUpdateSchema): 岗位更新模型
返回:
- Dict: 更新的岗位对象
- dict: 更新的岗位对象
"""
position = await PositionCRUD(auth).get_by_id_crud(id=id)
if not position:
@@ -125,12 +123,12 @@ class PositionService:
await PositionCRUD(auth).set_available_crud(ids=data.ids, status=data.status)
@classmethod
async def export_position_list_service(cls, position_list: List[Dict[str, Any]]) -> bytes:
async def export_position_list_service(cls, position_list: list[dict]) -> bytes:
"""
导出岗位列表
参数:
- position_list (List[Dict[str, Any]]): 岗位列表对象
- position_list (list[dict]): 岗位列表对象
返回:
- bytes: 导出的Excel文件字节流
@@ -144,7 +142,7 @@ class PositionService:
'created_time': '创建时间',
'updated_time': '更新时间',
'created_id': '创建者ID',
'creator': '创建者',
'updated_id': '更新者ID',
}
# 复制数据并转换状态