first commit
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
|
||||
import random
|
||||
import string
|
||||
from hashlib import md5
|
||||
from typing import Any, Dict, List, Union, Optional, get_origin, get_args, Type
|
||||
from pydantic import BaseModel
|
||||
|
||||
def gen_random_str(length=10, prefix="", suffix=""):
|
||||
"""
|
||||
生成随机字符串,默认长度为10,可添加前缀和后缀
|
||||
"""
|
||||
random_str = prefix + ''.join(random.choices(string.ascii_letters + string.digits, k=length)) + suffix
|
||||
return md5(random_str.encode()).hexdigest()
|
||||
|
||||
|
||||
def split_generator(iterable, chunk_size=50):
|
||||
"""
|
||||
将可迭代对象拆分为多个子列表
|
||||
"""
|
||||
chunk = []
|
||||
for item in iterable:
|
||||
chunk.append(item)
|
||||
if len(chunk) == chunk_size:
|
||||
yield chunk
|
||||
chunk = []
|
||||
if chunk:
|
||||
yield chunk
|
||||
|
||||
async def async_split_generator(iterable, chunk_size=50):
|
||||
"""
|
||||
将可迭代对象拆分为多个子列表
|
||||
"""
|
||||
chunk = []
|
||||
async for item in iterable:
|
||||
chunk.append(item)
|
||||
if len(chunk) == chunk_size:
|
||||
yield chunk
|
||||
chunk = []
|
||||
if chunk:
|
||||
yield chunk
|
||||
|
||||
async def async_generator_to_list(iterable):
|
||||
"""
|
||||
将可迭代对象转换为列表
|
||||
"""
|
||||
return [item async for item in iterable]
|
||||
|
||||
TYPE_MAPPING = {
|
||||
"str": "string",
|
||||
"int": "number",
|
||||
"float": "number",
|
||||
"bool": "boolean",
|
||||
"list": "array",
|
||||
"dict": "object",
|
||||
"NoneType": "null", # 注意:None 的类型名是 'NoneType'
|
||||
}
|
||||
|
||||
def transform_pydantic_to_list(
|
||||
cls: Type[BaseModel],
|
||||
prefix: str = "" # 新增:当前路径前缀
|
||||
) -> List[Dict[str, Any]]:
|
||||
if not issubclass(cls, BaseModel):
|
||||
raise TypeError(f"{cls} is not a Pydantic BaseModel")
|
||||
|
||||
result = []
|
||||
exclude_filter = getattr(cls, "__exclude_filter__", [])
|
||||
meta_mapping = getattr(cls, "__meta_mapping__", {})
|
||||
|
||||
for field_name, field_info in cls.model_fields.items():
|
||||
if field_name in exclude_filter:
|
||||
continue
|
||||
|
||||
# 构建当前字段的完整路径
|
||||
current_path = f"{prefix}.{field_name}" if prefix else field_name
|
||||
|
||||
field_meta = meta_mapping.get(field_name, {}) or {}
|
||||
|
||||
raw_type = field_info.annotation
|
||||
children = []
|
||||
display_type_name = "any"
|
||||
|
||||
origin = get_origin(raw_type)
|
||||
args = get_args(raw_type)
|
||||
|
||||
# 处理 Optional[T](即 Union[T, None])
|
||||
if origin is Union and type(None) in args:
|
||||
# 提取非 None 的类型
|
||||
non_none_types = [arg for arg in args if arg is not type(None)]
|
||||
if len(non_none_types) == 1:
|
||||
inner_type = non_none_types[0]
|
||||
else:
|
||||
inner_type = raw_type # 多类型 Union,暂不深入处理
|
||||
else:
|
||||
inner_type = raw_type
|
||||
|
||||
# 判断是否为 List[BaseModel]
|
||||
list_origin = get_origin(inner_type)
|
||||
if list_origin is list:
|
||||
item_type = get_args(inner_type)[0] if get_args(inner_type) else Any
|
||||
if isinstance(item_type, type) and issubclass(item_type, BaseModel):
|
||||
children = transform_pydantic_to_list(item_type, prefix=current_path)
|
||||
display_type_name = "list"
|
||||
elif isinstance(inner_type, type) and issubclass(inner_type, BaseModel):
|
||||
children = transform_pydantic_to_list(inner_type, prefix=current_path)
|
||||
display_type_name = "object"
|
||||
else:
|
||||
# 基础类型:获取类型名
|
||||
if inner_type is type(None):
|
||||
display_type_name = "NoneType"
|
||||
elif hasattr(inner_type, '__name__'):
|
||||
display_type_name = inner_type.__name__
|
||||
else:
|
||||
display_type_name = str(inner_type)
|
||||
|
||||
frontend_type = TYPE_MAPPING.get(display_type_name, "string")
|
||||
|
||||
item = {
|
||||
"value": current_path, # ✅ 使用层级路径
|
||||
"label": field_info.description or field_name,
|
||||
"type": frontend_type,
|
||||
**field_meta,
|
||||
}
|
||||
if children:
|
||||
item["children"] = children
|
||||
result.append(item)
|
||||
|
||||
return result
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(gen_random_str())
|
||||
print(gen_random_str())
|
||||
print(gen_random_str())
|
||||
print(gen_random_str())
|
||||
Reference in New Issue
Block a user