fix(tkfb): 연차 소수점 표시 개선 — 정수면 17, 소수면 0.75

- DB: vacation_balance_details DECIMAL(4,1) → DECIMAL(5,2)로 변경 (0.25 단위 지원)
- 표시: fmtNum() — 정수면 소수점 없이 (17), 소수면 2자리 (0.75)
- onblur 포맷팅도 동일 규칙 적용

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Hyungi Ahn
2026-03-30 09:27:53 +09:00
parent c769fa040d
commit 549e78ba61

View File

@@ -354,6 +354,12 @@
}, 50);
})();
// 숫자 포맷: 정수면 소수점 없이, 소수면 2자리
function fmtNum(v) {
const n = parseFloat(v) || 0;
return n % 1 === 0 ? n.toString() : n.toFixed(2);
}
// 전역 변수
let workers = [];
let currentYear = new Date().getFullYear();
@@ -488,24 +494,24 @@
<td class="worker-name">${w.worker_name}</td>
<td>
<input type="number" class="num-input ${carryover < 0 ? 'negative' : ''}"
value="${carryover.toFixed(2)}" step="0.25"
value="${fmtNum(carryover)}" step="0.25"
data-field="carryover"
onchange="updateField(${w.user_id}, 'carryover', this.value)"
onblur="this.value=parseFloat(this.value||0).toFixed(2)">
onblur="var n=parseFloat(this.value||0);this.value=n%1===0?n.toString():n.toFixed(2)">
</td>
<td>
<input type="number" class="num-input"
value="${annual.toFixed(2)}" step="0.25"
value="${fmtNum(annual)}" step="0.25"
data-field="annual"
onchange="updateField(${w.user_id}, 'annual', this.value)"
onblur="this.value=parseFloat(this.value||0).toFixed(2)">
onblur="var n=parseFloat(this.value||0);this.value=n%1===0?n.toString():n.toFixed(2)">
</td>
<td>
<input type="number" class="num-input"
value="${longService.toFixed(2)}" step="0.25"
value="${fmtNum(longService)}" step="0.25"
data-field="longService"
onchange="updateField(${w.user_id}, 'longService', this.value)"
onblur="this.value=parseFloat(this.value||0).toFixed(2)">
onblur="var n=parseFloat(this.value||0);this.value=n%1===0?n.toString():n.toFixed(2)">
</td>
<td>
<button class="special-btn" onclick="openSpecialModal(${w.user_id}, '${w.worker_name}')">
@@ -513,9 +519,9 @@
${(d.specials || []).length > 0 ? `<span class="special-count">${d.specials.length}</span>` : ''}
</button>
</td>
<td style="font-weight:600;color:#059669;">${totalGenerated.toFixed(2)}</td>
<td style="color:#6b7280;">${totalUsed.toFixed(2)}</td>
<td class="remaining ${remainingClass}">${remaining.toFixed(2)}</td>
<td style="font-weight:600;color:#059669;">${fmtNum(totalGenerated)}</td>
<td style="color:#6b7280;">${fmtNum(totalUsed)}</td>
<td class="remaining ${remainingClass}">${fmtNum(remaining)}</td>
</tr>
`;
}).join('');
@@ -555,9 +561,9 @@
const remaining = totalGenerated - totalUsed;
const cells = row.querySelectorAll('td');
cells[6].textContent = totalGenerated.toFixed(2);
cells[7].textContent = totalUsed.toFixed(2);
cells[8].textContent = remaining.toFixed(2);
cells[6].textContent = fmtNum(totalGenerated);
cells[7].textContent = fmtNum(totalUsed);
cells[8].textContent = fmtNum(remaining);
cells[8].className = `remaining ${remaining > 0 ? 'positive' : remaining < 0 ? 'negative' : 'zero'}`;
}
@@ -595,9 +601,9 @@
<option value="${st.code}" ${s.type === st.code ? 'selected' : ''}>${st.name}</option>
`).join('')}
</select>
<input type="number" value="${parseFloat(s.days).toFixed(2)}" step="0.25" min="0"
<input type="number" value="${fmtNum(s.days)}" step="0.25" min="0"
onchange="updateSpecialDays(${idx}, this.value)"
onblur="this.value=parseFloat(this.value||0).toFixed(2)">
onblur="var n=parseFloat(this.value||0);this.value=n%1===0?n.toString():n.toFixed(2)">
<span>일</span>
<button class="delete-btn" onclick="deleteSpecialItem(${idx})">삭제</button>
</div>