190 lines
7.6 KiB
Python
190 lines
7.6 KiB
Python
"""
|
||
推送接口通用schema
|
||
|
||
## 响应相关
|
||
1. BaseResponseSchema: 所有接口响应的基础schema
|
||
2. BasePushResponseSchema: 推送接口响应的基础schema,包含push_id
|
||
3. PushResultSchema: 查询推送结果的schema
|
||
|
||
## 请求相关
|
||
4. BaseCreateRequestSchema[T]: 创建资源的基础请求schema(泛型),业务数据在data字段
|
||
5. BaseUpdateRequestSchema[T]: 更新资源的基础请求schema(泛型),业务数据在data字段
|
||
6. BaseDeleteRequestSchema: 删除资源的基础请求schema,只需resource_id
|
||
7. BulkPushRequestSchema: 批量推送请求的schema
|
||
|
||
## 说明
|
||
- 所有元数据字段(timestamp, nonce, signature, uid, push_id)在请求体最外层
|
||
- push_id使用UUIDv7格式,支持时间排序,同时作为幂等键和查询键
|
||
- 业务数据嵌套在data字段中(删除操作除外,只需resource_id)
|
||
- 所有业务Schema必须继承BasePushData,确保包含project_type字段
|
||
- resource_id在外层,用于标识要操作的资源(更新/删除时必填)
|
||
- 使用泛型T可快速定义各业务的请求schema,T必须继承BasePushData
|
||
"""
|
||
|
||
from pydantic import BaseModel, Field
|
||
from typing import TypeVar, Generic, Optional, List, Dict, Any
|
||
from ..project.enums import ProjectType
|
||
from datetime import datetime
|
||
# from backend.modules.admin.approval.models import ApprovalStep
|
||
|
||
|
||
class ApprovalStep(BaseModel):
|
||
"""审批流程中的一个步骤"""
|
||
step_id: str = Field(description="步骤的唯一ID")
|
||
operator_id: Optional[str] = Field("",description="操作人ID")
|
||
operator_name: str = Field(description="操作人姓名")
|
||
action: str = Field(description="执行的动作,如 'submit', 'approve', 'reject'")
|
||
comment: Optional[str] = Field(None, description="审批意见")
|
||
created_at: datetime = Field(default_factory=datetime.utcnow, description="步骤的创建时间")
|
||
# 定义泛型
|
||
T = TypeVar('T', bound='BasePushData')
|
||
|
||
# ==================== 业务数据基类 ====================
|
||
|
||
class BasePushData(BaseModel):
|
||
"""
|
||
所有推送业务数据的基类
|
||
|
||
所有业务Schema必须继承此类,确保包含project_type字段
|
||
"""
|
||
project_type: ProjectType = Field(..., description="项目类型:offshore_wind/pumped_storage/photovoltaic等")
|
||
|
||
|
||
# ==================== Mixin ====================
|
||
|
||
class SignatureMixin(BaseModel):
|
||
"""签名字段混入"""
|
||
timestamp: int = Field(..., description="毫秒级 Unix 时间戳")
|
||
nonce: str = Field(..., description="随机字符串,防止重放攻击")
|
||
sign: str = Field(..., description="签名字符串")
|
||
uid: str = Field(..., description="集团侧用户id")
|
||
|
||
|
||
class PushRequestMixin(BaseModel):
|
||
"""推送ID字段混入"""
|
||
push_id: str = Field(..., description="推送ID,客户端生成的唯一标识(UUIDv7,支持时间排序)")
|
||
steps : List[ApprovalStep] =Field(default_factory=list,description="当前数据的审批流程步骤") # 加入字段step用来记录审批流程
|
||
|
||
# ==================== 响应相关 ====================
|
||
|
||
class BaseResponseSchema(BaseModel):
|
||
"""所有接口响应的基础schema"""
|
||
code: int = 200
|
||
message: Optional[str] = "OK"
|
||
data: Optional[T] = None
|
||
|
||
|
||
class BasePushResponseSchema(BaseModel):
|
||
"""推送接口响应的基础schema"""
|
||
biz_id: str | None = Field(None, description="资源ID(create操作成功后返回新创建的ID,update/delete返回原ID)")
|
||
|
||
|
||
class PushResultSchema(BaseModel):
|
||
"""查询推送结果的schema"""
|
||
push_id: str = Field(..., description="推送ID(客户端生成的UUIDv7)")
|
||
status: str = Field(..., description="推送状态:queued/processing/success/failed")
|
||
result: Dict[str, Any] | None = Field(None, description="处理结果(成功时包含created_id等信息)")
|
||
error: str | None = Field(None, description="错误信息(失败时)")
|
||
created_at: str = Field(..., description="推送创建时间(ISO 8601格式)")
|
||
updated_at: str = Field(..., description="推送更新时间(ISO 8601格式)")
|
||
|
||
|
||
class PushIdsSchema(BaseModel):
|
||
"""支持从请求体接收的 push_ids 列表字符串(逗号拼接)"""
|
||
push_ids: Optional[str] = Field(None, description="推送id字符串逗号拼接")
|
||
|
||
|
||
# ==================== 请求相关 ====================
|
||
|
||
class BaseCreateRequestSchema(SignatureMixin, PushRequestMixin, BaseModel, Generic[T]):
|
||
"""
|
||
创建资源的基础请求schema(泛型)
|
||
|
||
泛型T必须继承BasePushData,确保包含project_type字段
|
||
|
||
使用示例:
|
||
class ProjectInputSchema(BasePushData):
|
||
name: str = Field(...)
|
||
capacity: float = Field(...)
|
||
|
||
class ProjectCreateRequest(BaseCreateRequestSchema[ProjectInputSchema]):
|
||
pass
|
||
"""
|
||
# 业务数据(嵌套)
|
||
data: T = Field(..., description="业务数据")
|
||
|
||
|
||
class BaseUpdateRequestSchema(SignatureMixin, PushRequestMixin, BaseModel, Generic[T]):
|
||
"""
|
||
更新资源的基础请求schema(泛型)
|
||
|
||
泛型T必须继承BasePushData,确保包含project_type字段
|
||
resource_id在外层,用于标识要更新的资源
|
||
|
||
使用示例:
|
||
class ProjectInputSchema(BasePushData):
|
||
name: str = Field(...)
|
||
capacity: float = Field(...)
|
||
|
||
class ProjectUpdateRequest(BaseUpdateRequestSchema[ProjectInputSchema]):
|
||
pass
|
||
"""
|
||
# 资源标识
|
||
biz_id: str = Field(..., description="要更新的资源ID,类型id,如project传project_id,unit传unit_id")
|
||
|
||
# 业务数据(嵌套)
|
||
data: T = Field(..., description="业务数据(只需包含要更新的字段)")
|
||
|
||
|
||
class BaseDeleteRequestSchema(SignatureMixin, PushRequestMixin, BaseModel):
|
||
"""
|
||
删除资源的基础请求schema
|
||
|
||
使用示例:
|
||
class ProjectDeleteRequest(BaseDeleteRequestSchema):
|
||
pass
|
||
"""
|
||
|
||
# 资源标识
|
||
biz_id: str = Field(..., description="要删除的资源ID")
|
||
|
||
|
||
class BulkPushItem(PushRequestMixin, BaseModel):
|
||
"""
|
||
批量推送中的单个项目
|
||
|
||
注意:
|
||
- action为create时:data必填,resource_id留空
|
||
- action为update时:data和resource_id都必填
|
||
- action为delete时:resource_id必填,data留空
|
||
- data必须继承BasePushData,确保包含project_type字段
|
||
"""
|
||
action: str = Field(..., description="操作类型:create/update/delete")
|
||
resource_id: str | None = Field(None, description="资源ID(update/delete时必填,create时留空)")
|
||
data: BasePushData | None = Field(None, description="业务数据(create/update时必填,delete时留空,必须包含project_type字段)")
|
||
|
||
|
||
class BulkPushItemResult(BaseModel):
|
||
"""批量推送中单个项目的处理结果"""
|
||
push_id: str = Field(..., description="推送ID(对应请求中的push_id)")
|
||
status: str = Field(..., description="处理状态:queued/processing/success/failed")
|
||
resource_id: str | None = Field(None, description="资源ID(create成功时返回新ID,update/delete返回原ID)")
|
||
error: str | None = Field(None, description="错误信息(失败时)")
|
||
|
||
|
||
class BulkPushRequestSchema(SignatureMixin, BaseModel):
|
||
"""
|
||
批量推送请求的schema
|
||
|
||
一次请求可推送多条数据,每条都有独立的幂等键和操作类型
|
||
"""
|
||
# 批量数据
|
||
items: List[BulkPushItem] = Field(..., description="批量推送的数据列表")
|
||
|
||
|
||
class BulkPushResponseSchema(BaseResponseSchema):
|
||
"""批量推送响应的schema"""
|
||
batch_id: str = Field(..., description="批量推送的批次ID")
|
||
total: int = Field(..., description="总数量")
|
||
results: List[BulkPushItemResult] = Field(..., description="每条数据的处理结果,包含push_id和resource_id")
|