- wallet 테이블에 loan_rate/loan_method/loan_months/loan_start 컬럼 추가(ALTER TABLE) - 대출 계좌 폼에 연이자율(%), 상환방식(원리금균등/원금균등/만기일시), 기간, 시작일 입력 필드 추가 - 계좌 목록에 금리·상환방식 표시 - 상환 폼: 금리 설정된 대출 계좌 선택 시 납입금액 입력 → 이자/원금 자동계산 - 원리금균등/원금균등: 잔액 × 연이율/12 = 이자, 납입액-이자 = 원금 - 만기일시상환: 납입액 전체 이자로 처리 - 자동계산 후 수동 조정 가능 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -127,6 +127,33 @@ const repayTargetIsCard = computed(() => {
|
||||
const w = wallets.value.find((x) => x.id === form.toWalletId)
|
||||
return !!w && w.type === 'CARD'
|
||||
})
|
||||
// 금리가 설정된 대출 계좌를 선택한 경우 자동계산 활성
|
||||
const repayTargetLoanWallet = computed(() => {
|
||||
const w = wallets.value.find((x) => x.id === form.toWalletId)
|
||||
return w?.type === 'LOAN' && w.loanRate ? w : null
|
||||
})
|
||||
// 납입총액 입력 → 원금/이자 자동분리
|
||||
const loanPaymentAmount = ref(null)
|
||||
function calcLoanRepayment(payment) {
|
||||
const loan = repayTargetLoanWallet.value
|
||||
if (!loan || !payment || payment <= 0) return
|
||||
const monthlyRate = Number(loan.loanRate) / 100 / 12
|
||||
const remainingDebt = Math.abs(loan.balance || 0)
|
||||
const monthlyInterest = Math.round(remainingDebt * monthlyRate)
|
||||
if (loan.loanMethod === 'BULLET') {
|
||||
form.interest = payment
|
||||
form.principal = 0
|
||||
} else {
|
||||
form.interest = Math.min(monthlyInterest, payment)
|
||||
form.principal = Math.max(0, payment - form.interest)
|
||||
}
|
||||
}
|
||||
watch(loanPaymentAmount, (val) => { if (val) calcLoanRepayment(Number(val)) })
|
||||
watch(() => form.toWalletId, () => {
|
||||
loanPaymentAmount.value = null
|
||||
form.principal = null
|
||||
form.interest = null
|
||||
})
|
||||
// 카드 지출일 때만 할부 입력 노출 (2~24개월, 일시불은 빈값)
|
||||
const showInstallment = computed(() => form.type === 'EXPENSE' && form.walletKind === 'CARD')
|
||||
const installmentMonthly = computed(() => {
|
||||
@@ -1135,8 +1162,23 @@ onMounted(async () => {
|
||||
</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>원금<input v-model.number="form.principal" type="number" min="0" placeholder="원 (이체로 기록)" :disabled="submitting" /></label>
|
||||
<label>이자<input v-model.number="form.interest" type="number" min="0" placeholder="원 (지출·분류 이자)" :disabled="submitting" /></label>
|
||||
<!-- 금리 설정된 대출 계좌: 납입금액 입력 → 원금/이자 자동계산 -->
|
||||
<template v-if="repayTargetLoanWallet">
|
||||
<label>납입금액
|
||||
<input v-model.number="loanPaymentAmount" type="number" min="0"
|
||||
placeholder="이번 달 납입할 총금액" :disabled="submitting" @input="calcLoanRepayment(loanPaymentAmount)" />
|
||||
</label>
|
||||
<div v-if="loanPaymentAmount > 0" class="loan-breakdown">
|
||||
<span>이자 <b>{{ (form.interest || 0).toLocaleString('ko-KR') }}원</b></span>
|
||||
<span>원금상환 <b>{{ (form.principal || 0).toLocaleString('ko-KR') }}원</b></span>
|
||||
</div>
|
||||
<label>이자(조정)<input v-model.number="form.interest" type="number" min="0" :disabled="submitting" /></label>
|
||||
<label>원금(조정)<input v-model.number="form.principal" type="number" min="0" :disabled="submitting" /></label>
|
||||
</template>
|
||||
<template v-else>
|
||||
<label>원금<input v-model.number="form.principal" type="number" min="0" placeholder="원 (이체로 기록)" :disabled="submitting" /></label>
|
||||
<label>이자<input v-model.number="form.interest" type="number" min="0" placeholder="원 (지출·분류 이자)" :disabled="submitting" /></label>
|
||||
</template>
|
||||
<label v-if="repayTargetIsCard">연회비<input v-model.number="form.annualFee" type="number" min="0" placeholder="원 (지출·분류 연회비)" :disabled="submitting" /></label>
|
||||
</template>
|
||||
|
||||
@@ -1973,6 +2015,18 @@ button.primary {
|
||||
.acc-chip.add-chip.sub-add {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
.loan-breakdown {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
padding: 0.45rem 0.6rem;
|
||||
border-radius: 6px;
|
||||
background: var(--color-background-soft);
|
||||
font-size: 0.85rem;
|
||||
color: var(--color-text);
|
||||
}
|
||||
.loan-breakdown b {
|
||||
color: hsla(160, 100%, 37%, 1);
|
||||
}
|
||||
.tag-field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
Reference in New Issue
Block a user