feat:添加报告审核附件字段

master
HuangHuiKang 1 day ago
parent 2f4eee88f3
commit 9b071f2e74

@ -12,6 +12,7 @@ class EnergyReportReviewModel(ModelMixin, TenantMixin, UserMixin):
__loader_options__: list[str] = [
"template",
"file",
"attachment_file",
"reviewer",
"created_by",
"updated_by",
@ -34,7 +35,26 @@ class EnergyReportReviewModel(ModelMixin, TenantMixin, UserMixin):
index=True,
comment="审核文档文件ID",
)
status: Mapped[int] = mapped_column(Integer, default=0, nullable=False, comment="状态 0:待审查 1:审核通过 2:审核不通过", index=True)
attachment_file_id: Mapped[int | None] = mapped_column(
Integer,
ForeignKey("common_file.id", ondelete="SET NULL", onupdate="CASCADE"),
nullable=True,
index=True,
comment="附件文件ID",
)
attachment_url: Mapped[str | None] = mapped_column(
String(512),
default=None,
nullable=True,
comment="附件下载地址",
)
status: Mapped[int] = mapped_column(
Integer,
default=0,
nullable=False,
comment="状态 0:待审查 1:审核通过 2:审核不通过",
index=True,
)
reviewer_id: Mapped[int | None] = mapped_column(
Integer,
ForeignKey("sys_user.id", ondelete="SET NULL", onupdate="CASCADE"),
@ -46,6 +66,12 @@ class EnergyReportReviewModel(ModelMixin, TenantMixin, UserMixin):
template = relationship("EnergyReportTemplateModel", lazy="selectin", foreign_keys=[template_id], uselist=False)
file = relationship("FileModel", lazy="selectin", foreign_keys=[file_id], uselist=False)
attachment_file = relationship(
"FileModel",
lazy="selectin",
foreign_keys=[attachment_file_id],
uselist=False,
)
reviewer = relationship("UserModel", lazy="selectin", foreign_keys=[reviewer_id], uselist=False)

@ -17,6 +17,7 @@ class EnergyReportReviewCreateSchema(BaseModel):
task_name: str = Field(..., min_length=1, max_length=128, description="任务名称")
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=2, description="状态 0:待审查 1:审核通过 2:审核不通过")
reviewer_id: int | None = Field(default=None, ge=1, description="审查人ID")
description: str | None = Field(default=None, max_length=500, description="描述")
@ -48,11 +49,14 @@ class EnergyReportReviewOutSchema(EnergyReportReviewCreateSchema, BaseSchema, Us
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):

@ -1,4 +1,5 @@
from app.api.v1.module_common.file.crud import FileCRUD
from app.api.v1.module_common.file.service import FileService
from app.api.v1.module_energy.report_template.crud import EnergyReportTemplateCRUD
from app.api.v1.module_system.user.crud import UserCRUD
from app.core.base_schema import AuthSchema, PageResultSchema
@ -66,9 +67,17 @@ class EnergyReportReviewService:
async def create(self, data: EnergyReportReviewCreateSchema) -> EnergyReportReviewOutSchema:
await self._validate_template(template_id=data.template_id)
await self._validate_file(file_id=data.file_id)
attachment_file = await self._validate_attachment_file(
attachment_file_id=data.attachment_file_id,
file_id=data.file_id,
)
await self._validate_reviewer(reviewer_id=data.reviewer_id)
review = await EnergyReportReviewCRUD(self.auth).create(data=data)
create_data = data.model_dump()
create_data["attachment_url"] = attachment_file.file_url if attachment_file else None
review = await EnergyReportReviewCRUD(self.auth).create(data=create_data)
await self._bind_file(file_id=data.file_id, review_id=review.id)
if data.attachment_file_id:
await self._bind_file(file_id=data.attachment_file_id, review_id=review.id)
await EnergyReportReviewLogService(self.auth).create_system_log(
report_review_id=review.id,
task_name=review.task_name,
@ -81,11 +90,26 @@ class EnergyReportReviewService:
old_review = await EnergyReportReviewCRUD(self.auth).get_or_404(id=id, msg="更新失败,能源报告审核任务不存在")
await self._validate_template(template_id=data.template_id)
await self._validate_file(file_id=data.file_id, current_review_id=id)
if old_review.attachment_file_id and old_review.attachment_file_id == data.file_id:
raise CustomException(msg="更新失败,上传文档不能使用原附件文件")
if old_review.file_id == data.attachment_file_id:
raise CustomException(msg="更新失败,附件不能使用原审核文档文件")
attachment_file = await self._validate_attachment_file(
attachment_file_id=data.attachment_file_id,
file_id=data.file_id,
current_review_id=id,
)
await self._validate_reviewer(reviewer_id=data.reviewer_id)
review = await EnergyReportReviewCRUD(self.auth).update(id=id, data=data)
update_data = data.model_dump(exclude_unset=True)
update_data["attachment_url"] = attachment_file.file_url if attachment_file else None
review = await EnergyReportReviewCRUD(self.auth).update(id=id, data=update_data)
if old_review.file_id != data.file_id:
await self._unbind_file(file_id=old_review.file_id, review_id=id)
await self._delete_file_record(file_id=old_review.file_id)
await self._bind_file(file_id=data.file_id, review_id=id)
if data.attachment_file_id:
await self._bind_file(file_id=data.attachment_file_id, review_id=id)
if old_review.attachment_file_id and old_review.attachment_file_id != data.attachment_file_id:
await self._delete_file_record(file_id=old_review.attachment_file_id)
return self._to_out_schema(review)
async def delete(self, ids: list[int]) -> None:
@ -122,6 +146,9 @@ class EnergyReportReviewService:
if review_out.file:
review_out.file_url = review_out.file.file_url
review_out.original_name = review_out.file.original_name
if review_out.attachment_file:
review_out.attachment_url = review_out.attachment_file.file_url
review_out.attachment_original_name = review_out.attachment_file.original_name
if hasattr(review, "reviewer") and review.reviewer:
review_out.reviewer_name = review.reviewer.name
return review_out
@ -129,10 +156,13 @@ class EnergyReportReviewService:
def _fill_out_dict(self, item: dict) -> dict:
template_info = item.get("template") or {}
file_info = item.get("file") or {}
attachment_file_info = item.get("attachment_file") or {}
reviewer_info = item.get("reviewer") or {}
item["template_name"] = template_info.get("template_name")
item["file_url"] = file_info.get("file_url")
item["original_name"] = file_info.get("original_name")
item["attachment_url"] = attachment_file_info.get("file_url") or item.get("attachment_url")
item["attachment_original_name"] = attachment_file_info.get("original_name")
item["reviewer_name"] = reviewer_info.get("name")
return item
@ -150,6 +180,25 @@ class EnergyReportReviewService:
if file_record.business_id and file_record.business_id != current_review_id:
raise CustomException(msg="文件已绑定到其他能源报告审核任务")
async def _validate_attachment_file(
self,
attachment_file_id: int | None,
file_id: int,
current_review_id: int | None = None,
):
if attachment_file_id is None:
return None
if attachment_file_id == file_id:
raise CustomException(msg="附件文件不能和上传文档相同")
file_record = await FileCRUD(self.auth).get(id=attachment_file_id)
if not file_record:
raise CustomException(msg="附件文件记录不存在")
if file_record.business_type and file_record.business_type != ENERGY_REPORT_REVIEW_BUSINESS_TYPE:
raise CustomException(msg="附件文件已绑定到其他业务类型")
if file_record.business_id and file_record.business_id != current_review_id:
raise CustomException(msg="附件文件已绑定到其他能源报告审核任务")
return file_record
async def _validate_reviewer(self, reviewer_id: int | None) -> None:
if reviewer_id is None:
return
@ -171,6 +220,9 @@ class EnergyReportReviewService:
if file_record.business_type == ENERGY_REPORT_REVIEW_BUSINESS_TYPE and file_record.business_id == review_id:
await FileCRUD(self.auth).set(ids=[file_id], business_id=None)
async def _delete_file_record(self, file_id: int) -> None:
await FileService.delete_service(auth=self.auth, ids=[file_id], delete_object=True)
class EnergyReportReviewLogService:
"""能源报告审核操作记录服务。"""

Loading…
Cancel
Save