fix:修改能源报告模板模块相关接口

master
HuangHuiKang 1 week ago
parent 4f0fdbcdd8
commit 5d52158c3e

@ -1,6 +1,6 @@
from typing import Annotated from typing import Annotated
from fastapi import APIRouter, Depends, Query from fastapi import APIRouter, Depends, Path, Query
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
from app.common.response import ResponseSchema, SuccessResponse from app.common.response import ResponseSchema, SuccessResponse
@ -8,7 +8,7 @@ from app.core.base_schema import AuthSchema
from app.core.dependencies import AuthPermission from app.core.dependencies import AuthPermission
from app.core.router_class import OperationLogRoute from app.core.router_class import OperationLogRoute
from .schema import TemplateConfigSaveSchema from .schema import TemplateConfigSaveSchema, TemplateSingleChapterConfigSaveSchema
from .service import TemplateConfigService from .service import TemplateConfigService
TemplateConfigRouter = APIRouter(route_class=OperationLogRoute, prefix="/attachment-template/config", tags=["能源报告模板配置"]) TemplateConfigRouter = APIRouter(route_class=OperationLogRoute, prefix="/attachment-template/config", tags=["能源报告模板配置"])
@ -38,3 +38,30 @@ async def save_template_config_controller(
) -> JSONResponse: ) -> JSONResponse:
result = await TemplateConfigService(auth).save(data=data) result = await TemplateConfigService(auth).save(data=data)
return SuccessResponse(data=result, msg="保存模板配置成功") return SuccessResponse(data=result, msg="保存模板配置成功")
@TemplateConfigRouter.post(
"/chapter/create",
summary="创建单个章节标注并保存变量关联",
response_model=ResponseSchema[dict],
)
async def create_template_chapter_config_controller(
data: TemplateSingleChapterConfigSaveSchema,
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_energy:attachment_template:update"]))],
) -> JSONResponse:
result = await TemplateConfigService(auth).create_chapter_config(data=data)
return SuccessResponse(data=result, msg="创建章节标注变量配置成功")
@TemplateConfigRouter.put(
"/chapter/update/{chapter_id}",
summary="更新单个章节标注并保存变量关联",
response_model=ResponseSchema[dict],
)
async def update_template_chapter_config_controller(
data: TemplateSingleChapterConfigSaveSchema,
chapter_id: Annotated[int, Path(ge=1, description="章节标注ID")],
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_energy:attachment_template:update"]))],
) -> JSONResponse:
result = await TemplateConfigService(auth).update_chapter_config(chapter_id=chapter_id, data=data)
return SuccessResponse(data=result, msg="更新章节标注变量配置成功")

@ -27,3 +27,14 @@ class TemplateConfigSaveSchema(BaseModel):
template_id: int = Field(..., ge=1, description="模板ID") template_id: int = Field(..., ge=1, description="模板ID")
chapters: list[TemplateChapterRuleSchema] = Field(default_factory=list, description="章节规则标注列表") chapters: list[TemplateChapterRuleSchema] = Field(default_factory=list, description="章节规则标注列表")
variables: list[VariableItemSchema] = Field(default_factory=list, description="变量关联列表") variables: list[VariableItemSchema] = Field(default_factory=list, description="变量关联列表")
class TemplateSingleChapterConfigSaveSchema(TemplateConfigSaveSchema):
"""单个章节标注和变量关联保存模型。"""
@field_validator("chapters")
@classmethod
def validate_single_chapter(cls, value: list[TemplateChapterRuleSchema]) -> list[TemplateChapterRuleSchema]:
if len(value) != 1:
raise ValueError("chapters 只能传入一条章节规则标注")
return value

@ -1,11 +1,12 @@
from app.api.v1.module_energy.chapter.crud import ChapterCRUD from app.api.v1.module_energy.chapter.crud import ChapterCRUD
from app.api.v1.module_energy.variable.crud import VariableCRUD
from app.api.v1.module_energy.report_template.crud import EnergyReportTemplateCRUD from app.api.v1.module_energy.report_template.crud import EnergyReportTemplateCRUD
from app.api.v1.module_energy.variable.service import VariableService from app.api.v1.module_energy.variable.service import VariableService
from app.api.v1.module_rule.rule.crud import RuleCRUD from app.api.v1.module_rule.rule.crud import RuleCRUD
from app.core.base_schema import AuthSchema from app.core.base_schema import AuthSchema
from app.core.exceptions import CustomException from app.core.exceptions import CustomException
from .schema import TemplateChapterRuleSchema, TemplateConfigSaveSchema from .schema import TemplateChapterRuleSchema, TemplateConfigSaveSchema, TemplateSingleChapterConfigSaveSchema
class TemplateConfigService: class TemplateConfigService:
@ -33,6 +34,32 @@ class TemplateConfigService:
"variables": await VariableService(self.auth).list_by_template(template_id=template_id), "variables": await VariableService(self.auth).list_by_template(template_id=template_id),
} }
async def create_chapter_config(self, data: TemplateSingleChapterConfigSaveSchema) -> dict:
await self._validate_template(template_id=data.template_id)
await self._validate_rules(chapters=data.chapters)
chapter = await self._create_chapter(template_id=data.template_id, chapter=data.chapters[0])
await self._save_variables(
template_id=data.template_id,
chapter_name=chapter.chapter_name,
variables=data.variables,
)
return await VariableService(self.auth).list_by_chapter(chapter_id=chapter.id)
async def update_chapter_config(self, chapter_id: int, data: TemplateSingleChapterConfigSaveSchema) -> dict:
await self._validate_template(template_id=data.template_id)
await self._validate_rules(chapters=data.chapters)
chapter = await self._update_chapter(
template_id=data.template_id,
chapter_id=chapter_id,
chapter=data.chapters[0],
)
await self._save_variables(
template_id=data.template_id,
chapter_name=chapter.chapter_name,
variables=data.variables,
)
return await VariableService(self.auth).list_by_chapter(chapter_id=chapter.id)
async def _save_chapters(self, template_id: int, chapters: list[TemplateChapterRuleSchema]) -> None: async def _save_chapters(self, template_id: int, chapters: list[TemplateChapterRuleSchema]) -> None:
for chapter in chapters: for chapter in chapters:
chapter_data = chapter.model_dump(exclude={"id"}) chapter_data = chapter.model_dump(exclude={"id"})
@ -45,6 +72,69 @@ class TemplateConfigService:
else: else:
await ChapterCRUD(self.auth).create(data=chapter_data) await ChapterCRUD(self.auth).create(data=chapter_data)
async def _create_chapter(self, template_id: int, chapter: TemplateChapterRuleSchema):
if chapter.id:
raise CustomException(msg="新增章节标注时 chapters[0].id 不能传值")
chapter_data = chapter.model_dump(exclude={"id"})
chapter_data["template_id"] = template_id
return await ChapterCRUD(self.auth).create(data=chapter_data)
async def _update_chapter(self, template_id: int, chapter_id: int, chapter: TemplateChapterRuleSchema):
old_chapter = await ChapterCRUD(self.auth).get(id=chapter_id, template_id=template_id)
if not old_chapter:
raise CustomException(msg=f"章节规则标注不存在或不属于当前模板: {chapter_id}")
if chapter.id and chapter.id != chapter_id:
raise CustomException(msg="请求体 chapters[0].id 必须与路径标注ID一致")
chapter_data = chapter.model_dump(exclude={"id"})
return await ChapterCRUD(self.auth).update(id=chapter_id, data=chapter_data)
async def _save_variables(self, template_id: int, chapter_name: str, variables: list) -> None:
chapter_names = self._collect_variable_chapter_names(chapter_name=chapter_name, variables=variables)
await self._validate_variable_chapters(template_id=template_id, chapter_names=chapter_names)
for variable in variables:
existing = await VariableCRUD(self.auth).get_list(
search={"template_id": template_id, "variable_name": variable.variable_name},
)
if existing:
await VariableCRUD(self.auth).hard_delete(ids=[record.id for record in existing])
for variable_chapter_name in self._resolve_variable_chapter_names(
current_chapter_name=chapter_name,
variable=variable,
):
await VariableCRUD(self.auth).create(
data={
"template_id": template_id,
"variable_name": variable.variable_name,
"chapter_name": variable_chapter_name,
}
)
def _collect_variable_chapter_names(self, chapter_name: str, variables: list) -> list[str]:
chapter_names: list[str] = []
for variable in variables:
chapter_names.extend(self._resolve_variable_chapter_names(current_chapter_name=chapter_name, variable=variable))
return self._unique_names(chapter_names)
def _resolve_variable_chapter_names(self, current_chapter_name: str, variable) -> list[str]:
chapter_names = list(variable.chapter_names)
if variable.checked is True and current_chapter_name not in chapter_names:
chapter_names.append(current_chapter_name)
if variable.checked is False:
chapter_names = [chapter_name for chapter_name in chapter_names if chapter_name != current_chapter_name]
return self._unique_names(chapter_names)
def _unique_names(self, names: list[str]) -> list[str]:
return list(dict.fromkeys(name.strip() for name in names if name.strip()))
async def _validate_variable_chapters(self, template_id: int, chapter_names: list[str]) -> None:
if not chapter_names:
return
chapters = await ChapterCRUD(self.auth).get_list(search={"template_id": template_id})
exists_names = {chapter.chapter_name for chapter in chapters}
invalid_names = [chapter_name for chapter_name in chapter_names if chapter_name not in exists_names]
if invalid_names:
raise CustomException(msg=f"变量关联章节不存在或不属于当前模板: {invalid_names}")
async def _validate_template(self, template_id: int) -> None: async def _validate_template(self, template_id: int) -> None:
template = await EnergyReportTemplateCRUD(self.auth).get(id=template_id) template = await EnergyReportTemplateCRUD(self.auth).get(id=template_id)
if not template: if not template:

@ -6,6 +6,7 @@ class VariableItemSchema(BaseModel):
variable_name: str = Field(..., min_length=1, max_length=128, description="变量名称") variable_name: str = Field(..., min_length=1, max_length=128, description="变量名称")
chapter_names: list[str] = Field(default_factory=list, description="关联章节名称列表") chapter_names: list[str] = Field(default_factory=list, description="关联章节名称列表")
checked: bool | None = Field(default=None, description="当前标注是否勾选该变量,单标注保存接口使用")
@field_validator("variable_name") @field_validator("variable_name")
@classmethod @classmethod

@ -46,12 +46,18 @@ class VariableService:
variable_map[record.variable_name] = { variable_map[record.variable_name] = {
"variable_name": record.variable_name, "variable_name": record.variable_name,
"chapter_names": [], "chapter_names": [],
"chapters": [],
"checked": False, "checked": False,
} }
variable_map[record.variable_name]["chapter_names"].append(record.chapter_name) variable_map[record.variable_name]["chapter_names"].append(record.chapter_name)
chapter_map = await self._chapter_summary_map(template_id=chapter.template_id)
for variable in variable_map.values(): for variable in variable_map.values():
variable["chapter_names"] = self._unique_names(variable["chapter_names"]) variable["chapter_names"] = self._unique_names(variable["chapter_names"])
variable["chapters"] = [
chapter_map.get(chapter_name, {"chapter_name": chapter_name})
for chapter_name in variable["chapter_names"]
]
variable["checked"] = chapter.chapter_name in variable["chapter_names"] variable["checked"] = chapter.chapter_name in variable["chapter_names"]
return { return {

Loading…
Cancel
Save