from typing import List from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from app.database import get_db from app.core.deps import require_roles from app.models.user import User from app.schemas.common import ApiResponse, PagedData from app.schemas.workflow import WorkflowDefCreate, WorkflowDefUpdate, WorkflowDefOut, WorkflowNodeCreate, WorkflowNodeOut from app.services.workflow import WorkflowService router = APIRouter(prefix="/api/workflows", tags=["工作流配置"]) @router.get("/", response_model=ApiResponse[PagedData[WorkflowDefOut]]) def list_workflows( page: int = 1, pageSize: int = 10, db: Session = Depends(get_db), _: User = Depends(require_roles("ADMIN")), ): rows, total = WorkflowService.get_paged(db, page=page, page_size=pageSize) out_rows = [WorkflowDefOut.model_validate(r) for r in rows] paged_data = PagedData(rows=out_rows, total=total, page=page, page_size=pageSize) return ApiResponse(data=paged_data) @router.get("/biz/{biz_type}", response_model=ApiResponse[WorkflowDefOut]) def get_workflow_by_biz_type(biz_type: str, db: Session = Depends(get_db), _: User = Depends(require_roles("ADMIN"))): workflow = WorkflowService.get_by_biz_type(db, biz_type) if not workflow: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="工作流不存在") return ApiResponse(data=WorkflowDefOut.model_validate(workflow)) @router.get("/{workflow_id}", response_model=ApiResponse[WorkflowDefOut]) def get_workflow(workflow_id: int, db: Session = Depends(get_db), _: User = Depends(require_roles("ADMIN"))): workflow = WorkflowService.get_by_id(db, workflow_id) if not workflow: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="工作流不存在") return ApiResponse(data=WorkflowDefOut.model_validate(workflow)) @router.post("/", response_model=ApiResponse[WorkflowDefOut]) def create_workflow(body: WorkflowDefCreate, db: Session = Depends(get_db), _: User = Depends(require_roles("ADMIN"))): data = body.model_dump(exclude_unset=True) nodes_data = data.pop("nodes", []) workflow = WorkflowService.create(db, data) if nodes_data: for n in nodes_data: n["wf_id"] = workflow.id WorkflowService.save_nodes(db, workflow.id, nodes_data) db.refresh(workflow) return ApiResponse(data=WorkflowDefOut.model_validate(workflow)) @router.put("/{workflow_id}", response_model=ApiResponse[WorkflowDefOut]) def update_workflow(workflow_id: int, body: WorkflowDefUpdate, db: Session = Depends(get_db), _: User = Depends(require_roles("ADMIN"))): data = body.model_dump(exclude_unset=True) nodes_data = data.pop("nodes", None) workflow = WorkflowService.update(db, workflow_id, data) if not workflow: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="工作流不存在") if nodes_data is not None: WorkflowService.save_nodes(db, workflow_id, nodes_data) db.refresh(workflow) return ApiResponse(data=WorkflowDefOut.model_validate(workflow)) @router.put("/{workflow_id}/nodes", response_model=ApiResponse[WorkflowDefOut]) def save_workflow_nodes( workflow_id: int, body: List[WorkflowNodeCreate], db: Session = Depends(get_db), _: User = Depends(require_roles("ADMIN")), ): nodes_data = [n.model_dump(exclude_unset=True) for n in body] WorkflowService.save_nodes(db, workflow_id, nodes_data) workflow = WorkflowService.get_by_id(db, workflow_id) if not workflow: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="工作流不存在") return ApiResponse(data=WorkflowDefOut.model_validate(workflow)) @router.delete("/{workflow_id}", response_model=ApiResponse[None]) def delete_workflow(workflow_id: int, db: Session = Depends(get_db), _: User = Depends(require_roles("ADMIN"))): WorkflowService.soft_delete(db, workflow_id) return ApiResponse(data=None)