You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

156 lines
7.8 KiB
Python

from dataclasses import dataclass
from typing import Literal
from fastapi import Query
from pydantic import BaseModel, ConfigDict, Field, field_validator
from app.api.v1.module_common.file.schema import FileOutSchema
from app.api.v1.module_energy.report_template.schema import EnergyReportTemplateOutSchema
from app.common.enums import QueueEnum
from app.core.base_params import BaseQueryParam, TenantByQueryParam, UserByQueryParam
from app.core.base_schema import BaseSchema, CommonSchema, TenantBySchema, UserBySchema
class EnergyReportGenerationCreateSchema(BaseModel):
"""能源报告生成任务创建模型。"""
generation_name: str = Field(..., min_length=1, max_length=128, description="任务名称")
report_type: int = Field(default=1, ge=1, le=2, description="报告类型 1:能源报告 2:光伏报告")
template_id: int = Field(..., ge=1, description="能源报告模板ID")
file_id: int | None = Field(default=None, ge=1, description="生成源文档文件ID")
attachment_file_id: int | None = Field(default=None, ge=1, description="附件文件ID")
status: int = Field(default=0, ge=0, le=3, description="状态 0:待生成 1:生成中 2:已生成 3:生成失败")
generator_id: int | None = Field(default=None, ge=1, description="生成人ID")
description: str | None = Field(default=None, max_length=500, description="描述")
@field_validator("generation_name")
@classmethod
def validate_generation_name(cls, value: str) -> str:
value = value.strip()
if not value:
raise ValueError("任务名称不能为空")
return value
@field_validator("status")
@classmethod
def validate_status(cls, value: int) -> int:
if value not in {0, 1, 2, 3}:
raise ValueError("状态仅支持 0(待生成)、1(生成中)、2(已生成)、3(生成失败)")
return value
@field_validator("report_type")
@classmethod
def validate_report_type(cls, value: int) -> int:
if value not in {1, 2}:
raise ValueError("报告类型仅支持 1(能源报告) 或 2(光伏报告)")
return value
class EnergyReportGenerationUpdateSchema(EnergyReportGenerationCreateSchema):
"""能源报告生成任务更新模型。"""
class EnergyReportGenerationOutSchema(EnergyReportGenerationCreateSchema, BaseSchema, UserBySchema, TenantBySchema):
"""能源报告生成任务响应模型。"""
model_config = ConfigDict(from_attributes=True)
template: EnergyReportTemplateOutSchema | None = Field(default=None, description="能源报告模板")
file: FileOutSchema | None = Field(default=None, description="生成源文档")
attachment_file: FileOutSchema | None = Field(default=None, description="附件文件")
generator: CommonSchema | None = Field(default=None, description="生成人")
template_name: str | None = Field(default=None, description="模板名称")
generator_name: str | None = Field(default=None, description="生成人名称")
report_file_url: str | None = Field(default=None, description="报告文档访问地址")
report_file_original_name: str | None = Field(default=None, description="报告文档原始名称")
file_url: str | None = Field(default=None, description="文档访问地址")
original_name: str | None = Field(default=None, description="文档原始名称")
attachment_file_url: str | None = Field(default=None, description="附件文件访问地址")
attachment_file_original_name: str | None = Field(default=None, description="附件文件原始名称")
attachment_url: str | None = Field(default=None, description="附件下载地址")
attachment_original_name: str | None = Field(default=None, description="附件原始名称")
class EnergyReportGenerationStatsSchema(BaseModel):
"""能源报告生成任务统计模型。"""
submitted_count: int = Field(default=0, description="提交任务数")
generating_count: int = Field(default=0, description="生成中任务数")
generated_count: int = Field(default=0, description="已生成任务数")
pending_count: int = Field(default=0, description="待生成任务数")
failed_count: int = Field(default=0, description="生成失败任务数")
class EnergyReportGenerationPageOutSchema(BaseModel):
"""能源报告生成任务分页和统计响应模型。"""
page_no: int = Field(description="当前页码")
page_size: int = Field(description="每页数量")
total: int = Field(description="总数")
has_next: bool = Field(description="是否有下一页")
stats: EnergyReportGenerationStatsSchema = Field(description="统计数据")
items: list[dict] = Field(default_factory=list, description="列表数据")
@dataclass
class EnergyReportGenerationQueryParam(BaseQueryParam, UserByQueryParam, TenantByQueryParam):
"""能源报告生成任务查询参数。"""
generation_name: str | None = Query(None, description="任务名称")
report_type: int | None = Query(None, ge=1, le=2, description="报告类型 1:能源报告 2:光伏报告")
status: int | None = Query(None, ge=0, le=3, description="状态 0:待生成 1:生成中 2:已生成 3:生成失败")
template_id: int | None = Query(None, ge=1, description="模板ID")
generator_id: int | None = Query(None, ge=1, description="生成人ID")
def __post_init__(self) -> None:
if self.generation_name:
self.generation_name = (QueueEnum.like.value, self.generation_name)
if isinstance(self.report_type, int):
self.report_type = (QueueEnum.eq.value, self.report_type)
if isinstance(self.status, int):
self.status = (QueueEnum.eq.value, self.status)
if isinstance(self.template_id, int):
self.template_id = (QueueEnum.eq.value, self.template_id)
if isinstance(self.generator_id, int):
self.generator_id = (QueueEnum.eq.value, self.generator_id)
ReportGenerationLogActionType = Literal["create_task", "start_generation", "generation_success", "generation_failed"]
class EnergyReportGenerationLogCreateSchema(BaseModel):
"""能源报告生成操作记录创建模型。"""
report_generation_id: int = Field(..., ge=1, description="能源报告生成任务ID")
action_type: ReportGenerationLogActionType = Field(..., description="操作类型")
description: str | None = Field(default=None, max_length=500, description="操作描述")
generation_name: str = Field(default="", description="任务名称,由后端填充")
action_name: str = Field(default="", description="操作名称,由后端填充")
class EnergyReportGenerationLogOutSchema(EnergyReportGenerationLogCreateSchema, BaseSchema, UserBySchema, TenantBySchema):
"""能源报告生成操作记录响应模型。"""
model_config = ConfigDict(from_attributes=True)
generation: EnergyReportGenerationOutSchema | None = Field(default=None, description="生成任务")
operator_id: int | None = Field(default=None, description="操作人ID")
operator_name: str | None = Field(default=None, description="操作人名称")
@dataclass
class EnergyReportGenerationLogQueryParam(BaseQueryParam, UserByQueryParam, TenantByQueryParam):
"""能源报告生成操作记录查询参数。"""
report_generation_id: int | None = Query(None, ge=1, description="生成任务ID")
generation_name: str | None = Query(None, description="任务名称")
action_type: ReportGenerationLogActionType | None = Query(None, description="操作类型")
def __post_init__(self) -> None:
if isinstance(self.report_generation_id, int):
self.report_generation_id = (QueueEnum.eq.value, self.report_generation_id)
if self.generation_name:
self.generation_name = (QueueEnum.like.value, self.generation_name)
if self.action_type:
self.action_type = (QueueEnum.eq.value, self.action_type)