[migrate]:[FL-33][补齐防雷报告分级章节与图表输出]
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -819,6 +819,13 @@ def _prepare_report_payload(
|
||||
|
||||
source_job = get_job_by_id(db, str(execution_options.get("source_job_id") or ""))
|
||||
line = risk_job.line or job.line
|
||||
mitigation_execution_options = mitigation_job.execution_options_json or {} if mitigation_job is not None else {}
|
||||
non_construction = bool(
|
||||
execution_options.get("non_construction")
|
||||
or mitigation_execution_options.get("non_construction")
|
||||
or mitigation_execution_options.get("mitigation_mode") == "non_construction"
|
||||
or any(bool(_safe_dict(item.get("result_json")).get("non_construction")) for item in selected_mitigation_rows)
|
||||
)
|
||||
|
||||
return {
|
||||
"line": {
|
||||
@@ -846,6 +853,7 @@ def _prepare_report_payload(
|
||||
if scenario_job is not None
|
||||
else None
|
||||
),
|
||||
"non_construction": non_construction,
|
||||
},
|
||||
"risk_rows": risk_rows,
|
||||
"selected_risk_rows": selected_risk_rows,
|
||||
@@ -862,6 +870,8 @@ def _serialize_report_row(item: FlAnalysisTowerResult) -> dict[str, Any]:
|
||||
"tower_no": snapshot.tower_no if snapshot else None,
|
||||
"tower_model": snapshot.tower_model if snapshot else None,
|
||||
"tower_type": snapshot.tower_type if snapshot else None,
|
||||
"base_tower_json": snapshot.base_tower_json if snapshot else {},
|
||||
"profile_json": snapshot.profile_json if snapshot else {},
|
||||
"risk_level": item.risk_level,
|
||||
"summary_text": item.summary_text,
|
||||
"result_json": item.result_json or {},
|
||||
|
||||
@@ -5,7 +5,156 @@ from datetime import datetime
|
||||
from app.services.fl_analysis_report import build_report_document, build_report_summary_payload
|
||||
|
||||
|
||||
def _build_risk_row(
|
||||
*,
|
||||
tower_id: str,
|
||||
tower_no: str,
|
||||
tower_type: str,
|
||||
terrain: str,
|
||||
risk_level: str,
|
||||
risk_grade: int,
|
||||
score: int,
|
||||
cause_analysis: str,
|
||||
mitigation_recommendation: str,
|
||||
lightning_density: float,
|
||||
ground_resistance_ohm: float,
|
||||
slope_deg: float,
|
||||
protection_angle_deg: float,
|
||||
insulator_length_mm: float,
|
||||
shield_wire_height_m: float,
|
||||
counterstrike_withstand_ka: float,
|
||||
counterstrike_trip_rate: float,
|
||||
shielding_withstand_ka: float,
|
||||
shielding_trip_rate: float,
|
||||
reason_details: list[dict[str, object]],
|
||||
) -> dict[str, object]:
|
||||
return {
|
||||
"tower_id": tower_id,
|
||||
"tower_no": tower_no,
|
||||
"tower_type": tower_type,
|
||||
"base_tower_json": {
|
||||
"tower_type": tower_type,
|
||||
"terrain": terrain,
|
||||
"line_voltage_kv": 220,
|
||||
"lightning_density": lightning_density,
|
||||
"ground_resistance_ohm": ground_resistance_ohm,
|
||||
"slope_1": slope_deg,
|
||||
"slope_2": max(slope_deg - 2.0, 0.0),
|
||||
"longitude": 120.0 + score / 1000.0,
|
||||
"latitude": 30.0 + score / 1000.0,
|
||||
},
|
||||
"profile_json": {
|
||||
"structure_kind": "单回",
|
||||
"stroke_mode": "反击",
|
||||
"insulator_length_m": round(insulator_length_mm / 1000.0, 4),
|
||||
"shield_wire_height_m": shield_wire_height_m,
|
||||
},
|
||||
"risk_level": risk_level,
|
||||
"result_json": {
|
||||
"risk_grade": risk_grade,
|
||||
"score": score,
|
||||
"cause_analysis": cause_analysis,
|
||||
"mitigation_recommendation": mitigation_recommendation,
|
||||
"counterstrike_withstand_ka": counterstrike_withstand_ka,
|
||||
"counterstrike_trip_rate": counterstrike_trip_rate,
|
||||
"shielding_withstand_ka": shielding_withstand_ka,
|
||||
"shielding_trip_rate": shielding_trip_rate,
|
||||
"reason_details": reason_details,
|
||||
"inputs": {
|
||||
"ground_resistance_ohm": ground_resistance_ohm,
|
||||
"lightning_density": lightning_density,
|
||||
"insulator_length_mm": insulator_length_mm,
|
||||
"terrain_slope_deg": slope_deg,
|
||||
"protection_angle_deg": protection_angle_deg,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def _sample_report_data() -> dict[str, object]:
|
||||
high_row = _build_risk_row(
|
||||
tower_id="tower-1",
|
||||
tower_no="001",
|
||||
tower_type="直线",
|
||||
terrain="山地",
|
||||
risk_level="high",
|
||||
risk_grade=3,
|
||||
score=88,
|
||||
cause_analysis="接地电阻偏高;保护角暴露偏大",
|
||||
mitigation_recommendation="优先降低接地电阻;优化避雷线与保护角配置",
|
||||
lightning_density=4.2,
|
||||
ground_resistance_ohm=18.0,
|
||||
slope_deg=6.8,
|
||||
protection_angle_deg=23.0,
|
||||
insulator_length_mm=2400.0,
|
||||
shield_wire_height_m=46.0,
|
||||
counterstrike_withstand_ka=96.2,
|
||||
counterstrike_trip_rate=0.108,
|
||||
shielding_withstand_ka=118.6,
|
||||
shielding_trip_rate=0.021,
|
||||
reason_details=[
|
||||
{"code": "ground_resistance", "label": "接地电阻", "grade": 1, "triggered": True},
|
||||
{"code": "protection_angle", "label": "保护角", "grade": 2, "triggered": True},
|
||||
{"code": "shield_wire_height", "label": "高度档次", "grade": 1, "triggered": True, "value": 46.0, "standard_value": 33.0},
|
||||
{"code": "terrain_slope", "label": "地面倾角档次", "grade": 3, "triggered": False, "value": 6.8},
|
||||
{"code": "insulator_length", "label": "绝缘子串长度档次", "grade": 3, "triggered": False, "value": 2400.0, "standard_value": 2265.0},
|
||||
],
|
||||
)
|
||||
medium_row = _build_risk_row(
|
||||
tower_id="tower-2",
|
||||
tower_no="002",
|
||||
tower_type="耐张",
|
||||
terrain="丘陵",
|
||||
risk_level="medium",
|
||||
risk_grade=2,
|
||||
score=56,
|
||||
cause_analysis="地闪密度中等偏高",
|
||||
mitigation_recommendation="按高雷区口径校核绝缘与屏蔽配置",
|
||||
lightning_density=2.2,
|
||||
ground_resistance_ohm=9.0,
|
||||
slope_deg=3.5,
|
||||
protection_angle_deg=16.2,
|
||||
insulator_length_mm=2550.0,
|
||||
shield_wire_height_m=38.0,
|
||||
counterstrike_withstand_ka=105.0,
|
||||
counterstrike_trip_rate=0.052,
|
||||
shielding_withstand_ka=126.0,
|
||||
shielding_trip_rate=0.014,
|
||||
reason_details=[
|
||||
{"code": "lightning_density", "label": "地闪密度", "grade": 2, "triggered": True},
|
||||
{"code": "shield_wire_height", "label": "高度档次", "grade": 4, "triggered": False, "value": 38.0, "standard_value": 33.0},
|
||||
{"code": "terrain_slope", "label": "地面倾角档次", "grade": 4, "triggered": False, "value": 3.5},
|
||||
{"code": "insulator_length", "label": "绝缘子串长度档次", "grade": 4, "triggered": False, "value": 2550.0, "standard_value": 2265.0},
|
||||
{"code": "protection_angle", "label": "保护角", "grade": 3, "triggered": False, "value": 16.2},
|
||||
],
|
||||
)
|
||||
low_row = _build_risk_row(
|
||||
tower_id="tower-3",
|
||||
tower_no="003",
|
||||
tower_type="直线",
|
||||
terrain="平原",
|
||||
risk_level="low",
|
||||
risk_grade=1,
|
||||
score=18,
|
||||
cause_analysis="主要输入参数处于低风险区间",
|
||||
mitigation_recommendation="维持现有防雷配置并保持常规巡检",
|
||||
lightning_density=0.62,
|
||||
ground_resistance_ohm=4.0,
|
||||
slope_deg=1.2,
|
||||
protection_angle_deg=8.0,
|
||||
insulator_length_mm=3100.0,
|
||||
shield_wire_height_m=30.0,
|
||||
counterstrike_withstand_ka=132.8,
|
||||
counterstrike_trip_rate=0.008,
|
||||
shielding_withstand_ka=148.4,
|
||||
shielding_trip_rate=0.003,
|
||||
reason_details=[
|
||||
{"code": "shield_wire_height", "label": "高度档次", "grade": 5, "triggered": False, "value": 30.0, "standard_value": 33.0},
|
||||
{"code": "terrain_slope", "label": "地面倾角档次", "grade": 4, "triggered": False, "value": 1.2},
|
||||
{"code": "insulator_length", "label": "绝缘子串长度档次", "grade": 5, "triggered": False, "value": 3100.0, "standard_value": 2265.0},
|
||||
{"code": "protection_angle", "label": "保护角", "grade": 5, "triggered": False, "value": 8.0},
|
||||
],
|
||||
)
|
||||
return {
|
||||
"line": {
|
||||
"name": "示例线路",
|
||||
@@ -25,76 +174,10 @@ def _sample_report_data() -> dict[str, object]:
|
||||
"scenario_job_id": "scenario-job-1",
|
||||
"scenario_job_name": "示例线路-加装避雷器复算",
|
||||
"scenario_base_job_type": "normal",
|
||||
"non_construction": False,
|
||||
},
|
||||
"risk_rows": [
|
||||
{
|
||||
"tower_id": "tower-1",
|
||||
"tower_no": "001",
|
||||
"risk_level": "high",
|
||||
"result_json": {
|
||||
"score": 88,
|
||||
"cause_analysis": "接地电阻偏高;保护角暴露偏大",
|
||||
"mitigation_recommendation": "优先降低接地电阻;优化避雷线与保护角配置",
|
||||
"reason_details": [
|
||||
{"code": "ground_resistance", "label": "接地电阻", "grade": 1, "triggered": True},
|
||||
{"code": "protection_angle", "label": "保护角", "grade": 2, "triggered": True},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
"tower_id": "tower-2",
|
||||
"tower_no": "002",
|
||||
"risk_level": "medium",
|
||||
"result_json": {
|
||||
"score": 56,
|
||||
"cause_analysis": "地闪密度中等偏高",
|
||||
"mitigation_recommendation": "按高雷区口径校核绝缘与屏蔽配置",
|
||||
"reason_details": [
|
||||
{"code": "lightning_density", "label": "地闪密度", "grade": 2, "triggered": True},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
"tower_id": "tower-3",
|
||||
"tower_no": "003",
|
||||
"risk_level": "low",
|
||||
"result_json": {
|
||||
"score": 18,
|
||||
"cause_analysis": "主要输入参数处于低风险区间",
|
||||
"mitigation_recommendation": "维持现有防雷配置并保持常规巡检",
|
||||
"reason_details": [],
|
||||
},
|
||||
},
|
||||
],
|
||||
"selected_risk_rows": [
|
||||
{
|
||||
"tower_id": "tower-1",
|
||||
"tower_no": "001",
|
||||
"risk_level": "high",
|
||||
"result_json": {
|
||||
"score": 88,
|
||||
"cause_analysis": "接地电阻偏高;保护角暴露偏大",
|
||||
"mitigation_recommendation": "优先降低接地电阻;优化避雷线与保护角配置",
|
||||
"reason_details": [
|
||||
{"code": "ground_resistance", "label": "接地电阻", "grade": 1, "triggered": True},
|
||||
{"code": "protection_angle", "label": "保护角", "grade": 2, "triggered": True},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
"tower_id": "tower-2",
|
||||
"tower_no": "002",
|
||||
"risk_level": "medium",
|
||||
"result_json": {
|
||||
"score": 56,
|
||||
"cause_analysis": "地闪密度中等偏高",
|
||||
"mitigation_recommendation": "按高雷区口径校核绝缘与屏蔽配置",
|
||||
"reason_details": [
|
||||
{"code": "lightning_density", "label": "地闪密度", "grade": 2, "triggered": True},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
"risk_rows": [high_row, medium_row, low_row],
|
||||
"selected_risk_rows": [high_row, medium_row],
|
||||
"selected_mitigation_rows": [
|
||||
{
|
||||
"tower_id": "tower-1",
|
||||
@@ -104,9 +187,27 @@ def _sample_report_data() -> dict[str, object]:
|
||||
"current_risk_level": "high",
|
||||
"expected_risk_level": "medium",
|
||||
"recommendation_result": "需要安装避雷器",
|
||||
"non_construction": False,
|
||||
"inputs": {
|
||||
"ground_resistance_ohm": 18.0,
|
||||
"insulator_length_mm": 2400.0,
|
||||
"protection_angle_deg": 23.0,
|
||||
"lightning_density": 4.2,
|
||||
},
|
||||
"mitigation_actions": [
|
||||
{"code": "grounding_upgrade", "label": "接地治理", "summary": "降低接地电阻"},
|
||||
{"code": "arrester_install", "label": "安装避雷器", "summary": "关键相增设避雷器"},
|
||||
{
|
||||
"code": "grounding_upgrade",
|
||||
"label": "接地治理",
|
||||
"summary": "降低接地电阻",
|
||||
"current_value": 18.0,
|
||||
"target_value": 5.0,
|
||||
},
|
||||
{
|
||||
"code": "arrester_install",
|
||||
"label": "安装避雷器",
|
||||
"summary": "关键相增设避雷器",
|
||||
"phases": ["A", "B", "C"],
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
@@ -152,8 +253,12 @@ def test_build_report_document_renders_word_compatible_html() -> None:
|
||||
assert filename.endswith(".doc")
|
||||
assert "示例线路-报告" in filename
|
||||
assert "示例线路" in html
|
||||
assert "2.3线路杆塔高度" in html
|
||||
assert "图7 线路杆塔地闪密度雷区分布图(表格替代)" in html
|
||||
assert "图8 线路杆塔避雷线保护角信息统计图" in html
|
||||
assert "表10 输电线路雷击风险等级划分规则" in html
|
||||
assert "表13 高风险杆塔差异化防雷措施" in html
|
||||
assert "雷害风险评估结果" in html
|
||||
assert "差异化防雷措施与预期效果" in html
|
||||
assert "安装避雷器" in html
|
||||
assert "表14 采取措施后的计算结果表" in html
|
||||
assert "反击耐雷水平(kA)" in html
|
||||
|
||||
Reference in New Issue
Block a user