feat(b06,b07): 표 위 CAD 칸 미리 넣음 = 구조물 조합 이름 + 좌측 패널 옵션 줄 (166-1)
- 구조물마다 조합 줄 뒤에 좌측 패널 옵션 줄 — 폼과 같은 컨테이너 · 이름 · 보이는 칸(`structureOptionLines`) · 구조 갈래에 안 맞는 옛 값 뺌 · 필수 상자 빈 칸 = 폼 기본값 - B06 [상세] 모달 = 화면 TS 직접 · B07 = 같은 TS 를 Node 번들(B07_DesignDetail_Note_Options_Node · build:b07-note)로 받아 파이썬 짝이 붙임 · 실패는 조합 줄만 - 번들 낡음 판정에 A00_Common/design 더함 - 시험 test_166_1(진짜 명세 · B07 = 화면 같은 줄) · test_260 · test_265 기대값 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LLCk2y5xE8YGVgjbTntWsY
This commit is contained in:
@@ -7,20 +7,31 @@ B06 [상세] 모달을 한 번도 안 연 측점(칸 = 없음)에 B07 이 같은
|
||||
(빈 엔티티)은 덮지 않음 · 옛 글(`structure_note`)이 있으면 옛 글이 먼저
|
||||
(모달이 처음 열 때 옮기는 차례와 같음).
|
||||
그림 = 관 주인 측점 원형 마크(배수관 · Φ · L 정수) + 측점 · 그 측점 구조물마다 지정된
|
||||
구조물 조합 이름 줄(미지정 = 「이름 조합 미지정」).
|
||||
구조물 조합 이름 줄(미지정 = 「이름 조합 미지정」) + 그 구조물 좌측 패널 옵션 줄(166-1).
|
||||
옵션 줄은 파이썬으로 다시 짜지 않음 — 화면과 같은 TS(`structureOptionLines`)를 Node
|
||||
진입점(`B07_DesignDetail_Note_Options_Node.ts` · CLAUDE.md 5장 ②)으로 돌려 받음 ·
|
||||
실패는 비치명(조합 줄만).
|
||||
좌표 = 도면 mm(글 2.0 · 줄 3.0) · 칸 왼쪽 위 = (0, 0) · 아래로 음수.
|
||||
"""
|
||||
|
||||
import json
|
||||
import logging
|
||||
import math
|
||||
import re
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from B05_Profile.B05_Profile_Structures_Repository import load_structures
|
||||
from B05_Profile.B05_Profile_Structures_Schema import load_structure_types
|
||||
from B05_Profile.B05_Profile_Structures_Schema import load_definition, load_structure_types
|
||||
from B06_Section.B06_Section_Engine_Culvert import _culvert_set, pipe_points_file
|
||||
from common_util.common_util_drainage_pipes import PIPE_FACILITY_PIPE, parse_pipe_points
|
||||
from common_util.common_util_node_bundle import run_bundle_json
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
_OPTIONS_BUNDLE = ROOT / "config" / "b07_note_node" / "B07_DesignDetail_Note_Options_Node.js"
|
||||
_OPTIONS_NPM = "build:b07-note"
|
||||
|
||||
# TS `PIPE_MATCH_M`(`design_selection`) — 관 · 구조물 자리와 측점이 같은 자리로 보는 폭
|
||||
PIPE_MATCH_M = 0.51
|
||||
@@ -35,7 +46,8 @@ _GROUP_ID = re.compile(r"^g[0-9a-z]{1,16}$")
|
||||
|
||||
#: (관 누가거리, 세트, 옵션) — 원형 마크 재료
|
||||
Pipe = tuple[float, dict[str, Any], dict[str, Any]]
|
||||
#: 글 줄 재료 한 건 `{name, pipe, at, summary_item, group_items}` — TS `NoteThing`
|
||||
#: 글 줄 재료 한 건 `{name, pipe, at, summary_item, group_items, type_id, options, option_lines}`
|
||||
#: — TS `NoteThing`(option_lines = `optionLines`)
|
||||
Thing = dict[str, Any]
|
||||
|
||||
|
||||
@@ -98,22 +110,23 @@ def things_at(things: list[Thing], chainage_m: float) -> list[Thing]:
|
||||
def structure_note_lines(things: list[Thing], chainage_m: float) -> list[str]:
|
||||
"""구조물 조합 줄 — TS `structureNoteLines` 짝.
|
||||
|
||||
본체 → 그룹 차례 · 같은 이름 한 줄 · 미지정 = 「이름 조합 미지정」 · 배관 본체 뺌.
|
||||
본체 → 그룹 차례 · 같은 이름 한 줄 · 미지정 = 「이름 조합 미지정」 · 배관 본체 뺌 ·
|
||||
이어서 그 구조물 좌측 패널 옵션 줄(`option_lines` · 166-1).
|
||||
"""
|
||||
lines: list[str] = []
|
||||
for thing in things_at(things, chainage_m):
|
||||
own = _summary_item(thing.get("summary_item"))
|
||||
slots = ([("", own)] if own else []) + _group_items(thing.get("group_items"))
|
||||
if not slots:
|
||||
if not thing["pipe"]:
|
||||
lines.append(f"{thing['name']} 조합 미지정")
|
||||
continue
|
||||
names = [
|
||||
item["name"] or item["key"]
|
||||
for gid, item in slots
|
||||
if not (thing["pipe"] and gid in ("", _PIPE_BODY_LINK))
|
||||
]
|
||||
lines += list(dict.fromkeys(names))
|
||||
if slots:
|
||||
lines += list(dict.fromkeys(names))
|
||||
elif not thing["pipe"]:
|
||||
lines.append(f"{thing['name']} 조합 미지정")
|
||||
lines += [str(line) for line in thing.get("option_lines") or []]
|
||||
return lines
|
||||
|
||||
|
||||
@@ -207,6 +220,8 @@ def _things(points: list[Any], structures: list[Any], names: dict[str, str]) ->
|
||||
"at": float(point.chainage_m),
|
||||
"summary_item": point.summary_item,
|
||||
"group_items": point.group_items,
|
||||
"type_id": point.facility,
|
||||
"options": dict(point.options or {}),
|
||||
}
|
||||
for point in points
|
||||
]
|
||||
@@ -221,11 +236,46 @@ def _things(points: list[Any], structures: list[Any], names: dict[str, str]) ->
|
||||
"at": float(at),
|
||||
"summary_item": item.summary_item,
|
||||
"group_items": item.group_items,
|
||||
"type_id": item.type_id,
|
||||
"options": dict(item.options or {}),
|
||||
}
|
||||
)
|
||||
return things
|
||||
|
||||
|
||||
def with_option_lines(things: list[Thing]) -> list[Thing]:
|
||||
"""구조물마다 좌측 패널 옵션 줄(166-1) — 화면 TS 를 Node 로 한 번에 · 실패면 그대로."""
|
||||
if not things:
|
||||
return things
|
||||
try:
|
||||
# 지연 import — M02 정의 저장소가 B07 엔진 import 차례에 끼지 않게
|
||||
from M02_MasterTemplete.StructOptions.M02_SO_Options import with_visible
|
||||
|
||||
payload = {
|
||||
"things": [
|
||||
{"type_id": t["type_id"], "options": t.get("options") or {}} for t in things
|
||||
],
|
||||
"types": with_visible().model_dump(mode="json")["types"],
|
||||
"definition": load_definition(),
|
||||
}
|
||||
output = run_bundle_json(_OPTIONS_BUNDLE, _OPTIONS_NPM, payload)
|
||||
except Exception:
|
||||
logger.warning("B07 CAD 칸 옵션 줄 계산 실패 — 조합 줄만 넣음", exc_info=True)
|
||||
return things
|
||||
rows = output.get("lines") if isinstance(output, dict) else None
|
||||
if not isinstance(rows, list) or len(rows) != len(things):
|
||||
return things
|
||||
return [
|
||||
{
|
||||
**thing,
|
||||
"option_lines": [line for line in row if isinstance(line, str)]
|
||||
if isinstance(row, list)
|
||||
else [],
|
||||
}
|
||||
for thing, row in zip(things, rows)
|
||||
]
|
||||
|
||||
|
||||
def load_note_sources(project_root: Path) -> tuple[list[Pipe], list[Thing]]:
|
||||
"""정본 재료 — (원형 마크 배수관 · 관경 안 고름 = 없음, 글 줄 재료 = 관 지점 + 구조물 배치)."""
|
||||
try:
|
||||
@@ -242,7 +292,7 @@ def load_note_sources(project_root: Path) -> tuple[list[Pipe], list[Thing]]:
|
||||
pipes.append((float(point.chainage_m), spec, options))
|
||||
_revision, structures = load_structures(str(project_root))
|
||||
names = {kind.type_id: kind.name for kind in load_structure_types()}
|
||||
return pipes, _things(points, structures, names)
|
||||
return pipes, with_option_lines(_things(points, structures, names))
|
||||
|
||||
|
||||
def with_structure_note(
|
||||
|
||||
Reference in New Issue
Block a user