certflow.services.material_grade_service module

材质牌号服务

封装 material_grades 表的查询与写入逻辑,供两处复用: 1. 打印参数补充对话框:get_grades_by_category() 按阀门零件类别分组返回牌号列表; 2. 材质牌号管理界面:list_all / create / update / delete 提供完整 CRUD。

数据模型说明(与领域约束对齐): - grade + standard_code + element 唯一确定一条「牌号在某标准下的某元素性能范围」记录; - category_large / category_medium 表示材料形态维度(铸件类/锻件类/板材类/棒材类),

同一牌号挂不同形态/标准时范围可能不同;

  • category 表示阀门零件维度(body/stem/disc/common),仅用于打印对话框分组, 与材料形态维度正交。

class certflow.services.material_grade_service.MaterialGradeService(session)[源代码]

基类:object

材质牌号服务

封装 material_grades 表的读写,所有写操作由调用方(控制器)负责提交事务。

参数:

session (Session)

list_all(active_only=False)[源代码]

返回全部材质牌号记录(按牌号、标准号、元素排序)

参数:

active_only (bool) -- 仅返回启用记录

返回:

MaterialGrade 记录列表

返回类型:

list[MaterialGrade]

get_by_id(grade_id)[源代码]

按主键获取单条记录。

参数:

grade_id (int) -- 主键 ID。

返回:

对应记录,不存在时返回 None。

返回类型:

MaterialGrade | None

get_by_grade(grade)[源代码]

按牌号查询全部材质记录(化学成分 + 力学性能),大小写不敏感。

C0/C3:供 ReportBomEnricher 在报告生成时按命中牌号取化学/力学性能范围, 比 list_all``(全量、调用方自行过滤)更高效、语义更清晰;与 ``generate_composition_values 同口径经 canonical_grade 归并。

参数:

grade (str) -- 材质牌号(如 "WCB" / "20" / "304")。

返回:

list[MaterialGrade]:该牌号的全部记录(按 标准号、元素 排序); 牌号空 / 归一化后为空 → 返回 [];不存在该牌号 → 返回 []

返回类型:

list[MaterialGrade]

get_distinct_grades(active_only=True)[源代码]

返回去重后的牌号列表(用于下拉框等)。

参数:

active_only (bool) -- 仅返回启用记录,默认 True。

返回:

去重并排序后的牌号列表。

返回类型:

list[str]

get_grades_by_category()[源代码]

按阀门零件类别分组返回牌号列表(仅启用记录)

分组规则: - category 字段非空 → 归入对应类别(body/stem/disc); - category 为空 → 归入 "common",对话框会将 common 合并进各零件下拉框。

返回:

[牌号列表]},如 {"body": ["WCB", "CF8"], "common": ["304"]} 空表时返回 {}。

返回类型:

{类别

create(data)[源代码]

新增一条材质牌号记录

参数:

data (dict[str, Any]) -- 字段字典,至少包含 grade / standard_code / element; 可选 category_large / category_medium / category / standard_min / standard_max / decimal_places / actual_min / actual_max / is_active

返回:

新建的 MaterialGrade 实例

抛出:

ValueError -- 缺少必填字段,或 (grade, standard_code, element) 已存在

返回类型:

MaterialGrade

update(grade_id, data)[源代码]

更新指定记录

参数:
  • grade_id (int) -- 主键

  • data (dict[str, Any]) -- 待更新字段字典(空值字段忽略)

返回:

更新后的记录;id 不存在返回 None

返回类型:

MaterialGrade | None

delete(grade_id)[源代码]

删除指定记录

参数:

grade_id (int) -- 主键

返回:

是否删除成功

返回类型:

bool

generate_composition(grade, category_large=None)[源代码]

按牌号生成质保书所需的化学成分 / 力学性能字符串

从 material_grades 表中取出该牌号(可按材料形态过滤)的全部启用的 化学成分(chemical)与力学性能(mechanical)记录,对每条记录用 RandBetween 在 [standard_min, standard_max] 范围内按 decimal_places 取随机实测值, 分别拼成 "C:0.20%, Si:0.40%, ..." 与 "屈服强度:245MPa, ..." 形式的字符串。

参数:
  • grade (str) -- 材质牌号,如 "WCB" / "304"

  • category_large (str | None) -- 可选材料形态过滤(铸件类/锻件类/板材类/棒材类)

返回:

str, "mechanical_property": str} 牌号无数据(或库为空)时两者均返回空串,由调用方决定是否回退占位值。

返回类型:

{"chemical_composition"

示例

>>> service = MaterialGradeService(session)
>>> result = service.generate_composition("WCB", category_large="铸件类")
>>> print(result["chemical_composition"])
generate_composition_values(grade, category_large=None)[源代码]

按牌号生成质保书材质块所需的**数值字典**(供填充引擎逐列写入)。

generate_composition`(返回展示字符串)同源取数,但返回 float 数值并把 列键规范化到报告模板列:化学成分直接用元素符号(C/Mn/Si/...,两类模板一致), 力学性能经 :data:`_MECH_KEY_ALIASES() 映射到 ReL/Rm/A/Z 与 σs/σb/δ/ψ 两套别名, 使返回值同时适配质保书与材质证明书模板。

参数:
  • grade (str) -- 材质牌号,如 "WCB" / "304"。

  • category_large (str | None) -- 可选材料形态过滤(铸件类/锻件类/板材类/棒材类)。

返回:

{元素: 值}, "力学性能": {列键: 值}};牌号无数据时两者均为空 dict。

返回类型:

{"化学成分"

seed_common_grades()[源代码]

幂等灌入常见牌号的化学成分 + 力学性能示例数据

仅当库中不存在任何 material_grades 记录时才写入,重复调用安全。 供管理界面「载入示例」按钮、测试初始化使用。

C3 保证:种子每条元素记录均带 standard_min / standard_max (单侧上限元素取 min=0.00)且 is_active=True,从源头杜绝 「范围缺失 → 报告该列恒空」。若种子数据自身出现两端皆空的元素, 则跳过该元素(不写入),并记录告警,保证落库数据必然完整。

返回:

实际写入的记录条数(0 表示已存在,未写入)

返回类型:

int

find_incomplete_records()[源代码]

返回「启用但范围缺失」的牌号记录——这些会让质保书/材质报告对应列恒空。

判定:is_active == Truestandard_minstandard_max 为 NULL。 这类记录可被 generate_composition_values 命中(is_active 通过),但其 某元素无范围可取 → _randbetween_value 返回 None → 该元素被跳过 → 报告列空。

返回:

缺失范围的启用记录列表(按 牌号、元素 排序);空表/无缺失返回 []。

返回类型:

list[MaterialGrade]

count_incomplete_records()[源代码]

启用但范围缺失的记录条数(供管理界面提示数据质量)。

返回类型:

int

get_data_quality_summary()[源代码]

材质牌号表数据质量概览(供管理界面状态栏展示)。

返回:

{total, active, inactive, incomplete} 四项计数。

返回类型:

dict[str, int]