certflow.controllers.material_grade_controller 源代码

"""材质牌号控制器

桥接材质牌号管理界面(View)与材质牌号服务(Service):
- 读操作直接委托 MaterialGradeService;
- 写操作(新增/更新/删除)在此统一提交事务,失败时回滚并向上抛出。

架构层次:View (MaterialGradeManagerView) → Controller (MaterialGradeController)
         → Service (MaterialGradeService) → Model (MaterialGrade)
"""

from __future__ import annotations

from pathlib import Path
from typing import Any

from certflow.controllers.base_controller import BaseController
from certflow.services.dict_csv_sync import DictCsvSync
from certflow.services.material_grade_service import MaterialGrade, MaterialGradeService
from certflow.utils.logger import logger


[文档] class MaterialGradeController(BaseController): """材质牌号控制器 — 管理界面的业务调度层""" # CSV 列序 / 类型 / 唯一键(与 dictionaries.yaml 的 material_grades 段一致) _CSV_COLUMNS = [ "grade", "standard_code", "category_large", "category_medium", "category", "kind", "element", "standard_min", "standard_max", "decimal_places", "actual_min", "actual_max", "is_active", ] _CSV_FIELD_TYPES = { "grade": "text", "standard_code": "text", "category_large": "text", "category_medium": "text", "category": "text", "kind": "text", "element": "text", "standard_min": "float", "standard_max": "float", "decimal_places": "int", "actual_min": "float", "actual_max": "float", "is_active": "bool", } _CSV_UNIQUE_KEYS = ["grade", "standard_code", "element"] def __init__(self, db_session=None, db_manager=None, use_shared: bool = True): """初始化控制器 Args: db_session: 外部会话(可选);不传则按 BaseController 规则自动创建 db_manager: 数据库管理器(可选) use_shared: 是否使用全局共享管理器 """ super().__init__(db_session=db_session, db_manager=db_manager, use_shared=use_shared) self._service = self.get_service(MaterialGradeService) self._csv_sync = DictCsvSync( MaterialGrade, csv_columns=self._CSV_COLUMNS, field_types=self._CSV_FIELD_TYPES, unique_keys=self._CSV_UNIQUE_KEYS, ) # ============================================================ # 读操作(直接委托) # ============================================================
[文档] def list_all(self, active_only: bool = False) -> list[Any]: """返回全部材质牌号记录 Args: active_only: 为 True 时仅返回启用状态的牌号,默认为 False Returns: list[Any]: 材质牌号记录列表(ORM 对象或字典) """ return self._service.list_all(active_only=active_only)
[文档] def get_by_id(self, grade_id: int) -> Any: """按主键获取记录 Args: grade_id: 材质牌号记录主键 Returns: Any: 匹配的记录对象;不存在时返回 None """ return self._service.get_by_id(grade_id)
[文档] def get_grades_by_category(self) -> dict[str, list[str]]: """按阀门零件类别分组返回牌号(供打印对话框)""" return self._service.get_grades_by_category()
[文档] def get_data_quality_summary(self) -> dict[str, int]: """材质牌号表数据质量概览(总数/启用/停用/范围缺失),供管理界面状态栏。""" return self._service.get_data_quality_summary()
# ============================================================ # 写操作(提交事务) # ============================================================
[文档] def create(self, data: dict[str, Any]) -> int: """新增记录并提交 Returns: 新记录主键 id Raises: ValueError: 校验失败(交给上层提示用户) Examples: >>> controller = MaterialGradeController() >>> new_id = controller.create({ ... "category": "阀体", ... "grade": "WCB", ... "is_active": True, ... }) >>> print(new_id) """ mg = self._service.create(data) self.commit() return mg.id
[文档] def update(self, grade_id: int, data: dict[str, Any]) -> bool: """更新记录并提交 Returns: 是否更新成功(id 不存在返回 False) """ try: result = self._service.update(grade_id, data) if result is None: return False self.commit() return True except ValueError: self.rollback() raise
[文档] def delete(self, grade_id: int) -> bool: """删除记录并提交 Returns: 是否删除成功 """ result = self._service.delete(grade_id) if result: self.commit() return result
[文档] def seed_common_grades(self) -> int: """幂等灌入常见牌号示例(化学成分 + 力学性能) Returns: 实际写入的记录条数(0 表示库已有数据,未写入) """ count = self._service.seed_common_grades() if count: self.commit() return count
[文档] def export_csv(self, path: str | Path) -> int: """把当前 material_grades 表整表导出为 CSV 快照,返回行数。""" return self._csv_sync.export_csv(self.session, path)
[文档] def import_csv(self, path: str | Path) -> dict[str, int]: """把 CSV 快照 upsert 回 material_grades 表,返回统计。""" return self._csv_sync.import_csv(self.session, path)
[文档] def refresh(self) -> list[Any]: """重新加载全部记录(提交并刷新会话) Returns: list[Any]: 刷新后的全部材质牌号记录列表 """ try: self.session.commit() except Exception as e: # pragma: no cover - 防御性 logger.debug(f"refresh 提交失败(忽略): {e}") self.session.rollback() self.session.expire_all() return self.list_all()