mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-20 20:39:55 +00:00
style: 统一代码风格和格式 docs: 完善函数和方法的文档字符串 refactor(base_model): 移除冗余的表名和表参数生成方法 refactor(constant): 更新返回码注释格式 refactor(router_class): 添加路由处理器的详细文档 refactor(database): 完善数据库连接函数的文档 refactor(security): 添加认证类和方法的详细文档 refactor(validator): 更新验证器函数的文档格式 refactor(serialize): 优化序列化工具类的文档 refactor(response): 完善响应类的文档字符串 refactor(dependencies): 添加依赖函数的详细文档 refactor(initialize): 完善初始化脚本的文档 refactor(plugin): 添加生命周期和中间件注册的文档 refactor(service): 完善服务层方法的文档 refactor(controller): 添加控制器方法的详细文档 refactor(crud): 完善CRUD操作的文档字符串 refactor(schema): 简化模型类并移除冗余字段 refactor(param): 更新查询参数类的注释格式 refactor(template): 优化代码生成模板的格式 refactor(console): 添加控制台输出功能的实现 refactor(util): 完善工具函数的文档字符串
170 lines
4.6 KiB
Python
170 lines
4.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
import re
|
|
from datetime import datetime
|
|
from typing import Annotated, Optional, Union
|
|
from pydantic import AfterValidator, PlainSerializer, WithJsonSchema
|
|
|
|
from app.common.constant import RET
|
|
from app.core.exceptions import CustomException
|
|
|
|
|
|
# 自定义日期时间字符串类型
|
|
DateTimeStr = Annotated[
|
|
datetime,
|
|
AfterValidator(lambda x: datetime_validator(x)),
|
|
PlainSerializer(lambda x: x.strftime('%Y-%m-%d %H:%M:%S') if isinstance(x, datetime) else str(x), return_type=str),
|
|
WithJsonSchema({'type': 'string'}, mode='serialization')
|
|
]
|
|
|
|
# 自定义手机号类型
|
|
Telephone = Annotated[
|
|
str,
|
|
AfterValidator(lambda x: mobile_validator(x)),
|
|
PlainSerializer(lambda x: x, return_type=str),
|
|
WithJsonSchema({'type': 'string'}, mode='serialization')
|
|
]
|
|
|
|
# 自定义邮箱类型
|
|
Email = Annotated[
|
|
str,
|
|
AfterValidator(lambda x: email_validator(x)),
|
|
PlainSerializer(lambda x: x, return_type=str),
|
|
WithJsonSchema({'type': 'string'}, mode='serialization')
|
|
]
|
|
|
|
def datetime_validator(value: Union[str, datetime]) -> datetime:
|
|
"""
|
|
日期格式验证器。
|
|
|
|
参数:
|
|
- value (str | datetime): 日期值。
|
|
|
|
返回:
|
|
- datetime: 格式化后的日期。
|
|
|
|
异常:
|
|
- CustomException: 日期格式无效时抛出。
|
|
"""
|
|
pattern = "%Y-%m-%d %H:%M:%S"
|
|
try:
|
|
if isinstance(value, str):
|
|
return datetime.strptime(value, pattern)
|
|
elif isinstance(value, datetime):
|
|
return value
|
|
except Exception:
|
|
raise CustomException(code=RET.ERROR.code, msg="无效的日期格式")
|
|
|
|
# 如果 value 是 None 或其他类型,抛出异常
|
|
raise CustomException(code=RET.ERROR.code, msg="无效的日期格式")
|
|
|
|
|
|
def email_validator(value: str) -> str:
|
|
"""
|
|
邮箱地址验证器。
|
|
|
|
参数:
|
|
- value (str): 邮箱地址。
|
|
|
|
返回:
|
|
- str: 验证后的邮箱地址。
|
|
|
|
异常:
|
|
- CustomException: 邮箱格式无效时抛出。
|
|
"""
|
|
if not value:
|
|
raise CustomException(code=RET.ERROR.code, msg="邮箱地址不能为空")
|
|
|
|
regex = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
|
|
|
|
if not re.match(regex, value):
|
|
raise CustomException(code=RET.ERROR.code, msg="邮箱地址格式不正确")
|
|
|
|
return value
|
|
|
|
|
|
def mobile_validator(value: Optional[str]) -> Optional[str]:
|
|
"""
|
|
手机号验证器。
|
|
|
|
参数:
|
|
- value (str | None): 手机号。
|
|
|
|
返回:
|
|
- str | None: 验证后的手机号。
|
|
|
|
异常:
|
|
- CustomException: 手机号格式无效时抛出。
|
|
"""
|
|
if not value:
|
|
return value
|
|
|
|
if len(value) != 11 or not value.isdigit():
|
|
raise CustomException(code=RET.ERROR.code, msg="手机号格式不正确")
|
|
|
|
regex = r'^1(3\d|4[4-9]|5[0-35-9]|6[67]|7[013-8]|8[0-9]|9[0-9])\d{8}$'
|
|
|
|
if not re.match(regex, value):
|
|
raise CustomException(code=RET.ERROR.code, msg="手机号格式不正确")
|
|
|
|
return value
|
|
|
|
|
|
def menu_request_validator(data):
|
|
"""
|
|
菜单请求数据验证器。
|
|
|
|
参数:
|
|
- data (Any): 请求数据。
|
|
|
|
返回:
|
|
- Any: 验证后的请求数据。
|
|
|
|
异常:
|
|
- CustomException: 请求数据无效时抛出。
|
|
"""
|
|
menu_types = {1: "目录", 2: "功能", 3: "权限", 4: "外链"}
|
|
|
|
if data.type not in menu_types:
|
|
raise CustomException(code=RET.ERROR.code, msg=f"菜单类型必须为: {','.join(map(str, menu_types.keys()))}")
|
|
|
|
if data.type in [1, 2]:
|
|
if not data.route_name:
|
|
raise CustomException(code=RET.ERROR.code, msg="路由名称不能为空")
|
|
if not data.route_path:
|
|
raise CustomException(code=RET.ERROR.code, msg="路由路径不能为空")
|
|
|
|
if data.type == 2 and not data.component_path:
|
|
raise CustomException(code=RET.ERROR.code, msg="组件路径不能为空")
|
|
|
|
return data
|
|
|
|
|
|
def role_permission_request_validator(data):
|
|
"""
|
|
角色权限设置数据验证器。
|
|
|
|
参数:
|
|
- data (Any): 请求数据。
|
|
|
|
返回:
|
|
- Any: 验证后的请求数据。
|
|
|
|
异常:
|
|
- CustomException: 请求数据无效时抛出。
|
|
"""
|
|
data_scopes = {
|
|
1: "仅本人数据权限",
|
|
2: "本部门数据权限",
|
|
3: "本部门及以下数据权限",
|
|
4: "全部数据权限",
|
|
5: "自定义数据权限"
|
|
}
|
|
|
|
if data.data_scope not in data_scopes:
|
|
raise CustomException(code=RET.ERROR.code, msg=f"数据权限范围必须为: {','.join(map(str, data_scopes.keys()))}")
|
|
|
|
if not data.role_ids:
|
|
raise CustomException(code=RET.ERROR.code, msg="角色不能为空")
|
|
|
|
return data |