Преглед изворни кода

feat(oa): expose bank-receipts GET/PUT with menu permission

Gate instance bank receipt APIs behind oa:done:bank-receipt.

Co-authored-by: Cursor <cursoragent@cursor.com>
zlwu пре 2 недеља
родитељ
комит
0402f797c0
1 измењених фајлова са 65 додато и 0 уклоњено
  1. 65 0
      backend/app/api/oa_approval.py

+ 65 - 0
backend/app/api/oa_approval.py

@@ -19,6 +19,7 @@ from app.services.oa_receive_account import normalize_account_fields
 router = APIRouter(prefix="/web/admin/oa-approval", tags=["OA审批"])
 
 OA_START_HISTORY_ALL_PERM = "oa:start:history:all"
+OA_DONE_BANK_RECEIPT_PERM = "oa:done:bank-receipt"
 
 
 def _get_tenant_no(db: Session, user: dict) -> str:
@@ -773,6 +774,19 @@ class OaCommentCreateBody(BaseModel):
     mention_user_ids: Optional[List[str]] = Field(None, alias="mentionUserIds")
 
 
+class OaBankReceiptItemBody(BaseModel):
+    model_config = ConfigDict(populate_by_name=True)
+    file_url: str = Field(..., alias="fileUrl")
+    file_name: Optional[str] = Field(None, alias="fileName")
+    file_type: Optional[str] = Field(None, alias="fileType")
+    file_size: Optional[int] = Field(None, alias="fileSize")
+
+
+class OaBankReceiptReplaceBody(BaseModel):
+    model_config = ConfigDict(populate_by_name=True)
+    items: List[OaBankReceiptItemBody] = Field(default_factory=list)
+
+
 class OaResubmitBody(BaseModel):
     model_config = ConfigDict(populate_by_name=True)
     form_data: Optional[Dict[str, Any]] = Field(None, alias="formData")
@@ -1032,6 +1046,57 @@ async def list_oa_instance_form_attachments(
         return error_response(400, str(e))
 
 
+@router.get("/instances/{instance_id}/bank-receipts")
+async def list_oa_bank_receipts(
+    instance_id: str,
+    user: dict = Depends(require_admin_or_super_admin),
+    db: Session = Depends(get_db),
+):
+    from app.core.menu_guard import user_has_menu_perm
+    from app.services import oa_bank_receipt as br
+
+    if not user_has_menu_perm(db, user, OA_DONE_BANK_RECEIPT_PERM):
+        return error_response(403, "无权上传银行回执单")
+    try:
+        tenant_no = _get_tenant_no(db, user)
+        items = br.list_bank_receipts(db, instance_id=instance_id, tenant_no=tenant_no)
+        return success_response({"items": items})
+    except br.OaBankReceiptError as e:
+        return error_response(400, str(e))
+
+
+@router.put("/instances/{instance_id}/bank-receipts")
+async def replace_oa_bank_receipts(
+    instance_id: str,
+    body: OaBankReceiptReplaceBody,
+    user: dict = Depends(require_admin_or_super_admin),
+    db: Session = Depends(get_db),
+):
+    from app.core.menu_guard import user_has_menu_perm
+    from app.services import oa_bank_receipt as br
+
+    if not user_has_menu_perm(db, user, OA_DONE_BANK_RECEIPT_PERM):
+        return error_response(403, "无权上传银行回执单")
+    try:
+        tenant_no = _get_tenant_no(db, user)
+        items = br.replace_bank_receipts(
+            db,
+            instance_id=instance_id,
+            tenant_no=tenant_no,
+            items=[it.model_dump(by_alias=True) for it in (body.items or [])],
+            user_id=user.get("user_id") or "",
+            dept_id=user.get("dept_id") or "",
+        )
+        db.commit()
+        return success_response({"items": items})
+    except br.OaBankReceiptError as e:
+        db.rollback()
+        return error_response(400, str(e))
+    except Exception:
+        db.rollback()
+        raise
+
+
 @router.get("/instances/{instance_id}/comments")
 async def list_oa_instance_comments(
     instance_id: str,