from app.api.v1.module_common.file.crud import FileCRUD from app.core.base_schema import AuthSchema from app.core.exceptions import CustomException from .crud import EnergyReportTemplateCRUD from .schema import ( EnergyReportTemplateCreateSchema, EnergyReportTemplateOutSchema, EnergyReportTemplateQueryParam, EnergyReportTemplateUpdateSchema, ) ENERGY_REPORT_TEMPLATE_BUSINESS_TYPE = "energy_report_template" class EnergyReportTemplateService: """能源报告模板服务。""" def __init__(self, auth: AuthSchema) -> None: self.auth = auth async def detail(self, id: int) -> EnergyReportTemplateOutSchema: template = await EnergyReportTemplateCRUD(self.auth).get_or_404(id=id) return self._to_out_schema(template) async def page( self, page_no: int, page_size: int, search: EnergyReportTemplateQueryParam | None = None, order_by: list[dict[str, str]] | None = None, ) -> dict: offset = (page_no - 1) * page_size page_result = await EnergyReportTemplateCRUD(self.auth).page( offset=offset, limit=page_size, order_by=order_by or [{"order": "asc"}, {"id": "desc"}], search=vars(search) if search else None, out_schema=EnergyReportTemplateOutSchema, ) for item in page_result.items: file_info = item.get("file") or {} item["file_url"] = file_info.get("file_url") item["original_name"] = file_info.get("original_name") item["object_name"] = file_info.get("object_name") return page_result async def create(self, data: EnergyReportTemplateCreateSchema) -> EnergyReportTemplateOutSchema: await self._validate_unique_name(template_name=data.template_name) await self._validate_file(file_id=data.file_id) template = await EnergyReportTemplateCRUD(self.auth).create(data=data) await self._bind_file(file_id=data.file_id, template_id=template.id) return self._to_out_schema(template) async def update(self, id: int, data: EnergyReportTemplateUpdateSchema) -> EnergyReportTemplateOutSchema: old_template = await EnergyReportTemplateCRUD(self.auth).get_or_404(id=id, msg="更新失败,能源报告模板不存在") await self._validate_unique_name(template_name=data.template_name, exclude_id=id) await self._validate_file(file_id=data.file_id, current_template_id=id) template = await EnergyReportTemplateCRUD(self.auth).update(id=id, data=data) if old_template.file_id != data.file_id: await self._unbind_file(file_id=old_template.file_id, template_id=id) await self._bind_file(file_id=data.file_id, template_id=id) return self._to_out_schema(template) async def delete(self, ids: list[int]) -> None: if len(ids) < 1: raise CustomException(msg="删除失败,删除对象不能为空") templates = await EnergyReportTemplateCRUD(self.auth).get_list(search={"id": ("in", ids)}) template_map = {template.id: template for template in templates} for template_id in ids: if template_id not in template_map: raise CustomException(msg="删除失败,能源报告模板不存在") for template in templates: await self._unbind_file(file_id=template.file_id, template_id=template.id) await EnergyReportTemplateCRUD(self.auth).delete(ids=ids) def _to_out_schema(self, template) -> EnergyReportTemplateOutSchema: template_out = EnergyReportTemplateOutSchema.model_validate(template) if template_out.file: template_out.file_url = template_out.file.file_url template_out.original_name = template_out.file.original_name template_out.object_name = template_out.file.object_name return template_out async def _validate_unique_name(self, template_name: str, exclude_id: int | None = None) -> None: template = await EnergyReportTemplateCRUD(self.auth).get(template_name=template_name) if template and template.id != exclude_id: raise CustomException(msg="能源报告模板名称已存在") async def _validate_file(self, file_id: int, current_template_id: int | None = None) -> None: file_record = await FileCRUD(self.auth).get(id=file_id) if not file_record: raise CustomException(msg="文件记录不存在") if file_record.business_type and file_record.business_type != ENERGY_REPORT_TEMPLATE_BUSINESS_TYPE: raise CustomException(msg="文件已绑定到其他业务类型") if file_record.business_id and file_record.business_id != current_template_id: raise CustomException(msg="文件已绑定到其他能源报告模板") async def _bind_file(self, file_id: int, template_id: int) -> None: await FileCRUD(self.auth).set( ids=[file_id], business_type=ENERGY_REPORT_TEMPLATE_BUSINESS_TYPE, business_id=template_id, ) async def _unbind_file(self, file_id: int, template_id: int) -> None: file_record = await FileCRUD(self.auth).get(id=file_id) if not file_record: return if file_record.business_type == ENERGY_REPORT_TEMPLATE_BUSINESS_TYPE and file_record.business_id == template_id: await FileCRUD(self.auth).set(ids=[file_id], business_id=None)