feat(parse): report per-sheet recognition and block error sheets

- parseWorkbook returns a report per sheet (table counts, issues, ok)
- sheets with E-level issues cannot be selected (spec section 2.3)
- pier input carries its source sheet name

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
ypshimandClaude Haiku 5.5 committed 2026-10-21 17:43:36 +09:00
1 parent 35d89dc4e2
commit 01d2bf4958
8 files changed
+122 -16

No files matched your search

+19 -3
View File
@@ -118,6 +118,7 @@ export interface PierModel {
columnHeight: number;
soilCover: number;
pileCount: number;
pileLayout: string | null;
pileTipEl: number | null;
blockHeightFront: number;
blockHeightBack: number;
@@ -290,6 +291,7 @@ export function buildPier(input: PierInput): PierModel {
columnHeight: levelBottom - columns[0].bottom,
soilCover: input.groundEl - (input.foundationType === '현장타설말뚝' ? input.footingBottomEl : footingTop),
pileCount: piles.length,
pileLayout: input.foundationType === '말뚝기초' ? pileLayoutText() : null,
pileTipEl: piles.length ? pileTip : null,
blockHeightFront,
blockHeightBack,
@@ -313,12 +315,26 @@ function segmentTop(segments: Segment[], s: number): number {
* Piles under one footing (spec §4.6): rows across the footing width, piles along the length,
* both with an end distance of 0.7 m and an even spacing that never exceeds 2.25 m.
*/
export function pilesFor(s: number, topEl: number, length: number): PileModel[] {
export function pileGrid(): { countS: number; countN: number; spacingS: number; spacingN: number } {
const span = (size: number) => Math.floor((size - 2 * DIM.pileEnd) / DIM.pileSpacing) + 1;
const countS = span(DIM.footingL);
const countN = span(DIM.footingW);
const spacingS = (DIM.footingL - 2 * DIM.pileEnd) / (countS - 1);
const spacingN = (DIM.footingW - 2 * DIM.pileEnd) / (countN - 1);
return {
countS,
countN,
spacingS: (DIM.footingL - 2 * DIM.pileEnd) / (countS - 1),
spacingN: (DIM.footingW - 2 * DIM.pileEnd) / (countN - 1),
};
}
/** Display string such as "4@2250 × 3@2250 = 20본" (gaps along the length × gaps across the width). */
export function pileLayoutText(): string {
const g = pileGrid();
return `${g.countS - 1}@${Math.round(g.spacingS * 1000)} × ${g.countN - 1}@${Math.round(g.spacingN * 1000)} = ${g.countS * g.countN}본`;
}
export function pilesFor(s: number, topEl: number, length: number): PileModel[] {
const { countS, countN, spacingS, spacingN } = pileGrid();
const out: PileModel[] = [];
for (let i = 0; i < countS; i++) {
for (let j = 0; j < countN; j++) {