mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-25 13:51:04 +00:00
refactor: 统一项目中状态字段类型为数字类型
这是一个大规模的类型对齐优化: 1. 将多处字符串类型的status字段统一改为数字类型,包括前后端接口定义、数据模型、页面组件 2. 重构编排节点相关的命名和注释,统一改为"节点类型"替代"编排节点类型" 3. 移除了过时的忘记密码相关接口和模板代码 4. 优化搜索栏组件,支持展开仅显示次要字段 5. 调整部分接口参数和路由逻辑,对齐前后端参数格式
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
工作流编排子包(plugin.module_task.workflow):
|
||||
|
||||
- ``definition``: 工作流定义(画布 CRUD、发布、执行 API)
|
||||
- ``node_type``: 编排节点类型(palette / 与 task_node 分离)
|
||||
- ``node_type``: 节点类型(palette / 与 task_node 分离)
|
||||
- ``engine``: 拓扑分层并行执行引擎
|
||||
|
||||
动态路由仍统一挂在 ``/task`` 下(见各子包 ``controller.py`` 的 ``prefix``)。
|
||||
|
||||
@@ -42,17 +42,16 @@ class WorkflowCreateSchema(BaseModel):
|
||||
class WorkflowUpdateSchema(WorkflowCreateSchema):
|
||||
"""更新工作流"""
|
||||
|
||||
workflow_status: str | None = Field(default=None, max_length=32, description="draft/published/archived")
|
||||
workflow_status: int | None = Field(default=None, description="0:草稿 / 1:已发布 / 2:已归档")
|
||||
|
||||
@field_validator("workflow_status")
|
||||
@classmethod
|
||||
def validate_workflow_status(cls, v: str | None) -> str | None:
|
||||
def validate_workflow_status(cls, v: int | None) -> int | None:
|
||||
if v is None:
|
||||
return v
|
||||
allowed = {"draft", "published", "archived"}
|
||||
v = v.strip()
|
||||
allowed = {0, 1, 2}
|
||||
if v not in allowed:
|
||||
raise ValueError(f"流程状态必须为 {allowed}")
|
||||
raise ValueError(f"流程状态必须为 {sorted(allowed)}")
|
||||
return v
|
||||
|
||||
|
||||
@@ -68,7 +67,7 @@ class WorkflowOutSchema(BaseSchema, UserBySchema, TenantBySchema):
|
||||
updated_time: DateTimeStr | None = Field(default=None, description="更新时间")
|
||||
name: str = Field(description="流程名称")
|
||||
code: str = Field(description="流程编码")
|
||||
status: str = Field(description="流程状态 draft/published/archived")
|
||||
status: int = Field(description="流程状态 0:草稿 / 1:已发布 / 2:已归档")
|
||||
nodes: list | None = Field(default=None, description="节点")
|
||||
edges: list | None = Field(default=None, description="连线")
|
||||
|
||||
@@ -121,7 +120,7 @@ class WorkflowExecuteResultSchema(BaseModel):
|
||||
|
||||
workflow_id: int = Field(..., description="工作流ID")
|
||||
workflow_name: str = Field(..., description="工作流名称")
|
||||
status: str = Field(description="completed/failed")
|
||||
status: int = Field(description="执行状态 0:失败 / 1:已完成")
|
||||
start_time: str | None = Field(default=None, description="开始时间")
|
||||
end_time: str | None = Field(default=None, description="结束时间")
|
||||
variables: dict | None = Field(default=None, description="变量")
|
||||
|
||||
@@ -18,6 +18,16 @@ from .schema import (
|
||||
)
|
||||
|
||||
|
||||
# 工作流状态常量(与 WorkflowModel.status 保持一致:0:草稿 1:已发布 2:已归档)
|
||||
WORKFLOW_STATUS_DRAFT = 0
|
||||
WORKFLOW_STATUS_PUBLISHED = 1
|
||||
WORKFLOW_STATUS_ARCHIVED = 2
|
||||
|
||||
# 工作流执行结果状态(0:失败 1:已完成)
|
||||
WORKFLOW_EXEC_STATUS_FAILED = 0
|
||||
WORKFLOW_EXEC_STATUS_COMPLETED = 1
|
||||
|
||||
|
||||
class WorkflowService:
|
||||
"""工作流:画布存储 + 发布校验 + 分层并行执行"""
|
||||
|
||||
@@ -110,7 +120,7 @@ class WorkflowService:
|
||||
description=obj.description,
|
||||
nodes=obj.nodes,
|
||||
edges=obj.edges,
|
||||
workflow_status="published",
|
||||
workflow_status=WORKFLOW_STATUS_PUBLISHED,
|
||||
)
|
||||
updated = await WorkflowCRUD(self.auth).update_obj_crud(id=id, data=data)
|
||||
if not updated:
|
||||
@@ -121,7 +131,7 @@ class WorkflowService:
|
||||
obj = await WorkflowCRUD(self.auth).get_obj_by_id_crud(id=body.workflow_id)
|
||||
if not obj:
|
||||
raise CustomException(msg="工作流不存在")
|
||||
if obj.workflow_status != "published":
|
||||
if obj.workflow_status != WORKFLOW_STATUS_PUBLISHED:
|
||||
raise CustomException(msg="仅已发布的工作流可执行")
|
||||
|
||||
nodes = obj.nodes or []
|
||||
@@ -137,9 +147,9 @@ class WorkflowService:
|
||||
for code in codes_set:
|
||||
node_type = type_map.get(code)
|
||||
if not node_type:
|
||||
raise CustomException(msg=f"编排节点类型未注册(请在「工作流编排节点类型」中维护,非定时任务节点): {code}")
|
||||
raise CustomException(msg=f"节点类型未注册(请在「工作流节点类型」中维护,非定时任务节点): {code}")
|
||||
if not node_type.func or not str(node_type.func).strip():
|
||||
raise CustomException(msg=f"编排节点类型未配置 func 代码块: {code}")
|
||||
raise CustomException(msg=f"节点类型未配置 func 代码块: {code}")
|
||||
templates[code] = {
|
||||
"func": node_type.func,
|
||||
"args": node_type.args,
|
||||
@@ -165,7 +175,7 @@ class WorkflowService:
|
||||
err = WorkflowExecuteResultSchema(
|
||||
workflow_id=obj.id,
|
||||
workflow_name=obj.name,
|
||||
status="failed",
|
||||
status=WORKFLOW_EXEC_STATUS_FAILED,
|
||||
start_time=start,
|
||||
end_time=end,
|
||||
variables=variables,
|
||||
@@ -178,7 +188,7 @@ class WorkflowService:
|
||||
ok = WorkflowExecuteResultSchema(
|
||||
workflow_id=obj.id,
|
||||
workflow_name=obj.name,
|
||||
status="completed",
|
||||
status=WORKFLOW_EXEC_STATUS_COMPLETED,
|
||||
start_time=start,
|
||||
end_time=end,
|
||||
variables=variables,
|
||||
|
||||
@@ -125,7 +125,7 @@ def run_workflow_sync(
|
||||
for nid, fut in futures.items():
|
||||
results[nid] = fut.result()
|
||||
logger.info("工作流执行完成: nodes={}", list(results.keys()))
|
||||
return {"node_results": results, "status": "completed"}
|
||||
return {"node_results": results, "status": 1}
|
||||
|
||||
|
||||
def utc_now_iso() -> str:
|
||||
|
||||
@@ -1 +1 @@
|
||||
"""编排节点类型(palette、CRUD;与定时任务 task_node 无关)。"""
|
||||
"""节点类型(palette、CRUD;与定时任务 task_node 无关)。"""
|
||||
|
||||
@@ -26,7 +26,7 @@ WorkflowNodeTypeRouter = APIRouter(
|
||||
|
||||
@WorkflowNodeTypeRouter.get(
|
||||
"/options",
|
||||
summary="编排节点类型选项",
|
||||
summary="节点类型选项",
|
||||
response_model=ResponseSchema[list[dict]],
|
||||
)
|
||||
async def get_workflow_node_type_options_controller(
|
||||
@@ -34,12 +34,12 @@ async def get_workflow_node_type_options_controller(
|
||||
) -> JSONResponse:
|
||||
service = WorkflowNodeTypeService(auth)
|
||||
result = await service.get_options()
|
||||
return SuccessResponse(data=result, msg="获取编排节点类型选项成功")
|
||||
return SuccessResponse(data=result, msg="获取节点类型选项成功")
|
||||
|
||||
|
||||
@WorkflowNodeTypeRouter.get(
|
||||
"/detail/{id}",
|
||||
summary="编排节点类型详情",
|
||||
summary="节点类型详情",
|
||||
response_model=ResponseSchema[WorkflowNodeTypeOutSchema],
|
||||
)
|
||||
async def get_workflow_node_type_detail_controller(
|
||||
@@ -48,12 +48,12 @@ async def get_workflow_node_type_detail_controller(
|
||||
) -> JSONResponse:
|
||||
service = WorkflowNodeTypeService(auth)
|
||||
result_dict = await service.get_detail(id=id)
|
||||
return SuccessResponse(data=result_dict, msg="获取编排节点类型详情成功")
|
||||
return SuccessResponse(data=result_dict, msg="获取节点类型详情成功")
|
||||
|
||||
|
||||
@WorkflowNodeTypeRouter.get(
|
||||
"/list",
|
||||
summary="编排节点类型列表",
|
||||
summary="节点类型列表",
|
||||
response_model=ResponseSchema[PageResultSchema[WorkflowNodeTypeOutSchema]],
|
||||
)
|
||||
async def get_workflow_node_type_list_controller(
|
||||
@@ -71,12 +71,12 @@ async def get_workflow_node_type_list_controller(
|
||||
search=search,
|
||||
order_by=order_by,
|
||||
)
|
||||
return SuccessResponse(data=result_dict, msg="查询编排节点类型列表成功")
|
||||
return SuccessResponse(data=result_dict, msg="查询节点类型列表成功")
|
||||
|
||||
|
||||
@WorkflowNodeTypeRouter.post(
|
||||
"/create",
|
||||
summary="创建编排节点类型",
|
||||
summary="创建节点类型",
|
||||
response_model=ResponseSchema[WorkflowNodeTypeOutSchema],
|
||||
)
|
||||
async def create_workflow_node_type_controller(
|
||||
@@ -85,12 +85,12 @@ async def create_workflow_node_type_controller(
|
||||
) -> JSONResponse:
|
||||
service = WorkflowNodeTypeService(auth)
|
||||
result_dict = await service.create(data=data)
|
||||
return SuccessResponse(data=result_dict, msg="创建编排节点类型成功")
|
||||
return SuccessResponse(data=result_dict, msg="创建节点类型成功")
|
||||
|
||||
|
||||
@WorkflowNodeTypeRouter.put(
|
||||
"/update/{id}",
|
||||
summary="更新编排节点类型",
|
||||
summary="更新节点类型",
|
||||
response_model=ResponseSchema[WorkflowNodeTypeOutSchema],
|
||||
)
|
||||
async def update_workflow_node_type_controller(
|
||||
@@ -100,12 +100,12 @@ async def update_workflow_node_type_controller(
|
||||
) -> JSONResponse:
|
||||
service = WorkflowNodeTypeService(auth)
|
||||
result_dict = await service.update(id=id, data=data)
|
||||
return SuccessResponse(data=result_dict, msg="更新编排节点类型成功")
|
||||
return SuccessResponse(data=result_dict, msg="更新节点类型成功")
|
||||
|
||||
|
||||
@WorkflowNodeTypeRouter.delete(
|
||||
"/delete",
|
||||
summary="删除编排节点类型",
|
||||
summary="删除节点类型",
|
||||
response_model=ResponseSchema[None],
|
||||
)
|
||||
async def delete_workflow_node_type_controller(
|
||||
@@ -114,12 +114,12 @@ async def delete_workflow_node_type_controller(
|
||||
) -> JSONResponse:
|
||||
service = WorkflowNodeTypeService(auth)
|
||||
await service.delete(ids=ids)
|
||||
return SuccessResponse(msg="删除编排节点类型成功")
|
||||
return SuccessResponse(msg="删除节点类型成功")
|
||||
|
||||
|
||||
@WorkflowNodeTypeRouter.get(
|
||||
"/select",
|
||||
summary="编排节点类型选择列表",
|
||||
summary="节点类型选择列表",
|
||||
response_model=ResponseSchema[list[dict]],
|
||||
)
|
||||
async def get_workflow_node_type_select_controller(
|
||||
@@ -127,4 +127,4 @@ async def get_workflow_node_type_select_controller(
|
||||
) -> JSONResponse:
|
||||
service = WorkflowNodeTypeService(auth)
|
||||
result = await service.get_select()
|
||||
return SuccessResponse(data=result, msg="获取编排节点类型选择列表成功")
|
||||
return SuccessResponse(data=result, msg="获取节点类型选择列表成功")
|
||||
|
||||
@@ -10,11 +10,11 @@ from .schema import WorkflowNodeTypeCreateSchema, WorkflowNodeTypeUpdateSchema
|
||||
|
||||
|
||||
class WorkflowNodeTypeCRUD(CRUDBase[WorkflowNodeTypeModel, WorkflowNodeTypeCreateSchema, WorkflowNodeTypeUpdateSchema]):
|
||||
"""编排节点类型 CRUD"""
|
||||
"""节点类型 CRUD"""
|
||||
|
||||
def __init__(self, auth: AuthSchema) -> None:
|
||||
"""
|
||||
初始化编排节点类型 CRUD。
|
||||
初始化节点类型 CRUD。
|
||||
|
||||
参数:
|
||||
- auth (AuthSchema): 认证信息。
|
||||
|
||||
@@ -6,13 +6,13 @@ from app.core.base_model import ModelMixin, TenantMixin, UserMixin
|
||||
|
||||
class WorkflowNodeTypeModel(ModelMixin, TenantMixin, UserMixin):
|
||||
"""
|
||||
编排节点类型:用于 Vue Flow 左侧 palette 与执行引擎解析。
|
||||
节点类型:用于 Vue Flow 左侧 palette 与执行引擎解析。
|
||||
"""
|
||||
|
||||
__tablename__: str = "task_workflow_node_type"
|
||||
__table_args__ = (
|
||||
UniqueConstraint("tenant_id", "code"),
|
||||
{"comment": "工作流编排节点类型(非定时任务节点)"},
|
||||
{"comment": "工作流节点类型(非定时任务节点)"},
|
||||
)
|
||||
__loader_options__: list[str] = ["created_by", "updated_by", "deleted_by", "tenant_by"]
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ from app.core.base_schema import BaseSchema, TenantBySchema, UserBySchema
|
||||
|
||||
|
||||
class WorkflowNodeTypeCreateSchema(BaseModel):
|
||||
"""创建编排节点类型"""
|
||||
"""创建节点类型"""
|
||||
|
||||
name: str = Field(..., max_length=128, description="显示名称")
|
||||
code: str = Field(..., max_length=64, description="节点编码")
|
||||
@@ -56,7 +56,7 @@ class WorkflowNodeTypeCreateSchema(BaseModel):
|
||||
|
||||
|
||||
class WorkflowNodeTypeUpdateSchema(WorkflowNodeTypeCreateSchema):
|
||||
"""更新编排节点类型"""
|
||||
"""更新节点类型"""
|
||||
|
||||
|
||||
class WorkflowNodeTypeOutSchema(WorkflowNodeTypeCreateSchema, BaseSchema, UserBySchema, TenantBySchema):
|
||||
@@ -73,9 +73,12 @@ class WorkflowNodeTypeQueryParam(BaseQueryParam, UserByQueryParam, TenantByQuery
|
||||
code: str | None = Query(None, description="编码")
|
||||
category: str | None = Query(None, description="分类")
|
||||
is_active: bool | None = Query(None, description="是否启用")
|
||||
status: int | None = Query(None, ge=0, le=1, description="状态(0:启动 1:停用)")
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
self.name = (QueueEnum.like.value, self.name) if self.name else None
|
||||
self.code = (QueueEnum.like.value, self.code) if self.code else None
|
||||
self.category = (QueueEnum.eq.value, self.category) if self.category else None
|
||||
self.is_active = (QueueEnum.eq.value, self.is_active) if self.is_active is not None else None
|
||||
if isinstance(self.status, int):
|
||||
self.status = (QueueEnum.eq.value, self.status)
|
||||
|
||||
@@ -12,7 +12,7 @@ from .schema import (
|
||||
|
||||
|
||||
class WorkflowNodeTypeService:
|
||||
"""工作流编排节点类型(与定时任务 task_node 无关)"""
|
||||
"""工作流节点类型(与定时任务 task_node 无关)"""
|
||||
|
||||
def __init__(self, auth: AuthSchema) -> None:
|
||||
self.auth = auth
|
||||
@@ -38,7 +38,7 @@ class WorkflowNodeTypeService:
|
||||
async def get_detail(self, id: int) -> WorkflowNodeTypeOutSchema:
|
||||
obj = await WorkflowNodeTypeCRUD(self.auth).get_obj_by_id_crud(id=id)
|
||||
if not obj:
|
||||
raise CustomException(msg="编排节点类型不存在")
|
||||
raise CustomException(msg="节点类型不存在")
|
||||
return self._out(obj)
|
||||
|
||||
async def get_list(
|
||||
@@ -85,7 +85,7 @@ class WorkflowNodeTypeService:
|
||||
async def update(self, id: int, data: WorkflowNodeTypeUpdateSchema) -> WorkflowNodeTypeOutSchema:
|
||||
exist = await WorkflowNodeTypeCRUD(self.auth).get_obj_by_id_crud(id=id)
|
||||
if not exist:
|
||||
raise CustomException(msg="编排节点类型不存在")
|
||||
raise CustomException(msg="节点类型不存在")
|
||||
if exist.code != data.code:
|
||||
other = await WorkflowNodeTypeCRUD(self.auth).get(code=data.code)
|
||||
if other:
|
||||
|
||||
Reference in New Issue
Block a user