| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- """请假申请 API — 工作流测试"""
- from __future__ import annotations
- import logging
- from typing import Optional
- from fastapi import APIRouter, Depends, Query
- from sqlalchemy.orm import Session
- from app.core.menu_guard import require_admin_or_super_admin
- from app.core.database import get_db
- from app.core.response import success_response, error_response
- from app.crud import leave as leave_crud
- from app.crud.leave import total_pages
- from app.schemas.leave import LeaveCreate, LeaveUpdate
- logger = logging.getLogger(__name__)
- router = APIRouter(prefix="/web/admin/leave", tags=["请假管理"])
- _LEAVE_TYPE_MAP = {"personal": "事假", "sick": "病假", "annual": "年假", "other": "其他"}
- def _leave_local_callback(db: Session, business_id: str, event: str) -> None:
- if not business_id:
- return
- if event == "completed":
- leave_crud.update_leave_status(db, business_id, "approved")
- elif event == "rejected":
- leave_crud.update_leave_status(db, business_id, "rejected")
- db.commit()
- from app.services.workflow_callback import register_local_callback
- register_local_callback("/api/admin/leave/callback", _leave_local_callback)
- @router.get("")
- def list_leaves(
- page: int = Query(1, ge=1),
- pageSize: int = Query(10, ge=1, le=100),
- keyword: Optional[str] = Query(None),
- status: Optional[str] = Query(None),
- _user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- tenant_no = _user.get("tenant_no", "")
- user_id = _user.get("user_id") or _user.get("id", "")
- items, total = leave_crud.list_leaves(
- db, page=page, page_size=pageSize, keyword=keyword, status=status,
- tenant_no=tenant_no, create_by=user_id, user_info=_user,
- )
- for item in items:
- item["leaveTypeLabel"] = _LEAVE_TYPE_MAP.get(item.get("leaveType", ""), item.get("leaveType", ""))
- return success_response({
- "list": items, "total": total, "page": page, "pageSize": pageSize,
- "totalPages": total_pages(total, pageSize),
- })
- @router.post("")
- def create_leave(
- body: LeaveCreate,
- _user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- tenant_no = _user.get("tenant_no", "")
- user_id = _user.get("user_id") or _user.get("id", "")
- dept_id = _user.get("region_id", "")
- row = leave_crud.create_leave(
- db,
- leave_type=body.leaveType,
- start_date=body.startDate,
- end_date=body.endDate,
- days=body.days,
- reason=body.reason or "",
- tenant_no=tenant_no,
- user_id=user_id,
- dept_id=dept_id,
- remark=body.remark or "",
- )
- db.commit()
- return success_response(leave_crud._row_to_dict(row))
- @router.post("/{leave_id}/submit")
- def submit_leave(
- leave_id: str,
- _user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- from app.models.models import WfProcessDef
- from app.services.workflow_engine import WorkflowEngine
- tenant_no = _user.get("tenant_no", "")
- user_id = _user.get("user_id") or _user.get("id", "")
- leave = leave_crud.get_leave(db, leave_id)
- if not leave:
- return error_response(404, "请假记录不存在")
- if leave["status"] not in ("draft", "rejected"):
- return error_response(400, "只有草稿或已驳回的请假单可以提交")
- defn = db.query(WfProcessDef).filter(
- WfProcessDef.process_code == "leave_request",
- WfProcessDef.del_flag == 0,
- WfProcessDef.status == "1",
- ).first()
- if not defn:
- return error_response(400, "未找到请假审批流程(leave_request),请先在流程配置中创建并发布")
- variables = {
- "days": leave["days"],
- "leave_days": leave["days"],
- "leaveType": leave["leaveType"],
- "applicant": user_id,
- }
- try:
- engine = WorkflowEngine(db)
- instance = engine.start_process(
- process_def_id=defn.id,
- business_type="leave",
- business_id=leave_id,
- starter_user_id=user_id,
- variables=variables,
- callback_url="/api/admin/leave/callback",
- tenant_no=tenant_no,
- user_id=user_id,
- )
- leave_crud.update_leave_status(db, leave_id, "pending", wf_instance_id=instance.id, user_id=user_id)
- db.commit()
- return success_response({"instanceId": instance.id, "status": "pending"})
- except Exception as e:
- db.rollback()
- logger.exception("发起请假审批失败: %s", e)
- return error_response(500, f"发起审批失败: {e}")
- @router.post("/callback")
- def leave_workflow_callback(
- body: dict,
- db: Session = Depends(get_db),
- ):
- logger.info("请假工作流回调: %s", body)
- business_id = body.get("businessId", "")
- event = body.get("event", "")
- if not business_id:
- return success_response({"received": True})
- if event == "completed":
- leave_crud.update_leave_status(db, business_id, "approved")
- elif event == "rejected":
- leave_crud.update_leave_status(db, business_id, "rejected")
- db.commit()
- return success_response({"received": True})
- @router.get("/{leave_id}")
- def get_leave(
- leave_id: str,
- _user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- item = leave_crud.get_leave(db, leave_id)
- if not item:
- return error_response(404, "请假记录不存在")
- item["leaveTypeLabel"] = _LEAVE_TYPE_MAP.get(item.get("leaveType", ""), item.get("leaveType", ""))
- return success_response(item)
- @router.delete("/{leave_id}")
- def delete_leave(
- leave_id: str,
- _user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- user_id = _user.get("user_id") or _user.get("id", "")
- leave = leave_crud.get_leave(db, leave_id)
- if not leave:
- return error_response(404, "请假记录不存在")
- if leave["status"] == "pending":
- return error_response(400, "审批中的请假单不能删除")
- leave_crud.soft_delete_leave(db, leave_id, user_id=user_id, user_info=_user)
- db.commit()
- return success_response(None)
- @router.put("/{leave_id}")
- def update_leave(
- leave_id: str,
- body: LeaveUpdate,
- _user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- user_id = _user.get("user_id") or _user.get("id", "")
- leave = leave_crud.get_leave(db, leave_id)
- if not leave:
- return error_response(404, "请假记录不存在")
- if leave["status"] not in ("draft", "rejected"):
- return error_response(400, "只有草稿或已驳回状态可以编辑")
- leave_crud.update_leave(db, leave_id, user_id=user_id, **body.model_dump(exclude_none=True))
- db.commit()
- return success_response(leave_crud.get_leave(db, leave_id))
|