| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- import datetime
- import logging
- from fastapi import APIRouter, Depends, Query
- from typing import Any, Union, Optional
- from pydantic import ValidationError
- from alien_store.api.deps import get_contract_service
- from alien_store.schemas.request.contract_store import TemplatesCreate
- from alien_store.schemas.response.contract_store import (
- ModuleStatusResponse,
- TemplatesCreateResponse,
- ErrorResponse,
- ContractStoreResponse,
- PaginatedResponse,
- SuccessResponse
- )
- from alien_store.services.contract_server import ContractServer
- router = APIRouter()
- logger = logging.getLogger("alien_store")
- def _format_validation_errors(exc: ValidationError) -> list[dict[str, str]]:
- errors = []
- for err in exc.errors():
- loc = err.get("loc", ())
- field = ".".join(str(item) for item in loc if item != "body")
- errors.append(
- {
- "field": field or "body",
- "type": err.get("type", "validation_error"),
- "message": err.get("msg", "参数校验失败"),
- }
- )
- return errors
- @router.get("/", response_model=ModuleStatusResponse)
- async def index() -> ModuleStatusResponse:
- return ModuleStatusResponse(module="Contract", status="Ok")
- @router.post("/get_esign_templates", response_model=Union[TemplatesCreateResponse, ErrorResponse])
- async def create_esign_templates(
- templates_data_raw: dict[str, Any],
- templates_server: ContractServer = Depends(get_contract_service)
- ) -> Union[TemplatesCreateResponse, ErrorResponse]:
- """AI审核完调用 e签宝生成文件"""
- try:
- templates_data = TemplatesCreate.model_validate(templates_data_raw)
- except ValidationError as e:
- detail = _format_validation_errors(e)
- logger.error("get_esign_templates validation failed: %s", detail)
- return ErrorResponse(
- success=False,
- message="请求参数校验失败",
- raw={"errors": detail},
- )
- result = await templates_server.create_esign_templates(templates_data)
- if not result.get("success"):
- return ErrorResponse(**result)
-
- return TemplatesCreateResponse(**result)
- @router.get("/contracts/{store_id}", response_model=Union[dict, Any])
- async def list_contracts(
- store_id: int,
- status: Optional[int] = Query(None, description="筛选合同状态:0 未签署,1 已签署"),
- page: int = Query(1, ge=1, description="页码,从1开始"),
- page_size: int = Query(10, ge=1, le=100, description="每页条数,默认10"),
- templates_server: ContractServer = Depends(get_contract_service)
- ) -> Any:
- """根据 store_id 查询所有合同,支持根据 status 筛选和分页"""
- return await templates_server.list_contracts(store_id, status, page, page_size)
- @router.get("/contracts/detail/{sign_flow_id}", response_model=Union[dict, ErrorResponse])
- async def get_contract_detail(
- sign_flow_id: str,
- templates_server: ContractServer = Depends(get_contract_service)
- ) -> Union[dict, ErrorResponse]:
- """
- 根据 sign_flow_id 获取合同详情
- - status=0: 返回合同PDF链接(contract_url)和签署链接(sign_url)
- - status=1: 拉取最新下载链接并更新数据库,返回 contract_download_url
- """
- result = await templates_server.get_contract_detail(sign_flow_id)
- if not result.get("success", True): # get_contract_detail 返回的成功结果里没有 success 键,只有 status
- return ErrorResponse(**result)
- return result
- @router.get("/get_all_templates", response_model=PaginatedResponse)
- async def get_all_templates(
- page: int = Query(1, ge=1, description="页码,从1开始"),
- page_size: int = Query(10, ge=1, le=100, description="每页条数,默认10"),
- store_name: Optional[str] = Query(None, description="店铺名称(模糊查询)"),
- merchant_name: Optional[str] = Query(None, description="商家姓名(模糊查询)"),
- signing_status: Optional[str] = Query(None, description="签署状态"),
- business_segment: Optional[str] = Query(None, description="经营板块"),
- store_status: Optional[str] = Query(None, description="店铺状态:正常/禁用"),
- expiry_start: Optional[datetime.datetime] = Query(None, description="到期时间起"),
- expiry_end: Optional[datetime.datetime] = Query(None, description="到期时间止"),
- templates_server: ContractServer = Depends(get_contract_service)
- ) -> PaginatedResponse:
- """分页查询所有合同,支持筛选"""
- rows, total = await templates_server.list_all_paged(
- page,
- page_size,
- store_name=store_name,
- merchant_name=merchant_name,
- signing_status=signing_status,
- business_segment=business_segment,
- store_status=store_status,
- expiry_start=expiry_start,
- expiry_end=expiry_end,
- )
- total_pages = (total + page_size - 1) // page_size if total > 0 else 0
-
- items = [ContractStoreResponse(**row) for row in rows]
- return PaginatedResponse(
- items=items,
- total=total,
- page=page,
- page_size=page_size,
- total_pages=total_pages
- )
- @router.post("/esign/callback", response_model=Union[SuccessResponse, ErrorResponse])
- async def esign_callback(
- payload: dict,
- templates_server: ContractServer = Depends(get_contract_service)
- ) -> Union[SuccessResponse, ErrorResponse]:
- """
- e签宝签署结果回调
- 需求:签署完成 -> 更新 signing_status=已签署,contract_url 中 status=1
- """
- result = await templates_server.process_esign_callback(payload)
- if not result.get("success"):
- return ErrorResponse(**result)
- return SuccessResponse(code=result["code"], msg=result["msg"])
- # @router.post("/esign/callback_auth", response_model=SuccessResponse)
- # async def esign_callback_auth(
- # payload: dict,
- # templates_server: ContractServer = Depends(get_contract_service)
- # ) -> SuccessResponse:
- # logger.info(f"esign_callback_auth payload: {payload}")
- # return SuccessResponse(code="200", msg="success")
|