- 잇기 단추 글 「고르기」 → 「선택」(명세 · 정의 그룹 · 종류 단위 줄 공용) - 「지난 정의 값」 상자 모든 종류에서 숨김 — 값은 파일에 그대로 · 코드 남김 - 관 길이 = 보여 주는 칸(손 입력 칸 아님 · 정수 · 횡단 전 「횡단 설계 뒤 셈」) - 유입 집수정 = 길이 · 기준측점 전 · 후 칸 숨김 · 옛 값은 병합이 지킴 - 배관 유출 칸에 읽기 줄(관 길이 · 좌우 자동 자리 안내) 안 옮김 - [흙막이 추가] 없앰 — 흙막이 컨테이너 수 = 유출 「추가 기슭막이(단)」 N(늘 보임 · 줄면 끝에서 빠짐 · 잇기 함께 풂 · 이름 흙막이) - 단 수 소스 = 횡단 세션 값 → 캐시 patch · 종단 보기도 같은 횡단 자료(B05 = B06) - 지형이 단을 못 세워 되돌릴 때 캐시 patch 도 맞춤(옛 수로 돌아가던 흠) - 집계표 선택 컨테이너 이름 짝(서버) 흙막이 · 시험 기대값 · 52-1 · 52-13 화면 시나리오 고침 · 54-1 화면 점검 추가 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVPp2o6Mh2FZJr72yW3ofZ
188 lines
7.8 KiB
JavaScript
188 lines
7.8 KiB
JavaScript
/* 52-13 — 명세 폼 예외 모음(배관 1 · BOX암거 · 세월교 1) — 빈 값 · 오가기 · 종류 바꾸기 · 여러 개
|
|
* 시작 화면: B05 종단설계(#/b05-profile) · 검증 프로젝트 · 목록에 「배관 1」 「세월교 1」 · 로그인 상태
|
|
* 부르는 법: 단계마다 한 번씩 — 앞에 `window.__m5213 = "단계";` 를 붙여
|
|
* cache → 저장 안 하고 B05 → B06 → B05 오가기(캐시 값 그대로) · 종류 바꾸기(배관 → BOX → 배관)
|
|
* pipe → 배관 길이 · 전 · 후 비움 + 도수로/돌붙임 하나 → [저장](흙막이 = 유출 단 수 · [추가] 없음 · 54-1)
|
|
* (orca reload) pipe_v → 다시 열기 · 흙막이 수 = 저장 전 그대로 · 비운 칸 그대로
|
|
* bf → 258.12 를 BOX암거로(PUT) · 가로 비움 · 세월교 1 월류 폭 비움 → [저장]
|
|
* (orca reload) bf_v → 다시 열기 · 오류 없음
|
|
* restore → 원래 관 지점으로 되돌림(PUT) · 초안 비움
|
|
* 쓰는 것: 검증 프로젝트 pipe_points.json(되돌림 단계가 원래 값으로 다시 씀)
|
|
* 기대 수치: errors 0 · cache.same true · kind.leak 0 · soilCount pipe = pipe_v · soilAdd 0 · inletBlank 빈 칸 셋 · restored true
|
|
* (배관 도수로/돌붙임 [추가] 는 하나 뒤에도 보임 — 「하나만」은 물넘이 포장 · 기타만 · 52-3 · 52-10)
|
|
*/
|
|
(async () => {
|
|
const MODE = window.__m5213 || "cache";
|
|
const w = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
const until = async (fn, ms = 20000) => {
|
|
for (let t = 0; t < ms; t += 200) {
|
|
if (fn()) return true;
|
|
await w(200);
|
|
}
|
|
return false;
|
|
};
|
|
const errors = [];
|
|
const onErr = (e) => errors.push(String(e.message ?? e.reason ?? e));
|
|
window.addEventListener("error", onErr);
|
|
window.addEventListener("unhandledrejection", onErr);
|
|
const projectId = localStorage.getItem("frd_current_project_id");
|
|
const modUrl = (part) =>
|
|
performance
|
|
.getEntriesByType("resource")
|
|
.map((e) => e.name)
|
|
.filter((n) => n.includes(part))
|
|
.pop();
|
|
const fetchApi = await import(modUrl("/B04_PreProcess/B04_PreProcess_Api_Fetch.ts"));
|
|
const spec = () =>
|
|
[...document.querySelectorAll(".b05-structure__spec")].find((n) => n.offsetParent !== null);
|
|
const box = (c, i = 0) => spec()?.querySelectorAll(`[data-spec-container="${c}"]`)[i];
|
|
const ctl = (c, item, i = 0) =>
|
|
box(c, i)?.querySelector(`[data-spec-item="${c}.${item}"]`)?.querySelector("select, input");
|
|
const set = async (c, item, v, i = 0) => {
|
|
const el = ctl(c, item, i);
|
|
el.value = v;
|
|
el.dispatchEvent(new Event("change", { bubbles: true }));
|
|
await w(200);
|
|
};
|
|
const clearDrafts = () => {
|
|
for (const k of Object.keys(sessionStorage))
|
|
if (k.startsWith("aislo:draft:pipes:")) sessionStorage.removeItem(k);
|
|
};
|
|
const pick = async (re) => {
|
|
const find = () =>
|
|
[...document.querySelectorAll(".b05-route__irregular-list li")].find((l) =>
|
|
re.test(l.textContent.trim()),
|
|
);
|
|
await until(() => !!find());
|
|
const li = find();
|
|
(li.querySelector("button") ?? li).click();
|
|
await until(() => !!spec(), 6000);
|
|
if (!spec()) (li.querySelector("button") ?? li).click();
|
|
await until(() => !!spec());
|
|
await w(500);
|
|
};
|
|
const save = async () => {
|
|
document.querySelector('[data-dock-action="save"]').click();
|
|
await w(500);
|
|
return until(() => !document.querySelector(".ui-overlay.is-active"), 60000);
|
|
};
|
|
const items = () =>
|
|
[...spec().querySelectorAll("[data-spec-item]")].map((n) => n.dataset.specItem);
|
|
const point = async (lo, hi) =>
|
|
(await fetchApi.fetchDetailPipePoints(projectId)).pipe_points.find(
|
|
(p) => p.chainage_m > lo && p.chainage_m < hi,
|
|
);
|
|
const out = { mode: MODE };
|
|
|
|
if (MODE === "cache") {
|
|
await pick(/배관 1$/);
|
|
await set("inlet", "structure", "기슭막이");
|
|
await set("inlet", "length", "12");
|
|
out.before = ctl("inlet", "length").value;
|
|
location.hash = "#/b06-section";
|
|
await w(7000);
|
|
location.hash = "#/b05-profile";
|
|
await w(7000);
|
|
await pick(/배관 1$/);
|
|
out.after = ctl("inlet", "length")?.value;
|
|
out.same = out.before === out.after;
|
|
clearDrafts();
|
|
}
|
|
|
|
if (MODE === "pipe") {
|
|
sessionStorage.setItem(
|
|
"__5213_original",
|
|
JSON.stringify((await fetchApi.fetchDetailPipePoints(projectId)).pipe_points),
|
|
);
|
|
await pick(/배관 1$/);
|
|
await set("inlet", "structure", "기슭막이");
|
|
await set("inlet", "form", "돌망태");
|
|
await set("inlet", "length", "");
|
|
await set("inlet", "before", "");
|
|
await set("inlet", "after", "");
|
|
out.soilAdd = spec().querySelectorAll('[data-spec-add="soil_add"]').length;
|
|
spec().querySelector('[data-spec-add="chute_add"]').click();
|
|
await w(200);
|
|
await set("chute_add", "structure", "돌붙임");
|
|
out.soilCount = spec().querySelectorAll('[data-spec-container="soil_add"]').length;
|
|
out.saved = await save();
|
|
const p = await point(80, 90);
|
|
out.file = p && p.options;
|
|
}
|
|
|
|
if (MODE === "pipe_v") {
|
|
await pick(/배관 1$/);
|
|
out.soilCount = spec().querySelectorAll('[data-spec-container="soil_add"]').length;
|
|
out.chuteAdd = !!spec().querySelector('[data-spec-add="chute_add"]');
|
|
out.inletBlank = ["length", "before", "after"].map((k) => ctl("inlet", k)?.value);
|
|
}
|
|
|
|
if (MODE === "bf") {
|
|
const orig = (await fetchApi.fetchDetailPipePoints(projectId)).pipe_points;
|
|
if (!sessionStorage.getItem("__5213_original"))
|
|
sessionStorage.setItem("__5213_original", JSON.stringify(orig));
|
|
const pts = JSON.parse(JSON.stringify(orig)).map((p) =>
|
|
Math.abs(p.chainage_m - 258.12) < 0.05
|
|
? { ...p, facility: "box_culvert", options: { body_width_m: 3, body_height_m: 2.5 } }
|
|
: p,
|
|
);
|
|
await fetchApi.saveDetailPipePoints(projectId, pts);
|
|
clearDrafts();
|
|
out.ready = true;
|
|
}
|
|
|
|
if (MODE === "bf_edit") {
|
|
await pick(/BOX암거$/);
|
|
await set("body", "size", "사용자 입력");
|
|
await set("body", "width", "");
|
|
out.boxSaved = await save();
|
|
out.boxFile = (await point(250, 260))?.options;
|
|
await pick(/세월교 1$/);
|
|
await set("ford", "width", "");
|
|
out.fordSaved = await save();
|
|
out.fordFile = (await point(170, 176))?.options;
|
|
}
|
|
|
|
if (MODE === "bf_v") {
|
|
await pick(/BOX암거$/);
|
|
out.box = { size: ctl("body", "size")?.value, width: ctl("body", "width")?.value };
|
|
await pick(/세월교 1$/);
|
|
out.ford = { width: ctl("ford", "width")?.value, height: ctl("ford", "height")?.value };
|
|
}
|
|
|
|
if (MODE === "kind") {
|
|
const sec = document.querySelector(".b05-structure-section");
|
|
const sel = () => sec.querySelectorAll(".b05-structure__grid select");
|
|
const fire = (el, v) => {
|
|
el.value = v;
|
|
el.dispatchEvent(new Event("change", { bubbles: true }));
|
|
};
|
|
const seen = {};
|
|
for (const t of ["pipe", "box_culvert", "pipe"]) {
|
|
fire(sel()[0], "A");
|
|
await w(300);
|
|
fire(sel()[1], t);
|
|
await w(600);
|
|
seen[t + "#" + Object.keys(seen).length] = items().join(",");
|
|
}
|
|
const vals = Object.values(seen);
|
|
out.seen = vals;
|
|
out.leak = vals[0] === vals[2] && !/body\./.test(vals[0]) && !/pipe\./.test(vals[1]) ? 0 : 1;
|
|
}
|
|
|
|
if (MODE === "restore") {
|
|
const original = JSON.parse(sessionStorage.getItem("__5213_original") || "null");
|
|
if (!original) return JSON.stringify({ error: "원래 값 없음" });
|
|
await fetchApi.saveDetailPipePoints(projectId, original);
|
|
clearDrafts();
|
|
sessionStorage.removeItem("__5213_original");
|
|
const now = (await fetchApi.fetchDetailPipePoints(projectId)).pipe_points;
|
|
out.restored =
|
|
JSON.stringify(now.map((p) => [p.chainage_m, p.facility ?? null, p.options ?? null])) ===
|
|
JSON.stringify(original.map((p) => [p.chainage_m, p.facility ?? null, p.options ?? null]));
|
|
}
|
|
|
|
out.errors = errors;
|
|
return JSON.stringify(out);
|
|
})();
|