Files
FastapiAdmin/backend/app/modules/task/storage/transfer/schema.py
T
zhangtao 9e80f970d0 refactor(task): 重构定时任务与存储路由
- 移除各路由文件顶部冗余注释
- 将 JobRouter/NodeRouter 重命名为 CornJobRouter/CornJobNodeRouter
- 新增存储浏览、节点、传输、工作流路由注册
- 调整路由导入来源与任务表名
- 优化 main.py 启动方式及环境配置加载
2026-09-06 04:14:17 +08:00

136 lines
7.2 KiB
Python

from datetime import datetime
from typing import Literal
from pydantic import BaseModel, ConfigDict, Field, model_validator
from app.core.base_schema import BaseQueryParam, BaseSchema
TransferStatus = Literal["pending", "running", "success", "failed", "canceled"]
TransferTaskType = Literal["parallel", "chain"]
TransferSourceType = Literal["local", "remote"]
TransferMode = Literal["stream", "multipart"]
class TransferTargetSchema(BaseModel):
"""传输目标配置"""
target_id: int = Field(..., ge=1, description="目标存储源ID")
target_path: str = Field(..., min_length=1, max_length=1024, description="目标路径")
class TransferTaskCreateSchema(BaseModel):
"""创建传输任务(远端源,JSON 提交)"""
name: str = Field(..., min_length=1, max_length=128, description="任务名称")
task_type: TransferTaskType = Field(..., description="任务类型(parallel:多目标 chain:链式)")
source_type: TransferSourceType = Field(default="remote", description="源类型(local:本地 remote:远端)")
source_id: int | None = Field(default=None, ge=1, description="源存储源ID(remote 必填)")
source_path: str | None = Field(default=None, min_length=1, max_length=1024, description="源远端路径(remote 必填)")
targets: list[TransferTargetSchema] = Field(..., min_length=1, description="目标列表(顺序即链式执行顺序)")
transfer_mode: TransferMode | None = Field(default=None, description="传输方式(stream:流式 multipart:分片;空=用存储源默认)")
multipart_part_size: int | None = Field(default=None, ge=5, le=5000, description="分片大小(MB,分片传输时覆盖存储源配置)")
multipart_concurrency: int | None = Field(default=None, ge=1, le=64, description="分片上传并发路数(分片传输时覆盖存储源配置)")
@model_validator(mode="after")
def validate_source(self):
if self.source_type == "remote" and not self.source_id:
raise ValueError("远端源必须指定源存储源 source_id")
if self.source_type == "remote" and not self.source_path:
raise ValueError("远端源必须指定源路径 source_path")
return self
class LocalUploadInfoSchema(BaseModel):
"""本地源上传文件信息(服务端临时文件)"""
source_path: str = Field(..., description="服务端临时文件路径")
source_name: str = Field(..., description="原始文件名")
source_size: int = Field(..., ge=0, description="文件大小(字节)")
class TransferTaskStoreSchema(BaseModel):
"""传输任务落库模型(create 展开明细后持久化)"""
name: str = Field(..., min_length=1, max_length=128, description="任务名称")
task_type: TransferTaskType = Field(..., description="任务类型")
source_type: TransferSourceType = Field(default="remote", description="源类型")
source_id: int | None = Field(default=None, ge=1, description="源存储源ID")
source_path: str | None = Field(default=None, max_length=1024, description="源路径")
source_name: str | None = Field(default=None, max_length=255, description="源文件名")
source_size: int | None = Field(default=None, ge=0, description="源文件大小")
status: TransferStatus = Field(default="pending", description="状态")
class TransferStepCreateSchema(BaseModel):
"""传输步骤落库模型(由目标列表展开)"""
step_order: int = Field(..., ge=0, description="步骤序号")
source_id: int | None = Field(default=None, ge=1, description="源存储源ID")
source_path: str | None = Field(default=None, max_length=1024, description="源路径")
target_id: int = Field(..., ge=1, description="目标存储源ID")
target_path: str = Field(..., min_length=1, max_length=1024, description="目标路径")
transfer_mode: TransferMode | None = Field(default=None, description="传输方式")
multipart_part_size: int | None = Field(default=None, ge=1, description="分片大小(MB)")
multipart_concurrency: int | None = Field(default=None, ge=1, description="分片并发数")
class TransferStepOutSchema(BaseSchema):
"""传输步骤详情"""
model_config = ConfigDict(from_attributes=True)
task_id: int = Field(description="任务ID")
step_order: int = Field(description="步骤序号")
source_id: int | None = Field(default=None, description="源存储源ID")
source_path: str | None = Field(default=None, description="源路径")
target_id: int = Field(description="目标存储源ID")
target_path: str = Field(description="目标路径")
transfer_mode: TransferMode | None = Field(default=None, description="传输方式(空=用存储源默认)")
multipart_part_size: int | None = Field(default=None, description="分片大小(MB)")
multipart_concurrency: int | None = Field(default=None, description="分片上传并发路数")
status: TransferStatus = Field(description="状态")
progress: int = Field(default=0, description="进度(0-100)")
speed: float = Field(default=0.0, description="速度(B/s)")
total_size: int = Field(default=0, description="本步总字节")
transferred_size: int = Field(default=0, description="本步已传输字节")
error_msg: str | None = Field(default=None, description="错误信息")
started_at: datetime | None = Field(default=None, description="开始时间")
finished_at: datetime | None = Field(default=None, description="结束时间")
class TransferTaskCreateResultSchema(BaseModel):
"""创建传输任务结果"""
id: int = Field(..., ge=1, description="任务ID")
class TransferTaskOutSchema(BaseSchema):
"""传输任务详情"""
model_config = ConfigDict(from_attributes=True)
name: str = Field(description="任务名称")
task_type: TransferTaskType = Field(description="任务类型")
source_type: TransferSourceType = Field(description="源类型")
source_id: int | None = Field(default=None, description="源存储源ID")
source_path: str | None = Field(default=None, description="源远端路径")
source_name: str | None = Field(default=None, description="源文件名")
source_size: int | None = Field(default=None, description="源文件大小")
status: TransferStatus = Field(description="状态")
total_size: int = Field(default=0, description="总字节")
transferred_size: int = Field(default=0, description="已传输字节")
progress: int = Field(default=0, description="进度(0-100)")
speed: float = Field(default=0.0, description="实时速度(B/s)")
error_msg: str | None = Field(default=None, description="错误信息")
started_at: datetime | None = Field(default=None, description="开始时间")
finished_at: datetime | None = Field(default=None, description="结束时间")
steps: list[TransferStepOutSchema] = Field(default_factory=list, description="传输步骤")
class TransferTaskQueryParam(BaseQueryParam):
"""传输任务查询参数"""
name: str | None = Field(None, description="任务名称", json_schema_extra={"q": "like"})
task_type: TransferTaskType | None = Field(None, description="任务类型", json_schema_extra={"q": "eq"})
status: TransferStatus | None = Field(None, description="状态", json_schema_extra={"q": "eq"})