From e5ba2df9c70f1d46288d322093d5971b3b5fd686 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Mon, 19 Oct 2026 13:54:24 +0900 Subject: [PATCH] =?UTF-8?q?refactor(472-5=205-D=20=EB=82=98=EB=88=94):=20?= =?UTF-8?q?=EC=B8=A1=EC=A0=90=20=EC=A1=B0=EC=A0=95=EC=B0=BD=20=EC=A0=9C?= =?UTF-8?q?=EC=96=B4=20687=20=EC=A4=84=20=E2=86=92=20=EC=A0=80=EC=9E=A5=20?= =?UTF-8?q?=EB=AC=B6=EC=9D=8C=20=EC=A0=91=EA=B8=B0=20=EB=84=B7(4=EC=B6=95?= =?UTF-8?q?=20=C2=B7=20=EC=97=B0=EB=8F=99=20=C2=B7=20=EB=8B=A8=20=EC=88=98?= =?UTF-8?q?=20=C2=B7=20=EB=8B=A8=EB=B3=84=20=EA=B5=AC=EA=B0=84)=EC=9D=84?= =?UTF-8?q?=20Link=5FSession=20=EC=9C=BC=EB=A1=9C=20=C2=B7=20646=20?= =?UTF-8?q?=EC=A4=84=20=C2=B7=20=EB=8F=99=EC=9E=91=20=EA=B0=99=EC=9D=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- .../B06_Section_UI_Page_Link_Session.ts | 70 ++++++++++++++++++- .../B06_Section_UI_Page_Station_Controls.ts | 59 +++------------- 2 files changed, 78 insertions(+), 51 deletions(-) diff --git a/B06_Section/B06_Section_UI_Page_Link_Session.ts b/B06_Section/B06_Section_UI_Page_Link_Session.ts index 90077a288..ffefdcafb 100644 --- a/B06_Section/B06_Section_UI_Page_Link_Session.ts +++ b/B06_Section/B06_Section_UI_Page_Link_Session.ts @@ -9,7 +9,7 @@ * 검증 → 담기 / 쓰기 → 통째 직렬화)이라 제어기마다 짝을 두던 것을 하나로 모았다. * ========================================================================== */ -import type { CrossSection } from "./B06_Section_Api_Fetch"; +import type { CrossSection, StoredWallSpan } from "./B06_Section_Api_Fetch"; import type { RevetKey } from "./B06_Section_UI_Cross_Culvert"; import type { WallAdjust } from "./B06_Section_UI_Cross_Culvert_Types"; import { @@ -23,6 +23,7 @@ import { type InletStructureControl, type RevetLinkControl, type RevetOffsetControl, + type SpanValues, } from "./B06_Section_UI_Cross_Culvert_Wire"; import { culvertCardState } from "./B06_Section_UI_Cross_View_Structure"; import type { PipeRevetChoice } from "../A00_Common/design/design_structure_pipe_calc"; @@ -156,6 +157,73 @@ export function createLinkFlagSession(sessionKey: () => string | null): LinkFlag }; } +/* ── 확정 · 임시저장 payload — 세션 키(누가거리 · `:역할` · `b` 앞머리)를 측점별로 되접음 ── */ +type Each = Pick, "forEach">; + +/** 측점별 기슭막이 4축 조작값(역할 → 값 · null = 되돌림). */ +export function foldRevetAdjusts( + shifts: Each, +): Map> { + const result = new Map>(); + shifts.forEach((adjust, key) => { + const [chainage, role] = key.split(":"); + const value = Number(chainage); + if (!Number.isFinite(value) || !role) return; + const bucket = result.get(value) ?? {}; + bucket[role] = adjust; + result.set(value, bucket); + }); + return result; +} + +/** 측점별 연동 해제 · 종단경사 반영 플래그. */ +export function foldLinkFlags( + detachedFlags: Each, + gradeFlags: Each, +): Map { + const result = new Map(); + const put = (key: string, patch: { detached?: boolean; followGrade?: boolean }): void => { + const value = Number(key); + if (!Number.isFinite(value)) return; + result.set(value, { ...(result.get(value) ?? {}), ...patch }); + }; + detachedFlags.forEach((detached, key) => put(key, { detached })); + gradeFlags.forEach((followGrade, key) => put(key, { followGrade })); + return result; +} + +/** 측점별 다단 단 수 — 세션에 있는 쪽만 · 없는 쪽은 바탕(캐시 설계) 값 그대로(445 H3 · `mergeCrossPatches`). */ +export function foldExtraCounts( + counts: Each, +): Map> { + const result = new Map>(); + counts.forEach((count, key) => { + const basin = key.startsWith("b"); + const value = Number(basin ? key.slice(1) : key); + if (!Number.isFinite(value)) return; + const bucket = result.get(value) ?? {}; + bucket[basin ? "basin" : "outlet"] = count; + result.set(value, bucket); + }); + return result; +} + +/** 측점별 다단 단별 구간값. */ +export function foldExtraSpans( + spans: Each, +): Map> { + const result = new Map>(); + spans.forEach((value, key) => { + const [chainage, wall] = key.split(":"); + const chainageM = Number(chainage); + if (!Number.isFinite(chainageM) || !wall) return; + const bucket = result.get(chainageM) ?? {}; + bucket[wall] = { length_m: value.lengthM, before_m: value.beforeM, after_m: value.afterM }; + result.set(chainageM, bucket); + }); + return result; +} + /** * 연동을 푸는 순간(카드 [연동] · 좌측 [연동] 둘 다 · 139-2) — 그 카드가 그리던 벽마다 4축을 이 * 측점 값으로 굳힘: 위치(x · d) = 소유 측점 적용값(물려받던 값) · 높이 · 형태 = 그 카드가 그린 값. diff --git a/B06_Section/B06_Section_UI_Page_Station_Controls.ts b/B06_Section/B06_Section_UI_Page_Station_Controls.ts index 86de72a45..d23e749c1 100644 --- a/B06_Section/B06_Section_UI_Page_Station_Controls.ts +++ b/B06_Section/B06_Section_UI_Page_Station_Controls.ts @@ -29,6 +29,10 @@ import { createBodyControls } from "./B06_Section_UI_Page_Ford_Controls"; import { createLinkFlagSession, createSessionMap, + foldExtraCounts, + foldExtraSpans, + foldLinkFlags, + foldRevetAdjusts, freezeLinkedWalls, } from "./B06_Section_UI_Page_Link_Session"; import { createSpanControl } from "./B06_Section_UI_Page_Span_Control"; @@ -613,56 +617,11 @@ export function createStationControls(deps: StationControlDeps): StationControls widths: stationWidths, inletStructures, basinAdjustments, - // 확정·임시저장 payload용 — 세션 키(누가거리:역할)를 측점별로 되접는다. - revetAdjustsByChainage: () => { - const result = new Map>(); - revetShifts.forEach((adjust, key) => { - const [chainage, role] = key.split(":"); - const value = Number(chainage); - if (!Number.isFinite(value) || !role) return; - const bucket = result.get(value) ?? {}; - bucket[role] = adjust; - result.set(value, bucket); - }); - return result; - }, - // 확정 payload용 — 측점별 연동 해제·종단경사 반영 플래그. - linkFlagsByChainage: () => { - const result = new Map(); - const put = (key: string, patch: { detached?: boolean; followGrade?: boolean }): void => { - const value = Number(key); - if (!Number.isFinite(value)) return; - result.set(value, { ...(result.get(value) ?? {}), ...patch }); - }; - linkDetached.forEach((detached, key) => put(key, { detached })); - followGrades.forEach((followGrade, key) => put(key, { followGrade })); - return result; - }, - extraCountsByChainage: () => { - // 세션에 있는 쪽만 — 없는 쪽은 바탕(캐시 설계) 값 그대로(445 H3 · `mergeCrossPatches`) - const result = new Map>(); - extraCounts.forEach((count, key) => { - const basin = key.startsWith("b"); - const value = Number(basin ? key.slice(1) : key); - if (!Number.isFinite(value)) return; - const bucket = result.get(value) ?? {}; - bucket[basin ? "basin" : "outlet"] = count; - result.set(value, bucket); - }); - return result; - }, - extraSpansByChainage: () => { - const result = new Map>(); - extraSpans.forEach((value, key) => { - const [chainage, wall] = key.split(":"); - const chainageM = Number(chainage); - if (!Number.isFinite(chainageM) || !wall) return; - const bucket = result.get(chainageM) ?? {}; - bucket[wall] = { length_m: value.lengthM, before_m: value.beforeM, after_m: value.afterM }; - result.set(chainageM, bucket); - }); - return result; - }, + // 확정·임시저장 payload용 — 세션 키를 측점별로 되접음(`_Link_Session`) + revetAdjustsByChainage: () => foldRevetAdjusts(revetShifts), + linkFlagsByChainage: () => foldLinkFlags(linkDetached, followGrades), + extraCountsByChainage: () => foldExtraCounts(extraCounts), + extraSpansByChainage: () => foldExtraSpans(extraSpans), flushCulvertOptions: () => culvertOptions.flush(), queueCulvertOptions: (chainageM, patch) => culvertOptions.queue(chainageM, patch), load: () => {