workflow.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. from typing import List
  2. from fastapi import APIRouter, Depends, HTTPException, status, Query
  3. from sqlalchemy.orm import Session
  4. from app.core.bx_auth import BxUserContext, get_bx_current_user
  5. from app.core.database import get_db
  6. from app.core.tenant_context import get_tenant_no
  7. from app.schemas.bx.common import ApiResponse, PagedData
  8. from app.schemas.bx.workflow import (
  9. WorkflowDefCreate,
  10. WorkflowDefOut,
  11. WorkflowDefUpdate,
  12. WorkflowNodeCreate,
  13. )
  14. from app.services.bx.workflow import WorkflowService
  15. router = APIRouter(prefix="/workflows", tags=["工作流配置"])
  16. @router.get("/", response_model=ApiResponse[PagedData[WorkflowDefOut]])
  17. def list_workflows(
  18. page: int = 1,
  19. pageSize: int = Query(10, ge=1, le=500),
  20. db: Session = Depends(get_db),
  21. user: BxUserContext = Depends(get_bx_current_user),
  22. ):
  23. tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
  24. rows, total = WorkflowService.get_paged(db, tenant_no, page=page, page_size=pageSize, user=user)
  25. out_rows = [WorkflowDefOut.model_validate(r) for r in rows]
  26. paged_data = PagedData(rows=out_rows, total=total, page=page, page_size=pageSize)
  27. return ApiResponse(data=paged_data)
  28. @router.get("/biz/{biz_type}", response_model=ApiResponse[WorkflowDefOut])
  29. def get_workflow_by_biz_type(
  30. biz_type: str,
  31. db: Session = Depends(get_db),
  32. user: BxUserContext = Depends(get_bx_current_user),
  33. ):
  34. workflow = WorkflowService.ensure_by_biz_type(db, biz_type, user=user)
  35. if not workflow:
  36. return ApiResponse(data=None)
  37. return ApiResponse(data=WorkflowDefOut.model_validate(workflow))
  38. @router.get("/{workflow_id}", response_model=ApiResponse[WorkflowDefOut])
  39. def get_workflow(
  40. workflow_id: str,
  41. db: Session = Depends(get_db),
  42. user: BxUserContext = Depends(get_bx_current_user),
  43. ):
  44. tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
  45. workflow = WorkflowService.get_by_id(db, workflow_id, tenant_no, user=user)
  46. if not workflow:
  47. raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="工作流不存在")
  48. return ApiResponse(data=WorkflowDefOut.model_validate(workflow))
  49. @router.post("/", response_model=ApiResponse[WorkflowDefOut])
  50. def create_workflow(
  51. body: WorkflowDefCreate,
  52. db: Session = Depends(get_db),
  53. user: BxUserContext = Depends(get_bx_current_user),
  54. ):
  55. data = body.model_dump(exclude_unset=True)
  56. nodes_data = data.pop("nodes", []) or []
  57. workflow = WorkflowService.create(db, data, user=user)
  58. if nodes_data:
  59. try:
  60. WorkflowService.save_nodes(db, workflow.id, nodes_data, user=user)
  61. except ValueError as exc:
  62. db.rollback()
  63. code = (
  64. status.HTTP_404_NOT_FOUND
  65. if str(exc) == "工作流不存在"
  66. else status.HTTP_400_BAD_REQUEST
  67. )
  68. raise HTTPException(status_code=code, detail=str(exc)) from exc
  69. db.commit()
  70. db.refresh(workflow)
  71. return ApiResponse(data=WorkflowDefOut.model_validate(workflow))
  72. @router.put("/{workflow_id}", response_model=ApiResponse[WorkflowDefOut])
  73. def update_workflow(
  74. workflow_id: str,
  75. body: WorkflowDefUpdate,
  76. db: Session = Depends(get_db),
  77. user: BxUserContext = Depends(get_bx_current_user),
  78. ):
  79. tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
  80. data = body.model_dump(exclude_unset=True)
  81. nodes_data = data.pop("nodes", None)
  82. try:
  83. workflow = WorkflowService.update(db, workflow_id, data, user=user)
  84. except ValueError as exc:
  85. db.rollback()
  86. raise HTTPException(status_code=400, detail=str(exc)) from exc
  87. if not workflow:
  88. raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="工作流不存在")
  89. if nodes_data is not None:
  90. try:
  91. WorkflowService.save_nodes(db, workflow_id, nodes_data, user=user)
  92. except ValueError as exc:
  93. db.rollback()
  94. code = (
  95. status.HTTP_404_NOT_FOUND
  96. if str(exc) == "工作流不存在"
  97. else status.HTTP_400_BAD_REQUEST
  98. )
  99. raise HTTPException(status_code=code, detail=str(exc)) from exc
  100. db.commit()
  101. db.refresh(workflow)
  102. return ApiResponse(data=WorkflowDefOut.model_validate(workflow))
  103. @router.put("/{workflow_id}/nodes", response_model=ApiResponse[WorkflowDefOut])
  104. def save_workflow_nodes(
  105. workflow_id: str,
  106. body: List[WorkflowNodeCreate],
  107. db: Session = Depends(get_db),
  108. user: BxUserContext = Depends(get_bx_current_user),
  109. ):
  110. tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
  111. nodes_data = [n.model_dump(exclude_unset=True) for n in body]
  112. try:
  113. WorkflowService.save_nodes(db, workflow_id, nodes_data, user=user)
  114. except ValueError as exc:
  115. db.rollback()
  116. code = (
  117. status.HTTP_404_NOT_FOUND
  118. if str(exc) == "工作流不存在"
  119. else status.HTTP_400_BAD_REQUEST
  120. )
  121. raise HTTPException(status_code=code, detail=str(exc)) from exc
  122. workflow = WorkflowService.get_by_id(db, workflow_id, tenant_no, user=user)
  123. if not workflow:
  124. raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="工作流不存在")
  125. db.commit()
  126. db.refresh(workflow)
  127. return ApiResponse(data=WorkflowDefOut.model_validate(workflow))
  128. @router.delete("/{workflow_id}", response_model=ApiResponse[None])
  129. def delete_workflow(
  130. workflow_id: str,
  131. db: Session = Depends(get_db),
  132. user: BxUserContext = Depends(get_bx_current_user),
  133. ):
  134. tenant_no = get_tenant_no(db, user.to_tenant_user_dict())
  135. workflow = WorkflowService.get_by_id(db, workflow_id, tenant_no, user=user)
  136. if not workflow:
  137. raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="工作流不存在")
  138. try:
  139. WorkflowService.soft_delete(db, workflow_id, user=user)
  140. except ValueError as exc:
  141. db.rollback()
  142. raise HTTPException(status_code=400, detail=str(exc)) from exc
  143. db.commit()
  144. return ApiResponse(data=None)