- Hopyo_Sheet.ts: [수정] = 시트 아래 줄 판(createJudgeRows · 그 호표 자리 뜀) · 오른쪽 판 아래 [옮기기](createJudgeMove) · 고름 캐시 한 벌 · 옮긴 뒤 목록 · 칠 · 단가산출 목록 다시 읽음 - Hopyo_SheetSk.ts: 단가산출 목록 = 새 블록 판정(hopyo-judge 목록 · 판정 · 고를 것 n · 표지 · 부름 · 만든 SK · 캐시 확인) · 줄 누름 = 그 자리 + 블록 판(createJudgeBlock) - Hopyo_JudgeApi.ts: 목록 블록 줄 판정 · 고를수 · Block.ts 타입 흠 둘 - 낡은 시험 고침(까닭 = 785-6 이 옛 마법사 단가산출 칸 · 확인 창을 새 판으로 갈음): test_627_sheet_sk(판 바꿈 · 강조 · 뛰기를 새 목록으로 · helper_778_5 sheetSk 대역 새 꼴) · test_785_4 줄 판 자리 손잡이 · test_m02_hopyo_screen [수정] = 줄 판 - test_642_6: 엑셀 보기 이음 · 가운데 페이지 없음 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
266 lines
7.5 KiB
TypeScript
266 lines
7.5 KiB
TypeScript
/* =============================================================================
|
|
* M02_MasterTemplete_Hopyo_JudgeApi.ts
|
|
* 엑셀 불러오기 새 판정 길(PLAN 785-5 · 785-6 · 요구 641 · 642 · 설계 642-A 2-9) — 타입 + 부름만.
|
|
* · GET `/layers/{파일 층}/hopyo-judge/{키}` = 호표 · 블록 목록(판정 수 · 만든)
|
|
* · GET `/layers/{파일 층}/hopyo-judge/{키}/{번}` = 호표 줄 판(785-3 줄 판 + 단산 줄 `풀이`)
|
|
* · GET `/layers/{파일 층}/hopyo-judge/{키}/block/{번}` = 블록 풀이(`Solve.block` 꼴 + 이름 · 근거 · 만든)
|
|
* · POST `/layers/{파일 층}/hopyo/{키}/check` = 고른 것 검산(저장 없음 · 서버 셈)
|
|
* · POST `/layers/{만들 층}/hopyo/{키}/move` = 확인한 것 옮김(서버가 다시 셈 · 금액 · 품 칸 안 보냄)
|
|
* 판정 · 금액은 서버 — 화면은 보이기 · 고르기만(옛 `Hopyo_Api.ts` 는 785-7 에서 걷음).
|
|
* ========================================================================== */
|
|
|
|
import { call } from "./M02_MasterTemplete_Api_Fetch";
|
|
import { at, type HopyoScope, type Money } from "./M02_MasterTemplete_Hopyo_Api";
|
|
|
|
export type PickKind =
|
|
"기초" | "단가산출" | "일위대가" | "인력" | "재료" | "유가" | "기계" | "율" | "고정";
|
|
export type RowVerdict = "제안 있음" | "2차 필요" | "후보 여럿" | "후보 없음";
|
|
export type BlockVerdict = "기초로 풂" | "기초+덧" | "줄 조합" | "고를 것";
|
|
|
|
/** 값 출처 — 길 B1~B6 · 사용자 · 기본 */
|
|
export interface PickSource {
|
|
길: string;
|
|
행?: number | null;
|
|
글?: string;
|
|
}
|
|
|
|
/** 고른 것(785-3 꼴 + 배) */
|
|
export interface Pick {
|
|
갈래: PickKind;
|
|
키: string | null;
|
|
이름: string;
|
|
규격?: string;
|
|
단위?: string;
|
|
단가?: Partial<Money> | number | null;
|
|
입력값: Record<string, unknown>;
|
|
출처: Record<string, PickSource>;
|
|
몫: number | null;
|
|
비목?: string;
|
|
기준?: unknown;
|
|
별도계상?: boolean;
|
|
층?: string;
|
|
주인?: string | null;
|
|
배?: number | null;
|
|
}
|
|
|
|
export interface Binding {
|
|
입력값: Record<string, unknown>;
|
|
출처: Record<string, PickSource>;
|
|
엇갈림: Record<string, { 값: unknown; 길: string; 행: number | null }[]>;
|
|
안씀: string[];
|
|
입력필요: string[];
|
|
비움: string[];
|
|
기본: Record<string, unknown>;
|
|
}
|
|
|
|
export type PairVerdict = "품 같음" | "품 다름" | "입력 필요" | "엑셀만" | "우리만";
|
|
|
|
/** 줄 대조 — 엑셀 단위 줄 ↔ 우리 줄 */
|
|
export interface PairLine {
|
|
엑셀: { 묶음: string; 이름: string; 품: number | null; 행: number | null; 별도?: boolean } | null;
|
|
우리: { 이름: string; 종류: string; 단위: string; 품: number | null; 까닭?: string } | null;
|
|
판정: PairVerdict;
|
|
표지?: string;
|
|
}
|
|
|
|
export type CandMoney = Money | { 계: null; 까닭: string };
|
|
|
|
/** 절 기초 후보 하나 */
|
|
export interface BaseCand {
|
|
키: string;
|
|
이름: string;
|
|
바인딩: Binding;
|
|
줄: PairLine[];
|
|
셈: Partial<Record<PairVerdict, number>>;
|
|
판정: string;
|
|
금액: CandMoney;
|
|
}
|
|
|
|
export interface Section {
|
|
제목: string;
|
|
번?: string | null;
|
|
판정: "기초 풂" | "후보 여럿" | "기초 없음";
|
|
고름: string | null;
|
|
후보: BaseCand[];
|
|
몫?: { 글?: string; 값: number | null; 행?: number | null } | null;
|
|
}
|
|
|
|
/** 덧 줄(엑셀만 줄 → 덧 줄 후보 · `Units` 잇기) */
|
|
export interface ExtraLine {
|
|
절: string;
|
|
행: number | null;
|
|
이름: string;
|
|
방법?: string;
|
|
후보?: {
|
|
자재?: string;
|
|
키?: string;
|
|
노임?: string;
|
|
이름?: string;
|
|
규격?: string;
|
|
단위?: string;
|
|
}[];
|
|
}
|
|
|
|
export interface Solved {
|
|
번: number;
|
|
판정: BlockVerdict;
|
|
고를수: number;
|
|
절: Section[];
|
|
덧: ExtraLine[];
|
|
}
|
|
|
|
export interface Basis {
|
|
표지: string | null;
|
|
글: string;
|
|
출처: [string, string][];
|
|
}
|
|
|
|
export interface JudgeBlock extends Solved {
|
|
이름: string;
|
|
단위: string;
|
|
부름: number[];
|
|
근거: Basis | null;
|
|
만든: string | null;
|
|
/** 엑셀 블록 금액(참고 · 길이 실을 때만) */
|
|
금액?: Partial<Money> | null;
|
|
}
|
|
|
|
/** 호표 줄 판 한 줄(785-3 + 엑셀 글 · 단산 줄 풀이) */
|
|
export interface JudgeRow {
|
|
차례: number;
|
|
행: number | null;
|
|
갈래: PickKind[];
|
|
근거: string;
|
|
번?: number;
|
|
후보: Pick[];
|
|
판정: RowVerdict;
|
|
수량: { 엑셀: number | null; 배: number | null; 갈래: string };
|
|
이름?: string;
|
|
규격?: string;
|
|
단위?: string;
|
|
단가?: Partial<Money> | null;
|
|
풀이?: Solved | null;
|
|
}
|
|
|
|
export interface JudgeBrief {
|
|
번: number;
|
|
이름: string;
|
|
규격: string;
|
|
단위: string;
|
|
줄수: number;
|
|
판정: Partial<Record<RowVerdict, number>>;
|
|
만든: string | null;
|
|
}
|
|
|
|
export interface JudgeBlockBrief {
|
|
번: number;
|
|
이름: string;
|
|
단위: string;
|
|
부름: number[];
|
|
표지: string | null;
|
|
만든: string | null;
|
|
/** 블록 풀이 파생 저장본(셈 전 = 없음) */
|
|
판정?: BlockVerdict | null;
|
|
고를수?: number | null;
|
|
}
|
|
|
|
export interface JudgeList {
|
|
키: string;
|
|
파일: string;
|
|
호표: JudgeBrief[];
|
|
블록: JudgeBlockBrief[];
|
|
}
|
|
|
|
export interface JudgeOne {
|
|
번: number;
|
|
이름: string;
|
|
규격: string;
|
|
단위: string;
|
|
만든: string | null;
|
|
줄: JudgeRow[];
|
|
}
|
|
|
|
export interface CheckBody {
|
|
호표?: number;
|
|
차례?: number;
|
|
블록?: number;
|
|
고른: Pick[];
|
|
}
|
|
|
|
export interface CheckOne {
|
|
차례: number;
|
|
갈래: PickKind;
|
|
키: string | null;
|
|
입력값: Record<string, unknown>;
|
|
입력필요: string[];
|
|
줄?: PairLine[];
|
|
판정: string;
|
|
금액: CandMoney;
|
|
}
|
|
|
|
export interface CheckResult {
|
|
고른: CheckOne[];
|
|
수량?: { 엑셀: number | null; 배: number | null; 몫: number | null };
|
|
}
|
|
|
|
export interface MoveBody {
|
|
층: string;
|
|
주인?: string | null;
|
|
호표: Record<string, Record<string, Pick[]>>;
|
|
블록: Record<string, Pick[]>;
|
|
}
|
|
|
|
export interface MoveBlocked {
|
|
호표?: number;
|
|
블록?: number;
|
|
차례?: number;
|
|
까닭: string;
|
|
칸: string[];
|
|
}
|
|
|
|
export interface MoveResult {
|
|
만듦: { 번: number; 키: string; 이름: string; 다시씀?: boolean; 재사용?: boolean }[];
|
|
단가산출: { 번: number; 키: string; 이름: string }[];
|
|
막힘: MoveBlocked[];
|
|
하위: { 번: number; 키: string; 새로: boolean }[];
|
|
장부: { 씀: number };
|
|
}
|
|
|
|
const enc = encodeURIComponent;
|
|
const toQuery = (to?: HopyoScope): string =>
|
|
to ? `?to=${to.layer}${to.owner ? `&to_owner=${enc(to.owner)}` : ""}` : "";
|
|
|
|
export const readJudge = (scope: HopyoScope, key: string, to?: HopyoScope): Promise<JudgeList> =>
|
|
call(at(scope, `/hopyo-judge/${enc(key)}${toQuery(to)}`));
|
|
|
|
export const readJudgeOne = (
|
|
scope: HopyoScope,
|
|
key: string,
|
|
no: number,
|
|
to?: HopyoScope,
|
|
): Promise<JudgeOne> => call(at(scope, `/hopyo-judge/${enc(key)}/${no}${toQuery(to)}`));
|
|
|
|
export const readJudgeBlock = (
|
|
scope: HopyoScope,
|
|
key: string,
|
|
no: number,
|
|
to?: HopyoScope,
|
|
): Promise<JudgeBlock> => call(at(scope, `/hopyo-judge/${enc(key)}/block/${no}${toQuery(to)}`));
|
|
|
|
/** 검산(저장 없음) — `signal` = 옛 요청 끊기 */
|
|
export const checkJudge = (
|
|
scope: HopyoScope,
|
|
key: string,
|
|
body: CheckBody,
|
|
signal?: AbortSignal,
|
|
): Promise<CheckResult> =>
|
|
call(at(scope, `/hopyo/${enc(key)}/check`), {
|
|
method: "POST",
|
|
body: JSON.stringify(body),
|
|
signal,
|
|
});
|
|
|
|
/** 옮기기 — `target` = 만들 층 · 몸 `층` · `주인` = 파일 층 */
|
|
export const moveJudge = (target: HopyoScope, key: string, body: MoveBody): Promise<MoveResult> =>
|
|
call(at(target, `/hopyo/${enc(key)}/move`), { method: "POST", body: JSON.stringify(body) });
|