| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863 |
- """OA 审批管理接口(钉钉交互)"""
- from typing import Any, Dict, List, Optional
- from fastapi import APIRouter, Depends, Query
- from pydantic import BaseModel, ConfigDict, Field
- from sqlalchemy.orm import Session
- from app.core.database import get_db
- from app.core.menu_guard import require_admin_or_super_admin
- from app.core.response import error_response, success_response
- from app.crud import oa_approval as oa_crud
- from app.models.models import SysUser
- router = APIRouter(prefix="/web/admin/oa-approval", tags=["OA审批"])
- def _get_tenant_no(db: Session, user: dict) -> str:
- tenant = (user.get("tenant_no") or "").strip()
- if tenant:
- return tenant
- uid = user.get("user_id")
- if uid:
- row = db.query(SysUser).filter(SysUser.id == uid, SysUser.del_flag == 0).first()
- if row and row.tenant_no:
- return row.tenant_no
- return "zkxw"
- # ---------------------------------------------------------------------------
- # 工作流角色
- # ---------------------------------------------------------------------------
- class OaRoleCreateBody(BaseModel):
- model_config = ConfigDict(populate_by_name=True)
- role_name: str = Field(..., alias="roleName")
- role_code: str = Field(..., alias="roleCode")
- status: Optional[str] = Field("1")
- order_num: Optional[int] = Field(None, alias="orderNum")
- remark: Optional[str] = None
- class OaRoleUpdateBody(BaseModel):
- model_config = ConfigDict(populate_by_name=True)
- role_name: Optional[str] = Field(None, alias="roleName")
- status: Optional[str] = None
- order_num: Optional[int] = Field(None, alias="orderNum")
- remark: Optional[str] = None
- class OaRoleUsersBody(BaseModel):
- model_config = ConfigDict(populate_by_name=True)
- user_ids: List[str] = Field(default_factory=list, alias="userIds")
- @router.get("/roles")
- async def list_oa_roles(
- keyword: Optional[str] = None,
- status: Optional[str] = None,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- tenant_no = _get_tenant_no(db, user)
- items = oa_crud.list_roles(db, tenant_no=tenant_no, keyword=keyword, status=status)
- return success_response({"list": items})
- @router.post("/roles/ensure-presets")
- async def ensure_oa_role_presets(
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- tenant_no = _get_tenant_no(db, user)
- created = oa_crud.ensure_presets(db, tenant_no, user_id=user.get("user_id"))
- return success_response(
- {"createdCount": len(created)},
- message="预置角色已就绪",
- )
- @router.post("/roles")
- async def create_oa_role(
- body: OaRoleCreateBody,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- try:
- tenant_no = _get_tenant_no(db, user)
- obj = oa_crud.create_role(
- db,
- tenant_no=tenant_no,
- role_name=body.role_name,
- role_code=body.role_code,
- status=body.status or "1",
- order_num=body.order_num,
- remark=body.remark,
- user_id=user.get("user_id"),
- )
- return success_response(oa_crud._role_to_dict(obj), message="创建成功")
- except ValueError as e:
- return error_response(400, str(e))
- @router.put("/roles/{role_id}")
- async def update_oa_role(
- role_id: str,
- body: OaRoleUpdateBody,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- try:
- tenant_no = _get_tenant_no(db, user)
- payload: dict[str, Any] = body.model_dump(exclude_unset=True, by_alias=False)
- obj = oa_crud.update_role(
- db,
- role_id,
- tenant_no=tenant_no,
- role_name=payload.get("role_name"),
- status=payload.get("status"),
- order_num=payload.get("order_num"),
- remark=payload.get("remark"),
- user_id=user.get("user_id"),
- )
- return success_response(oa_crud._role_to_dict(obj), message="更新成功")
- except ValueError as e:
- return error_response(400, str(e))
- @router.delete("/roles/{role_id}")
- async def delete_oa_role(
- role_id: str,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- try:
- tenant_no = _get_tenant_no(db, user)
- oa_crud.delete_role(db, role_id, tenant_no=tenant_no, user_id=user.get("user_id"))
- return success_response(None, message="删除成功")
- except ValueError as e:
- return error_response(400, str(e))
- @router.get("/roles/{role_id}/users")
- async def list_oa_role_users(
- role_id: str,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- tenant_no = _get_tenant_no(db, user)
- if not oa_crud.get_role(db, role_id, tenant_no):
- return error_response(404, "角色不存在")
- return success_response({"list": oa_crud.list_role_users(db, role_id, tenant_no)})
- @router.put("/roles/{role_id}/users")
- async def replace_oa_role_users(
- role_id: str,
- body: OaRoleUsersBody,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- try:
- tenant_no = _get_tenant_no(db, user)
- oa_crud.replace_role_users(
- db,
- role_id,
- tenant_no=tenant_no,
- user_ids=body.user_ids,
- operator_id=user.get("user_id"),
- )
- return success_response(
- {"list": oa_crud.list_role_users(db, role_id, tenant_no)},
- message="成员已更新",
- )
- except ValueError as e:
- return error_response(400, str(e))
- # ---------------------------------------------------------------------------
- # 分组
- # ---------------------------------------------------------------------------
- class OaGroupCreateBody(BaseModel):
- model_config = ConfigDict(populate_by_name=True)
- group_name: str = Field(..., alias="groupName")
- order_num: Optional[int] = Field(None, alias="orderNum")
- remark: Optional[str] = None
- class OaGroupUpdateBody(BaseModel):
- model_config = ConfigDict(populate_by_name=True)
- group_name: Optional[str] = Field(None, alias="groupName")
- order_num: Optional[int] = Field(None, alias="orderNum")
- remark: Optional[str] = None
- @router.get("/groups")
- async def list_oa_groups(
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- tenant_no = _get_tenant_no(db, user)
- return success_response({"list": oa_crud.list_groups(db, tenant_no=tenant_no)})
- @router.post("/groups")
- async def create_oa_group(
- body: OaGroupCreateBody,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- try:
- tenant_no = _get_tenant_no(db, user)
- obj = oa_crud.create_group(
- db,
- tenant_no=tenant_no,
- group_name=body.group_name,
- order_num=body.order_num,
- remark=body.remark,
- user_id=user.get("user_id"),
- )
- return success_response(oa_crud._group_to_dict(obj), message="创建成功")
- except ValueError as e:
- return error_response(400, str(e))
- @router.put("/groups/{group_id}")
- async def update_oa_group(
- group_id: str,
- body: OaGroupUpdateBody,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- try:
- tenant_no = _get_tenant_no(db, user)
- payload = body.model_dump(exclude_unset=True, by_alias=False)
- obj = oa_crud.update_group(
- db,
- group_id,
- tenant_no=tenant_no,
- group_name=payload.get("group_name"),
- order_num=payload.get("order_num"),
- remark=payload.get("remark"),
- user_id=user.get("user_id"),
- )
- return success_response(oa_crud._group_to_dict(obj), message="更新成功")
- except ValueError as e:
- return error_response(400, str(e))
- @router.delete("/groups/{group_id}")
- async def delete_oa_group(
- group_id: str,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- try:
- tenant_no = _get_tenant_no(db, user)
- oa_crud.delete_group(db, group_id, tenant_no=tenant_no, user_id=user.get("user_id"))
- return success_response(None, message="删除成功")
- except ValueError as e:
- return error_response(400, str(e))
- # ---------------------------------------------------------------------------
- # 应用 / 草稿
- # ---------------------------------------------------------------------------
- class OaAppCreateBody(BaseModel):
- model_config = ConfigDict(populate_by_name=True)
- app_name: str = Field(..., alias="appName")
- group_id: Optional[str] = Field(None, alias="groupId")
- icon_url: Optional[str] = Field(None, alias="iconUrl")
- description: Optional[str] = None
- initiator_scope: Optional[str] = Field("all", alias="initiatorScope")
- initiator_user_ids: Optional[List[str]] = Field(None, alias="initiatorUserIds")
- admin_scope: Optional[str] = Field("all_oa_admin", alias="adminScope")
- admin_user_ids: Optional[List[str]] = Field(None, alias="adminUserIds")
- status: Optional[str] = "1"
- order_num: Optional[int] = Field(None, alias="orderNum")
- remark: Optional[str] = None
- class OaAppUpdateBody(BaseModel):
- model_config = ConfigDict(populate_by_name=True)
- app_name: Optional[str] = Field(None, alias="appName")
- group_id: Optional[str] = Field(None, alias="groupId")
- icon_url: Optional[str] = Field(None, alias="iconUrl")
- description: Optional[str] = None
- initiator_scope: Optional[str] = Field(None, alias="initiatorScope")
- initiator_user_ids: Optional[List[str]] = Field(None, alias="initiatorUserIds")
- admin_scope: Optional[str] = Field(None, alias="adminScope")
- admin_user_ids: Optional[List[str]] = Field(None, alias="adminUserIds")
- status: Optional[str] = None
- order_num: Optional[int] = Field(None, alias="orderNum")
- remark: Optional[str] = None
- class OaDraftSaveBody(BaseModel):
- model_config = ConfigDict(populate_by_name=True)
- basic: Optional[Dict[str, Any]] = None
- form_schema_json: Optional[Any] = Field(None, alias="formSchemaJson")
- flow_tree_json: Optional[Any] = Field(None, alias="flowTreeJson")
- advanced_settings_json: Optional[Any] = Field(None, alias="advancedSettingsJson")
- @router.get("/apps")
- async def list_oa_apps(
- groupId: Optional[str] = None,
- keyword: Optional[str] = None,
- status: Optional[str] = None,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- tenant_no = _get_tenant_no(db, user)
- items = oa_crud.list_apps(
- db, tenant_no=tenant_no, group_id=groupId, keyword=keyword, status=status
- )
- return success_response({"list": items})
- @router.post("/apps")
- async def create_oa_app(
- body: OaAppCreateBody,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- try:
- tenant_no = _get_tenant_no(db, user)
- obj = oa_crud.create_app(
- db,
- tenant_no=tenant_no,
- app_name=body.app_name,
- group_id=body.group_id,
- icon_url=body.icon_url,
- description=body.description,
- initiator_scope=body.initiator_scope or "all",
- initiator_user_ids=body.initiator_user_ids,
- admin_scope=body.admin_scope or "all_oa_admin",
- admin_user_ids=body.admin_user_ids,
- status=body.status or "1",
- order_num=body.order_num,
- remark=body.remark,
- user_id=user.get("user_id"),
- )
- group_name = ""
- if obj.group_id:
- g = oa_crud.get_group(db, obj.group_id, tenant_no)
- group_name = g.group_name if g else ""
- return success_response(
- oa_crud._app_to_dict(obj, group_name=group_name, has_draft=True),
- message="创建成功",
- )
- except ValueError as e:
- return error_response(400, str(e))
- @router.put("/apps/{app_id}")
- async def update_oa_app(
- app_id: str,
- body: OaAppUpdateBody,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- try:
- tenant_no = _get_tenant_no(db, user)
- payload = body.model_dump(exclude_unset=True, by_alias=False)
- obj = oa_crud.update_app(db, app_id, tenant_no=tenant_no, user_id=user.get("user_id"), **payload)
- group_name = ""
- if obj.group_id:
- g = oa_crud.get_group(db, obj.group_id, tenant_no)
- group_name = g.group_name if g else ""
- return success_response(oa_crud._app_to_dict(obj, group_name=group_name), message="更新成功")
- except ValueError as e:
- return error_response(400, str(e))
- @router.delete("/apps/{app_id}")
- async def delete_oa_app(
- app_id: str,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- try:
- tenant_no = _get_tenant_no(db, user)
- oa_crud.delete_app(db, app_id, tenant_no=tenant_no, user_id=user.get("user_id"))
- return success_response(None, message="删除成功")
- except ValueError as e:
- return error_response(400, str(e))
- @router.get("/apps/{app_id}/draft")
- async def get_oa_app_draft(
- app_id: str,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- try:
- tenant_no = _get_tenant_no(db, user)
- data = oa_crud.get_or_create_draft(
- db, app_id, tenant_no=tenant_no, user_id=user.get("user_id")
- )
- return success_response(data)
- except ValueError as e:
- return error_response(400, str(e))
- @router.put("/apps/{app_id}/draft")
- async def save_oa_app_draft(
- app_id: str,
- body: OaDraftSaveBody,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- try:
- tenant_no = _get_tenant_no(db, user)
- data = oa_crud.save_draft(
- db,
- app_id,
- tenant_no=tenant_no,
- basic=body.basic,
- form_schema_json=body.form_schema_json,
- flow_tree_json=body.flow_tree_json,
- advanced_settings_json=body.advanced_settings_json,
- user_id=user.get("user_id"),
- )
- return success_response(data, message="草稿已保存")
- except ValueError as e:
- return error_response(400, str(e))
- @router.post("/apps/{app_id}/publish")
- async def publish_oa_app(
- app_id: str,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- from app.services.oa_publish import publish_app
- tenant_no = _get_tenant_no(db, user)
- data, errors = publish_app(
- db, app_id, tenant_no=tenant_no, user_id=user.get("user_id")
- )
- if errors:
- return error_response(400, "发布校验未通过", data={"errors": errors})
- return success_response(data, message="发布成功")
- # ---------------------------------------------------------------------------
- # 运行时:模板 / 实例 / 任务
- # ---------------------------------------------------------------------------
- class OaStartInstanceBody(BaseModel):
- model_config = ConfigDict(populate_by_name=True)
- app_id: str = Field(..., alias="appId")
- form_data: Optional[Dict[str, Any]] = Field(None, alias="formData")
- title: Optional[str] = None
- initiator_dept_id: Optional[str] = Field(None, alias="initiatorDeptId")
- initiator_select_by_node: Optional[Dict[str, List[str]]] = Field(
- None, alias="initiatorSelectByNode"
- )
- related_instance_ids: Optional[List[str]] = Field(None, alias="relatedInstanceIds")
- source_instance_id: Optional[str] = Field(None, alias="sourceInstanceId")
- class OaFlowPreviewBody(BaseModel):
- model_config = ConfigDict(populate_by_name=True)
- form_data: Optional[Dict[str, Any]] = Field(None, alias="formData")
- initiator_select_by_node: Optional[Dict[str, List[str]]] = Field(
- None, alias="initiatorSelectByNode"
- )
- class OaTaskActionBody(BaseModel):
- model_config = ConfigDict(populate_by_name=True)
- comment: Optional[str] = None
- class OaAddSignBody(BaseModel):
- model_config = ConfigDict(populate_by_name=True)
- user_ids: List[str] = Field(default_factory=list, alias="userIds")
- comment: Optional[str] = None
- class OaTransferBody(BaseModel):
- model_config = ConfigDict(populate_by_name=True)
- target_user_id: str = Field(..., alias="targetUserId")
- comment: Optional[str] = None
- class OaResubmitBody(BaseModel):
- model_config = ConfigDict(populate_by_name=True)
- form_data: Optional[Dict[str, Any]] = Field(None, alias="formData")
- initiator_select_by_node: Optional[Dict[str, List[str]]] = Field(
- None, alias="initiatorSelectByNode"
- )
- @router.get("/templates")
- async def list_oa_templates(
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- from app.services import oa_engine
- tenant_no = _get_tenant_no(db, user)
- items = oa_engine.list_templates(db, tenant_no=tenant_no, user_id=user.get("user_id") or "")
- return success_response({"list": items})
- @router.get("/templates/{app_id}")
- async def get_oa_template(
- app_id: str,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- from app.services.oa_engine import OaEngineError, get_template_detail
- try:
- tenant_no = _get_tenant_no(db, user)
- data = get_template_detail(
- db,
- tenant_no=tenant_no,
- app_id=app_id,
- user_id=user.get("user_id") or "",
- )
- return success_response(data)
- except OaEngineError as e:
- return error_response(400, str(e))
- @router.post("/templates/{app_id}/flow-preview")
- async def preview_oa_template_flow(
- app_id: str,
- body: OaFlowPreviewBody,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- """发起前预览审批链(条件齐后解析最终路径与审批人)。"""
- from app.services.oa_engine import OaEngineError, preview_start_flow
- try:
- tenant_no = _get_tenant_no(db, user)
- uid = user.get("user_id") or ""
- dept_id = None
- if uid:
- row = db.query(SysUser).filter(SysUser.id == uid, SysUser.del_flag == 0).first()
- if row:
- dept_id = row.dept_id
- data = preview_start_flow(
- db,
- tenant_no=tenant_no,
- app_id=app_id,
- initiator_user_id=uid,
- initiator_dept_id=dept_id,
- initiator_select_by_node=body.initiator_select_by_node,
- form_data=body.form_data,
- )
- return success_response(data)
- except OaEngineError as e:
- return error_response(400, str(e))
- @router.get("/templates/{app_id}/flow-preview")
- async def preview_oa_template_flow_get(
- app_id: str,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- """兼容旧 GET:无 formData,含条件分支时多为待确定占位。"""
- from app.services.oa_engine import OaEngineError, preview_start_flow
- try:
- tenant_no = _get_tenant_no(db, user)
- uid = user.get("user_id") or ""
- dept_id = None
- if uid:
- row = db.query(SysUser).filter(SysUser.id == uid, SysUser.del_flag == 0).first()
- if row:
- dept_id = row.dept_id
- data = preview_start_flow(
- db,
- tenant_no=tenant_no,
- app_id=app_id,
- initiator_user_id=uid,
- initiator_dept_id=dept_id,
- initiator_select_by_node=None,
- form_data=None,
- )
- return success_response(data)
- except OaEngineError as e:
- return error_response(400, str(e))
- @router.post("/instances")
- async def start_oa_instance(
- body: OaStartInstanceBody,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- from app.services.oa_engine import OaEngineError, start_instance
- try:
- tenant_no = _get_tenant_no(db, user)
- data = start_instance(
- db,
- tenant_no=tenant_no,
- app_id=body.app_id,
- initiator_user_id=user.get("user_id") or "",
- initiator_dept_id=body.initiator_dept_id,
- form_data=body.form_data,
- title=body.title,
- initiator_select_by_node=body.initiator_select_by_node,
- related_instance_ids=body.related_instance_ids,
- source_instance_id=body.source_instance_id,
- )
- return success_response(data, message="发起成功")
- except OaEngineError as e:
- return error_response(400, str(e))
- @router.get("/instances/{instance_id}")
- async def get_oa_instance(
- instance_id: str,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- from app.services.oa_engine import OaEngineError, get_instance_detail
- try:
- tenant_no = _get_tenant_no(db, user)
- return success_response(get_instance_detail(db, instance_id, tenant_no=tenant_no))
- except OaEngineError as e:
- return error_response(400, str(e))
- @router.get("/related-candidates")
- async def list_related_candidates(
- keyword: str = Query(""),
- page: int = Query(1),
- pageSize: int = Query(20, alias="pageSize"),
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- from app.services import oa_related_approval as rel
- tenant_no = _get_tenant_no(db, user)
- data = rel.list_related_candidates(
- db,
- tenant_no=tenant_no,
- user_id=user.get("user_id") or "",
- keyword=keyword,
- page=page,
- page_size=pageSize,
- )
- return success_response(data)
- @router.get("/related-summaries")
- async def get_related_summaries(
- ids: str = Query("", description="comma-separated instance ids"),
- mode: str = Query("picker"),
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- from app.services import oa_related_approval as rel
- from app.services.oa_engine import OaEngineError
- tenant_no = _get_tenant_no(db, user)
- id_list = [x.strip() for x in (ids or "").split(",") if x.strip()]
- try:
- items = rel.build_related_summaries(
- db,
- tenant_no=tenant_no,
- user_id=user.get("user_id") or "",
- ids=id_list,
- mode=mode,
- )
- except OaEngineError as e:
- return error_response(400, str(e))
- return success_response({"list": items})
- @router.get("/tasks/{kind}")
- async def list_oa_tasks(
- kind: str,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- from app.services.oa_engine import OaEngineError, list_tasks
- try:
- tenant_no = _get_tenant_no(db, user)
- items = list_tasks(
- db, tenant_no=tenant_no, user_id=user.get("user_id") or "", kind=kind
- )
- return success_response({"list": items})
- except OaEngineError as e:
- return error_response(400, str(e))
- @router.post("/tasks/{task_id}/approve")
- async def approve_oa_task(
- task_id: str,
- body: Optional[OaTaskActionBody] = None,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- from app.services.oa_engine import OaEngineError, complete_task
- try:
- tenant_no = _get_tenant_no(db, user)
- data = complete_task(
- db,
- task_id,
- tenant_no=tenant_no,
- user_id=user.get("user_id") or "",
- action="approve",
- comment=(body.comment if body else None),
- )
- return success_response(data, message="已同意")
- except OaEngineError as e:
- return error_response(400, str(e))
- @router.post("/tasks/{task_id}/reject")
- async def reject_oa_task(
- task_id: str,
- body: Optional[OaTaskActionBody] = None,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- from app.services.oa_engine import OaEngineError, complete_task
- try:
- tenant_no = _get_tenant_no(db, user)
- data = complete_task(
- db,
- task_id,
- tenant_no=tenant_no,
- user_id=user.get("user_id") or "",
- action="reject",
- comment=(body.comment if body else None),
- )
- return success_response(data, message="已拒绝")
- except OaEngineError as e:
- return error_response(400, str(e))
- @router.post("/tasks/{task_id}/return")
- async def return_oa_task(
- task_id: str,
- body: Optional[OaTaskActionBody] = None,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- from app.services.oa_engine import OaEngineError, return_task
- try:
- tenant_no = _get_tenant_no(db, user)
- data = return_task(
- db,
- task_id,
- tenant_no=tenant_no,
- user_id=user.get("user_id") or "",
- comment=(body.comment if body else None),
- )
- return success_response(data, message="已打回")
- except OaEngineError as e:
- return error_response(400, str(e))
- @router.post("/instances/{instance_id}/resubmit")
- async def resubmit_oa_instance(
- instance_id: str,
- body: Optional[OaResubmitBody] = None,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- from app.services.oa_engine import OaEngineError, resubmit_instance
- try:
- tenant_no = _get_tenant_no(db, user)
- data = resubmit_instance(
- db,
- instance_id,
- tenant_no=tenant_no,
- user_id=user.get("user_id") or "",
- form_data=(body.form_data if body else None),
- initiator_select_by_node=(body.initiator_select_by_node if body else None),
- )
- return success_response(data, message="已再次提交")
- except OaEngineError as e:
- return error_response(400, str(e))
- @router.post("/tasks/{task_id}/add-sign")
- async def add_sign_oa_task(
- task_id: str,
- body: OaAddSignBody,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- from app.services.oa_engine import OaEngineError, add_sign
- try:
- tenant_no = _get_tenant_no(db, user)
- data = add_sign(
- db,
- task_id,
- tenant_no=tenant_no,
- user_id=user.get("user_id") or "",
- user_ids=body.user_ids,
- comment=body.comment,
- )
- return success_response(data, message="加签成功")
- except OaEngineError as e:
- return error_response(400, str(e))
- @router.post("/tasks/{task_id}/transfer")
- async def transfer_oa_task(
- task_id: str,
- body: OaTransferBody,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- from app.services.oa_engine import OaEngineError, transfer_task
- try:
- tenant_no = _get_tenant_no(db, user)
- data = transfer_task(
- db,
- task_id,
- tenant_no=tenant_no,
- user_id=user.get("user_id") or "",
- target_user_id=body.target_user_id,
- comment=body.comment,
- )
- return success_response(data, message="已转交")
- except OaEngineError as e:
- return error_response(400, str(e))
- @router.post("/instances/{instance_id}/withdraw")
- async def withdraw_oa_instance(
- instance_id: str,
- user: dict = Depends(require_admin_or_super_admin),
- db: Session = Depends(get_db),
- ):
- from app.services.oa_engine import OaEngineError, withdraw_instance
- try:
- tenant_no = _get_tenant_no(db, user)
- data = withdraw_instance(
- db, instance_id, tenant_no=tenant_no, user_id=user.get("user_id") or ""
- )
- return success_response(data, message="已撤销")
- except OaEngineError as e:
- return error_response(400, str(e))
|