feat: Refactor transaction handling and add new features

- Updated ReasonGroupList.vue to modify classify button behavior for adding new classifications.
- Refactored TransactionDetail.vue to integrate PopupContainer and enhance transaction detail display.
- Improved TransactionDetailDialog.vue with updated classify button functionality.
- Simplified BalanceView.vue by removing manual entry button.
- Enhanced PeriodicRecord.vue to update classify button interactions.
- Removed unused add transaction dialog from TransactionsRecord.vue.
- Added new API endpoints in TransactionRecordController for parsing transactions and handling offsets.
- Introduced BillForm.vue and ManualBillAdd.vue for streamlined bill entry.
- Implemented OneLineBillAdd.vue for intelligent transaction parsing.
- Created GlobalAddBill.vue for a unified bill addition interface.
This commit is contained in:
2026-01-01 14:43:43 +08:00
parent 8dfe7f1688
commit e00b5cffb7
18 changed files with 977 additions and 384 deletions

View File

@@ -1,18 +1,15 @@
<template>
<van-popup
v-model:show="visible"
position="bottom"
:style="{ height: '85%' }"
round
closeable
@update:show="handleVisibleChange"
<PopupContainer
v-model="visible"
title="交易详情"
height="85%"
:closeable="false"
>
<div class="popup-container" v-if="transaction">
<div class="popup-header-fixed">
<h3>交易详情</h3>
</div>
<div class="popup-scroll-content">
<template #header-actions>
<van-button size="small" type="primary" plain @click="handleOffsetClick">抵账</van-button>
</template>
<div v-if="transaction">
<van-form @submit="onSubmit" style="margin-top: 12px;">
<van-cell-group inset>
<van-cell title="卡号" :value="transaction.card" />
@@ -67,6 +64,14 @@
<!-- 分类按钮网格 -->
<div class="classify-buttons">
<van-button
type="success"
size="small"
class="classify-btn"
@click="showAddClassify = true"
>
+ 新增
</van-button>
<van-button
v-for="item in classifyColumns"
:key="item.id"
@@ -77,14 +82,6 @@
>
{{ item.text }}
</van-button>
<van-button
type="success"
size="small"
class="classify-btn"
@click="showAddClassify = true"
>
+ 新增
</van-button>
<van-button
v-if="editForm.classify"
type="warning"
@@ -103,9 +100,8 @@
</van-button>
</div>
</van-form>
</div>
</div>
</van-popup>
</PopupContainer>
<!-- 交易类型选择器 -->
<van-popup v-model:show="showTypePicker" position="bottom" round>
@@ -126,12 +122,33 @@
>
<van-field v-model="newClassify" placeholder="请输入新的交易分类" />
</van-dialog>
<!-- 抵账候选列表弹窗 -->
<PopupContainer
v-model="showOffsetPopup"
title="选择抵账交易"
height="70%"
>
<van-list>
<van-cell
v-for="item in offsetCandidates"
:key="item.id"
:title="item.reason"
:label="formatDate(item.occurredAt)"
:value="item.amount"
is-link
@click="handleCandidateSelect(item)"
/>
<van-empty v-if="offsetCandidates.length === 0" description="暂无匹配的抵账交易" />
</van-list>
</PopupContainer>
</template>
<script setup>
import { ref, reactive, watch, defineProps, defineEmits } from 'vue'
import { showToast } from 'vant'
import { updateTransaction } from '@/api/transactionRecord'
import { showToast, showConfirmDialog } from 'vant'
import PopupContainer from '@/components/PopupContainer.vue'
import { updateTransaction, getCandidatesForOffset, offsetTransactions } from '@/api/transactionRecord'
import { getCategoryList, createCategory } from '@/api/transactionCategory'
const props = defineProps({
@@ -207,10 +224,6 @@ watch(() => editForm.type, (newVal) => {
loadClassifyList(newVal)
})
const handleVisibleChange = (newVal) => {
emit('update:show', newVal)
}
// 加载分类列表
const loadClassifyList = async (type = null) => {
try {
@@ -332,6 +345,51 @@ const formatDate = (dateString) => {
minute: '2-digit'
})
}
// 抵账相关
const showOffsetPopup = ref(false)
const offsetCandidates = ref([])
const handleOffsetClick = async () => {
try {
const res = await getCandidatesForOffset(editForm.id)
if (res.success) {
offsetCandidates.value = res.data || []
showOffsetPopup.value = true
} else {
showToast(res.message || '获取抵账列表失败')
}
} catch (error) {
console.error('获取抵账列表出错:', error)
showToast('获取抵账列表失败')
}
}
const handleCandidateSelect = (candidate) => {
showConfirmDialog({
title: '确认抵账',
message: `确认将当前交易与 "${candidate.reason}" (${candidate.amount}) 互相抵消吗?\n抵消后两笔交易将被删除。`,
})
.then(async () => {
try {
const res = await offsetTransactions(editForm.id, candidate.id)
if (res.success) {
showToast('抵账成功')
showOffsetPopup.value = false
visible.value = false
emit('save') // 触发列表刷新
} else {
showToast(res.message || '抵账失败')
}
} catch (error) {
console.error('抵账出错:', error)
showToast('抵账失败')
}
})
.catch(() => {
// on cancel
});
}
</script>
<style scoped>