This commit is contained in:
SunCheng
2026-02-15 10:10:28 +08:00
parent e51a3edd50
commit a88556c784
92 changed files with 6751 additions and 776 deletions

View File

@@ -1,4 +1,4 @@
<template>
<template>
<div class="page-container-flex">
<van-nav-bar
:title="navTitle"
@@ -111,9 +111,13 @@
</div>
<!-- 新增分类对话框 -->
<van-dialog
<PopupContainer
v-model:show="showAddDialog"
title="新增分类"
show-cancel-button
show-confirm-button
confirm-text="确认"
cancel-text="取消"
@confirm="handleConfirmAdd"
@cancel="resetAddForm"
>
@@ -126,14 +130,18 @@
:rules="[{ required: true, message: '请输入分类名称' }]"
/>
</van-form>
</van-dialog>
</PopupContainer>
<!-- 编辑分类对话框 -->
<van-dialog
<PopupContainer
v-model:show="showEditDialog"
title="编辑分类"
show-cancel-button
show-confirm-button
confirm-text="保存"
cancel-text="取消"
@confirm="handleConfirmEdit"
@cancel="showEditDialog = false"
>
<van-form ref="editFormRef">
<van-field
@@ -144,22 +152,45 @@
:rules="[{ required: true, message: '请输入分类名称' }]"
/>
</van-form>
</van-dialog>
</PopupContainer>
<!-- 删除确认对话框 -->
<van-dialog
<PopupContainer
v-model:show="showDeleteConfirm"
title="删除分类"
message="删除后无法恢复,确定要删除吗?"
show-confirm-button
show-cancel-button
confirm-text="确定"
cancel-text="取消"
@confirm="handleConfirmDelete"
/>
@cancel="showDeleteConfirm = false"
>
<p style="text-align: center; padding: 20px; color: var(--van-text-color-2)">
删除后无法恢复确定要删除吗
</p>
</PopupContainer>
<!-- 删除图标确认对话框 -->
<PopupContainer
v-model:show="showDeleteIconConfirm"
title="删除图标"
show-confirm-button
show-cancel-button
confirm-text="确定"
cancel-text="取消"
@confirm="handleConfirmDeleteIcon"
@cancel="showDeleteIconConfirm = false"
>
<p style="text-align: center; padding: 20px; color: var(--van-text-color-2)">
确定要删除图标吗
</p>
</PopupContainer>
<!-- 图标选择对话框 -->
<van-dialog
<PopupContainer
v-model:show="showIconDialog"
title="选择图标"
show-cancel-button
@confirm="handleConfirmIconSelect"
:closeable="false"
>
<div class="icon-selector">
<div
@@ -185,7 +216,8 @@
>
<van-empty description="暂无图标" />
</div>
</div>
<template #footer>
<div class="icon-actions">
<van-button
type="primary"
@@ -196,9 +228,28 @@
>
{{ isGeneratingIcon ? 'AI生成中...' : '生成新图标' }}
</van-button>
<van-button
v-if="currentCategory && currentCategory.icon"
type="danger"
size="small"
plain
:disabled="isDeletingIcon"
style="margin-left: 20px;"
@click="handleDeleteIcon"
>
{{ isDeletingIcon ? '删除中...' : '删除图标' }}
</van-button>
<van-button
size="small"
plain
style="margin-left: 10px;"
@click="showIconDialog = false"
>
关闭
</van-button>
</div>
</div>
</van-dialog>
</template>
</PopupContainer>
</div>
</div>
</template>
@@ -213,8 +264,10 @@ import {
deleteCategory,
updateCategory,
generateIcon,
updateSelectedIcon
updateSelectedIcon,
deleteCategoryIcon
} from '@/api/transactionCategory'
import PopupContainer from '@/components/PopupContainer.vue'
const router = useRouter()
@@ -261,6 +314,10 @@ const currentCategory = ref(null) // 当前正在编辑图标的分类
const selectedIconIndex = ref(0)
const isGeneratingIcon = ref(false)
// 删除图标确认对话框
const showDeleteIconConfirm = ref(false)
const isDeletingIcon = ref(false)
// 计算导航栏标题
const navTitle = computed(() => {
if (currentLevel.value === 0) {
@@ -437,7 +494,9 @@ const handleGenerateIcon = async () => {
* 确认选择图标
*/
const handleConfirmIconSelect = async () => {
if (!currentCategory.value) {return}
if (!currentCategory.value) {
return
}
try {
showLoadingToast({
@@ -466,6 +525,51 @@ const handleConfirmIconSelect = async () => {
}
}
/**
* 删除图标
*/
const handleDeleteIcon = () => {
if (!currentCategory.value || !currentCategory.value.icon) {
return
}
showDeleteIconConfirm.value = true
}
/**
* 确认删除图标
*/
const handleConfirmDeleteIcon = async () => {
if (!currentCategory.value) {
return
}
try {
isDeletingIcon.value = true
showLoadingToast({
message: '删除中...',
forbidClick: true,
duration: 0
})
const { success, message } = await deleteCategoryIcon(currentCategory.value.id)
if (success) {
showSuccessToast('图标删除成功')
showDeleteIconConfirm.value = false
showIconDialog.value = false
await loadCategories()
} else {
showToast(message || '删除失败')
}
} catch (error) {
console.error('删除图标失败:', error)
showToast('删除图标失败: ' + (error.message || '未知错误'))
} finally {
isDeletingIcon.value = false
closeToast()
}
}
/**
* 编辑分类
*/
@@ -564,7 +668,9 @@ const resetAddForm = () => {
* 解析图标数组(第一个图标为当前选中的)
*/
const parseIcon = (iconJson) => {
if (!iconJson) {return ''}
if (!iconJson) {
return ''
}
try {
const icons = JSON.parse(iconJson)
return Array.isArray(icons) && icons.length > 0 ? icons[0] : ''
@@ -577,7 +683,9 @@ const parseIcon = (iconJson) => {
* 解析图标数组为完整数组
*/
const parseIconArray = (iconJson) => {
if (!iconJson) {return []}
if (!iconJson) {
return []
}
try {
const icons = JSON.parse(iconJson)
return Array.isArray(icons) ? icons : []
@@ -679,12 +787,14 @@ onMounted(() => {
}
.icon-actions {
padding-top: 16px;
border-top: 1px solid var(--van-border-color);
display: flex;
justify-content: center;
gap: 8px;
padding: 8px 0;
}
/* PopupContainer 的 footer 已有边框,所以这里不需要重复 */
/* 深色模式 */
/* @media (prefers-color-scheme: dark) {
.level-container {