Merge branch 'dev'
This commit is contained in:
@@ -653,6 +653,7 @@ async function doRegisterRecurring() {
|
||||
// ===== 자주 쓰는 내역(빠른 등록 템플릿) =====
|
||||
const quickEntries = ref([])
|
||||
const quickEditMode = ref(false)
|
||||
const quickPickerOpen = ref(false) // 불러오기 모달 피커
|
||||
async function loadQuick() {
|
||||
try {
|
||||
quickEntries.value = await accountApi.quickEntries()
|
||||
@@ -706,11 +707,9 @@ function applyQuick(q) {
|
||||
}
|
||||
syncCategoryMajor()
|
||||
}
|
||||
function onQuickPick(e) {
|
||||
const id = Number(e.target.value)
|
||||
e.target.value = '' // 다시 선택 가능하게 초기화
|
||||
const q = quickEntries.value.find((x) => x.id === id)
|
||||
if (q) applyQuick(q)
|
||||
function pickQuick(q) {
|
||||
applyQuick(q)
|
||||
quickPickerOpen.value = false
|
||||
}
|
||||
// 현재 폼 값을 자주 쓰는 내역으로 저장
|
||||
async function saveAsQuick() {
|
||||
@@ -968,12 +967,16 @@ onMounted(async () => {
|
||||
자동 입력됨
|
||||
</span>
|
||||
<span v-else class="receipt-hint">사진에서 금액·날짜·상호를 자동 입력</span>
|
||||
<!-- 문자/푸시 붙여넣기 (영수증 스캔과 같은 행, 우측) -->
|
||||
<button
|
||||
type="button" class="paste-btn"
|
||||
:disabled="submitting" @click="pasteFromClipboard"
|
||||
>📋 문자·푸시</button>
|
||||
<div v-if="ocrRunning" class="receipt-progress"><div class="bar"></div></div>
|
||||
</div>
|
||||
|
||||
<!-- 문자/푸시 붙여넣기 → 자동 채움 (iPhone 등 알림 자동수집 불가 대비) -->
|
||||
<div v-if="!isRepayment" class="paste-box">
|
||||
<button type="button" class="paste-btn" :disabled="submitting" @click="pasteFromClipboard">📋 문자·푸시 붙여넣기</button>
|
||||
<!-- 붙여넣기 감지 결과 / 수동 입력 -->
|
||||
<div v-if="!isRepayment && (pasteDetected || pasteOpen)" class="paste-extra">
|
||||
<div v-if="pasteDetected" class="paste-detected">
|
||||
감지: {{ pasteDetected.type === 'INCOME' ? '수입' : '지출' }} {{ won(pasteDetected.amount) }}<template v-if="pasteDetected.merchant"> · {{ pasteDetected.merchant }}</template>
|
||||
<button type="button" class="pd-apply" @click="applyParsed(pasteDetected)">채우기</button>
|
||||
@@ -984,15 +987,12 @@ onMounted(async () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 신규 추가 시: 자주 쓰는 내역 불러오기(폼 채움) -->
|
||||
<label v-if="!editId && quickEntries.length" class="quick-load">⭐ 자주 쓰는 내역 불러오기
|
||||
<select :disabled="submitting" @change="onQuickPick">
|
||||
<option value="">선택해서 불러오기</option>
|
||||
<option v-for="q in quickEntries" :key="q.id" :value="q.id">
|
||||
{{ quickLabel(q) }} · {{ q.type === 'INCOME' ? '+' : '-' }}{{ won(q.amount) }}
|
||||
</option>
|
||||
</select>
|
||||
</label>
|
||||
<!-- 신규 추가 시: 자주 쓰는 내역 불러오기(모달 피커) -->
|
||||
<button
|
||||
v-if="!editId && quickEntries.length"
|
||||
type="button" class="to-recurring to-quick"
|
||||
:disabled="submitting" @click="quickPickerOpen = true"
|
||||
>⭐ 자주 쓰는 내역 불러오기</button>
|
||||
|
||||
<label>거래일<input v-model="form.entryDate" type="date" :disabled="submitting" /></label>
|
||||
<label>구분
|
||||
@@ -1176,6 +1176,30 @@ onMounted(async () => {
|
||||
</div>
|
||||
</Transition>
|
||||
</Teleport>
|
||||
|
||||
<!-- 자주 쓰는 내역 불러오기 (모달 피커) -->
|
||||
<Teleport to="body">
|
||||
<Transition name="fade">
|
||||
<div v-if="quickPickerOpen" class="modal-backdrop quick-picker-backdrop" @click.self="quickPickerOpen = false">
|
||||
<div class="modal quick-picker" role="dialog" aria-modal="true">
|
||||
<button class="close" type="button" @click="quickPickerOpen = false">×</button>
|
||||
<h2>자주 쓰는 내역 불러오기</h2>
|
||||
<ul v-if="quickEntries.length" class="qp-list">
|
||||
<li v-for="q in quickEntries" :key="q.id">
|
||||
<button type="button" class="qp-item" @click="pickQuick(q)">
|
||||
<span class="qp-label">{{ quickLabel(q) }}</span>
|
||||
<span class="qp-meta">
|
||||
<span v-if="q.category" class="qp-cat">{{ q.category }}</span>
|
||||
<span class="qp-amt" :class="q.type === 'INCOME' ? 'income' : 'expense'">{{ q.type === 'INCOME' ? '+' : '-' }}{{ won(q.amount) }}</span>
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<p v-else class="msg">저장된 자주 쓰는 내역이 없습니다.</p>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</Teleport>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
@@ -1824,20 +1848,21 @@ button.primary {
|
||||
cursor: pointer;
|
||||
}
|
||||
/* 문자/푸시 붙여넣기 */
|
||||
.paste-box {
|
||||
.paste-extra {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
.paste-btn {
|
||||
align-self: flex-start;
|
||||
margin-left: auto; /* 영수증 행 우측으로 */
|
||||
padding: 0.4rem 0.7rem;
|
||||
font-size: 0.82rem;
|
||||
font-size: 0.8rem;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: 6px;
|
||||
background: var(--color-background-soft);
|
||||
background: var(--color-background);
|
||||
color: var(--color-text);
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.paste-detected {
|
||||
font-size: 0.82rem;
|
||||
@@ -1894,6 +1919,58 @@ button.primary {
|
||||
color: #b8860b;
|
||||
border-color: rgba(184, 134, 11, 0.6);
|
||||
}
|
||||
/* 자주 쓰는 내역 불러오기 피커 모달 */
|
||||
.quick-picker-backdrop {
|
||||
z-index: 1300; /* 내역 모달 위 */
|
||||
}
|
||||
.qp-list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
max-height: 60vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.qp-list li {
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
}
|
||||
.qp-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.5rem;
|
||||
width: 100%;
|
||||
padding: 0.7rem 0.4rem;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
color: var(--color-text);
|
||||
font: inherit;
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
}
|
||||
.qp-item:hover {
|
||||
background: var(--color-background-soft);
|
||||
}
|
||||
.qp-label {
|
||||
font-weight: 600;
|
||||
}
|
||||
.qp-meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
.qp-cat {
|
||||
font-size: 0.78rem;
|
||||
opacity: 0.6;
|
||||
}
|
||||
.qp-amt.income {
|
||||
color: #2e7d32;
|
||||
font-weight: 600;
|
||||
}
|
||||
.qp-amt.expense {
|
||||
color: #c0392b;
|
||||
font-weight: 600;
|
||||
}
|
||||
.to-recurring:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: default;
|
||||
|
||||
Reference in New Issue
Block a user