feat: 添加部门字段显示并优化用户界面

fix(service): 修复创建时编码重复检查问题
refactor(middleware): 优化CORS中间件配置
style(model): 更新用户模型默认性别值
perf(request): 增强前端请求错误处理
docs(cli): 改进命令行帮助文本
chore: 清理无用配置并更新依赖
This commit is contained in:
zhangtao
2025-11-21 01:11:08 +08:00
parent 30118a4148
commit 749c97f4e3
15 changed files with 237 additions and 122 deletions
+64 -21
View File
@@ -6,7 +6,7 @@
from datetime import datetime
from typing import Optional
from sqlalchemy import ForeignKey, Integer, DateTime, Text
from sqlalchemy import ForeignKey, Integer, DateTime, String, Text
from sqlalchemy.ext.asyncio import AsyncAttrs
from sqlalchemy.orm import relationship, DeclarativeBase, Mapped, declared_attr, mapped_column
@@ -27,30 +27,15 @@ class MappedBase(AsyncAttrs, DeclarativeBase):
__abstract__ = True
class ModelMixin(MappedBase):
"""
基础模型混合类
"""
# Mixin: 一种面向对象编程概念, 使结构变得更加清晰, `Wiki <https://en.wikipedia.org/wiki/Mixin/>`__
class UserMixin(MappedBase):
"""用户 Mixin 数据类"""
__abstract__ = True
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True, comment='主键ID')
description: Mapped[Optional[str]] = mapped_column(Text, nullable=True, default=None, comment="备注/描述")
created_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True, default=datetime.now, comment='创建时间')
updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True, default=datetime.now, onupdate=datetime.now, comment='更新时间')
created_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey('system_users.id', ondelete="SET NULL", onupdate="CASCADE"), nullable=True, index=True, comment="创建人ID")
updated_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey('system_users.id', ondelete="SET NULL", onupdate="CASCADE"), nullable=True, index=True, comment="更新人ID")
class CreatorMixin(ModelMixin):
"""
创建人混合类
"""
__abstract__ = True
# creator_id: Mapped[Optional[int]] = mapped_column(Integer, nullable=True, index=True, comment="创建人ID")
creator_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey('system_users.id', ondelete="SET NULL", onupdate="CASCADE"), nullable=True, index=True, comment="创建人ID")
@declared_attr
def creator(cls) -> Mapped[Optional["UserModel"]]: # type: ignore
"""
创建人关联关系(延迟加载,避免循环依赖)
SQLAlchemy ORM 中的这些加载策略用于控制关联对象的加载行为,它们的主要区别如下:
@@ -64,7 +49,65 @@ class CreatorMixin(ModelMixin):
8.immediate :立即加载,在主对象加载后立即执行额外查询获取关联数据,类似 select 但不延迟。
9.write_only :专为写入优化,不允许读取关联数据,只可添加新记录,适合只写不读的场景。
10.dynamic :返回动态查询对象而非实际结果集,允许进一步过滤和分页,适合处理大量关联数据。
"""
@declared_attr
def created_by(cls) -> Mapped[Optional["UserModel"]]: # type: ignore
"""
创建人关联关系(延迟加载,避免循环依赖)
"""
return relationship(
"UserModel",
primaryjoin=f"{cls.__name__}.creator_id == UserModel.id",
lazy="selectin",
foreign_keys=lambda: [cls.creator_id], # type: ignore
viewonly=True,
uselist=False # 明确指定返回单个对象
)
@declared_attr
def updated_by(cls) -> Mapped[Optional["UserModel"]]: # type: ignore
"""
更新人关联关系(延迟加载,避免循环依赖)
"""
return relationship(
"UserModel",
primaryjoin=f"{cls.__name__}.creator_id == UserModel.id",
lazy="selectin",
foreign_keys=lambda: [cls.creator_id], # type: ignore
viewonly=True,
uselist=False # 明确指定返回单个对象
)
class DateTimeMixin(MappedBase):
"""日期时间 Mixin 数据类"""
__abstract__ = True
created_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True, default=datetime.now, comment='创建时间')
updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True, default=datetime.now, onupdate=datetime.now, comment='更新时间')
class ModelMixin(DateTimeMixin):
"""
基础模型混合类
"""
__abstract__ = True
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True, comment='主键ID')
uuid: Mapped[str] = mapped_column(String(64), unique=True)
description: Mapped[Optional[str]] = mapped_column(Text, nullable=True, default=None, comment="备注/描述")
class CreatorMixin(ModelMixin):
"""
创建人混合类
"""
__abstract__ = True
creator_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey('system_users.id', ondelete="SET NULL", onupdate="CASCADE"), nullable=True, index=True, comment="创建人ID")
@declared_attr
def creator(cls) -> Mapped[Optional["UserModel"]]: # type: ignore
# 其他模型保持原有配置
return relationship(
"UserModel",
+8 -8
View File
@@ -20,14 +20,14 @@ from app.api.v1.module_system.params.service import ParamsService
class CustomCORSMiddleware(CORSMiddleware):
"""CORS跨域中间件"""
def __init__(self, app: ASGIApp) -> None:
CORSMiddlewareConfig: dict[str, Any] = {
"allow_origins": settings.ALLOW_ORIGINS,
"allow_methods": settings.ALLOW_METHODS,
"allow_headers": settings.ALLOW_HEADERS,
"allow_credentials": settings.ALLOW_CREDENTIALS,
"expose_headers": settings.CORS_EXPOSE_HEADERS,
}
super().__init__(app, **CORSMiddlewareConfig)
super().__init__(
app,
allow_origins=settings.ALLOW_ORIGINS,
allow_methods=settings.ALLOW_METHODS,
allow_headers=settings.ALLOW_HEADERS,
allow_credentials=settings.ALLOW_CREDENTIALS,
expose_headers=settings.CORS_EXPOSE_HEADERS,
)
class RequestLogMiddleware(BaseHTTPMiddleware):