mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-22 21:06:32 +00:00
本次提交包含多项优化和修复: 1. 修复CRUD初始化参数传递、搜索参数处理逻辑 2. 更新环境配置中的大模型相关参数 3. 重构部分服务方法命名,统一代码风格 4. 新增多个枚举类型,补充模型关联关系和加载选项 5. 优化查询参数类实现,完善字段校验逻辑 6. 调整Pydantic模型字段注释和类型定义 7. 简化并移除冗余的CRUD方法实现 8. 新增超级管理员权限装饰器 9. 修复邮件日志模型的租户关联和字段定义
134 lines
5.1 KiB
Python
134 lines
5.1 KiB
Python
import re
|
|
from dataclasses import dataclass
|
|
from typing import Any
|
|
|
|
from fastapi import Query
|
|
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
|
|
|
|
from app.common.enums import QueueEnum
|
|
from app.core.base_params import BaseQueryParam, TenantByQueryParam, UserByQueryParam
|
|
from app.core.base_schema import BaseSchema, TenantBySchema, UserBySchema
|
|
from app.core.validator import DateTimeStr
|
|
|
|
|
|
class WorkflowCreateSchema(BaseModel):
|
|
"""创建工作流"""
|
|
|
|
name: str = Field(..., max_length=128, description="流程名称")
|
|
code: str = Field(..., max_length=64, description="流程编码")
|
|
description: str | None = Field(default=None, description="描述")
|
|
nodes: list | None = Field(default=None, description="Vue Flow nodes")
|
|
edges: list | None = Field(default=None, description="Vue Flow edges")
|
|
|
|
@field_validator("name")
|
|
@classmethod
|
|
def validate_name(cls, v: str) -> str:
|
|
v = v.strip()
|
|
if len(v) < 1 or len(v) > 128:
|
|
raise ValueError("流程名称长度必须在1-128个字符之间")
|
|
return v
|
|
|
|
@field_validator("code")
|
|
@classmethod
|
|
def validate_code(cls, v: str) -> str:
|
|
v = v.strip()
|
|
if len(v) < 2 or len(v) > 64:
|
|
raise ValueError("流程编码长度必须在2-64个字符之间")
|
|
if not re.match(r"^[A-Za-z][A-Za-z0-9_]*$", v):
|
|
raise ValueError("流程编码必须以字母开头,仅允许字母、数字、下划线")
|
|
return v
|
|
|
|
|
|
class WorkflowUpdateSchema(WorkflowCreateSchema):
|
|
"""更新工作流"""
|
|
|
|
workflow_status: str | None = Field(default=None, max_length=32, description="draft/published/archived")
|
|
|
|
@field_validator("workflow_status")
|
|
@classmethod
|
|
def validate_workflow_status(cls, v: str | None) -> str | None:
|
|
if v is None:
|
|
return v
|
|
allowed = {"draft", "published", "archived"}
|
|
v = v.strip()
|
|
if v not in allowed:
|
|
raise ValueError(f"流程状态必须为 {allowed}")
|
|
return v
|
|
|
|
|
|
class WorkflowOutSchema(BaseSchema, UserBySchema, TenantBySchema):
|
|
"""工作流输出(status 表示流程状态 draft/published/archived,与 ModelMixin.status 区分)"""
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int | None = Field(default=None, description="主键ID")
|
|
uuid: str | None = Field(default=None, description="UUID")
|
|
description: str | None = Field(default=None, description="描述")
|
|
created_time: DateTimeStr | None = Field(default=None, description="创建时间")
|
|
updated_time: DateTimeStr | None = Field(default=None, description="更新时间")
|
|
name: str = Field(description="流程名称")
|
|
code: str = Field(description="流程编码")
|
|
status: str = Field(description="流程状态 draft/published/archived")
|
|
nodes: list | None = Field(default=None, description="节点")
|
|
edges: list | None = Field(default=None, description="连线")
|
|
|
|
@model_validator(mode="before")
|
|
@classmethod
|
|
def _map_workflow_status(cls, data: Any) -> Any:
|
|
from .model import WorkflowModel
|
|
|
|
if isinstance(data, WorkflowModel):
|
|
return {
|
|
"id": data.id,
|
|
"uuid": data.uuid,
|
|
"description": data.description,
|
|
"created_time": data.created_time,
|
|
"updated_time": data.updated_time,
|
|
"created_id": data.created_id,
|
|
"updated_id": data.updated_id,
|
|
"name": data.name,
|
|
"code": data.code,
|
|
"status": data.workflow_status,
|
|
"nodes": data.nodes,
|
|
"edges": data.edges,
|
|
}
|
|
return data
|
|
|
|
|
|
@dataclass
|
|
class WorkflowQueryParam(BaseQueryParam, UserByQueryParam, TenantByQueryParam):
|
|
"""工作流查询"""
|
|
|
|
def __init__(
|
|
self,
|
|
name: str | None = Query(None, description="流程名称"),
|
|
code: str | None = Query(None, description="流程编码"),
|
|
*args,
|
|
**kwargs,
|
|
) -> None:
|
|
super().__init__(*args, **kwargs)
|
|
self.name = (QueueEnum.like.value, name) if name else None
|
|
self.code = (QueueEnum.like.value, code) if code else None
|
|
|
|
|
|
class WorkflowExecuteSchema(BaseModel):
|
|
"""执行工作流"""
|
|
|
|
workflow_id: int = Field(..., description="工作流ID")
|
|
variables: dict | None = Field(default=None, description="注入到各节点的 variables 上下文")
|
|
business_key: str | None = Field(default=None, description="业务键")
|
|
job_id: int | None = Field(default=None, description="关联任务ID")
|
|
|
|
|
|
class WorkflowExecuteResultSchema(BaseModel):
|
|
"""执行结果"""
|
|
|
|
workflow_id: int = Field(..., description="工作流ID")
|
|
workflow_name: str = Field(..., description="工作流名称")
|
|
status: str = Field(description="completed/failed")
|
|
start_time: str | None = Field(default=None, description="开始时间")
|
|
end_time: str | None = Field(default=None, description="结束时间")
|
|
variables: dict | None = Field(default=None, description="变量")
|
|
node_results: dict | None = Field(default=None, description="节点结果")
|
|
error: str | None = Field(default=None, description="错误信息")
|