feat(m02-df): 36-2 덧 — 재료 조건 찾기 「검색어」 틀 · 표 범위 경계 규칙 칸
- Model CfMaterialRule field 「검색어」 + template(「레미콘 {a}-{b}-{c}」) + slots(자리마다 알약) · materialSources · depends · 흐름 따라가기에 자리 알약도
- Compute 재료 조건 찾기 검색어 = 틀에 자리 알약 값을 끼운 글(옛 fill)을 dv.slot_price 값으로 넘김(서버 찾기는 sub4)
- 표 찾기: 표 블록 「·범위규칙」 칸(줄마다 초과·이하 · 이상·이하 · 이상·미만 · 이하)을 Rule lookup · Compute _lookup 이 따름 · 없으면 초과·이하
- 변환: 재료 검색어 자리 = 검색어 틀 · scope 구분 · 상세구분 · 조건 찾기 요소로 들어가는 선은 안 만듦(depends 로 이음)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VBToTCGk5dqDKeXCEP3vhk
This commit is contained in:
@@ -27,9 +27,19 @@ export interface CfScope {
|
||||
* field 「키」 = 요소 ref 의 자리 표시 {…} 에 알약 값을 끼운 요소(op 같음) — ref 꼴 「EQ:{기계}」 · 「EQ:{기계}#가격」 ·
|
||||
* 「MO:경유:{지역}」 · 「LB:{직종}」 · 재료 검색어 묶음 JSON(검색어 안 {…}) · 옛 엔진 `fill` → `Master.get` 과 같은 뜻 */
|
||||
export interface CfMaterialRule {
|
||||
field: "규격" | "이름" | "키";
|
||||
field: "규격" | "이름" | "키" | "검색어";
|
||||
op: "포함" | "같음";
|
||||
from: CfPort;
|
||||
/** field 「검색어」 — 옛 재료 검색어 찾기(master_pick.search) 의 틀(「레미콘 {a}-{b}-{c}」) · scope 구분 · 상세구분 안 */
|
||||
template?: string;
|
||||
/** 틀의 자리 {이름} 마다 값을 줄 알약 — from = 첫 자리 */
|
||||
slots?: { name: string; from: CfPort }[];
|
||||
}
|
||||
|
||||
/** 재료 조건 찾기가 값을 받는 알약 — from + 틀 자리들(겹침 없이) */
|
||||
export function materialSources(rule: CfMaterialRule): CfPort[] {
|
||||
const all = [rule.from, ...(rule.slots ?? []).map((x) => x.from)];
|
||||
return all.filter((p, i) => all.findIndex((q) => q.box === p.box && q.name === p.name) === i);
|
||||
}
|
||||
|
||||
/** 입력 상자가 고른 요소 — ref = 마스터 키 또는 사용자 요소 id
|
||||
@@ -446,7 +456,8 @@ export function depends(lg: CfLogic): { from: string; to: string }[] {
|
||||
}
|
||||
for (const b of lg.boxes)
|
||||
for (const e of b.input?.elements ?? [])
|
||||
if (e.mode === "rule" && e.rule) out.push({ from: e.rule.from.box, to: b.id });
|
||||
if (e.mode === "rule" && e.rule)
|
||||
for (const p of materialSources(e.rule)) out.push({ from: p.box, to: b.id });
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -584,7 +595,8 @@ export function traceBack(lg: CfLogic, port: CfPort): CfStep[] {
|
||||
lg.links.find((l) => l.to.box === box.id && l.to.name === q.name),
|
||||
);
|
||||
for (const e of box.input?.elements ?? [])
|
||||
if (e.mode === "rule" && e.rule && elementPort(e) === p.name) visit(e.rule.from, "out");
|
||||
if (e.mode === "rule" && e.rule && elementPort(e) === p.name)
|
||||
for (const q of materialSources(e.rule)) visit(q, "out");
|
||||
};
|
||||
const box = boxOf(lg, port.box);
|
||||
if (!box) return [];
|
||||
@@ -630,7 +642,11 @@ export function traceForward(lg: CfLogic, port: CfPort): CfStep[] {
|
||||
visit(l.to, "in", l);
|
||||
for (const b of lg.boxes)
|
||||
for (const e of b.input?.elements ?? [])
|
||||
if (e.mode === "rule" && e.rule?.from.box === p.box && e.rule.from.name === p.name)
|
||||
if (
|
||||
e.mode === "rule" &&
|
||||
e.rule &&
|
||||
materialSources(e.rule).some((q) => q.box === p.box && q.name === p.name)
|
||||
)
|
||||
visit({ box: b.id, name: elementPort(e) }, "out");
|
||||
};
|
||||
const box = boxOf(lg, port.box);
|
||||
|
||||
Reference in New Issue
Block a user