feat(846-2): 기계 줄 시간당 작업량 화면 — 산출근거 「시간당 작업량」 줄 먼저 · 비목 ÷ 시간당 작업량 · 제어 구역 일당 / 시간당 식 고르기 · 변수 칸 · 기계 보기 작업량 식

- 산출근거: 일당 「시간당 작업량 = 시공량 560 ㎥/일 ÷ (1 대 × 8 시간) = 70 ㎥/시간」 · 시간당 식 = q · K · f · E · cm 값 줄 + 한 층 분수 Q 식 · 비목 줄 「59,020 원/시간 ÷ 70 ㎥/시간 = 843.1 원」(금액 그대로)
- 제어 구역: 「시간당 작업량」 묶음 맨 위 — 방식 고르기(식 없는 기계 = 잠김 + 까닭) · 시간당 = 작업량 틀 변수 칸(고침 · 원래 값) · 덮음 = 기계덮음.<기계>.작업량
- 기계 보기: 왼쪽 작업량 카드(기계 정본 변수) · 오른쪽 풀이 · 서버가 작업량 틀 연결을 실음(M02_MyMachine_Sheet._work)
- 시험: test_846_2_work_view 새로 · test_845_2 GC000088 비목 줄 기대값을 새 꼴로 고침(846-2 표시 변경) · 헬퍼 가짜 DOM 이 진짜 DOM 처럼 요소를 옮김(같은 요소 두 줄 재사용 흠을 잡게)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-16 00:00:35 +09:00
co-authored by Claude Opus 5.5
parent 3a8ba840f4
commit c8cd98dec1
16 changed files with 925 additions and 22 deletions
+30 -3
View File
@@ -4,6 +4,7 @@
* ㉠ 값 칸 = 그 기계 식이 읽는 기계 칸(단위 · 기본 = 사본 값 · 고친 칸 = 「고침」 + [원래 값])
* ㉡ 조종원 = 인력 줄(노임 고르기 · 인/일 · 더하기 · 빼기 · 기본 = 기계 값 조종원 · 직종)
* ㉢ 잡품 = 재료 줄(재료 · 유가 고르기 · 수량 · 율 % · 기본 = 밑 재료 줄 · 품셈 잡재료율)
* ㉣ 시간당 작업량(846-2 · 맨 위) = 일당 / 시간당 식 고르기 · 시간당 변수 칸(`line_stack_machine_work`)
* 고침 = 문서 칸 `기계덮음`(캐시 · [저장] 때 서버가 정본으로 다시 셈) · 원본과 같으면 지움(`putCover`)
* 기본값 = 덮음 없이 셈한 그 기계 식 답 + 기계 줄 인력 · 잡품 목록(`defaultsOf` · `rowEntry` · 842-3) ·
* 읽기(M01 기초) = 칸 잠김 · 단추 없음
@@ -32,8 +33,11 @@ import {
import { subInputs, type StackDoc } from "../common_util/common_util_line_stack";
import type { Picked } from "../common_util/common_util_line_stack_pick";
import { machineUnit } from "../common_util/common_util_line_stack_unit";
import { workAt, workOfMachine } from "../common_util/common_util_line_stack_work";
import { sites, type WorkCover, type WorkSpec } from "../common_util/common_util_formula_doc_work";
import { machineCellName } from "../common_util/common_util_machine_symbol_name";
import { openFindPicker } from "../M02_MasterTemplete/M02_MasterTemplete_Find_Pick";
import { buildWorkGroup } from "./line_stack_machine_work";
import { openStackPick } from "./line_stack_pick";
import { lt } from "./line_stack_text";
@@ -51,6 +55,8 @@ export interface CtlHooks {
lists?: (given: Record<string, unknown>) => Record<string, unknown> | null;
/** 잠긴 값 칸 */
lock?: string[];
/** 846-2 그 기계 작업량 줄(기계 값 칸 `작업량`) */
work?: (machine: string) => WorkSpec[];
}
const FUELS = ["경유", "휘발유", "실내등유"];
@@ -80,7 +86,7 @@ const num = (t: string): number | null => {
};
/** 수 칸 — 빈 글 = 원래대로(null) · 음수 · 글 = 알림 · 단위 = 칸 바로 뒤(공식 묶음 값 칸과 같은 자리 · 845-2 ㉥) */
function numBox(
export function numBox(
label: string,
value: unknown,
unit: string,
@@ -115,8 +121,12 @@ function numBox(
const kind = (text: string): HTMLElement => el("span", { className: "lstk-kind", text });
/** 기계 제어 구역 — `link` = 그 기계 줄 단가 기호 연결 */
export function buildMachineCtl(h: CtlHooks, link: Link | undefined): HTMLElement | null {
/** 기계 제어 구역 — `link` = 그 기계 줄 단가 기호 연결 · `at` = 그 금액 줄 차례(작업량) */
export function buildMachineCtl(
h: CtlHooks,
link: Link | undefined,
at?: number,
): HTMLElement | null {
const got = ctlOf(h, link);
if (!got) return null;
const { machine, sub, vals, base } = got;
@@ -269,10 +279,27 @@ export function buildMachineCtl(h: CtlHooks, link: Link | undefined): HTMLElemen
]),
],
});
// ㉣ 시간당 작업량(846-2)
const info = (at === undefined ? null : workAt(h.answer, at)) ?? workOfMachine(h.answer, machine);
const workNow = (entry as MachineCover & { 작업량?: WorkCover }).작업량;
const work = info
? buildWorkGroup({
doc: h.doc,
info,
kind: info.꼴 === "시간당" ? (sites(h.doc, h.doc.금액?.[at ?? -1]?.수량)[0]?.꼴 ?? "일당") : info.꼴, // prettier-ignore
entry: workNow,
specs: h.work?.(machine) ?? [],
subDoc: h.subDoc,
vals: (h.answer.값 ?? {}) as Record<string, unknown>,
ro,
put: (w) => put({ ...entry, 작업량: w } as MachineCover),
})
: [];
const box = el("div", {
className: "lstk-mctl lstk-wide",
attrs: { "data-mctl": machine },
children: [
...work,
...(values.length
? [el("div", { className: "lstk-fhead", children: [kind(lt("Ctl_Values"))] }), ...values]
: []),