feat(M02): 켜쌓기 적용율 — 골쌓기 기준 로직 세부항목 수량 × 율 · 문서 · 사본 · 서고 같은 함수 · 옵션 칸 · 줄 아래 글(85-2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W4uKaV4ZBhsJN4GHG7yRj4
This commit is contained in:
@@ -39,6 +39,17 @@ function footer(
|
||||
export interface LaborInputResult {
|
||||
입력값: LaborValues;
|
||||
메모: string | null;
|
||||
/** 켜쌓기 적용율 %(85-2 · 대상 로직만 · 빈 칸 · 100 = null) */
|
||||
켜쌓기율: number | null;
|
||||
}
|
||||
|
||||
/** 켜쌓기율 칸 글 → 값 — 빈 글 · 100 = null · 0 초과 200 이하 · 소수 한 자리 밖 = NaN */
|
||||
export function layerRate(raw: string): number | null {
|
||||
if (raw.trim() === "") return null;
|
||||
const v = Number(raw);
|
||||
const ok =
|
||||
Number.isFinite(v) && v > 0 && v <= 200 && Math.abs(v * 10 - Math.round(v * 10)) < 1e-9;
|
||||
return !ok ? NaN : v === 100 ? null : v;
|
||||
}
|
||||
|
||||
export interface LaborInputOptions {
|
||||
@@ -48,6 +59,8 @@ export interface LaborInputOptions {
|
||||
logic: ItemLogic | null;
|
||||
values: LaborValues;
|
||||
memo: string | null;
|
||||
/** 켜쌓기율(85-2) — 로직이 대상일 때만 칸 */
|
||||
rate?: number | null;
|
||||
readOnly: boolean;
|
||||
done: (next: LaborInputResult) => void;
|
||||
/** 머리 한 줄 알림(51-14 · 서고 원본 고침) */
|
||||
@@ -100,9 +113,27 @@ export function openLaborInput(opt: LaborInputOptions): void {
|
||||
}) as HTMLInputElement;
|
||||
memo.value = opt.memo ?? "";
|
||||
memo.readOnly = opt.readOnly;
|
||||
const rate = opt.logic?.켜쌓기
|
||||
? (el("input", {
|
||||
className: "ui-input m02-inputval__control",
|
||||
attrs: {
|
||||
type: "number",
|
||||
min: "0.1",
|
||||
max: "200",
|
||||
step: "0.1",
|
||||
placeholder: "100",
|
||||
"data-labor-layer": "",
|
||||
},
|
||||
}) as HTMLInputElement)
|
||||
: null;
|
||||
if (rate) {
|
||||
rate.value = opt.rate == null ? "" : String(opt.rate);
|
||||
rate.readOnly = opt.readOnly;
|
||||
}
|
||||
const ok = (): void => {
|
||||
if (bad.size) return showToast(tc("In_Bad"), "error");
|
||||
opt.done({ 입력값: { ...draft }, 메모: memo.value.trim() || null });
|
||||
const layer = rate ? layerRate(rate.value) : null;
|
||||
if (bad.size || Number.isNaN(layer)) return showToast(tc("In_Bad"), "error");
|
||||
opt.done({ 입력값: { ...draft }, 메모: memo.value.trim() || null, 켜쌓기율: layer });
|
||||
close();
|
||||
};
|
||||
body.append(
|
||||
@@ -129,6 +160,21 @@ export function openLaborInput(opt: LaborInputOptions): void {
|
||||
...(rows.length
|
||||
? rows
|
||||
: [el("p", { className: "m02-labin__muted", text: tc("In_None") })]),
|
||||
...(rate
|
||||
? [
|
||||
el("div", {
|
||||
className: "m02-inputval__row",
|
||||
children: [
|
||||
el("span", {
|
||||
className: "m02-inputval__name",
|
||||
text: tc("In_Layer"),
|
||||
attrs: { title: tc("In_LayerHint") },
|
||||
}),
|
||||
rate,
|
||||
],
|
||||
}),
|
||||
]
|
||||
: []),
|
||||
el("div", {
|
||||
className: "m02-inputval__row",
|
||||
children: [
|
||||
|
||||
Reference in New Issue
Block a user