mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-22 13:05:18 +00:00
本次提交包含多项优化和修复: 1. 修复CRUD初始化参数传递、搜索参数处理逻辑 2. 更新环境配置中的大模型相关参数 3. 重构部分服务方法命名,统一代码风格 4. 新增多个枚举类型,补充模型关联关系和加载选项 5. 优化查询参数类实现,完善字段校验逻辑 6. 调整Pydantic模型字段注释和类型定义 7. 简化并移除冗余的CRUD方法实现 8. 新增超级管理员权限装饰器 9. 修复邮件日志模型的租户关联和字段定义
122 lines
4.7 KiB
Python
122 lines
4.7 KiB
Python
from fastapi import Query
|
|
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
|
|
|
from app.common.enums import QueueEnum
|
|
from app.core.base_params import BaseQueryParam
|
|
from app.core.base_schema import BaseSchema
|
|
|
|
|
|
class PackageCreateSchema(BaseModel):
|
|
"""新增套餐"""
|
|
|
|
name: str = Field(..., min_length=1, max_length=100, description="套餐名称")
|
|
code: str = Field(..., min_length=2, max_length=100, description="套餐编码")
|
|
status: int = Field(default=0, ge=0, le=1, description="状态(0:启动 1:停用)")
|
|
description: str | None = Field(default=None, max_length=255, description="描述")
|
|
sort: int = Field(default=0, ge=0, description="排序")
|
|
price: int = Field(default=0, ge=0, description="价格(分)")
|
|
period: str = Field(default="month", pattern=r"^(month|year)$", description="计费周期")
|
|
trial_days: int = Field(default=0, ge=0, description="免费试用天数")
|
|
max_users: int = Field(default=10, ge=0, description="最大用户数")
|
|
max_roles: int = Field(default=5, ge=0, description="最大角色数")
|
|
max_depts: int = Field(default=10, ge=0, description="最大部门数")
|
|
max_storage_mb: int = Field(default=1024, ge=0, description="最大存储(MB)")
|
|
rate_limit: int = Field(default=60, ge=10, description="API速率限制(请求/10秒)")
|
|
|
|
@field_validator("name")
|
|
@classmethod
|
|
def _validate_name(cls, v: str) -> str:
|
|
v = v.strip()
|
|
if not v:
|
|
raise ValueError("套餐名称不能为空")
|
|
return v
|
|
|
|
@field_validator("code")
|
|
@classmethod
|
|
def _validate_code(cls, v: str) -> str:
|
|
v = v.strip()
|
|
if not v:
|
|
raise ValueError("套餐编码不能为空")
|
|
if not v.isalnum():
|
|
raise ValueError("套餐编码仅允许字母和数字")
|
|
return v
|
|
|
|
@field_validator("status")
|
|
@classmethod
|
|
def _validate_status(cls, v: int) -> int:
|
|
if v not in {0, 1}:
|
|
raise ValueError("状态仅支持 0(正常) 或 1(禁用)")
|
|
return v
|
|
|
|
|
|
class PackageUpdateSchema(PackageCreateSchema):
|
|
"""更新套餐"""
|
|
|
|
name: str | None = Field(default=None, max_length=100, description="套餐名称") # type: ignore[assignment]
|
|
code: str | None = Field(default=None, max_length=100, description="套餐编码") # type: ignore[assignment]
|
|
status: int | None = Field(default=None, ge=0, le=1, description="状态(0:启动 1:停用)")
|
|
sort: int | None = Field(default=None, ge=0, description="排序")
|
|
description: str | None = Field(default=None, max_length=255, description="描述")
|
|
price: int | None = Field(default=None, ge=0, description="价格(分)")
|
|
period: str | None = Field(default=None, pattern=r"^(month|year)$", description="计费周期")
|
|
trial_days: int | None = Field(default=None, ge=0, description="免费试用天数")
|
|
max_users: int | None = Field(default=None, ge=0, description="最大用户数")
|
|
max_roles: int | None = Field(default=None, ge=0, description="最大角色数")
|
|
max_depts: int | None = Field(default=None, ge=0, description="最大部门数")
|
|
max_storage_mb: int | None = Field(default=None, ge=0, description="最大存储(MB)")
|
|
rate_limit: int | None = Field(default=None, ge=10, description="API速率限制(请求/10秒)")
|
|
|
|
@field_validator("code")
|
|
@classmethod
|
|
def _validate_code(cls, v: str | None) -> str | None:
|
|
if v is None:
|
|
return v
|
|
v = v.strip()
|
|
if not v.isalnum():
|
|
raise ValueError("套餐编码仅允许字母和数字")
|
|
return v
|
|
|
|
@field_validator("status")
|
|
@classmethod
|
|
def _validate_status(cls, v: int | None) -> int | None:
|
|
if v is None:
|
|
return v
|
|
if v not in {0, 1}:
|
|
raise ValueError("状态仅支持 0(正常) 或 1(禁用)")
|
|
return v
|
|
|
|
|
|
class PackageOutSchema(PackageCreateSchema, BaseSchema):
|
|
"""套餐响应"""
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class PackageQueryParam(BaseQueryParam):
|
|
"""套餐查询参数"""
|
|
|
|
def __init__(
|
|
self,
|
|
name: str | None = Query(None, description="套餐名称"),
|
|
code: str | None = Query(None, description="套餐编码"),
|
|
*args,
|
|
**kwargs,
|
|
) -> None:
|
|
super().__init__(*args, **kwargs)
|
|
if name:
|
|
self.name = (QueueEnum.like.value, name)
|
|
if code:
|
|
self.code = (QueueEnum.like.value, code)
|
|
|
|
|
|
class PackageMenuSetSchema(BaseModel):
|
|
"""批量设置套餐菜单权限"""
|
|
|
|
menu_ids: list[int] = Field(..., description="菜单ID列表")
|
|
|
|
|
|
class PackagePluginSetSchema(BaseModel):
|
|
"""批量设置套餐插件"""
|
|
|
|
plugin_ids: list[int] = Field(..., description="插件ID列表")
|