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.

153 lines
7.2 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 EnergyReportReviewCreateSchema(BaseModel):
"""能源报告审核任务创建模型。"""
task_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 = Field(..., 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:审查失败")
reviewer_id: int | None = Field(default=None, ge=1, description="审查人ID")
description: str | None = Field(default=None, max_length=500, description="描述")
@field_validator("task_name")
@classmethod
def validate_task_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 EnergyReportReviewUpdateSchema(EnergyReportReviewCreateSchema):
"""能源报告审核任务更新模型。"""
class EnergyReportReviewOutSchema(EnergyReportReviewCreateSchema, 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="附件文件")
reviewer: CommonSchema | None = Field(default=None, description="审查人")
template_name: str | None = Field(default=None, description="模板名称")
reviewer_name: str | None = Field(default=None, description="审查人名称")
file_url: str | None = Field(default=None, description="文档访问地址")
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 EnergyReportReviewStatsSchema(BaseModel):
"""能源报告审核任务统计模型。"""
submitted_count: int = Field(default=0, description="提交任务数")
reviewing_count: int = Field(default=0, description="审查中任务数")
reviewed_count: int = Field(default=0, description="已审查任务数")
pending_count: int = Field(default=0, description="待审查任务数")
failed_count: int = Field(default=0, description="审查失败任务数")
class EnergyReportReviewPageOutSchema(BaseModel):
"""能源报告审核任务分页和统计响应模型。"""
page_no: int = Field(description="当前页码")
page_size: int = Field(description="每页数量")
total: int = Field(description="总数")
has_next: bool = Field(description="是否有下一页")
stats: EnergyReportReviewStatsSchema = Field(description="统计数据")
items: list[dict] = Field(default_factory=list, description="列表数据")
@dataclass
class EnergyReportReviewQueryParam(BaseQueryParam, UserByQueryParam, TenantByQueryParam):
"""能源报告审核任务查询参数。"""
task_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")
reviewer_id: int | None = Query(None, ge=1, description="审查人ID")
def __post_init__(self) -> None:
if self.task_name:
self.task_name = (QueueEnum.like.value, self.task_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.reviewer_id, int):
self.reviewer_id = (QueueEnum.eq.value, self.reviewer_id)
ReportReviewLogActionType = Literal["create_task", "start_review", "review_pass", "review_reject"]
class EnergyReportReviewLogCreateSchema(BaseModel):
"""能源报告审核操作记录创建模型。"""
report_review_id: int = Field(..., ge=1, description="能源报告审核任务ID")
action_type: ReportReviewLogActionType = Field(..., description="操作类型")
description: str | None = Field(default=None, max_length=500, description="操作描述")
task_name: str = Field(default="", description="任务名称,由后端填充")
action_name: str = Field(default="", description="操作名称,由后端填充")
class EnergyReportReviewLogOutSchema(EnergyReportReviewLogCreateSchema, BaseSchema, UserBySchema, TenantBySchema):
"""能源报告审核操作记录响应模型。"""
model_config = ConfigDict(from_attributes=True)
task_name: str = Field(description="任务名称")
action_name: str = Field(description="操作名称")
operator_id: int | None = Field(default=None, description="操作人ID")
operator_name: str | None = Field(default=None, description="操作人名称")
@dataclass
class EnergyReportReviewLogQueryParam(BaseQueryParam, UserByQueryParam, TenantByQueryParam):
"""能源报告审核操作记录查询参数。"""
report_review_id: int | None = Query(None, ge=1, description="能源报告审核任务ID")
task_name: str | None = Query(None, description="任务名称")
action_type: str | None = Query(None, description="操作类型")
def __post_init__(self) -> None:
if isinstance(self.report_review_id, int):
self.report_review_id = (QueueEnum.eq.value, self.report_review_id)
if self.task_name:
self.task_name = (QueueEnum.like.value, self.task_name)
if self.action_type:
self.action_type = (QueueEnum.eq.value, self.action_type)