- budgets/createBudget에 year/month 전달, copyBudget 추가 - BudgetView: '전월 예산 가져오기' / '다음 달로 복사' 버튼 - 백업 export는 현재 월 예산을 담음 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -127,7 +127,7 @@ async function load() {
|
||||
error.value = null
|
||||
try {
|
||||
const params = { year: year.value, month: month.value }
|
||||
const [st, raw] = await Promise.all([accountApi.budgetStatus(params), accountApi.budgets()])
|
||||
const [st, raw] = await Promise.all([accountApi.budgetStatus(params), accountApi.budgets(params)])
|
||||
statuses.value = st
|
||||
budgetsRaw.value = raw
|
||||
} catch (e) {
|
||||
@@ -154,6 +154,46 @@ function nextMonth() {
|
||||
loadIncome()
|
||||
}
|
||||
|
||||
// ===== 월별 예산 복사 =====
|
||||
const copying = ref(false)
|
||||
const ym = (y, m) => `${y}.${String(m).padStart(2, '0')}`
|
||||
async function copyToNextMonth() {
|
||||
if (copying.value || !budgetsRaw.value.length) return
|
||||
const to = month.value === 12 ? { y: year.value + 1, m: 1 } : { y: year.value, m: month.value + 1 }
|
||||
const ok = await dialog.confirm(
|
||||
`${ym(year.value, month.value)} 예산을 ${ym(to.y, to.m)}(다음 달)로 복사할까요?\n다음 달의 같은 분류 예산은 덮어씁니다.`,
|
||||
{ title: '다음 달로 복사' },
|
||||
)
|
||||
if (!ok) return
|
||||
copying.value = true
|
||||
try {
|
||||
await accountApi.copyBudget({ fromYear: year.value, fromMonth: month.value, toYear: to.y, toMonth: to.m })
|
||||
await dialog.alert(`${ym(to.y, to.m)}로 예산을 복사했어요.`)
|
||||
} catch (e) {
|
||||
error.value = e.response?.data?.message || '복사에 실패했습니다.'
|
||||
} finally {
|
||||
copying.value = false
|
||||
}
|
||||
}
|
||||
async function copyFromPrevMonth() {
|
||||
if (copying.value) return
|
||||
const prev = month.value === 1 ? { y: year.value - 1, m: 12 } : { y: year.value, m: month.value - 1 }
|
||||
const ok = await dialog.confirm(
|
||||
`전월(${ym(prev.y, prev.m)}) 예산을 ${ym(year.value, month.value)}로 가져올까요?\n이 달의 같은 분류 예산은 덮어씁니다.`,
|
||||
{ title: '전월 예산 복사' },
|
||||
)
|
||||
if (!ok) return
|
||||
copying.value = true
|
||||
try {
|
||||
await accountApi.copyBudget({ fromYear: prev.y, fromMonth: prev.m, toYear: year.value, toMonth: month.value })
|
||||
await load()
|
||||
} catch (e) {
|
||||
error.value = e.response?.data?.message || '복사에 실패했습니다.'
|
||||
} finally {
|
||||
copying.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function openCreate() {
|
||||
editId.value = null
|
||||
Object.assign(form, {
|
||||
@@ -213,7 +253,7 @@ async function submit() {
|
||||
submitting.value = true
|
||||
try {
|
||||
if (editId.value) await accountApi.updateBudget(editId.value, payload)
|
||||
else await accountApi.createBudget(payload)
|
||||
else await accountApi.createBudget(payload, { year: year.value, month: month.value })
|
||||
formOpen.value = false
|
||||
await load()
|
||||
} catch (e) {
|
||||
@@ -252,6 +292,12 @@ onMounted(() => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 월별 예산 복사 -->
|
||||
<div class="copy-actions">
|
||||
<button type="button" class="copy-btn" :disabled="copying" @click="copyFromPrevMonth">↤ 전월 예산 가져오기</button>
|
||||
<button type="button" class="copy-btn" :disabled="copying || !budgetsRaw.length" @click="copyToNextMonth">다음 달로 복사 ↦</button>
|
||||
</div>
|
||||
|
||||
<!-- 월 예상 수입 vs 총 예산 -->
|
||||
<div class="income-panel">
|
||||
<div class="inc-input">
|
||||
@@ -431,6 +477,26 @@ button.primary {
|
||||
text-align: center;
|
||||
}
|
||||
/* 예상 수입 vs 예산 */
|
||||
.copy-actions {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
justify-content: flex-end;
|
||||
flex-wrap: wrap;
|
||||
margin: -0.4rem 0 1rem;
|
||||
}
|
||||
.copy-btn {
|
||||
padding: 0.4rem 0.8rem;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: 6px;
|
||||
background: var(--color-background-soft);
|
||||
color: var(--color-text);
|
||||
font-size: 0.82rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
.copy-btn:disabled {
|
||||
opacity: 0.45;
|
||||
cursor: default;
|
||||
}
|
||||
.income-panel {
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: 8px;
|
||||
|
||||
Reference in New Issue
Block a user