feat: 优化预算统计逻辑,支持跨周期统计并修复相关计算问题
All checks were successful
Docker Build & Deploy / Build Docker Image (push) Successful in 16s
Docker Build & Deploy / Deploy to Production (push) Successful in 10s
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 1s
Docker Build & Deploy / WeChat Notification (push) Successful in 2s
All checks were successful
Docker Build & Deploy / Build Docker Image (push) Successful in 16s
Docker Build & Deploy / Deploy to Production (push) Successful in 10s
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 1s
Docker Build & Deploy / WeChat Notification (push) Successful in 2s
This commit is contained in:
@@ -202,29 +202,57 @@ const activeTabTitle = computed(() => {
|
||||
})
|
||||
|
||||
const overallStats = computed(() => {
|
||||
const allBudgets = [...expenseBudgets.value, ...incomeBudgets.value, ...savingsBudgets.value]
|
||||
const allBudgetsList = [...expenseBudgets.value, ...incomeBudgets.value, ...savingsBudgets.value]
|
||||
|
||||
const getStatsForType = (type) => {
|
||||
const getStats = (statType) => {
|
||||
const category = activeTab.value
|
||||
const filtered = allBudgets.filter(b => b.type === type && b.category === category && !b.isStopped)
|
||||
// 获取当前 tab 类别下所有未停止的预算
|
||||
const relevant = allBudgetsList.filter(b => b.category === category && !b.isStopped)
|
||||
|
||||
if (filtered.length === 0) return { rate: '0.0', current: 0, limit: 0, count: 0 }
|
||||
if (relevant.length === 0) return { rate: '0.0', current: 0, limit: 0, count: 0 }
|
||||
|
||||
const current = filtered.reduce((sum, b) => sum + (b.current || 0), 0)
|
||||
const limit = filtered.reduce((sum, b) => sum + (b.limit || 0), 0)
|
||||
const rate = limit > 0 ? (current / limit) * 100 : 0
|
||||
let totalC = 0
|
||||
let totalL = 0
|
||||
|
||||
relevant.forEach(b => {
|
||||
// 限额折算
|
||||
let itemLimit = b.limit || 0
|
||||
if (statType === BudgetPeriodType.Month && b.type === BudgetPeriodType.Year) {
|
||||
itemLimit = b.limit / 12
|
||||
} else if (statType === BudgetPeriodType.Year && b.type === BudgetPeriodType.Month) {
|
||||
itemLimit = b.limit * 12
|
||||
}
|
||||
totalL += itemLimit
|
||||
|
||||
// 当前值累加
|
||||
// 注意:由于前端 items 只有当前周期的 current,如果是跨周期统计,这里只能视为一种“参考”或“当前进度”
|
||||
if (b.type === statType) {
|
||||
totalC += (b.current || 0)
|
||||
} else {
|
||||
// 如果周期不匹配(例如在年度统计中统计月度预算),
|
||||
// 只有在当前是 1 月的情况下,月度支出才等同于年度累计。
|
||||
// 为保持统计的严谨性,这里仅在类型匹配时计入 Current,或者根据业务需求进行估计。
|
||||
// 但为了解决用户反馈的“统计不对”,我们需要把所有的匹配项都算进来。
|
||||
if (statType === BudgetPeriodType.Year) {
|
||||
// 在年度视图下,月度预算我们也计入它当前的 current(作为它对年度目前的贡献)
|
||||
totalC += (b.current || 0)
|
||||
}
|
||||
// 月度视图下,年度预算的 current 无法直接折算,此处暂不计入支出。
|
||||
}
|
||||
})
|
||||
|
||||
const rate = totalL > 0 ? (totalC / totalL) * 100 : 0
|
||||
return {
|
||||
rate: rate.toFixed(1),
|
||||
current,
|
||||
limit,
|
||||
count: filtered.length
|
||||
current: totalC,
|
||||
limit: totalL,
|
||||
count: relevant.length
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
month: getStatsForType(BudgetPeriodType.Month),
|
||||
year: getStatsForType(BudgetPeriodType.Year)
|
||||
month: getStats(BudgetPeriodType.Month),
|
||||
year: getStats(BudgetPeriodType.Year)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user