fix
All checks were successful
Docker Build & Deploy / Build Docker Image (push) Successful in 16s
Docker Build & Deploy / Deploy to Production (push) Successful in 6s
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 1s
Docker Build & Deploy / WeChat Notification (push) Successful in 1s

This commit is contained in:
SunCheng
2026-02-20 14:57:19 +08:00
parent 6e95568906
commit 32d5ed62d0
27 changed files with 1520 additions and 1114 deletions

View File

@@ -94,26 +94,41 @@
</div>
<!-- 提示词设置弹窗 -->
<PopupContainer
<PopupContainerV2
v-model:show="showPromptDialog"
title="编辑分析提示词"
show-cancel-button
show-confirm-button
confirm-text="保存"
cancel-text="取消"
@confirm="confirmPrompt"
@cancel="showPromptDialog = false"
:height="'75%'"
>
<van-field
v-model="promptValue"
rows="4"
autosize
type="textarea"
maxlength="2000"
placeholder="输入自定义的分析提示词..."
show-word-limit
/>
</PopupContainer>
<div style="padding: 16px">
<van-field
v-model="promptValue"
rows="4"
autosize
type="textarea"
maxlength="2000"
placeholder="输入自定义的分析提示词..."
show-word-limit
/>
</div>
<template #footer>
<div style="display: flex; gap: 12px">
<van-button
plain
style="flex: 1"
@click="showPromptDialog = false"
>
取消
</van-button>
<van-button
type="primary"
style="flex: 1"
@click="confirmPrompt"
>
保存
</van-button>
</div>
</template>
</PopupContainerV2>
</div>
</template>
@@ -122,7 +137,7 @@ import { ref, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import { showToast, showLoadingToast, closeToast } from 'vant'
import { getConfig, setConfig } from '@/api/config'
import PopupContainer from '@/components/PopupContainer.vue'
import PopupContainerV2 from '@/components/PopupContainerV2.vue'
const router = useRouter()
const userInput = ref('')

View File

@@ -112,64 +112,107 @@
</div>
<!-- 新增分类对话框 -->
<PopupContainer
<PopupContainerV2
v-model:show="showAddDialog"
title="新增分类"
show-cancel-button
show-confirm-button
confirm-text="确认"
cancel-text="取消"
@confirm="handleConfirmAdd"
@cancel="resetAddForm"
:height="'auto'"
>
<van-form ref="addFormRef">
<van-field
v-model="addForm.name"
name="name"
label="分类名称"
placeholder="请输入分类名称"
:rules="[{ required: true, message: '请输入分类名称' }]"
/>
</van-form>
</PopupContainer>
<div style="padding: 16px">
<van-form ref="addFormRef">
<van-field
v-model="addForm.name"
name="name"
label="分类名称"
placeholder="请输入分类名称"
:rules="[{ required: true, message: '请输入分类名称' }]"
/>
</van-form>
</div>
<template #footer>
<div style="display: flex; gap: 12px">
<van-button
plain
style="flex: 1"
@click="resetAddForm"
>
取消
</van-button>
<van-button
type="primary"
style="flex: 1"
@click="handleConfirmAdd"
>
确认
</van-button>
</div>
</template>
</PopupContainerV2>
<!-- 编辑分类对话框 -->
<PopupContainer
<PopupContainerV2
v-model:show="showEditDialog"
title="编辑分类"
show-cancel-button
show-confirm-button
confirm-text="保存"
cancel-text="取消"
@confirm="handleConfirmEdit"
@cancel="showEditDialog = false"
:height="'auto'"
>
<van-form ref="editFormRef">
<van-field
v-model="editForm.name"
name="name"
label="分类名称"
placeholder="请输入分类名称"
:rules="[{ required: true, message: '请输入分类名称' }]"
/>
</van-form>
</PopupContainer>
<div style="padding: 16px">
<van-form ref="editFormRef">
<van-field
v-model="editForm.name"
name="name"
label="分类名称"
placeholder="请输入分类名称"
:rules="[{ required: true, message: '请输入分类名称' }]"
/>
</van-form>
</div>
<template #footer>
<div style="display: flex; gap: 12px">
<van-button
plain
style="flex: 1"
@click="showEditDialog = false"
>
取消
</van-button>
<van-button
type="primary"
style="flex: 1"
@click="handleConfirmEdit"
>
保存
</van-button>
</div>
</template>
</PopupContainerV2>
<!-- 删除确认对话框 -->
<PopupContainer
<PopupContainerV2
v-model:show="showDeleteConfirm"
title="删除分类"
show-cancel-button
show-confirm-button
confirm-text="确定"
cancel-text="取消"
@confirm="handleConfirmDelete"
@cancel="showDeleteConfirm = false"
:height="'auto'"
>
<p style="text-align: center; padding: 20px; color: var(--van-text-color-2)">
删除后无法恢复确定要删除吗
</p>
</PopupContainer>
<template #footer>
<div style="display: flex; gap: 12px">
<van-button
plain
style="flex: 1"
@click="showDeleteConfirm = false"
>
取消
</van-button>
<van-button
type="primary"
style="flex: 1"
@click="handleConfirmDelete"
>
确定
</van-button>
</div>
</template>
</PopupContainerV2>
<!-- 图标选择对话框 -->
<IconSelector
@@ -189,7 +232,7 @@ import { useRouter } from 'vue-router'
import { showSuccessToast, showToast, showLoadingToast, closeToast } from 'vant'
import Icon from '@/components/Icon.vue'
import IconSelector from '@/components/IconSelector.vue'
import PopupContainer from '@/components/PopupContainer.vue'
import PopupContainerV2 from '@/components/PopupContainerV2.vue'
import {
getCategoryList,
createCategory,

View File

@@ -71,12 +71,12 @@
/>
<!-- 记录列表弹窗 -->
<PopupContainer
v-model="showRecordsList"
<PopupContainerV2
v-model:show="showRecordsList"
title="交易记录列表"
height="75%"
:height="'75%'"
>
<div style="background: var(--van-background)">
<div style="background: var(--van-background); padding: 0">
<!-- 批量操作按钮 -->
<div class="batch-actions">
<van-button
@@ -122,7 +122,7 @@
/>
</div>
</div>
</PopupContainer>
</PopupContainerV2>
</div>
</template>
@@ -133,7 +133,7 @@ import { showToast, showConfirmDialog } from 'vant'
import { nlpAnalysis, batchUpdateClassify } from '@/api/transactionRecord'
import BillListComponent from '@/components/Bill/BillListComponent.vue'
import TransactionDetail from '@/components/TransactionDetail.vue'
import PopupContainer from '@/components/PopupContainer.vue'
import PopupContainerV2 from '@/components/PopupContainerV2.vue'
const router = useRouter()
const userInput = ref('')

View File

@@ -73,23 +73,24 @@
</van-pull-refresh>
<!-- 详情弹出层 -->
<PopupContainer
v-model="detailVisible"
<PopupContainerV2
v-model:show="detailVisible"
:title="currentEmail ? currentEmail.Subject || currentEmail.subject || '(无主题)' : ''"
height="75%"
:height="'75%'"
>
<template #header-actions>
<van-button
size="small"
type="primary"
:loading="refreshingAnalysis"
@click="handleRefreshAnalysis"
>
重新分析
</van-button>
</template>
<div v-if="currentEmail">
<!-- 操作按钮栏 -->
<div style="padding: 12px 16px; text-align: right; border-bottom: 1px solid var(--van-border-color)">
<van-button
size="small"
type="primary"
:loading="refreshingAnalysis"
@click="handleRefreshAnalysis"
>
重新分析
</van-button>
</div>
<van-cell-group
inset
style="margin-top: 12px"
@@ -140,13 +141,13 @@
</div>
</div>
</div>
</PopupContainer>
</PopupContainerV2>
<!-- 账单列表弹出层 -->
<PopupContainer
v-model="transactionListVisible"
<PopupContainerV2
v-model:show="transactionListVisible"
title="关联账单列表"
height="75%"
:height="'75%'"
>
<BillListComponent
data-source="custom"
@@ -158,7 +159,7 @@
@click="handleTransactionClick"
@delete="handleTransactionDelete"
/>
</PopupContainer>
</PopupContainerV2>
<!-- 账单详情编辑弹出层 -->
<TransactionDetail
@@ -184,7 +185,7 @@ import {
import { getTransactionDetail } from '@/api/transactionRecord'
import BillListComponent from '@/components/Bill/BillListComponent.vue'
import TransactionDetail from '@/components/TransactionDetail.vue'
import PopupContainer from '@/components/PopupContainer.vue'
import PopupContainerV2 from '@/components/PopupContainerV2.vue'
const emailList = ref([])
const loading = ref(false)

View File

@@ -71,22 +71,27 @@
</van-pull-refresh>
<!-- 详情弹出层 -->
<PopupContainer
v-model="detailVisible"
<PopupContainerV2
v-model:show="detailVisible"
:title="currentMessage.title"
:subtitle="currentMessage.createTime"
height="75%"
:height="'75%'"
>
<div
v-if="currentMessage.messageType === 2"
class="detail-content rich-html-content"
v-html="currentMessage.content"
/>
<div
v-else
class="detail-content"
>
{{ currentMessage.content }}
<div style="padding: 16px">
<p style="color: #999; font-size: 14px; margin-bottom: 12px; margin-top: 0">
{{ currentMessage.createTime }}
</p>
<div
v-if="currentMessage.messageType === 2"
class="rich-html-content"
style="font-size: 14px; line-height: 1.6"
v-html="currentMessage.content"
/>
<div
v-else
style="font-size: 14px; line-height: 1.6; white-space: pre-wrap"
>
{{ currentMessage.content }}
</div>
</div>
<template
v-if="currentMessage.url && currentMessage.messageType === 1"
@@ -101,7 +106,7 @@
查看详情
</van-button>
</template>
</PopupContainer>
</PopupContainerV2>
</div>
</template>
@@ -111,7 +116,7 @@ import { useRouter } from 'vue-router'
import { showToast, showDialog } from 'vant'
import { getMessageList, markAsRead, deleteMessage, markAllAsRead } from '@/api/message'
import { useMessageStore } from '@/stores/message'
import PopupContainer from '@/components/PopupContainer.vue'
import PopupContainerV2 from '@/components/PopupContainerV2.vue'
const messageStore = useMessageStore()
const router = useRouter()
@@ -325,22 +330,6 @@ defineExpose({
height: 100%;
}
.detail-time {
color: var(--van-text-color-2);
font-size: 14px;
}
.detail-content {
padding: 16px;
font-size: 14px;
line-height: 1.6;
color: var(--van-text-color);
}
.detail-content:not(.rich-html-content) {
white-space: pre-wrap;
}
:deep(.van-pull-refresh) {
flex: 1;
overflow-y: auto;

View File

@@ -107,141 +107,143 @@
</div>
<!-- 新增/编辑弹窗 -->
<PopupContainer
v-model="dialogVisible"
<PopupContainerV2
v-model:show="dialogVisible"
:title="isEdit ? '编辑周期账单' : '新增周期账单'"
height="75%"
:height="'75%'"
>
<van-form>
<van-cell-group
inset
title="周期设置"
>
<van-field
v-model="form.periodicTypeText"
is-link
readonly
name="periodicType"
label="周期"
placeholder="请选择周期类型"
:rules="[{ required: true, message: '请选择周期类型' }]"
@click="showPeriodicTypePicker = true"
/>
<!-- 每周配置 -->
<van-field
v-if="form.periodicType === 1"
v-model="form.weekdaysText"
is-link
readonly
name="weekdays"
label="星期"
placeholder="请选择星期几"
:rules="[{ required: true, message: '请选择星期几' }]"
@click="showWeekdaysPicker = true"
/>
<!-- 每月配置 -->
<van-field
v-if="form.periodicType === 2"
v-model="form.monthDaysText"
is-link
readonly
name="monthDays"
label="日期"
placeholder="请选择每月的日期"
:rules="[{ required: true, message: '请选择日期' }]"
@click="showMonthDaysPicker = true"
/>
<!-- 每季度配置 -->
<van-field
v-if="form.periodicType === 3"
v-model="form.quarterDay"
name="quarterDay"
label="季度第几天"
placeholder="请输入季度开始后第几天"
type="number"
:rules="[{ required: true, message: '请输入季度开始后第几天' }]"
/>
<!-- 每年配置 -->
<van-field
v-if="form.periodicType === 4"
v-model="form.yearDay"
name="yearDay"
label="年第几天"
placeholder="请输入年开始后第几天"
type="number"
:rules="[{ required: true, message: '请输入年开始后第几天' }]"
/>
</van-cell-group>
<van-cell-group
inset
title="基本信息"
>
<van-field
v-model="form.reason"
name="reason"
label="摘要"
placeholder="请输入交易摘要"
type="textarea"
rows="2"
autosize
maxlength="200"
show-word-limit
/>
<van-field
v-model="form.amount"
name="amount"
label="金额"
placeholder="请输入金额"
type="number"
:rules="[{ required: true, message: '请输入金额' }]"
/>
<van-field
v-model="form.type"
name="type"
label="类型"
<div style="padding: 0">
<van-form>
<van-cell-group
inset
title="周期设置"
>
<template #input>
<van-radio-group
v-model="form.type"
direction="horizontal"
>
<van-radio :value="0">
支出
</van-radio>
<van-radio :value="1">
收入
</van-radio>
<van-radio :value="2">
不计
</van-radio>
</van-radio-group>
</template>
</van-field>
<van-field
name="classify"
label="分类"
>
<template #input>
<span
v-if="!form.classify"
style="color: var(--van-gray-5)"
>请选择交易分类</span>
<span v-else>{{ form.classify }}</span>
</template>
</van-field>
<van-field
v-model="form.periodicTypeText"
is-link
readonly
name="periodicType"
label="周期"
placeholder="请选择周期类型"
:rules="[{ required: true, message: '请选择周期类型' }]"
@click="showPeriodicTypePicker = true"
/>
<!-- 分类选择组件 -->
<ClassifySelector
v-model="form.classify"
:type="form.type"
/>
</van-cell-group>
</van-form>
<!-- 每周配置 -->
<van-field
v-if="form.periodicType === 1"
v-model="form.weekdaysText"
is-link
readonly
name="weekdays"
label="星期"
placeholder="请选择星期几"
:rules="[{ required: true, message: '请选择星期几' }]"
@click="showWeekdaysPicker = true"
/>
<!-- 每月配置 -->
<van-field
v-if="form.periodicType === 2"
v-model="form.monthDaysText"
is-link
readonly
name="monthDays"
label="日期"
placeholder="请选择每月的日期"
:rules="[{ required: true, message: '请选择日期' }]"
@click="showMonthDaysPicker = true"
/>
<!-- 每季度配置 -->
<van-field
v-if="form.periodicType === 3"
v-model="form.quarterDay"
name="quarterDay"
label="季度第几天"
placeholder="请输入季度开始后第几天"
type="number"
:rules="[{ required: true, message: '请输入季度开始后第几天' }]"
/>
<!-- 每年配置 -->
<van-field
v-if="form.periodicType === 4"
v-model="form.yearDay"
name="yearDay"
label="年第几天"
placeholder="请输入年开始后第几天"
type="number"
:rules="[{ required: true, message: '请输入年开始后第几天' }]"
/>
</van-cell-group>
<van-cell-group
inset
title="基本信息"
>
<van-field
v-model="form.reason"
name="reason"
label="摘要"
placeholder="请输入交易摘要"
type="textarea"
rows="2"
autosize
maxlength="200"
show-word-limit
/>
<van-field
v-model="form.amount"
name="amount"
label="金额"
placeholder="请输入金额"
type="number"
:rules="[{ required: true, message: '请输入金额' }]"
/>
<van-field
v-model="form.type"
name="type"
label="类型"
>
<template #input>
<van-radio-group
v-model="form.type"
direction="horizontal"
>
<van-radio :value="0">
支出
</van-radio>
<van-radio :value="1">
收入
</van-radio>
<van-radio :value="2">
不计
</van-radio>
</van-radio-group>
</template>
</van-field>
<van-field
name="classify"
label="分类"
>
<template #input>
<span
v-if="!form.classify"
style="color: var(--van-gray-5)"
>请选择交易分类</span>
<span v-else>{{ form.classify }}</span>
</template>
</van-field>
<!-- 分类选择组件 -->
<ClassifySelector
v-model="form.classify"
:type="form.type"
/>
</van-cell-group>
</van-form>
</div>
<template #footer>
<van-button
round
@@ -253,7 +255,7 @@
{{ isEdit ? '更新' : '确认添加' }}
</van-button>
</template>
</PopupContainer>
</PopupContainerV2>
<!-- 周期类型选择器 -->
<van-popup
@@ -310,7 +312,7 @@ import {
createPeriodic,
updatePeriodic
} from '@/api/transactionPeriodic'
import PopupContainer from '@/components/PopupContainer.vue'
import PopupContainerV2 from '@/components/PopupContainerV2.vue'
import ClassifySelector from '@/components/ClassifySelector.vue'
import dayjs from 'dayjs'

View File

@@ -151,183 +151,43 @@
<!-- 储蓄配置弹窗 -->
<SavingsConfigPopup
ref="savingsConfigRef"
@success="loadBudgetData"
@change="loadBudgetData"
/>
<!-- 预算明细列表弹窗 -->
<PopupContainer
v-model="showListPopup"
:title="popupTitle"
height="80%"
>
<template #header-actions>
<van-icon
name="plus"
size="20"
title="添加预算"
@click="budgetEditRef.open({ category: activeTab })"
/>
</template>
<van-pull-refresh
v-model="refreshing"
style="min-height: 100%"
@refresh="onRefresh"
>
<div class="budget-list">
<!-- 支出列表 -->
<template v-if="activeTab === BudgetCategory.Expense && expenseBudgets?.length > 0">
<van-swipe-cell
v-for="budget in expenseBudgets"
:key="budget.id"
>
<BudgetCard
:budget="budget"
:progress-color="getProgressColor(budget)"
:percent-class="{ warning: budget.current / budget.limit > 0.8 }"
:period-label="getPeriodLabel(budget.type)"
@click="handleEdit(budget)"
>
<template #amount-info>
<div class="info-item">
<div class="label">
已支出
</div>
<div class="value expense">
¥{{ formatMoney(budget.current) }}
</div>
</div>
<div class="info-item">
<div class="label">
预算
</div>
<div class="value">
¥{{ formatMoney(budget.limit) }}
</div>
</div>
<div class="info-item">
<div class="label">
余额
</div>
<div
class="value"
:class="budget.limit - budget.current >= 0 ? 'income' : 'expense'"
>
¥{{ formatMoney(budget.limit - budget.current) }}
</div>
</div>
</template>
</BudgetCard>
<template #right>
<van-button
square
text="删除"
type="danger"
class="delete-button"
@click="handleDelete(budget)"
/>
</template>
</van-swipe-cell>
</template>
<!-- 收入列表 -->
<template v-if="activeTab === BudgetCategory.Income && incomeBudgets?.length > 0">
<van-swipe-cell
v-for="budget in incomeBudgets"
:key="budget.id"
>
<BudgetCard
:budget="budget"
:progress-color="getProgressColor(budget)"
:percent-class="{ income: budget.current / budget.limit >= 1 }"
:period-label="getPeriodLabel(budget.type)"
@click="handleEdit(budget)"
>
<template #amount-info>
<div class="info-item">
<div class="label">
已收入
</div>
<div class="value income">
¥{{ formatMoney(budget.current) }}
</div>
</div>
<div class="info-item">
<div class="label">
目标
</div>
<div class="value">
¥{{ formatMoney(budget.limit) }}
</div>
</div>
<div class="info-item">
<div class="label">
差额
</div>
<div
class="value"
:class="budget.current >= budget.limit ? 'income' : 'expense'"
>
¥{{ formatMoney(Math.abs(budget.limit - budget.current)) }}
</div>
</div>
</template>
</BudgetCard>
<template #right>
<van-button
square
text="删除"
type="danger"
class="delete-button"
@click="handleDelete(budget)"
/>
</template>
</van-swipe-cell>
</template>
<!-- 空状态 -->
<van-empty
v-if="
activeTab !== BudgetCategory.Savings &&
!loading &&
!hasError &&
((activeTab === BudgetCategory.Expense && expenseBudgets?.length === 0) ||
(activeTab === BudgetCategory.Income && incomeBudgets?.length === 0))
"
:description="`暂无${activeTab === BudgetCategory.Expense ? '支出' : '收入'}预算`"
/>
</div>
<div style="height: calc(95px + env(safe-area-inset-bottom, 0px))" />
</van-pull-refresh>
</PopupContainer>
<!-- 未覆盖分类弹窗 -->
<PopupContainer
v-model="showUncoveredDetails"
<PopupContainerV2
v-model:show="showUncoveredDetails"
title="未覆盖预算的分类"
:subtitle="`本月共 <b style='color:var(--van-primary-color)'>${uncoveredCategories.length}</b> 个分类未设置预算`"
height="60%"
:height="'60%'"
>
<div class="uncovered-list">
<div style="padding: 0">
<!-- subtitle 作为内容区域顶部 -->
<div
v-for="item in uncoveredCategories"
:key="item.category"
class="uncovered-item"
>
<div class="item-left">
<div class="category-name">
{{ item.category }}
style="padding: 12px 16px; text-align: center; color: #999; font-size: 14px; border-bottom: 1px solid var(--van-border-color)"
v-html="`本月共 <b style='color:var(--van-primary-color)'>${uncoveredCategories.length}</b> 个分类未设置预算`"
/>
<div class="uncovered-list">
<div
v-for="item in uncoveredCategories"
:key="item.category"
class="uncovered-item"
>
<div class="item-left">
<div class="category-name">
{{ item.category }}
</div>
<div class="transaction-count">
{{ item.transactionCount }} 笔记录
</div>
</div>
<div class="transaction-count">
{{ item.transactionCount }} 笔记录
</div>
</div>
<div class="item-right">
<div
class="item-amount"
:class="activeTab === BudgetCategory.Expense ? 'expense' : 'income'"
>
¥{{ formatMoney(item.totalAmount) }}
<div class="item-right">
<div
class="item-amount"
:class="activeTab === BudgetCategory.Expense ? 'expense' : 'income'"
>
¥{{ formatMoney(item.totalAmount) }}
</div>
</div>
</div>
</div>
@@ -343,25 +203,31 @@
我知道了
</van-button>
</template>
</PopupContainer>
</PopupContainerV2>
<!-- 归档总结弹窗 -->
<PopupContainer
v-model="showSummaryPopup"
<PopupContainerV2
v-model:show="showSummaryPopup"
title="月份归档总结"
:subtitle="`${selectedDate.getFullYear()}年${selectedDate.getMonth() + 1}月`"
height="70%"
:height="'70%'"
>
<div style="padding: 16px">
<div
class="rich-html-content"
v-html="
archiveSummary ||
'<p style=\'text-align:center;color:var(--van-text-color-3)\'>暂无总结</p>'
"
/>
<div style="padding: 0">
<!-- subtitle -->
<div style="padding: 12px 16px; text-align: center; color: #999; font-size: 14px; border-bottom: 1px solid var(--van-border-color)">
{{ selectedDate.getFullYear() }}年{{ selectedDate.getMonth() + 1 }}月
</div>
<div style="padding: 16px">
<div
class="rich-html-content"
v-html="
archiveSummary ||
'<p style=\'text-align:center;color:var(--van-text-color-3)\'>暂无总结</p>'
"
/>
</div>
</div>
</PopupContainer>
</PopupContainerV2>
<!-- 日期选择器 -->
<van-popup
@@ -401,7 +267,7 @@ import BudgetTypeTabs from '@/components/BudgetTypeTabs.vue'
import BudgetCard from '@/components/Budget/BudgetCard.vue'
import BudgetEditPopup from '@/components/Budget/BudgetEditPopup.vue'
import SavingsConfigPopup from '@/components/Budget/SavingsConfigPopup.vue'
import PopupContainer from '@/components/PopupContainer.vue'
import PopupContainerV2 from '@/components/PopupContainerV2.vue'
import ExpenseBudgetContent from './modules/ExpenseBudgetContent.vue'
import IncomeBudgetContent from './modules/IncomeBudgetContent.vue'
import SavingsBudgetContent from './modules/SavingsBudgetContent.vue'

View File

@@ -71,10 +71,10 @@
</div>
<!-- 计划存款明细弹窗 -->
<PopupContainer
v-model="showDetailPopup"
<PopupContainerV2
v-model:show="showDetailPopup"
title="计划存款明细"
height="80%"
:height="'80%'"
>
<div class="popup-body">
<div
@@ -169,14 +169,14 @@
</div>
</div>
</div>
</PopupContainer>
</PopupContainerV2>
</template>
<script setup>
import { ref, computed } from 'vue'
import BudgetCard from '@/components/Budget/BudgetCard.vue'
import { BudgetPeriodType } from '@/constants/enums'
import PopupContainer from '@/components/PopupContainer.vue'
import PopupContainerV2 from '@/components/PopupContainerV2.vue'
// Props
const props = defineProps({