mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-21 04:46:26 +00:00
chore: 完成多批次代码优化与重构
- 重构工作流模块目录结构,迁移代码文件 - 修复类型断言空值安全问题,添加 ! 操作符 - 优化样式类名,替换 flex-cc 为标准 flex 工具类 - 更新路由标签简化文案,移除冗余注释 - 调整 ruff 配置,放宽行长度限制 - 更新 README 与多语言文案,优化项目描述 - 修复表单、图表组件的类型与样式问题 - 简化搜索表单、数据卡片的布局代码
This commit is contained in:
@@ -13,7 +13,7 @@ from app.core.router_class import OperationLogRoute
|
||||
from .schema import DeptCreateSchema, DeptOutSchema, DeptQueryParam, DeptUpdateSchema
|
||||
from .service import DeptService
|
||||
|
||||
DeptRouter = APIRouter(route_class=OperationLogRoute, prefix="/dept", tags=["系统管理/部门管理"])
|
||||
DeptRouter = APIRouter(route_class=OperationLogRoute, prefix="/dept", tags=["部门管理"])
|
||||
|
||||
_DEPT_NS = "dept"
|
||||
|
||||
@@ -26,7 +26,7 @@ _DEPT_NS = "dept"
|
||||
@cache(expire=300, namespace=_DEPT_NS)
|
||||
async def get_dept_tree_controller(
|
||||
search: Annotated[DeptQueryParam, Depends()],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(['module_system:dept:query']))],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dept:query"]))],
|
||||
) -> JSONResponse:
|
||||
"""
|
||||
查询部门树
|
||||
@@ -42,9 +42,7 @@ async def get_dept_tree_controller(
|
||||
- CustomException: 查询部门树失败时抛出异常。
|
||||
"""
|
||||
order_by = [{"order": "asc"}]
|
||||
result_dict_list = await DeptService.get_dept_tree_service(
|
||||
search=search, auth=auth, order_by=order_by
|
||||
)
|
||||
result_dict_list = await DeptService.get_dept_tree_service(search=search, auth=auth, order_by=order_by)
|
||||
return SuccessResponse(data=result_dict_list, msg="查询部门树成功")
|
||||
|
||||
|
||||
@@ -55,7 +53,7 @@ async def get_dept_tree_controller(
|
||||
)
|
||||
async def get_obj_detail_controller(
|
||||
id: Annotated[int, Path(description="部门ID")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(['module_system:dept:detail']))],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dept:detail"]))],
|
||||
) -> JSONResponse:
|
||||
"""
|
||||
查询部门详情
|
||||
@@ -81,7 +79,7 @@ async def get_obj_detail_controller(
|
||||
)
|
||||
async def create_obj_controller(
|
||||
data: DeptCreateSchema,
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(['module_system:dept:create']))],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dept:create"]))],
|
||||
) -> JSONResponse:
|
||||
"""
|
||||
创建部门
|
||||
@@ -109,7 +107,7 @@ async def create_obj_controller(
|
||||
async def update_obj_controller(
|
||||
data: DeptUpdateSchema,
|
||||
id: Annotated[int, Path(description="部门ID")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(['module_system:dept:update']))],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dept:update"]))],
|
||||
) -> JSONResponse:
|
||||
"""
|
||||
修改部门
|
||||
@@ -137,7 +135,7 @@ async def update_obj_controller(
|
||||
)
|
||||
async def delete_obj_controller(
|
||||
ids: Annotated[list[int], Body(description="ID列表")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(['module_system:dept:delete']))],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dept:delete"]))],
|
||||
) -> JSONResponse:
|
||||
"""
|
||||
删除部门
|
||||
@@ -164,7 +162,7 @@ async def delete_obj_controller(
|
||||
)
|
||||
async def batch_set_available_obj_controller(
|
||||
data: BatchSetAvailable,
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(['module_system:dept:patch']))],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dept:patch"]))],
|
||||
) -> JSONResponse:
|
||||
"""
|
||||
批量修改部门状态
|
||||
|
||||
@@ -22,13 +22,13 @@ class DeptModel(ModelMixin, TenantMixin):
|
||||
__permission_strategy__: PermissionFilterStrategy = PermissionFilterStrategy.DEPT_BASED
|
||||
|
||||
name: Mapped[str] = mapped_column(String(64), nullable=False, comment="部门名称")
|
||||
status: Mapped[int] = mapped_column(Integer, default=0, nullable=False, comment="状态(0:启动 1:停用)", index=True)
|
||||
description: Mapped[str | None] = mapped_column(Text, default=None, nullable=True, comment="备注")
|
||||
order: Mapped[int] = mapped_column(Integer, nullable=False, default=999, comment="显示排序")
|
||||
code: Mapped[str] = mapped_column(String(64), nullable=False, comment="部门编码")
|
||||
leader: Mapped[str | None] = mapped_column(String(32), default=None, comment="部门负责人")
|
||||
phone: Mapped[str | None] = mapped_column(String(20), default=None, comment="手机")
|
||||
email: Mapped[str | None] = mapped_column(String(128), default=None, comment="邮箱")
|
||||
|
||||
# 树形结构字段
|
||||
parent_id: Mapped[int | None] = mapped_column(
|
||||
Integer,
|
||||
ForeignKey("sys_dept.id", ondelete="SET NULL", onupdate="CASCADE"),
|
||||
@@ -36,19 +36,14 @@ class DeptModel(ModelMixin, TenantMixin):
|
||||
index=True,
|
||||
comment="父级部门ID",
|
||||
)
|
||||
# 关联关系
|
||||
parent: Mapped["DeptModel | None"] = relationship(
|
||||
back_populates="children",
|
||||
remote_side="DeptModel.id",
|
||||
foreign_keys=[parent_id],
|
||||
uselist=False,
|
||||
)
|
||||
children: Mapped[list["DeptModel"]] = relationship(
|
||||
back_populates="parent", foreign_keys=[parent_id], lazy="selectin"
|
||||
)
|
||||
roles: Mapped[list["RoleModel"]] = relationship(
|
||||
secondary="sys_role_depts", back_populates="depts", lazy="selectin"
|
||||
)
|
||||
children: Mapped[list["DeptModel"]] = relationship(back_populates="parent", foreign_keys=[parent_id], lazy="selectin")
|
||||
roles: Mapped[list["RoleModel"]] = relationship(secondary="sys_role_depts", back_populates="depts", lazy="selectin")
|
||||
users: Mapped[list["UserModel"]] = relationship(
|
||||
back_populates="dept",
|
||||
foreign_keys="UserModel.dept_id",
|
||||
|
||||
@@ -2,8 +2,9 @@ from fastapi import Query
|
||||
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
||||
|
||||
from app.common.enums import QueueEnum
|
||||
from app.core.base_schema import BaseSchema
|
||||
from app.core.validator import DateTimeStr, validate_required_code
|
||||
from app.core.base_params import BaseQueryParam, TenantByQueryParam, UserByQueryParam
|
||||
from app.core.base_schema import BaseSchema, TenantBySchema, UserBySchema
|
||||
from app.core.validator import validate_required_code
|
||||
|
||||
|
||||
class DeptCreateSchema(BaseModel):
|
||||
@@ -16,7 +17,7 @@ class DeptCreateSchema(BaseModel):
|
||||
phone: str | None = Field(default=None, max_length=20, description="联系电话")
|
||||
email: str | None = Field(default=None, max_length=128, description="邮箱")
|
||||
parent_id: int | None = Field(default=None, ge=0, description="父部门ID")
|
||||
status: int = Field(default=0, ge=0, le=1, description="状态(0:正常 1:禁用)")
|
||||
status: int = Field(default=0, ge=0, le=1, description="状态(0:启动 1:停用)")
|
||||
description: str | None = Field(default=None, max_length=255, description="备注")
|
||||
|
||||
@field_validator("name")
|
||||
@@ -46,7 +47,7 @@ class DeptUpdateSchema(DeptCreateSchema):
|
||||
"""部门更新模型"""
|
||||
|
||||
|
||||
class DeptDetailOutSchema(DeptCreateSchema, BaseSchema):
|
||||
class DeptDetailOutSchema(DeptCreateSchema, BaseSchema, UserBySchema, TenantBySchema):
|
||||
"""部门详情响应模型(不含 children,用于详情和更新)"""
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
@@ -64,33 +65,14 @@ class DeptTreeOutSchema(DeptDetailOutSchema):
|
||||
DeptOutSchema = DeptDetailOutSchema
|
||||
|
||||
|
||||
class DeptQueryParam:
|
||||
class DeptQueryParam(BaseQueryParam, UserByQueryParam, TenantByQueryParam):
|
||||
"""部门管理查询参数"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: str | None = Query(None, description="部门名称"),
|
||||
status: str | None = Query(None, description="部门状态(True正常 False停用)"),
|
||||
created_time: list[DateTimeStr] | None = Query(
|
||||
None,
|
||||
description="创建时间范围",
|
||||
examples=["2025-01-01 00:00:00", "2025-12-31 23:59:59"],
|
||||
),
|
||||
updated_time: list[DateTimeStr] | None = Query(
|
||||
None,
|
||||
description="更新时间范围",
|
||||
examples=["2025-01-01 00:00:00", "2025-12-31 23:59:59"],
|
||||
),
|
||||
*args,
|
||||
**kwargs,
|
||||
) -> None:
|
||||
|
||||
# 模糊查询字段
|
||||
super().__init__(*args, **kwargs)
|
||||
self.name = (QueueEnum.like.value, name)
|
||||
|
||||
# 精确查询字段
|
||||
self.status = (QueueEnum.eq.value, status)
|
||||
|
||||
# 时间范围查询
|
||||
if created_time and len(created_time) == 2:
|
||||
self.created_time = (QueueEnum.between.value, (created_time[0], created_time[1]))
|
||||
if updated_time and len(updated_time) == 2:
|
||||
self.updated_time = (QueueEnum.between.value, (updated_time[0], updated_time[1]))
|
||||
|
||||
@@ -63,9 +63,7 @@ class DeptService:
|
||||
- list[dict]: 部门树形列表对象。
|
||||
"""
|
||||
# 使用树形结构查询,预加载children关系
|
||||
dept_list = await DeptCRUD(auth).get_tree_list(
|
||||
search=search.__dict__ if search else {}, order_by=order_by
|
||||
)
|
||||
dept_list = await DeptCRUD(auth).get_tree_list(search=search.__dict__ if search else {}, order_by=order_by)
|
||||
# 转换为字典列表(使用树形 Schema),tree_list 已通过 selectin 预加载 children
|
||||
dept_dict_list = [DeptTreeOutSchema.model_validate(dept).model_dump() for dept in dept_list]
|
||||
# 仅保留根节点,子树已在 model_dump 中递归序列化
|
||||
@@ -95,6 +93,7 @@ class DeptService:
|
||||
|
||||
# 检查租户配额
|
||||
from app.api.v1.module_platform.tenant.service import TenantService
|
||||
|
||||
await TenantService.check_quota_service(auth, auth.tenant_id, "dept")
|
||||
|
||||
dept = await DeptCRUD(auth).create(data=data)
|
||||
|
||||
Reference in New Issue
Block a user