新增定时账单功能
All checks were successful
Docker Build & Deploy / Build Docker Image (push) Successful in 30s
Docker Build & Deploy / Deploy to Production (push) Successful in 7s

This commit is contained in:
孙诚
2025-12-29 15:20:32 +08:00
parent 13bf23a48c
commit 9719c6043a
19 changed files with 2409 additions and 27 deletions

View File

@@ -0,0 +1,169 @@
<template>
<!-- 分类选择器弹窗 -->
<van-popup v-model:show="visible" position="bottom" round>
<van-picker
ref="pickerRef"
:columns="classifyColumns"
@confirm="onConfirm"
@cancel="onCancel"
>
<template #toolbar>
<div class="picker-toolbar">
<van-button class="toolbar-cancel" size="small" @click="onClear">清空</van-button>
<van-button class="toolbar-add" size="small" type="primary" @click="showAddDialog = true">新增</van-button>
<van-button class="toolbar-confirm" size="small" type="primary" @click="confirmSelect">确认</van-button>
</div>
</template>
</van-picker>
</van-popup>
<!-- 新增分类对话框 -->
<van-dialog
v-model:show="showAddDialog"
title="新增交易分类"
show-cancel-button
@confirm="addNewClassify"
>
<van-field v-model="newClassifyName" placeholder="请输入新的交易分类" />
</van-dialog>
</template>
<script setup>
import { ref, watch } from 'vue'
import { showToast } from 'vant'
import { getCategoryList, createCategory } from '@/api/transactionCategory'
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
// 当前选中的分类
selectedClassify: {
type: String,
default: ''
},
// 交易类型(用于新增分类时传递)
transactionType: {
type: Number,
default: 0
}
})
const emit = defineEmits(['update:modelValue', 'confirm', 'clear'])
const visible = ref(props.modelValue)
const pickerRef = ref(null)
const classifyColumns = ref([])
const showAddDialog = ref(false)
const newClassifyName = ref('')
// 监听外部显示状态变化
watch(() => props.modelValue, (val) => {
visible.value = val
if (val) {
loadClassifyList()
}
})
// 监听内部显示状态变化
watch(visible, (val) => {
emit('update:modelValue', val)
})
// 加载分类列表
const loadClassifyList = async () => {
try {
const response = await getCategoryList()
if (response.success) {
classifyColumns.value = (response.data || []).map(item => ({
text: item.name,
value: item.name,
id: item.id
}))
}
} catch (error) {
console.error('加载分类列表出错:', error)
}
}
// 确认选择
const onConfirm = ({ selectedOptions }) => {
if (selectedOptions && selectedOptions[0]) {
emit('confirm', selectedOptions[0].text)
}
visible.value = false
}
// 取消
const onCancel = () => {
visible.value = false
}
// 清空分类
const onClear = () => {
emit('clear')
visible.value = false
showToast('已清空分类')
}
// 确认选择(从 picker 中获取选中值)
const confirmSelect = () => {
if (pickerRef.value) {
const selectedValues = pickerRef.value.getSelectedOptions()
if (selectedValues && selectedValues[0]) {
emit('confirm', selectedValues[0].text)
}
}
visible.value = false
}
// 新增分类
const addNewClassify = async () => {
if (!newClassifyName.value.trim()) {
showToast('请输入分类名称')
return
}
try {
const response = await createCategory({
name: newClassifyName.value.trim(),
type: props.transactionType
})
if (response.success) {
showToast('新增分类成功')
const newClassify = response.data.name
newClassifyName.value = ''
// 重新加载分类列表
await loadClassifyList()
// 自动选中新增的分类
emit('confirm', newClassify)
visible.value = false
} else {
showToast(response.message || '新增分类失败')
}
} catch (error) {
console.error('新增分类失败:', error)
showToast('新增分类失败')
}
}
</script>
<style scoped>
.picker-toolbar {
display: flex;
width: 100%;
align-items: center;
padding: 5px 10px;
border-bottom: 1px solid var(--van-border-color);
}
.toolbar-cancel {
margin-right: auto;
}
.toolbar-confirm {
margin-left: auto;
}
</style>